diff --git a/server/db/db.go b/server/db/db.go index 3fef4bc..21f81a2 100644 --- a/server/db/db.go +++ b/server/db/db.go @@ -16,7 +16,10 @@ type Manager interface { AddUser(user User) (User, error) GetUsers() ([]User, error) GetUserByEmail(email string) (User, error) + UpdateVerificationTime(verifiedAt int64, email string) error AddVerification(verification Verification) (Verification, error) + GetVerificationByToken(token string) (Verification, error) + DeleteToken(email string) error } type manager struct { diff --git a/server/db/user.go b/server/db/user.go index 926024d..bc33236 100644 --- a/server/db/user.go +++ b/server/db/user.go @@ -60,3 +60,13 @@ func (mgr *manager) GetUserByEmail(email string) (User, error) { return user, nil } + +func (mgr *manager) UpdateVerificationTime(verifiedAt int64, email string) error { + result := mgr.db.Model(&User{}).Where("email = ?", email).Update("email_verified_at", verifiedAt) + + if result.Error != nil { + return result.Error + } + + return nil +} diff --git a/server/db/verification.go b/server/db/verification.go index bd64ef9..b019241 100644 --- a/server/db/verification.go +++ b/server/db/verification.go @@ -7,8 +7,8 @@ import ( ) type Verification struct { - ID uint `gorm:"primaryKey"` - Token string + ID uint `gorm:"primaryKey"` + Token string `gorm:"index"` Identifier string ExpiresAt int64 CreatedAt int64 `gorm:"autoCreateTime"` @@ -28,3 +28,27 @@ func (mgr *manager) AddVerification(verification Verification) (Verification, er } return verification, nil } + +func (mgr *manager) GetVerificationByToken(token string) (Verification, error) { + var verification Verification + result := mgr.db.Where("token = ?", token).First(&verification) + + if result.Error != nil { + log.Println(`Error getting verification token:`, result.Error) + return verification, result.Error + } + + return verification, nil +} + +func (mgr *manager) DeleteToken(email string) error { + var verification Verification + result := mgr.db.Where("email = ?", email).Delete(&verification) + + if result.Error != nil { + log.Println(`Error deleting token:`, result.Error) + return result.Error + } + + return nil +} diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index a86efdb..065d406 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -6,7 +6,6 @@ import ( "bytes" "context" "errors" - "fmt" "strconv" "sync" "sync/atomic" @@ -67,14 +66,22 @@ type ComplexityRoot struct { } Mutation struct { - BasicAuthLogin func(childComplexity int, params model.BasicAuthLoginInput) int - BasicAuthSignUp func(childComplexity int, params model.BasicAuthSignupInput) int + BasicAuthLogin func(childComplexity int, params model.BasicAuthLoginInput) int + BasicAuthSignUp func(childComplexity int, params model.BasicAuthSignupInput) int + VerifySignupToken func(childComplexity int, params model.VerifySignupTokenInput) int } Query struct { Users func(childComplexity int) int } + Response struct { + Errors func(childComplexity int) int + Message func(childComplexity int) int + StatusCode func(childComplexity int) int + Success func(childComplexity int) int + } + User struct { CreatedAt func(childComplexity int) int Email func(childComplexity int) int @@ -100,6 +107,7 @@ type ComplexityRoot struct { } type MutationResolver interface { + VerifySignupToken(ctx context.Context, params model.VerifySignupTokenInput) (*model.Response, error) BasicAuthSignUp(ctx context.Context, params model.BasicAuthSignupInput) (*model.BasicAuthSignupResponse, error) BasicAuthLogin(ctx context.Context, params model.BasicAuthLoginInput) (*model.BasicAuthLoginResponse, error) } @@ -237,6 +245,18 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Mutation.BasicAuthSignUp(childComplexity, args["params"].(model.BasicAuthSignupInput)), true + case "Mutation.verifySignupToken": + if e.complexity.Mutation.VerifySignupToken == nil { + break + } + + args, err := ec.field_Mutation_verifySignupToken_args(context.TODO(), rawArgs) + if err != nil { + return 0, false + } + + return e.complexity.Mutation.VerifySignupToken(childComplexity, args["params"].(model.VerifySignupTokenInput)), true + case "Query.users": if e.complexity.Query.Users == nil { break @@ -244,6 +264,34 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Query.Users(childComplexity), true + case "Response.errors": + if e.complexity.Response.Errors == nil { + break + } + + return e.complexity.Response.Errors(childComplexity), true + + case "Response.message": + if e.complexity.Response.Message == nil { + break + } + + return e.complexity.Response.Message(childComplexity), true + + case "Response.statusCode": + if e.complexity.Response.StatusCode == nil { + break + } + + return e.complexity.Response.StatusCode(childComplexity), true + + case "Response.success": + if e.complexity.Response.Success == nil { + break + } + + return e.complexity.Response.Success(childComplexity), true + case "User.createdAt": if e.complexity.User.CreatedAt == nil { break @@ -460,14 +508,14 @@ type Error { reason: String! } -interface Response { +type Response { success: Boolean! message: String! errors: [Error!] statusCode: Int! } -type BasicAuthLoginResponse implements Response { +type BasicAuthLoginResponse { success: Boolean! message: String! errors: [Error!] @@ -476,7 +524,7 @@ type BasicAuthLoginResponse implements Response { user: User } -type BasicAuthSignupResponse implements Response { +type BasicAuthSignupResponse { success: Boolean! message: String! errors: [Error!] @@ -502,7 +550,12 @@ input BasicAuthLoginInput { password: String! } +input VerifySignupTokenInput { + token: String! +} + type Mutation { + verifySignupToken(params: VerifySignupTokenInput!): Response! basicAuthSignUp(params: BasicAuthSignupInput!): BasicAuthSignupResponse! basicAuthLogin(params: BasicAuthLoginInput!): BasicAuthLoginResponse! } @@ -544,6 +597,21 @@ func (ec *executionContext) field_Mutation_basicAuthSignUp_args(ctx context.Cont return args, nil } +func (ec *executionContext) field_Mutation_verifySignupToken_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { + var err error + args := map[string]interface{}{} + var arg0 model.VerifySignupTokenInput + if tmp, ok := rawArgs["params"]; ok { + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params")) + arg0, err = ec.unmarshalNVerifySignupTokenInput2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerifySignupTokenInput(ctx, tmp) + if err != nil { + return nil, err + } + } + args["params"] = arg0 + return args, nil +} + func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -1037,6 +1105,48 @@ func (ec *executionContext) _Error_reason(ctx context.Context, field graphql.Col return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _Mutation_verifySignupToken(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Mutation", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + rawArgs := field.ArgumentMap(ec.Variables) + args, err := ec.field_Mutation_verifySignupToken_args(ctx, rawArgs) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + fc.Args = args + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.Mutation().VerifySignupToken(rctx, args["params"].(model.VerifySignupTokenInput)) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(*model.Response) + fc.Result = res + return ec.marshalNResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res) +} + func (ec *executionContext) _Mutation_basicAuthSignUp(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -1227,6 +1337,143 @@ func (ec *executionContext) _Query___schema(ctx context.Context, field graphql.C return ec.marshalO__Schema2ᚖgithubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐSchema(ctx, field.Selections, res) } +func (ec *executionContext) _Response_success(ctx context.Context, field graphql.CollectedField, obj *model.Response) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Response", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Success, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(bool) + fc.Result = res + return ec.marshalNBoolean2bool(ctx, field.Selections, res) +} + +func (ec *executionContext) _Response_message(ctx context.Context, field graphql.CollectedField, obj *model.Response) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Response", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Message, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(string) + fc.Result = res + return ec.marshalNString2string(ctx, field.Selections, res) +} + +func (ec *executionContext) _Response_errors(ctx context.Context, field graphql.CollectedField, obj *model.Response) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Response", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.Errors, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*model.Error) + fc.Result = res + return ec.marshalOError2ᚕᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐErrorᚄ(ctx, field.Selections, res) +} + +func (ec *executionContext) _Response_statusCode(ctx context.Context, field graphql.CollectedField, obj *model.Response) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "Response", + Field: field, + Args: nil, + IsMethod: false, + IsResolver: false, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.StatusCode, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + if !graphql.HasFieldError(ctx, fc) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + res := resTmp.(int) + fc.Result = res + return ec.marshalNInt2int(ctx, field.Selections, res) +} + func (ec *executionContext) _User_id(ctx context.Context, field graphql.CollectedField, obj *model.User) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -2958,38 +3205,35 @@ func (ec *executionContext) unmarshalInputBasicAuthSignupInput(ctx context.Conte return it, nil } +func (ec *executionContext) unmarshalInputVerifySignupTokenInput(ctx context.Context, obj interface{}) (model.VerifySignupTokenInput, error) { + var it model.VerifySignupTokenInput + var asMap = obj.(map[string]interface{}) + + for k, v := range asMap { + switch k { + case "token": + var err error + + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("token")) + it.Token, err = ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + } + } + + return it, nil +} + // endregion **************************** input.gotpl ***************************** // region ************************** interface.gotpl *************************** -func (ec *executionContext) _Response(ctx context.Context, sel ast.SelectionSet, obj model.Response) graphql.Marshaler { - switch obj := (obj).(type) { - case nil: - return graphql.Null - case model.BasicAuthLoginResponse: - return ec._BasicAuthLoginResponse(ctx, sel, &obj) - case *model.BasicAuthLoginResponse: - if obj == nil { - return graphql.Null - } - return ec._BasicAuthLoginResponse(ctx, sel, obj) - case model.BasicAuthSignupResponse: - return ec._BasicAuthSignupResponse(ctx, sel, &obj) - case *model.BasicAuthSignupResponse: - if obj == nil { - return graphql.Null - } - return ec._BasicAuthSignupResponse(ctx, sel, obj) - default: - panic(fmt.Errorf("unexpected type %T", obj)) - } -} - // endregion ************************** interface.gotpl *************************** // region **************************** object.gotpl **************************** -var basicAuthLoginResponseImplementors = []string{"BasicAuthLoginResponse", "Response"} +var basicAuthLoginResponseImplementors = []string{"BasicAuthLoginResponse"} func (ec *executionContext) _BasicAuthLoginResponse(ctx context.Context, sel ast.SelectionSet, obj *model.BasicAuthLoginResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, basicAuthLoginResponseImplementors) @@ -3032,7 +3276,7 @@ func (ec *executionContext) _BasicAuthLoginResponse(ctx context.Context, sel ast return out } -var basicAuthSignupResponseImplementors = []string{"BasicAuthSignupResponse", "Response"} +var basicAuthSignupResponseImplementors = []string{"BasicAuthSignupResponse"} func (ec *executionContext) _BasicAuthSignupResponse(ctx context.Context, sel ast.SelectionSet, obj *model.BasicAuthSignupResponse) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, basicAuthSignupResponseImplementors) @@ -3120,6 +3364,11 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("Mutation") + case "verifySignupToken": + out.Values[i] = ec._Mutation_verifySignupToken(ctx, field) + if out.Values[i] == graphql.Null { + invalids++ + } case "basicAuthSignUp": out.Values[i] = ec._Mutation_basicAuthSignUp(ctx, field) if out.Values[i] == graphql.Null { @@ -3185,6 +3434,45 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr return out } +var responseImplementors = []string{"Response"} + +func (ec *executionContext) _Response(ctx context.Context, sel ast.SelectionSet, obj *model.Response) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, responseImplementors) + + out := graphql.NewFieldSet(fields) + var invalids uint32 + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("Response") + case "success": + out.Values[i] = ec._Response_success(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "message": + out.Values[i] = ec._Response_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + case "errors": + out.Values[i] = ec._Response_errors(ctx, field, obj) + case "statusCode": + out.Values[i] = ec._Response_statusCode(ctx, field, obj) + if out.Values[i] == graphql.Null { + invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch() + if invalids > 0 { + return graphql.Null + } + return out +} + var userImplementors = []string{"User"} func (ec *executionContext) _User(ctx context.Context, sel ast.SelectionSet, obj *model.User) graphql.Marshaler { @@ -3613,6 +3901,20 @@ func (ec *executionContext) marshalNInt2int(ctx context.Context, sel ast.Selecti return res } +func (ec *executionContext) marshalNResponse2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐResponse(ctx context.Context, sel ast.SelectionSet, v model.Response) graphql.Marshaler { + return ec._Response(ctx, sel, &v) +} + +func (ec *executionContext) marshalNResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐResponse(ctx context.Context, sel ast.SelectionSet, v *model.Response) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + ec.Errorf(ctx, "must not be null") + } + return graphql.Null + } + return ec._Response(ctx, sel, v) +} + func (ec *executionContext) unmarshalNString2string(ctx context.Context, v interface{}) (string, error) { res, err := graphql.UnmarshalString(v) return res, graphql.ErrorOnPath(ctx, err) @@ -3675,6 +3977,11 @@ func (ec *executionContext) marshalNUser2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋse return ec._User(ctx, sel, v) } +func (ec *executionContext) unmarshalNVerifySignupTokenInput2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerifySignupTokenInput(ctx context.Context, v interface{}) (model.VerifySignupTokenInput, error) { + res, err := ec.unmarshalInputVerifySignupTokenInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + func (ec *executionContext) marshalN__Directive2githubᚗcomᚋ99designsᚋgqlgenᚋgraphqlᚋintrospectionᚐDirective(ctx context.Context, sel ast.SelectionSet, v introspection.Directive) graphql.Marshaler { return ec.___Directive(ctx, sel, &v) } diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index a39f5a0..d0e317b 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -2,10 +2,6 @@ package model -type Response interface { - IsResponse() -} - type BasicAuthLoginInput struct { Email string `json:"email"` Password string `json:"password"` @@ -20,8 +16,6 @@ type BasicAuthLoginResponse struct { User *User `json:"user"` } -func (BasicAuthLoginResponse) IsResponse() {} - type BasicAuthSignupInput struct { FirstName *string `json:"firstName"` LastName *string `json:"lastName"` @@ -39,13 +33,18 @@ type BasicAuthSignupResponse struct { User *User `json:"user"` } -func (BasicAuthSignupResponse) IsResponse() {} - type Error struct { Message string `json:"message"` Reason string `json:"reason"` } +type Response struct { + Success bool `json:"success"` + Message string `json:"message"` + Errors []*Error `json:"errors"` + StatusCode int `json:"statusCode"` +} + type User struct { ID string `json:"id"` Email string `json:"email"` @@ -68,3 +67,7 @@ type VerificationRequest struct { CreatedAt *int64 `json:"createdAt"` UpdatedAt *int64 `json:"updatedAt"` } + +type VerifySignupTokenInput struct { + Token string `json:"token"` +} diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index a1fcab3..7e724c0 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -31,14 +31,14 @@ type Error { reason: String! } -interface Response { +type Response { success: Boolean! message: String! errors: [Error!] statusCode: Int! } -type BasicAuthLoginResponse implements Response { +type BasicAuthLoginResponse { success: Boolean! message: String! errors: [Error!] @@ -47,7 +47,7 @@ type BasicAuthLoginResponse implements Response { user: User } -type BasicAuthSignupResponse implements Response { +type BasicAuthSignupResponse { success: Boolean! message: String! errors: [Error!] @@ -73,7 +73,12 @@ input BasicAuthLoginInput { password: String! } +input VerifySignupTokenInput { + token: String! +} + type Mutation { + verifySignupToken(params: VerifySignupTokenInput!): Response! basicAuthSignUp(params: BasicAuthSignupInput!): BasicAuthSignupResponse! basicAuthLogin(params: BasicAuthLoginInput!): BasicAuthLoginResponse! } diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index 2a7a11c..e8f2954 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -16,6 +16,52 @@ import ( "github.com/yauthdev/yauth/server/utils" ) +func (r *mutationResolver) VerifySignupToken(ctx context.Context, params model.VerifySignupTokenInput) (*model.Response, error) { + // // verify if token is valid + var res *model.Response + _, err := db.Mgr.GetVerificationByToken(params.Token) + if err != nil { + res = &model.Response{ + Success: false, + Message: `Invalid token`, + StatusCode: 400, + Errors: []*model.Error{&model.Error{ + Message: `Invalid token`, + Reason: `invalid token`, + }}, + } + } else { + + // verify if token exists in db + claim, err := utils.VerifyVerificationToken(params.Token) + if err != nil { + res = &model.Response{ + Success: false, + Message: `Invalid token`, + StatusCode: 400, + Errors: []*model.Error{&model.Error{ + Message: `Invalid token`, + Reason: `invalid token`, + }}, + } + } else { + res = &model.Response{ + Success: true, + Message: `Email verified successfully. Login to access the system.`, + StatusCode: 200, + } + + // update email_verified_at in users table + db.Mgr.UpdateVerificationTime(time.Now().Unix(), claim.Email) + // delete from verification table + db.Mgr.DeleteToken(claim.Email) + } + + } + + return res, nil +} + func (r *mutationResolver) BasicAuthSignUp(ctx context.Context, params model.BasicAuthSignupInput) (*model.BasicAuthSignupResponse, error) { var res *model.BasicAuthSignupResponse if params.CofirmPassword != params.Password { diff --git a/server/server.go b/server/server.go index caa3df2..2eed843 100644 --- a/server/server.go +++ b/server/server.go @@ -21,8 +21,8 @@ func main() { srv := handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}})) - http.Handle("/", playground.Handler("GraphQL playground", "/query")) - http.Handle("/query", srv) + http.Handle("/", playground.Handler("GraphQL playground", "/graphql")) + http.Handle("/graphql", srv) log.Printf("connect to http://localhost:%s/ for GraphQL playground", port) diff --git a/server/utils/verificationToken.go b/server/utils/verificationToken.go index efcf5fc..3b89a01 100644 --- a/server/utils/verificationToken.go +++ b/server/utils/verificationToken.go @@ -11,7 +11,7 @@ type UserInfo struct { Email string `json:"email"` } -type CustomClaimsExample struct { +type CustomClaim struct { *jwt.StandardClaims TokenType string `json:"token_type"` UserInfo @@ -21,7 +21,7 @@ type CustomClaimsExample struct { func CreateVerificationToken(email string, tokenType string) (string, error) { t := jwt.New(jwt.GetSigningMethod(constants.JWT_TYPE)) - t.Claims = &CustomClaimsExample{ + t.Claims = &CustomClaim{ &jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), @@ -33,17 +33,14 @@ func CreateVerificationToken(email string, tokenType string) (string, error) { return t.SignedString([]byte(constants.JWT_SECRET)) } -func VerifyVerificationToken(email string, tokenType string) (string, error) { - t := jwt.New(jwt.GetSigningMethod(constants.JWT_TYPE)) - - t.Claims = &CustomClaimsExample{ - &jwt.StandardClaims{ - - ExpiresAt: time.Now().Add(time.Minute * 30).Unix(), - }, - tokenType, - UserInfo{Email: email}, +func VerifyVerificationToken(token string) (*CustomClaim, error) { + claims := &CustomClaim{} + _, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) { + return []byte(constants.JWT_SECRET), nil + }) + if err != nil { + return claims, err } - return t.SignedString([]byte(constants.JWT_SECRET)) + return claims, nil }