Working registration
This commit is contained in:
parent
a79a4166bd
commit
57ab820693
|
@ -1,4 +1,4 @@
|
||||||
ADMIN_API_KEY=changeMe
|
ADMIN_API_KEY=changeMe
|
||||||
AUTH_API_URL=http://auth-api:4000
|
API_URL=http://auth-api:4000
|
||||||
JWT_SHARED_SECRET=changeMe
|
JWT_SHARED_SECRET=changeMe
|
||||||
PORT=4001
|
PORT=4001
|
1
go.mod
1
go.mod
|
@ -10,6 +10,7 @@ require (
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/andybalholm/brotli v1.0.4 // indirect
|
github.com/andybalholm/brotli v1.0.4 // indirect
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||||
github.com/klauspost/compress v1.14.3 // indirect
|
github.com/klauspost/compress v1.14.3 // indirect
|
||||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||||
github.com/valyala/fasthttp v1.33.0 // indirect
|
github.com/valyala/fasthttp v1.33.0 // indirect
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -135,6 +135,8 @@ github.com/gofiber/template v1.6.23 h1:rxIzrukkFrRiC22Z/WRwuySU2z09m932/RkVMAuwc
|
||||||
github.com/gofiber/template v1.6.23/go.mod h1:OpKYcUcfli731QNdeN8Y/EkIdKIzN6zenwOj2JrL/pg=
|
github.com/gofiber/template v1.6.23/go.mod h1:OpKYcUcfli731QNdeN8Y/EkIdKIzN6zenwOj2JrL/pg=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
||||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||||
|
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||||
|
|
162
src/api/api.go
Normal file
162
src/api/api.go
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Method must be a valid REST method, like GET, POST, PUT, DELETE etc
|
||||||
|
func (api Api) Call(method string, path string, jsonPayload []byte) (ApiRes, error) {
|
||||||
|
respObj := ApiRes{}
|
||||||
|
|
||||||
|
adminToken, _, err := api.getAdminToken()
|
||||||
|
if err != nil {
|
||||||
|
return ApiRes{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest(method, api.URL+path, bytes.NewBuffer(jsonPayload))
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not create request", "method", method, "err", err.Error())
|
||||||
|
return ApiRes{}, err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
req.Header.Set("Authorization", "bearer "+adminToken)
|
||||||
|
|
||||||
|
httpClient := &http.Client{}
|
||||||
|
res, err := httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not call backend API", "err", err.Error())
|
||||||
|
return ApiRes{}, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
api.Log.Debug("API res status", "status", res.StatusCode)
|
||||||
|
respObj.StatusCode = res.StatusCode
|
||||||
|
|
||||||
|
if strconv.Itoa(res.StatusCode)[0:1] == "5" {
|
||||||
|
api.Log.Error("API gave internal server error", "statusCode", res.StatusCode)
|
||||||
|
return ApiRes{}, errors.New("API gave internal server error")
|
||||||
|
} else if res.StatusCode == 403 {
|
||||||
|
api.Log.Error("API responded with 403, Forbidden")
|
||||||
|
return ApiRes{}, errors.New("API responded with 403, Forbidden")
|
||||||
|
} else if res.StatusCode == 401 {
|
||||||
|
api.Log.Error("API responded with 401, Unauthorized")
|
||||||
|
return ApiRes{}, errors.New("API responded with 403, Unauthorized")
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not read res body", "err", err.Error())
|
||||||
|
return ApiRes{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
respObj.Body = body
|
||||||
|
|
||||||
|
return respObj, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api Api) getAdminToken() (string, AdminClaims, error) {
|
||||||
|
if api.AdminToken == "" {
|
||||||
|
// No adminToken exists, obtain it
|
||||||
|
|
||||||
|
adminToken, err := api.getAdminTokenCall()
|
||||||
|
api.AdminToken = adminToken
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not get admin token")
|
||||||
|
return "", AdminClaims{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedToken, err := api.parseAdminToken(api.AdminToken)
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not parse admin token")
|
||||||
|
return "", AdminClaims{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.AdminToken, parsedToken, err
|
||||||
|
}
|
||||||
|
|
||||||
|
parsedToken, err := api.parseAdminToken(api.AdminToken)
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not parse admin token")
|
||||||
|
return "", AdminClaims{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return api.AdminToken, parsedToken, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api Api) getAdminTokenCall() (string, error) {
|
||||||
|
req, err := http.NewRequest("POST", api.URL+"/auth/api-key", bytes.NewBufferString("\""+api.AdminApiKey+"\""))
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not create request", "err", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
httpClient := &http.Client{}
|
||||||
|
res, err := httpClient.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not call backend API", "err", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
api.Log.Debug("API res status", "status", res.StatusCode)
|
||||||
|
|
||||||
|
if strconv.Itoa(res.StatusCode)[0:1] == "5" {
|
||||||
|
api.Log.Error("API gave internal server error", "statusCode", res.StatusCode)
|
||||||
|
return "", errors.New("API gave internal server error")
|
||||||
|
} else if res.StatusCode != 200 {
|
||||||
|
api.Log.Error("API gave unexpected statusCode", "statusCode", res.StatusCode)
|
||||||
|
return "", errors.New("API gave unexpected statusCode")
|
||||||
|
}
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(res.Body)
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not read res body", "err", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
var jsonResp TokenRes
|
||||||
|
|
||||||
|
err = json.Unmarshal(body, &jsonResp)
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not parse JSON from API", "err", err.Error())
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return jsonResp.Jwt, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (api Api) parseAdminToken(token string) (AdminClaims, error) {
|
||||||
|
claims := &AdminClaims{}
|
||||||
|
parsedToken, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte(api.JwtSharedSecret), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
api.Log.Error("Could not parse admin token", "err", err.Error())
|
||||||
|
return AdminClaims{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if !parsedToken.Valid {
|
||||||
|
err := errors.New("invalid token")
|
||||||
|
api.Log.Error("Invalid token")
|
||||||
|
return AdminClaims{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
claims, ok := parsedToken.Claims.(*AdminClaims)
|
||||||
|
if !ok {
|
||||||
|
err := errors.New("parsedToken.Claims.(*AdminClaims) did not return ok")
|
||||||
|
api.Log.Error(err.Error())
|
||||||
|
return AdminClaims{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *claims, nil
|
||||||
|
}
|
36
src/api/types.go
Normal file
36
src/api/types.go
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/golang-jwt/jwt"
|
||||||
|
"go.uber.org/zap"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Api struct {
|
||||||
|
AdminApiKey string
|
||||||
|
AdminToken string
|
||||||
|
JwtSharedSecret string
|
||||||
|
Log *zap.SugaredLogger
|
||||||
|
URL string
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiRes struct {
|
||||||
|
Body []byte
|
||||||
|
StatusCode int
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiResError struct {
|
||||||
|
Error string `json:"error"`
|
||||||
|
Field string `json:"field"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type TokenRes struct {
|
||||||
|
Jwt string `json:"jwt"`
|
||||||
|
RenewalToken string `json:"renewalToken"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AdminClaims struct {
|
||||||
|
AccountID string `json:"accountId"`
|
||||||
|
AccountFields map[string][]string `json:"accountFields"`
|
||||||
|
AccountName string `json:"accountName"`
|
||||||
|
jwt.StandardClaims
|
||||||
|
}
|
|
@ -1,26 +1,25 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"strconv"
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
|
|
||||||
|
"gitlab.larvit.se/power-plan/auth-ui/src/api"
|
||||||
"gitlab.larvit.se/power-plan/auth-ui/src/views"
|
"gitlab.larvit.se/power-plan/auth-ui/src/views"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h Handlers) Register(c *fiber.Ctx) error {
|
func (h Handlers) Register(c *fiber.Ctx) error {
|
||||||
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
c.Set(fiber.HeaderContentType, fiber.MIMETextHTML)
|
||||||
return c.SendString(views.Register())
|
return c.SendString(views.Register(views.RegisterData{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
type NewUser struct {
|
type NewUser struct {
|
||||||
Username string
|
Name string `json:"name"`
|
||||||
Password string
|
Username string `json:"username"`
|
||||||
RepeatPassword string
|
Password string `json:"password"`
|
||||||
|
RepeatPassword string `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h Handlers) RegisterPost(c *fiber.Ctx) error {
|
func (h Handlers) RegisterPost(c *fiber.Ctx) error {
|
||||||
|
@ -32,8 +31,7 @@ func (h Handlers) RegisterPost(c *fiber.Ctx) error {
|
||||||
h.Log.Debug("Invalid input data", "err", err.Error())
|
h.Log.Debug("Invalid input data", "err", err.Error())
|
||||||
c.Status(400)
|
c.Status(400)
|
||||||
}
|
}
|
||||||
|
newUser.Name = newUser.Username
|
||||||
fmt.Printf("newUser: %v", newUser)
|
|
||||||
|
|
||||||
jsonPayload, err := json.Marshal(newUser)
|
jsonPayload, err := json.Marshal(newUser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -41,30 +39,33 @@ func (h Handlers) RegisterPost(c *fiber.Ctx) error {
|
||||||
return c.Status(500).SendString(views.Error500())
|
return c.Status(500).SendString(views.Error500())
|
||||||
}
|
}
|
||||||
|
|
||||||
req, err := http.NewRequest("POST", "http://localhost:4000/account", bytes.NewBuffer(jsonPayload))
|
apiRes, err := h.Api.Call("POST", "/account", jsonPayload)
|
||||||
if err != nil {
|
|
||||||
h.Log.Error("Could not create POST request", "err", err.Error())
|
|
||||||
return c.Status(500).SendString(views.Error500())
|
|
||||||
}
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
|
||||||
|
|
||||||
httpClient := &http.Client{}
|
|
||||||
res, err := httpClient.Do(req)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
h.Log.Error("Could not call backend API", "err", err.Error())
|
h.Log.Error("Could not call backend API", "err", err.Error())
|
||||||
return c.Status(500).SendString(views.Error500())
|
return c.Status(500).SendString(views.Error500())
|
||||||
}
|
}
|
||||||
defer res.Body.Close()
|
|
||||||
|
|
||||||
h.Log.Debug("API res status", "status", res.Status)
|
h.Log.Debug("API res status", "status", apiRes.StatusCode)
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(res.Body)
|
if apiRes.StatusCode == 201 {
|
||||||
if err != nil {
|
return c.SendString(views.Register(views.RegisterData{
|
||||||
h.Log.Error("Could not read res body", "err", err.Error())
|
OkMsg: "New user created!",
|
||||||
|
}))
|
||||||
|
} else if strconv.Itoa(apiRes.StatusCode)[0:1] == "4" {
|
||||||
|
var jsonResp []api.ApiResError
|
||||||
|
|
||||||
|
err := json.Unmarshal(apiRes.Body, &jsonResp)
|
||||||
|
if err != nil {
|
||||||
|
h.Log.Error("Could not unmarshal api error response", "err", err.Error())
|
||||||
|
return c.Status(500).SendString(views.Error500())
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.Status(apiRes.StatusCode).SendString(views.Register(views.RegisterData{
|
||||||
|
ErrField: jsonResp[0].Field,
|
||||||
|
ErrMsg: jsonResp[0].Error,
|
||||||
|
}))
|
||||||
|
} else {
|
||||||
|
h.Log.Error("Unexpected API response status", "status", apiRes.StatusCode)
|
||||||
return c.Status(500).SendString(views.Error500())
|
return c.Status(500).SendString(views.Error500())
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("response Body:", string(body))
|
|
||||||
|
|
||||||
return c.SendString(views.Register())
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,12 @@ package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// jwt "github.com/dgrijalva/jwt-go"
|
// jwt "github.com/dgrijalva/jwt-go"
|
||||||
|
"gitlab.larvit.se/power-plan/auth-ui/src/api"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handlers is the overall struct for all http request handlers
|
// Handlers is the overall struct for all http request handlers
|
||||||
type Handlers struct {
|
type Handlers struct {
|
||||||
JwtKey []byte
|
Api api.Api
|
||||||
Log *zap.SugaredLogger
|
Log *zap.SugaredLogger
|
||||||
}
|
}
|
||||||
|
|
17
src/main.go
17
src/main.go
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"github.com/joho/godotenv"
|
"github.com/joho/godotenv"
|
||||||
|
"gitlab.larvit.se/power-plan/auth-ui/src/api"
|
||||||
h "gitlab.larvit.se/power-plan/auth-ui/src/handlers"
|
h "gitlab.larvit.se/power-plan/auth-ui/src/handlers"
|
||||||
"gitlab.larvit.se/power-plan/auth-ui/src/utils"
|
"gitlab.larvit.se/power-plan/auth-ui/src/utils"
|
||||||
)
|
)
|
||||||
|
@ -24,11 +25,23 @@ func main() {
|
||||||
if os.Getenv("ADMIN_API_KEY") == "changeMe" {
|
if os.Getenv("ADMIN_API_KEY") == "changeMe" {
|
||||||
log.Error("ADMIN_API_KEY ENV is not set, using very insecure \"changeMe\"")
|
log.Error("ADMIN_API_KEY ENV is not set, using very insecure \"changeMe\"")
|
||||||
}
|
}
|
||||||
jwtKey := []byte(os.Getenv("JWT_SHARED_SECRET"))
|
jwtSharedSecret := os.Getenv("JWT_SHARED_SECRET")
|
||||||
|
adminApiKey := os.Getenv("ADMIN_API_KEY")
|
||||||
|
apiUrl := os.Getenv("API_URL")
|
||||||
|
|
||||||
app := fiber.New()
|
app := fiber.New()
|
||||||
|
|
||||||
handlers := h.Handlers{JwtKey: jwtKey, Log: log}
|
apiInstance := api.Api{
|
||||||
|
AdminApiKey: adminApiKey,
|
||||||
|
JwtSharedSecret: jwtSharedSecret,
|
||||||
|
Log: log,
|
||||||
|
URL: apiUrl,
|
||||||
|
}
|
||||||
|
|
||||||
|
handlers := h.Handlers{
|
||||||
|
Api: apiInstance,
|
||||||
|
Log: log,
|
||||||
|
}
|
||||||
|
|
||||||
// Log all requests
|
// Log all requests
|
||||||
app.Use(handlers.LogReq)
|
app.Use(handlers.LogReq)
|
||||||
|
|
12
src/view-utils/vutils.go
Normal file
12
src/view-utils/vutils.go
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
package vu // View Utils
|
||||||
|
|
||||||
|
// Replacement for ternary. Use like:
|
||||||
|
// str := "Foo " + Tern(len("") != 0, "bar", "baz") + " yes" // Evaluates to: "Foo baz yes"
|
||||||
|
// str := "Foo " + Tern(true, "bar", "baz") + " yes" // Evaluates to: "Foo bar yes"
|
||||||
|
func TernStr(exp bool, expTrue string, expFalse string) string {
|
||||||
|
if exp {
|
||||||
|
return expTrue
|
||||||
|
} else {
|
||||||
|
return expFalse
|
||||||
|
}
|
||||||
|
}
|
25
src/view-utils/vutils_test.go
Normal file
25
src/view-utils/vutils_test.go
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
package vu
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestTern(t *testing.T) {
|
||||||
|
test1 := "a" + TernStr(1 == 2, "b", "c") + "d"
|
||||||
|
if test1 != "acd" {
|
||||||
|
t.Fatalf("Expected \"acd\" but got %v", test1)
|
||||||
|
}
|
||||||
|
|
||||||
|
test2 := "a" + TernStr(1 == 1, "b", "c") + "d"
|
||||||
|
if test2 != "abd" {
|
||||||
|
t.Fatalf("Expected \"abd\" but got %v", test1)
|
||||||
|
}
|
||||||
|
|
||||||
|
test3 := "a" + TernStr(false, "b", "c") + "d"
|
||||||
|
if test3 != "acd" {
|
||||||
|
t.Fatalf("Expected \"acd\" but got %v", test1)
|
||||||
|
}
|
||||||
|
|
||||||
|
test4 := "a" + TernStr(true, "b", "c") + "d"
|
||||||
|
if test4 != "abd" {
|
||||||
|
t.Fatalf("Expected \"abd\" but got %v", test1)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,11 +1,21 @@
|
||||||
package views
|
package views
|
||||||
|
|
||||||
import "gitlab.larvit.se/power-plan/auth-ui/src/views/layouts"
|
import (
|
||||||
|
vu "gitlab.larvit.se/power-plan/auth-ui/src/view-utils"
|
||||||
|
"gitlab.larvit.se/power-plan/auth-ui/src/views/layouts"
|
||||||
|
)
|
||||||
|
|
||||||
func Register() string {
|
type RegisterData struct {
|
||||||
|
ErrField string
|
||||||
|
ErrMsg string
|
||||||
|
OkMsg string
|
||||||
|
}
|
||||||
|
|
||||||
|
func Register(data RegisterData) string {
|
||||||
content := `
|
content := `
|
||||||
<h1 class="main-title">Register</h1>
|
<h1 class="main-title">Register</h1>
|
||||||
<form method="post" class="pure-form pure-form-aligned primary-form">
|
<form method="post" class="pure-form pure-form-aligned primary-form">
|
||||||
|
` + vu.TernStr(len(data.OkMsg) != 0, "<p>"+data.OkMsg+" <a href=\"/\">Login</a></p>", "") + `
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="pure-control-group">
|
<div class="pure-control-group">
|
||||||
<label for="username">Username</label>
|
<label for="username">Username</label>
|
||||||
|
@ -21,7 +31,7 @@ func Register() string {
|
||||||
<label for="repeatPassword">Repeat password</label>
|
<label for="repeatPassword">Repeat password</label>
|
||||||
<input type="password" placeholder="Repeat password" name="repeatPassword" id="repeatPassword" />
|
<input type="password" placeholder="Repeat password" name="repeatPassword" id="repeatPassword" />
|
||||||
</div>
|
</div>
|
||||||
|
` + vu.TernStr(len(data.ErrMsg) != 0, "<p>ERROR! "+data.ErrMsg+"<p>", "") + `
|
||||||
<div class="pure-controls">
|
<div class="pure-controls">
|
||||||
<a href="/" class="pure-button">Cancel</a>
|
<a href="/" class="pure-button">Cancel</a>
|
||||||
<button type="submit" class="pure-button pure-button-primary">Register</button>
|
<button type="submit" class="pure-button pure-button-primary">Register</button>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user