diff --git a/ent/client.go b/ent/client.go index 7b249f1..59dc9fc 100644 --- a/ent/client.go +++ b/ent/client.go @@ -338,5 +338,6 @@ func (c *UserClient) QueryOwner(u *User) *PasswordTokenQuery { // Hooks returns the client hooks. func (c *UserClient) Hooks() []Hook { - return c.hooks.User + hooks := c.hooks.User + return append(hooks[:len(hooks):len(hooks)], user.Hooks[:]...) } diff --git a/ent/runtime.go b/ent/runtime.go index 1a08773..e4bc5f5 100644 --- a/ent/runtime.go +++ b/ent/runtime.go @@ -2,43 +2,4 @@ package ent -import ( - "goweb/ent/passwordtoken" - "goweb/ent/schema" - "goweb/ent/user" - "time" -) - -// 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() { - passwordtokenFields := schema.PasswordToken{}.Fields() - _ = passwordtokenFields - // passwordtokenDescHash is the schema descriptor for hash field. - passwordtokenDescHash := passwordtokenFields[0].Descriptor() - // passwordtoken.HashValidator is a validator for the "hash" field. It is called by the builders before save. - passwordtoken.HashValidator = passwordtokenDescHash.Validators[0].(func(string) error) - // passwordtokenDescCreatedAt is the schema descriptor for created_at field. - passwordtokenDescCreatedAt := passwordtokenFields[1].Descriptor() - // passwordtoken.DefaultCreatedAt holds the default value on creation for the created_at field. - passwordtoken.DefaultCreatedAt = passwordtokenDescCreatedAt.Default.(func() time.Time) - userFields := schema.User{}.Fields() - _ = userFields - // userDescName is the schema descriptor for name field. - userDescName := userFields[0].Descriptor() - // user.NameValidator is a validator for the "name" field. It is called by the builders before save. - user.NameValidator = userDescName.Validators[0].(func(string) error) - // userDescEmail is the schema descriptor for email field. - userDescEmail := userFields[1].Descriptor() - // user.EmailValidator is a validator for the "email" field. It is called by the builders before save. - user.EmailValidator = userDescEmail.Validators[0].(func(string) error) - // userDescPassword is the schema descriptor for password field. - userDescPassword := userFields[2].Descriptor() - // user.PasswordValidator is a validator for the "password" field. It is called by the builders before save. - user.PasswordValidator = userDescPassword.Validators[0].(func(string) error) - // userDescCreatedAt is the schema descriptor for created_at field. - userDescCreatedAt := userFields[3].Descriptor() - // user.DefaultCreatedAt holds the default value on creation for the created_at field. - user.DefaultCreatedAt = userDescCreatedAt.Default.(func() time.Time) -} +// The schema-stitching logic is generated in goweb/ent/runtime/runtime.go diff --git a/ent/runtime/runtime.go b/ent/runtime/runtime.go index ec67ba9..9c3be62 100644 --- a/ent/runtime/runtime.go +++ b/ent/runtime/runtime.go @@ -2,7 +2,48 @@ package runtime -// The schema-stitching logic is generated in goweb/ent/runtime.go +import ( + "goweb/ent/passwordtoken" + "goweb/ent/schema" + "goweb/ent/user" + "time" +) + +// 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() { + passwordtokenFields := schema.PasswordToken{}.Fields() + _ = passwordtokenFields + // passwordtokenDescHash is the schema descriptor for hash field. + passwordtokenDescHash := passwordtokenFields[0].Descriptor() + // passwordtoken.HashValidator is a validator for the "hash" field. It is called by the builders before save. + passwordtoken.HashValidator = passwordtokenDescHash.Validators[0].(func(string) error) + // passwordtokenDescCreatedAt is the schema descriptor for created_at field. + passwordtokenDescCreatedAt := passwordtokenFields[1].Descriptor() + // passwordtoken.DefaultCreatedAt holds the default value on creation for the created_at field. + passwordtoken.DefaultCreatedAt = passwordtokenDescCreatedAt.Default.(func() time.Time) + userHooks := schema.User{}.Hooks() + user.Hooks[0] = userHooks[0] + userFields := schema.User{}.Fields() + _ = userFields + // userDescName is the schema descriptor for name field. + userDescName := userFields[0].Descriptor() + // user.NameValidator is a validator for the "name" field. It is called by the builders before save. + user.NameValidator = userDescName.Validators[0].(func(string) error) + // userDescEmail is the schema descriptor for email field. + userDescEmail := userFields[1].Descriptor() + // user.EmailValidator is a validator for the "email" field. It is called by the builders before save. + user.EmailValidator = userDescEmail.Validators[0].(func(string) error) + // userDescPassword is the schema descriptor for password field. + userDescPassword := userFields[2].Descriptor() + // user.PasswordValidator is a validator for the "password" field. It is called by the builders before save. + user.PasswordValidator = userDescPassword.Validators[0].(func(string) error) + // userDescCreatedAt is the schema descriptor for created_at field. + userDescCreatedAt := userFields[3].Descriptor() + // user.DefaultCreatedAt holds the default value on creation for the created_at field. + user.DefaultCreatedAt = userDescCreatedAt.Default.(func() time.Time) +} const ( Version = "v0.9.1" // Version of ent codegen. diff --git a/ent/schema/user.go b/ent/schema/user.go index d81ec5a..0938267 100644 --- a/ent/schema/user.go +++ b/ent/schema/user.go @@ -1,8 +1,13 @@ package schema import ( + "context" + "strings" "time" + ge "goweb/ent" + "goweb/ent/hook" + "entgo.io/ent" "entgo.io/ent/schema/edge" "entgo.io/ent/schema/field" @@ -37,3 +42,20 @@ func (User) Edges() []ent.Edge { Ref("user"), } } + +func (User) Hooks() []ent.Hook { + return []ent.Hook{ + hook.On( + func(next ent.Mutator) ent.Mutator { + return hook.UserFunc(func(ctx context.Context, m *ge.UserMutation) (ent.Value, error) { + if v, exists := m.Email(); exists { + m.SetEmail(strings.ToLower(v)) + } + return next.Mutate(ctx, m) + }) + }, + // Limit the hook only for these operations. + ent.OpCreate|ent.OpUpdate|ent.OpUpdateOne, + ), + } +} diff --git a/ent/user/user.go b/ent/user/user.go index d411174..4d7a487 100644 --- a/ent/user/user.go +++ b/ent/user/user.go @@ -4,6 +4,8 @@ package user import ( "time" + + "entgo.io/ent" ) const ( @@ -51,7 +53,14 @@ func ValidColumn(column string) bool { return false } +// Note that the variables below are initialized by the runtime +// package on the initialization of the application. Therefore, +// it should be imported in the main as follows: +// +// import _ "goweb/ent/runtime" +// var ( + Hooks [1]ent.Hook // NameValidator is a validator for the "name" field. It is called by the builders before save. NameValidator func(string) error // EmailValidator is a validator for the "email" field. It is called by the builders before save. diff --git a/ent/user_create.go b/ent/user_create.go index 470242f..ca26043 100644 --- a/ent/user_create.go +++ b/ent/user_create.go @@ -79,7 +79,9 @@ func (uc *UserCreate) Save(ctx context.Context) (*User, error) { err error node *User ) - uc.defaults() + if err := uc.defaults(); err != nil { + return nil, err + } if len(uc.hooks) == 0 { if err = uc.check(); err != nil { return nil, err @@ -138,11 +140,15 @@ func (uc *UserCreate) ExecX(ctx context.Context) { } // defaults sets the default values of the builder before save. -func (uc *UserCreate) defaults() { +func (uc *UserCreate) defaults() error { if _, ok := uc.mutation.CreatedAt(); !ok { + if user.DefaultCreatedAt == nil { + return fmt.Errorf("ent: uninitialized user.DefaultCreatedAt (forgotten import ent/runtime?)") + } v := user.DefaultCreatedAt() uc.mutation.SetCreatedAt(v) } + return nil } // check runs all checks and user-defined validators on the builder. diff --git a/go.sum b/go.sum index f9187dd..b1b4126 100644 --- a/go.sum +++ b/go.sum @@ -150,6 +150,7 @@ github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4= github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= @@ -403,6 +404,7 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= @@ -445,6 +447,7 @@ github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtb github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -562,11 +565,13 @@ github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkU github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -666,6 +671,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -812,6 +818,7 @@ golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/routes/forgot_password.go b/routes/forgot_password.go index 4dfb7cb..5871041 100644 --- a/routes/forgot_password.go +++ b/routes/forgot_password.go @@ -2,6 +2,7 @@ package routes import ( "fmt" + "strings" "goweb/context" "goweb/controller" @@ -63,7 +64,7 @@ func (c *ForgotPassword) Post(ctx echo.Context) error { // Attempt to load the user u, err := c.Container.ORM.User. Query(). - Where(user.Email(form.Email)). + Where(user.Email(strings.ToLower(form.Email))). Only(ctx.Request().Context()) switch err.(type) { diff --git a/routes/login.go b/routes/login.go index 8bc2296..a9d03c3 100644 --- a/routes/login.go +++ b/routes/login.go @@ -2,6 +2,7 @@ package routes import ( "fmt" + "strings" "goweb/context" "goweb/controller" @@ -65,7 +66,7 @@ func (c *Login) Post(ctx echo.Context) error { // Attempt to load the user u, err := c.Container.ORM.User. Query(). - Where(user.Email(form.Email)). + Where(user.Email(strings.ToLower(form.Email))). Only(ctx.Request().Context()) switch err.(type) { diff --git a/services/container.go b/services/container.go index b8cd7e1..cf26bc2 100644 --- a/services/container.go +++ b/services/container.go @@ -16,6 +16,7 @@ import ( "goweb/config" "goweb/ent" + _ "goweb/ent/runtime" ) // Container contains all services used by the application and provides an easy way to handle dependency diff --git a/templates/pages/contact.gohtml b/templates/pages/contact.gohtml index 53ca9cc..7298d31 100644 --- a/templates/pages/contact.gohtml +++ b/templates/pages/contact.gohtml @@ -22,7 +22,7 @@ {{- else}} -
+
diff --git a/templates/pages/login.gohtml b/templates/pages/login.gohtml index d56d433..ac64cec 100644 --- a/templates/pages/login.gohtml +++ b/templates/pages/login.gohtml @@ -1,5 +1,5 @@ {{define "content"}} - + {{template "messages" .}}
diff --git a/templates/pages/register.gohtml b/templates/pages/register.gohtml index 200ae27..a17d564 100644 --- a/templates/pages/register.gohtml +++ b/templates/pages/register.gohtml @@ -1,5 +1,5 @@ {{define "content"}} - +
diff --git a/templates/pages/reset-password.gohtml b/templates/pages/reset-password.gohtml index a1f5ce0..7783483 100644 --- a/templates/pages/reset-password.gohtml +++ b/templates/pages/reset-password.gohtml @@ -1,5 +1,5 @@ {{define "content"}} - +