@@ -14,13 +14,13 @@ import (
1414
1515// SignInByEmail happens when user request to sign in by email
1616type SignInByEmail struct {
17- Email string `json:"email" format:"lower"`
18- VerificationKey string
17+ Email string `json:"email" format:"lower"`
18+ VerificationCode string
1919}
2020
2121func NewSignInByEmail () * SignInByEmail {
2222 return & SignInByEmail {
23- VerificationKey : entity .GenerateEmailVerificationKey (),
23+ VerificationCode : entity .GenerateEmailVerificationCode (),
2424 }
2525}
2626
@@ -74,6 +74,105 @@ func (action *SignInByEmail) GetKind() enum.EmailVerificationKind {
7474 return enum .EmailVerificationKindSignIn
7575}
7676
77+ // VerifySignInCode happens when user enters the verification code received via email
78+ type VerifySignInCode struct {
79+ Email string `json:"email" format:"lower"`
80+ Code string `json:"code"`
81+ }
82+
83+ // IsAuthorized returns true if current user is authorized to perform this action
84+ func (action * VerifySignInCode ) IsAuthorized (ctx context.Context , user * entity.User ) bool {
85+ return true
86+ }
87+
88+ // Validate if current model is valid
89+ func (action * VerifySignInCode ) Validate (ctx context.Context , user * entity.User ) * validate.Result {
90+ result := validate .Success ()
91+
92+ if action .Email == "" {
93+ result .AddFieldFailure ("email" , propertyIsRequired (ctx , "email" ))
94+ } else {
95+ messages := validate .Email (ctx , action .Email )
96+ result .AddFieldFailure ("email" , messages ... )
97+ }
98+
99+ if action .Code == "" {
100+ result .AddFieldFailure ("code" , propertyIsRequired (ctx , "code" ))
101+ } else if len (action .Code ) != 6 {
102+ result .AddFieldFailure ("code" , "Verification code must be 6 digits" )
103+ } else {
104+ // Validate that code contains only digits
105+ for _ , char := range action .Code {
106+ if char < '0' || char > '9' {
107+ result .AddFieldFailure ("code" , "Verification code must contain only digits" )
108+ break
109+ }
110+ }
111+ }
112+
113+ return result
114+ }
115+
116+ // SignInByEmailWithName happens when a new user (without account) requests to sign in by email
117+ type SignInByEmailWithName struct {
118+ Email string `json:"email" format:"lower"`
119+ Name string `json:"name"`
120+ VerificationCode string
121+ }
122+
123+ func NewSignInByEmailWithName () * SignInByEmailWithName {
124+ return & SignInByEmailWithName {
125+ VerificationCode : entity .GenerateEmailVerificationCode (),
126+ }
127+ }
128+
129+ // IsAuthorized returns true if current user is authorized to perform this action
130+ func (action * SignInByEmailWithName ) IsAuthorized (ctx context.Context , user * entity.User ) bool {
131+ tenant := ctx .Value (app .TenantCtxKey ).(* entity.Tenant )
132+ // New users can only sign in if tenant allows email auth or is not private
133+ return tenant .IsEmailAuthAllowed || ! tenant .IsPrivate
134+ }
135+
136+ // Validate if current model is valid
137+ func (action * SignInByEmailWithName ) Validate (ctx context.Context , user * entity.User ) * validate.Result {
138+ result := validate .Success ()
139+
140+ if action .Email == "" {
141+ result .AddFieldFailure ("email" , propertyIsRequired (ctx , "email" ))
142+ } else {
143+ messages := validate .Email (ctx , action .Email )
144+ result .AddFieldFailure ("email" , messages ... )
145+ }
146+
147+ if action .Name == "" {
148+ result .AddFieldFailure ("name" , propertyIsRequired (ctx , "name" ))
149+ } else if len (action .Name ) > 100 {
150+ result .AddFieldFailure ("name" , propertyMaxStringLen (ctx , "name" , 100 ))
151+ }
152+
153+ return result
154+ }
155+
156+ // GetEmail returns the email being verified
157+ func (action * SignInByEmailWithName ) GetEmail () string {
158+ return action .Email
159+ }
160+
161+ // GetName returns the name provided by the user
162+ func (action * SignInByEmailWithName ) GetName () string {
163+ return action .Name
164+ }
165+
166+ // GetUser returns the current user performing this action
167+ func (action * SignInByEmailWithName ) GetUser () * entity.User {
168+ return nil
169+ }
170+
171+ // GetKind returns EmailVerificationKindSignIn
172+ func (action * SignInByEmailWithName ) GetKind () enum.EmailVerificationKind {
173+ return enum .EmailVerificationKindSignIn
174+ }
175+
77176// CompleteProfile happens when users completes their profile during first time sign in
78177type CompleteProfile struct {
79178 Kind enum.EmailVerificationKind `json:"kind"`
0 commit comments