folder structure refactor volgens doc
This commit is contained in:
parent
c2f4ae10e8
commit
7e8788f7f8
2
.gitignore
vendored
2
.gitignore
vendored
@ -1 +1 @@
|
|||||||
/.env
|
/api/.env
|
||||||
|
|||||||
1
.idea/vcs.xml
generated
1
.idea/vcs.xml
generated
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="VcsDirectoryMappings">
|
<component name="VcsDirectoryMappings">
|
||||||
|
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||||
<mapping directory="$PROJECT_DIR$/../portfolio-backend" vcs="Git" />
|
<mapping directory="$PROJECT_DIR$/../portfolio-backend" vcs="Git" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
||||||
@ -4,7 +4,7 @@ FROM golang:latest
|
|||||||
# Set the working directory to /app
|
# Set the working directory to /app
|
||||||
WORKDIR .
|
WORKDIR .
|
||||||
# Copy the current directory contents into the container at /app
|
# Copy the current directory contents into the container at /app
|
||||||
COPY . .
|
COPY .. .
|
||||||
|
|
||||||
# Download and install any required dependencies
|
# Download and install any required dependencies
|
||||||
RUN go mod download
|
RUN go mod download
|
||||||
@ -11,4 +11,5 @@ func ApiRoutes(mux **http.ServeMux) {
|
|||||||
m.HandleFunc("/api/", handler.CatchAllHandler)
|
m.HandleFunc("/api/", handler.CatchAllHandler)
|
||||||
m.HandleFunc("POST /api/user", handler.CreateUser)
|
m.HandleFunc("POST /api/user", handler.CreateUser)
|
||||||
m.HandleFunc("GET /api/user/{id}", handler.GetUser)
|
m.HandleFunc("GET /api/user/{id}", handler.GetUser)
|
||||||
|
m.HandleFunc("POST /api/login", handler.Login)
|
||||||
}
|
}
|
||||||
51
api/api/handler/authHandler.go
Normal file
51
api/api/handler/authHandler.go
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
package handler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"portfolio/database/ent"
|
||||||
|
"portfolio/database/ent/user"
|
||||||
|
"portfolio/database/query"
|
||||||
|
"portfolio/service/bcrypt"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Login(w http.ResponseWriter, r *http.Request) {
|
||||||
|
fmt.Println("test")
|
||||||
|
var u *ent.User
|
||||||
|
|
||||||
|
isHtmx := r.Header.Get("HX-Request")
|
||||||
|
|
||||||
|
if isHtmx == "true" {
|
||||||
|
u = &ent.User{
|
||||||
|
Name: r.PostFormValue("name"),
|
||||||
|
Password: r.PostFormValue("password"),
|
||||||
|
Role: user.Role(r.PostFormValue("role")),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
err := json.NewDecoder(r.Body).Decode(&u)
|
||||||
|
if err != nil {
|
||||||
|
InternalServerErrorHandler(w)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
User, err := query.GetLogin(context.Background(), u.Name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if bcrypt.CheckPasswordHash(u.Password, User.Password) {
|
||||||
|
w.Header().Set("HX-Location", "/")
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
err = json.NewEncoder(w).Encode(User)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
24
api/api/webHandler/loginpageHandler.go
Normal file
24
api/api/webHandler/loginpageHandler.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package webHandler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func InitLoginpage(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
tmpl := template.Must(template.ParseFiles(
|
||||||
|
"./templates/login/index.html",
|
||||||
|
"./templates/navbar/index.html",
|
||||||
|
"./templates/themeSelector/index.html",
|
||||||
|
))
|
||||||
|
|
||||||
|
err := tmpl.Execute(w, nil)
|
||||||
|
if err != nil {
|
||||||
|
_, err := w.Write([]byte("failed to load"))
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -11,6 +11,7 @@ func WebRoutes(mux **http.ServeMux) {
|
|||||||
m.HandleFunc("GET /{$}", webHandler.InitHomepage)
|
m.HandleFunc("GET /{$}", webHandler.InitHomepage)
|
||||||
m.HandleFunc("GET /projecten/{$}", webHandler.InitProjectpage)
|
m.HandleFunc("GET /projecten/{$}", webHandler.InitProjectpage)
|
||||||
m.HandleFunc("GET /about/{$}", webHandler.InitAboutpage)
|
m.HandleFunc("GET /about/{$}", webHandler.InitAboutpage)
|
||||||
|
m.HandleFunc("GET /login/{$}", webHandler.InitLoginpage)
|
||||||
|
|
||||||
m.HandleFunc("POST /theme", webHandler.UpdateTheme)
|
m.HandleFunc("POST /theme", webHandler.UpdateTheme)
|
||||||
|
|
||||||
@ -42,7 +42,8 @@ var (
|
|||||||
// UsersColumns holds the columns for the "users" table.
|
// UsersColumns holds the columns for the "users" table.
|
||||||
UsersColumns = []*schema.Column{
|
UsersColumns = []*schema.Column{
|
||||||
{Name: "id", Type: field.TypeInt, Increment: true},
|
{Name: "id", Type: field.TypeInt, Increment: true},
|
||||||
{Name: "name", Type: field.TypeString, Default: "John doe"},
|
{Name: "name", Type: field.TypeString, Unique: true},
|
||||||
|
{Name: "password", Type: field.TypeString},
|
||||||
{Name: "role", Type: field.TypeEnum, Enums: []string{"admin", "user", "visitor"}},
|
{Name: "role", Type: field.TypeEnum, Enums: []string{"admin", "user", "visitor"}},
|
||||||
}
|
}
|
||||||
// UsersTable holds the schema information for the "users" table.
|
// UsersTable holds the schema information for the "users" table.
|
||||||
@ -932,6 +932,7 @@ type UserMutation struct {
|
|||||||
typ string
|
typ string
|
||||||
id *int
|
id *int
|
||||||
name *string
|
name *string
|
||||||
|
password *string
|
||||||
role *user.Role
|
role *user.Role
|
||||||
clearedFields map[string]struct{}
|
clearedFields map[string]struct{}
|
||||||
teams map[int]struct{}
|
teams map[int]struct{}
|
||||||
@ -1076,6 +1077,42 @@ func (m *UserMutation) ResetName() {
|
|||||||
m.name = nil
|
m.name = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPassword sets the "password" field.
|
||||||
|
func (m *UserMutation) SetPassword(s string) {
|
||||||
|
m.password = &s
|
||||||
|
}
|
||||||
|
|
||||||
|
// Password returns the value of the "password" field in the mutation.
|
||||||
|
func (m *UserMutation) Password() (r string, exists bool) {
|
||||||
|
v := m.password
|
||||||
|
if v == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return *v, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// OldPassword returns the old "password" field's value of the User entity.
|
||||||
|
// If the User object wasn't provided to the builder, the object is fetched from the database.
|
||||||
|
// An error is returned if the mutation operation is not UpdateOne, or the database query fails.
|
||||||
|
func (m *UserMutation) OldPassword(ctx context.Context) (v string, err error) {
|
||||||
|
if !m.op.Is(OpUpdateOne) {
|
||||||
|
return v, errors.New("OldPassword is only allowed on UpdateOne operations")
|
||||||
|
}
|
||||||
|
if m.id == nil || m.oldValue == nil {
|
||||||
|
return v, errors.New("OldPassword requires an ID field in the mutation")
|
||||||
|
}
|
||||||
|
oldValue, err := m.oldValue(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return v, fmt.Errorf("querying old value for OldPassword: %w", err)
|
||||||
|
}
|
||||||
|
return oldValue.Password, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetPassword resets all changes to the "password" field.
|
||||||
|
func (m *UserMutation) ResetPassword() {
|
||||||
|
m.password = nil
|
||||||
|
}
|
||||||
|
|
||||||
// SetRole sets the "role" field.
|
// SetRole sets the "role" field.
|
||||||
func (m *UserMutation) SetRole(u user.Role) {
|
func (m *UserMutation) SetRole(u user.Role) {
|
||||||
m.role = &u
|
m.role = &u
|
||||||
@ -1200,10 +1237,13 @@ func (m *UserMutation) Type() string {
|
|||||||
// order to get all numeric fields that were incremented/decremented, call
|
// order to get all numeric fields that were incremented/decremented, call
|
||||||
// AddedFields().
|
// AddedFields().
|
||||||
func (m *UserMutation) Fields() []string {
|
func (m *UserMutation) Fields() []string {
|
||||||
fields := make([]string, 0, 2)
|
fields := make([]string, 0, 3)
|
||||||
if m.name != nil {
|
if m.name != nil {
|
||||||
fields = append(fields, user.FieldName)
|
fields = append(fields, user.FieldName)
|
||||||
}
|
}
|
||||||
|
if m.password != nil {
|
||||||
|
fields = append(fields, user.FieldPassword)
|
||||||
|
}
|
||||||
if m.role != nil {
|
if m.role != nil {
|
||||||
fields = append(fields, user.FieldRole)
|
fields = append(fields, user.FieldRole)
|
||||||
}
|
}
|
||||||
@ -1217,6 +1257,8 @@ func (m *UserMutation) Field(name string) (ent.Value, bool) {
|
|||||||
switch name {
|
switch name {
|
||||||
case user.FieldName:
|
case user.FieldName:
|
||||||
return m.Name()
|
return m.Name()
|
||||||
|
case user.FieldPassword:
|
||||||
|
return m.Password()
|
||||||
case user.FieldRole:
|
case user.FieldRole:
|
||||||
return m.Role()
|
return m.Role()
|
||||||
}
|
}
|
||||||
@ -1230,6 +1272,8 @@ func (m *UserMutation) OldField(ctx context.Context, name string) (ent.Value, er
|
|||||||
switch name {
|
switch name {
|
||||||
case user.FieldName:
|
case user.FieldName:
|
||||||
return m.OldName(ctx)
|
return m.OldName(ctx)
|
||||||
|
case user.FieldPassword:
|
||||||
|
return m.OldPassword(ctx)
|
||||||
case user.FieldRole:
|
case user.FieldRole:
|
||||||
return m.OldRole(ctx)
|
return m.OldRole(ctx)
|
||||||
}
|
}
|
||||||
@ -1248,6 +1292,13 @@ func (m *UserMutation) SetField(name string, value ent.Value) error {
|
|||||||
}
|
}
|
||||||
m.SetName(v)
|
m.SetName(v)
|
||||||
return nil
|
return nil
|
||||||
|
case user.FieldPassword:
|
||||||
|
v, ok := value.(string)
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field %s", value, name)
|
||||||
|
}
|
||||||
|
m.SetPassword(v)
|
||||||
|
return nil
|
||||||
case user.FieldRole:
|
case user.FieldRole:
|
||||||
v, ok := value.(user.Role)
|
v, ok := value.(user.Role)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -1307,6 +1358,9 @@ func (m *UserMutation) ResetField(name string) error {
|
|||||||
case user.FieldName:
|
case user.FieldName:
|
||||||
m.ResetName()
|
m.ResetName()
|
||||||
return nil
|
return nil
|
||||||
|
case user.FieldPassword:
|
||||||
|
m.ResetPassword()
|
||||||
|
return nil
|
||||||
case user.FieldRole:
|
case user.FieldRole:
|
||||||
m.ResetRole()
|
m.ResetRole()
|
||||||
return nil
|
return nil
|
||||||
9
api/database/ent/runtime.go
Normal file
9
api/database/ent/runtime.go
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// Code generated by ent, DO NOT EDIT.
|
||||||
|
|
||||||
|
package ent
|
||||||
|
|
||||||
|
// The init function reads all schema descriptors with runtime code
|
||||||
|
// (default values, validators, hooks and policies) and stitches it
|
||||||
|
// to their package variables.
|
||||||
|
func init() {
|
||||||
|
}
|
||||||
@ -15,7 +15,8 @@ type User struct {
|
|||||||
func (User) Fields() []ent.Field {
|
func (User) Fields() []ent.Field {
|
||||||
return []ent.Field{
|
return []ent.Field{
|
||||||
field.String("name").
|
field.String("name").
|
||||||
Default("John doe"),
|
Unique(),
|
||||||
|
field.String("password"),
|
||||||
field.Enum("role").
|
field.Enum("role").
|
||||||
Values("admin", "user", "visitor"),
|
Values("admin", "user", "visitor"),
|
||||||
}
|
}
|
||||||
@ -18,6 +18,8 @@ type User struct {
|
|||||||
ID int `json:"id,omitempty"`
|
ID int `json:"id,omitempty"`
|
||||||
// Name holds the value of the "name" field.
|
// Name holds the value of the "name" field.
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
|
// Password holds the value of the "password" field.
|
||||||
|
Password string `json:"password,omitempty"`
|
||||||
// Role holds the value of the "role" field.
|
// Role holds the value of the "role" field.
|
||||||
Role user.Role `json:"role,omitempty"`
|
Role user.Role `json:"role,omitempty"`
|
||||||
// Edges holds the relations/edges for other nodes in the graph.
|
// Edges holds the relations/edges for other nodes in the graph.
|
||||||
@ -51,7 +53,7 @@ func (*User) scanValues(columns []string) ([]any, error) {
|
|||||||
switch columns[i] {
|
switch columns[i] {
|
||||||
case user.FieldID:
|
case user.FieldID:
|
||||||
values[i] = new(sql.NullInt64)
|
values[i] = new(sql.NullInt64)
|
||||||
case user.FieldName, user.FieldRole:
|
case user.FieldName, user.FieldPassword, user.FieldRole:
|
||||||
values[i] = new(sql.NullString)
|
values[i] = new(sql.NullString)
|
||||||
default:
|
default:
|
||||||
values[i] = new(sql.UnknownType)
|
values[i] = new(sql.UnknownType)
|
||||||
@ -80,6 +82,12 @@ func (u *User) assignValues(columns []string, values []any) error {
|
|||||||
} else if value.Valid {
|
} else if value.Valid {
|
||||||
u.Name = value.String
|
u.Name = value.String
|
||||||
}
|
}
|
||||||
|
case user.FieldPassword:
|
||||||
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
|
return fmt.Errorf("unexpected type %T for field password", values[i])
|
||||||
|
} else if value.Valid {
|
||||||
|
u.Password = value.String
|
||||||
|
}
|
||||||
case user.FieldRole:
|
case user.FieldRole:
|
||||||
if value, ok := values[i].(*sql.NullString); !ok {
|
if value, ok := values[i].(*sql.NullString); !ok {
|
||||||
return fmt.Errorf("unexpected type %T for field role", values[i])
|
return fmt.Errorf("unexpected type %T for field role", values[i])
|
||||||
@ -130,6 +138,9 @@ func (u *User) String() string {
|
|||||||
builder.WriteString("name=")
|
builder.WriteString("name=")
|
||||||
builder.WriteString(u.Name)
|
builder.WriteString(u.Name)
|
||||||
builder.WriteString(", ")
|
builder.WriteString(", ")
|
||||||
|
builder.WriteString("password=")
|
||||||
|
builder.WriteString(u.Password)
|
||||||
|
builder.WriteString(", ")
|
||||||
builder.WriteString("role=")
|
builder.WriteString("role=")
|
||||||
builder.WriteString(fmt.Sprintf("%v", u.Role))
|
builder.WriteString(fmt.Sprintf("%v", u.Role))
|
||||||
builder.WriteByte(')')
|
builder.WriteByte(')')
|
||||||
@ -16,6 +16,8 @@ const (
|
|||||||
FieldID = "id"
|
FieldID = "id"
|
||||||
// FieldName holds the string denoting the name field in the database.
|
// FieldName holds the string denoting the name field in the database.
|
||||||
FieldName = "name"
|
FieldName = "name"
|
||||||
|
// FieldPassword holds the string denoting the password field in the database.
|
||||||
|
FieldPassword = "password"
|
||||||
// FieldRole holds the string denoting the role field in the database.
|
// FieldRole holds the string denoting the role field in the database.
|
||||||
FieldRole = "role"
|
FieldRole = "role"
|
||||||
// EdgeTeams holds the string denoting the teams edge name in mutations.
|
// EdgeTeams holds the string denoting the teams edge name in mutations.
|
||||||
@ -33,6 +35,7 @@ const (
|
|||||||
var Columns = []string{
|
var Columns = []string{
|
||||||
FieldID,
|
FieldID,
|
||||||
FieldName,
|
FieldName,
|
||||||
|
FieldPassword,
|
||||||
FieldRole,
|
FieldRole,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,11 +55,6 @@ func ValidColumn(column string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
|
||||||
// DefaultName holds the default value on creation for the "name" field.
|
|
||||||
DefaultName string
|
|
||||||
)
|
|
||||||
|
|
||||||
// Role defines the type for the "role" enum field.
|
// Role defines the type for the "role" enum field.
|
||||||
type Role string
|
type Role string
|
||||||
|
|
||||||
@ -94,6 +92,11 @@ func ByName(opts ...sql.OrderTermOption) OrderOption {
|
|||||||
return sql.OrderByField(FieldName, opts...).ToFunc()
|
return sql.OrderByField(FieldName, opts...).ToFunc()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ByPassword orders the results by the password field.
|
||||||
|
func ByPassword(opts ...sql.OrderTermOption) OrderOption {
|
||||||
|
return sql.OrderByField(FieldPassword, opts...).ToFunc()
|
||||||
|
}
|
||||||
|
|
||||||
// ByRole orders the results by the role field.
|
// ByRole orders the results by the role field.
|
||||||
func ByRole(opts ...sql.OrderTermOption) OrderOption {
|
func ByRole(opts ...sql.OrderTermOption) OrderOption {
|
||||||
return sql.OrderByField(FieldRole, opts...).ToFunc()
|
return sql.OrderByField(FieldRole, opts...).ToFunc()
|
||||||
@ -59,6 +59,11 @@ func Name(v string) predicate.User {
|
|||||||
return predicate.User(sql.FieldEQ(FieldName, v))
|
return predicate.User(sql.FieldEQ(FieldName, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Password applies equality check predicate on the "password" field. It's identical to PasswordEQ.
|
||||||
|
func Password(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEQ(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
// NameEQ applies the EQ predicate on the "name" field.
|
// NameEQ applies the EQ predicate on the "name" field.
|
||||||
func NameEQ(v string) predicate.User {
|
func NameEQ(v string) predicate.User {
|
||||||
return predicate.User(sql.FieldEQ(FieldName, v))
|
return predicate.User(sql.FieldEQ(FieldName, v))
|
||||||
@ -124,6 +129,71 @@ func NameContainsFold(v string) predicate.User {
|
|||||||
return predicate.User(sql.FieldContainsFold(FieldName, v))
|
return predicate.User(sql.FieldContainsFold(FieldName, v))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PasswordEQ applies the EQ predicate on the "password" field.
|
||||||
|
func PasswordEQ(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEQ(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordNEQ applies the NEQ predicate on the "password" field.
|
||||||
|
func PasswordNEQ(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldNEQ(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordIn applies the In predicate on the "password" field.
|
||||||
|
func PasswordIn(vs ...string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldIn(FieldPassword, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordNotIn applies the NotIn predicate on the "password" field.
|
||||||
|
func PasswordNotIn(vs ...string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldNotIn(FieldPassword, vs...))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordGT applies the GT predicate on the "password" field.
|
||||||
|
func PasswordGT(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldGT(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordGTE applies the GTE predicate on the "password" field.
|
||||||
|
func PasswordGTE(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldGTE(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordLT applies the LT predicate on the "password" field.
|
||||||
|
func PasswordLT(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldLT(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordLTE applies the LTE predicate on the "password" field.
|
||||||
|
func PasswordLTE(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldLTE(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordContains applies the Contains predicate on the "password" field.
|
||||||
|
func PasswordContains(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldContains(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordHasPrefix applies the HasPrefix predicate on the "password" field.
|
||||||
|
func PasswordHasPrefix(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldHasPrefix(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordHasSuffix applies the HasSuffix predicate on the "password" field.
|
||||||
|
func PasswordHasSuffix(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldHasSuffix(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordEqualFold applies the EqualFold predicate on the "password" field.
|
||||||
|
func PasswordEqualFold(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldEqualFold(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
// PasswordContainsFold applies the ContainsFold predicate on the "password" field.
|
||||||
|
func PasswordContainsFold(v string) predicate.User {
|
||||||
|
return predicate.User(sql.FieldContainsFold(FieldPassword, v))
|
||||||
|
}
|
||||||
|
|
||||||
// RoleEQ applies the EQ predicate on the "role" field.
|
// RoleEQ applies the EQ predicate on the "role" field.
|
||||||
func RoleEQ(v Role) predicate.User {
|
func RoleEQ(v Role) predicate.User {
|
||||||
return predicate.User(sql.FieldEQ(FieldRole, v))
|
return predicate.User(sql.FieldEQ(FieldRole, v))
|
||||||
@ -26,11 +26,9 @@ func (uc *UserCreate) SetName(s string) *UserCreate {
|
|||||||
return uc
|
return uc
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetNillableName sets the "name" field if the given value is not nil.
|
// SetPassword sets the "password" field.
|
||||||
func (uc *UserCreate) SetNillableName(s *string) *UserCreate {
|
func (uc *UserCreate) SetPassword(s string) *UserCreate {
|
||||||
if s != nil {
|
uc.mutation.SetPassword(s)
|
||||||
uc.SetName(*s)
|
|
||||||
}
|
|
||||||
return uc
|
return uc
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +60,6 @@ func (uc *UserCreate) Mutation() *UserMutation {
|
|||||||
|
|
||||||
// Save creates the User in the database.
|
// Save creates the User in the database.
|
||||||
func (uc *UserCreate) Save(ctx context.Context) (*User, error) {
|
func (uc *UserCreate) Save(ctx context.Context) (*User, error) {
|
||||||
uc.defaults()
|
|
||||||
return withHooks(ctx, uc.sqlSave, uc.mutation, uc.hooks)
|
return withHooks(ctx, uc.sqlSave, uc.mutation, uc.hooks)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,19 +85,14 @@ func (uc *UserCreate) ExecX(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaults sets the default values of the builder before save.
|
|
||||||
func (uc *UserCreate) defaults() {
|
|
||||||
if _, ok := uc.mutation.Name(); !ok {
|
|
||||||
v := user.DefaultName
|
|
||||||
uc.mutation.SetName(v)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check runs all checks and user-defined validators on the builder.
|
// check runs all checks and user-defined validators on the builder.
|
||||||
func (uc *UserCreate) check() error {
|
func (uc *UserCreate) check() error {
|
||||||
if _, ok := uc.mutation.Name(); !ok {
|
if _, ok := uc.mutation.Name(); !ok {
|
||||||
return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "User.name"`)}
|
return &ValidationError{Name: "name", err: errors.New(`ent: missing required field "User.name"`)}
|
||||||
}
|
}
|
||||||
|
if _, ok := uc.mutation.Password(); !ok {
|
||||||
|
return &ValidationError{Name: "password", err: errors.New(`ent: missing required field "User.password"`)}
|
||||||
|
}
|
||||||
if _, ok := uc.mutation.Role(); !ok {
|
if _, ok := uc.mutation.Role(); !ok {
|
||||||
return &ValidationError{Name: "role", err: errors.New(`ent: missing required field "User.role"`)}
|
return &ValidationError{Name: "role", err: errors.New(`ent: missing required field "User.role"`)}
|
||||||
}
|
}
|
||||||
@ -139,6 +131,10 @@ func (uc *UserCreate) createSpec() (*User, *sqlgraph.CreateSpec) {
|
|||||||
_spec.SetField(user.FieldName, field.TypeString, value)
|
_spec.SetField(user.FieldName, field.TypeString, value)
|
||||||
_node.Name = value
|
_node.Name = value
|
||||||
}
|
}
|
||||||
|
if value, ok := uc.mutation.Password(); ok {
|
||||||
|
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||||
|
_node.Password = value
|
||||||
|
}
|
||||||
if value, ok := uc.mutation.Role(); ok {
|
if value, ok := uc.mutation.Role(); ok {
|
||||||
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
||||||
_node.Role = value
|
_node.Role = value
|
||||||
@ -180,7 +176,6 @@ func (ucb *UserCreateBulk) Save(ctx context.Context) ([]*User, error) {
|
|||||||
for i := range ucb.builders {
|
for i := range ucb.builders {
|
||||||
func(i int, root context.Context) {
|
func(i int, root context.Context) {
|
||||||
builder := ucb.builders[i]
|
builder := ucb.builders[i]
|
||||||
builder.defaults()
|
|
||||||
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
var mut Mutator = MutateFunc(func(ctx context.Context, m Mutation) (Value, error) {
|
||||||
mutation, ok := m.(*UserMutation)
|
mutation, ok := m.(*UserMutation)
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -42,6 +42,20 @@ func (uu *UserUpdate) SetNillableName(s *string) *UserUpdate {
|
|||||||
return uu
|
return uu
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPassword sets the "password" field.
|
||||||
|
func (uu *UserUpdate) SetPassword(s string) *UserUpdate {
|
||||||
|
uu.mutation.SetPassword(s)
|
||||||
|
return uu
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePassword sets the "password" field if the given value is not nil.
|
||||||
|
func (uu *UserUpdate) SetNillablePassword(s *string) *UserUpdate {
|
||||||
|
if s != nil {
|
||||||
|
uu.SetPassword(*s)
|
||||||
|
}
|
||||||
|
return uu
|
||||||
|
}
|
||||||
|
|
||||||
// SetRole sets the "role" field.
|
// SetRole sets the "role" field.
|
||||||
func (uu *UserUpdate) SetRole(u user.Role) *UserUpdate {
|
func (uu *UserUpdate) SetRole(u user.Role) *UserUpdate {
|
||||||
uu.mutation.SetRole(u)
|
uu.mutation.SetRole(u)
|
||||||
@ -149,6 +163,9 @@ func (uu *UserUpdate) sqlSave(ctx context.Context) (n int, err error) {
|
|||||||
if value, ok := uu.mutation.Name(); ok {
|
if value, ok := uu.mutation.Name(); ok {
|
||||||
_spec.SetField(user.FieldName, field.TypeString, value)
|
_spec.SetField(user.FieldName, field.TypeString, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := uu.mutation.Password(); ok {
|
||||||
|
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||||
|
}
|
||||||
if value, ok := uu.mutation.Role(); ok {
|
if value, ok := uu.mutation.Role(); ok {
|
||||||
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
||||||
}
|
}
|
||||||
@ -231,6 +248,20 @@ func (uuo *UserUpdateOne) SetNillableName(s *string) *UserUpdateOne {
|
|||||||
return uuo
|
return uuo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetPassword sets the "password" field.
|
||||||
|
func (uuo *UserUpdateOne) SetPassword(s string) *UserUpdateOne {
|
||||||
|
uuo.mutation.SetPassword(s)
|
||||||
|
return uuo
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetNillablePassword sets the "password" field if the given value is not nil.
|
||||||
|
func (uuo *UserUpdateOne) SetNillablePassword(s *string) *UserUpdateOne {
|
||||||
|
if s != nil {
|
||||||
|
uuo.SetPassword(*s)
|
||||||
|
}
|
||||||
|
return uuo
|
||||||
|
}
|
||||||
|
|
||||||
// SetRole sets the "role" field.
|
// SetRole sets the "role" field.
|
||||||
func (uuo *UserUpdateOne) SetRole(u user.Role) *UserUpdateOne {
|
func (uuo *UserUpdateOne) SetRole(u user.Role) *UserUpdateOne {
|
||||||
uuo.mutation.SetRole(u)
|
uuo.mutation.SetRole(u)
|
||||||
@ -368,6 +399,9 @@ func (uuo *UserUpdateOne) sqlSave(ctx context.Context) (_node *User, err error)
|
|||||||
if value, ok := uuo.mutation.Name(); ok {
|
if value, ok := uuo.mutation.Name(); ok {
|
||||||
_spec.SetField(user.FieldName, field.TypeString, value)
|
_spec.SetField(user.FieldName, field.TypeString, value)
|
||||||
}
|
}
|
||||||
|
if value, ok := uuo.mutation.Password(); ok {
|
||||||
|
_spec.SetField(user.FieldPassword, field.TypeString, value)
|
||||||
|
}
|
||||||
if value, ok := uuo.mutation.Role(); ok {
|
if value, ok := uuo.mutation.Role(); ok {
|
||||||
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
_spec.SetField(user.FieldRole, field.TypeEnum, value)
|
||||||
}
|
}
|
||||||
23
api/database/query/authQuery.go
Normal file
23
api/database/query/authQuery.go
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"portfolio/database"
|
||||||
|
"portfolio/database/ent"
|
||||||
|
"portfolio/database/ent/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetLogin(ctx context.Context, name string) (*ent.User, error) {
|
||||||
|
|
||||||
|
u, err := database.Client.User.
|
||||||
|
Query().
|
||||||
|
Where(user.Name(name)).
|
||||||
|
Only(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed querying user: %w", err)
|
||||||
|
}
|
||||||
|
log.Println("user returned: ", u)
|
||||||
|
return u, nil
|
||||||
|
}
|
||||||
@ -19,6 +19,7 @@ require (
|
|||||||
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
|
github.com/hashicorp/hcl/v2 v2.19.1 // indirect
|
||||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||||
github.com/zclconf/go-cty v1.14.2 // indirect
|
github.com/zclconf/go-cty v1.14.2 // indirect
|
||||||
|
golang.org/x/crypto v0.21.0 // indirect
|
||||||
golang.org/x/mod v0.15.0 // indirect
|
golang.org/x/mod v0.15.0 // indirect
|
||||||
golang.org/x/text v0.14.0 // indirect
|
golang.org/x/text v0.14.0 // indirect
|
||||||
)
|
)
|
||||||
@ -58,6 +58,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
|
|||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/zclconf/go-cty v1.14.2 h1:kTG7lqmBou0Zkx35r6HJHUQTvaRPr5bIAf3AoHS0izI=
|
github.com/zclconf/go-cty v1.14.2 h1:kTG7lqmBou0Zkx35r6HJHUQTvaRPr5bIAf3AoHS0izI=
|
||||||
github.com/zclconf/go-cty v1.14.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
github.com/zclconf/go-cty v1.14.2/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||||
|
golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
|
||||||
|
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||||
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
golang.org/x/mod v0.15.0 h1:SernR4v+D55NyBH2QiEQrlBAnj1ECL6AGrA5+dPaMY8=
|
||||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||||
@ -15,7 +15,7 @@ func main() {
|
|||||||
log.Fatalf(".env not found: %v", err)
|
log.Fatalf(".env not found: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
print("test")
|
||||||
// Create a new request multiplexer
|
// Create a new request multiplexer
|
||||||
// Take incoming requests and dispatch them to the matching webHandler
|
// Take incoming requests and dispatch them to the matching webHandler
|
||||||
mux := http.NewServeMux()
|
mux := http.NewServeMux()
|
||||||
15
api/service/bcrypt/password.go
Normal file
15
api/service/bcrypt/password.go
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
package bcrypt
|
||||||
|
|
||||||
|
import "golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
func HashPassword(password string) (string, error) {
|
||||||
|
//generate hash from password
|
||||||
|
bytes, err := bcrypt.GenerateFromPassword([]byte(password), 14)
|
||||||
|
return string(bytes), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckPasswordHash(password, hash string) bool {
|
||||||
|
//check password with hash
|
||||||
|
err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password))
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 1.5 MiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 1007 B After Width: | Height: | Size: 1007 B |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
157
api/templates/login/index.html
Normal file
157
api/templates/login/index.html
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" data-bs-theme="auto">
|
||||||
|
<head><script src="../assets/js/color-modes.js"></script>
|
||||||
|
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="Mark Otto, Jacob Thornton, and Bootstrap contributors">
|
||||||
|
<meta name="generator" content="Hugo 0.122.0">
|
||||||
|
<title>Signin Template · Bootstrap v5.3</title>
|
||||||
|
|
||||||
|
<link rel="canonical" href="https://getbootstrap.com/docs/5.3/examples/sign-in/">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@docsearch/css@3">
|
||||||
|
|
||||||
|
<link href="../assets/dist/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.bd-placeholder-img {
|
||||||
|
font-size: 1.125rem;
|
||||||
|
text-anchor: middle;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.bd-placeholder-img-lg {
|
||||||
|
font-size: 3.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-divider {
|
||||||
|
width: 100%;
|
||||||
|
height: 3rem;
|
||||||
|
background-color: rgba(0, 0, 0, .1);
|
||||||
|
border: solid rgba(0, 0, 0, .15);
|
||||||
|
border-width: 1px 0;
|
||||||
|
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.b-example-vr {
|
||||||
|
flex-shrink: 0;
|
||||||
|
width: 1.5rem;
|
||||||
|
height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bi {
|
||||||
|
vertical-align: -.125em;
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller {
|
||||||
|
position: relative;
|
||||||
|
z-index: 2;
|
||||||
|
height: 2.75rem;
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-scroller .nav {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
padding-bottom: 1rem;
|
||||||
|
margin-top: -1px;
|
||||||
|
overflow-x: auto;
|
||||||
|
text-align: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-bd-primary {
|
||||||
|
--bd-violet-bg: #712cf9;
|
||||||
|
--bd-violet-rgb: 112.520718, 44.062154, 249.437846;
|
||||||
|
|
||||||
|
--bs-btn-font-weight: 600;
|
||||||
|
--bs-btn-color: var(--bs-white);
|
||||||
|
--bs-btn-bg: var(--bd-violet-bg);
|
||||||
|
--bs-btn-border-color: var(--bd-violet-bg);
|
||||||
|
--bs-btn-hover-color: var(--bs-white);
|
||||||
|
--bs-btn-hover-bg: #6528e0;
|
||||||
|
--bs-btn-hover-border-color: #6528e0;
|
||||||
|
--bs-btn-focus-shadow-rgb: var(--bd-violet-rgb);
|
||||||
|
--bs-btn-active-color: var(--bs-btn-hover-color);
|
||||||
|
--bs-btn-active-bg: #5a23c8;
|
||||||
|
--bs-btn-active-border-color: #5a23c8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle {
|
||||||
|
z-index: 1500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-mode-toggle .dropdown-menu .active .bi {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin {
|
||||||
|
max-width: 330px;
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin .form-floating:focus-within {
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="email"] {
|
||||||
|
margin-bottom: -1px;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-signin input[type="password"] {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body class="d-flex align-items-center py-4 bg-body-tertiary">
|
||||||
|
|
||||||
|
{{template "themeSelector"}}
|
||||||
|
|
||||||
|
<main class="form-signin w-100 m-auto">
|
||||||
|
<form hx-post="/api/login" hx-target="body">
|
||||||
|
<img class="mb-4" src="../assets/brand/bootstrap-logo.svg" alt="" width="72" height="57">
|
||||||
|
<h1 class="h3 mb-3 fw-normal">Please sign in</h1>
|
||||||
|
|
||||||
|
<div class="form-floating">
|
||||||
|
<input type="email" class="form-control" name="name" id="floatingInput" placeholder="name@example.com">
|
||||||
|
<label for="floatingInput">Naam</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating">
|
||||||
|
<input type="password" class="form-control" name="password" id="floatingPassword" placeholder="Password">
|
||||||
|
<label for="floatingPassword">Password</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check text-start my-3">
|
||||||
|
<input class="form-check-input" type="checkbox" value="remember-me" id="flexCheckDefault">
|
||||||
|
<label class="form-check-label" for="flexCheckDefault">
|
||||||
|
Remember me
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary w-100 py-2" type="submit">Sign in</button>
|
||||||
|
<p class="mt-5 mb-3 text-body-secondary">© 2017–2024</p>
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
<script src="../assets/dist/js/bootstrap.bundle.min.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -20,10 +20,7 @@
|
|||||||
<a class="nav-link disabled" aria-disabled="true">Servers</a>
|
<a class="nav-link disabled" aria-disabled="true">Servers</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<form class="d-flex" role="search">
|
<a class="btn btn-primary" href="/login">Login</a>
|
||||||
<input class="form-control me-2" type="search" placeholder="Search" aria-label="Search">
|
|
||||||
<button class="btn btn-outline-success" type="submit">Search</button>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
@ -1,20 +0,0 @@
|
|||||||
// Code generated by ent, DO NOT EDIT.
|
|
||||||
|
|
||||||
package ent
|
|
||||||
|
|
||||||
import (
|
|
||||||
"portfolio/database/ent/schema"
|
|
||||||
"portfolio/database/ent/user"
|
|
||||||
)
|
|
||||||
|
|
||||||
// The init function reads all schema descriptors with runtime code
|
|
||||||
// (default values, validators, hooks and policies) and stitches it
|
|
||||||
// to their package variables.
|
|
||||||
func init() {
|
|
||||||
userFields := schema.User{}.Fields()
|
|
||||||
_ = userFields
|
|
||||||
// userDescName is the schema descriptor for name field.
|
|
||||||
userDescName := userFields[0].Descriptor()
|
|
||||||
// user.DefaultName holds the default value on creation for the name field.
|
|
||||||
user.DefaultName = userDescName.Default.(string)
|
|
||||||
}
|
|
||||||
@ -2,7 +2,7 @@ version: '3.8'
|
|||||||
|
|
||||||
services:
|
services:
|
||||||
api:
|
api:
|
||||||
build: .
|
build: ./api
|
||||||
ports:
|
ports:
|
||||||
- "4002:4002"
|
- "4002:4002"
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
Loading…
x
Reference in New Issue
Block a user