parent
83b3149c0b
commit
7d17032fc2
|
@ -14,6 +14,7 @@ import (
|
|||
|
||||
type Manager interface {
|
||||
SaveUser(user User) (User, error)
|
||||
UpdateUser(user User) (User, error)
|
||||
GetUsers() ([]User, error)
|
||||
GetUserByEmail(email string) (User, error)
|
||||
UpdateVerificationTime(verifiedAt int64, id uint) error
|
||||
|
|
|
@ -19,9 +19,28 @@ type User struct {
|
|||
Image string
|
||||
}
|
||||
|
||||
// SaveUser function to add user
|
||||
// SaveUser function to add user even with email conflict
|
||||
func (mgr *manager) SaveUser(user User) (User, error) {
|
||||
result := mgr.db.Clauses(clause.OnConflict{UpdateAll: true, Columns: []clause.Column{{Name: "email"}}}).Create(&user)
|
||||
result := mgr.db.Clauses(
|
||||
clause.OnConflict{
|
||||
UpdateAll: true,
|
||||
Columns: []clause.Column{{Name: "email"}},
|
||||
}).Create(&user)
|
||||
|
||||
if result.Error != nil {
|
||||
log.Println(result.Error)
|
||||
return user, result.Error
|
||||
}
|
||||
return user, nil
|
||||
}
|
||||
|
||||
// UpdateUser function to update user with ID conflict
|
||||
func (mgr *manager) UpdateUser(user User) (User, error) {
|
||||
result := mgr.db.Clauses(
|
||||
clause.OnConflict{
|
||||
UpdateAll: true,
|
||||
Columns: []clause.Column{{Name: "id"}},
|
||||
}).Create(&user)
|
||||
|
||||
if result.Error != nil {
|
||||
log.Println(result.Error)
|
||||
|
|
15
server/enum/verification.go
Normal file
15
server/enum/verification.go
Normal file
|
@ -0,0 +1,15 @@
|
|||
package enum
|
||||
|
||||
type VerificationType int
|
||||
|
||||
const (
|
||||
BasicAuthSignup VerificationType = iota
|
||||
UpdateEmail
|
||||
)
|
||||
|
||||
func (d VerificationType) String() string {
|
||||
return [...]string{
|
||||
"basic_auth_signup",
|
||||
"update_email",
|
||||
}[d]
|
||||
}
|
|
@ -59,7 +59,8 @@ type ComplexityRoot struct {
|
|||
Login func(childComplexity int, params model.LoginInput) int
|
||||
Logout func(childComplexity int) int
|
||||
Signup func(childComplexity int, params model.SignUpInput) int
|
||||
VerifySignupToken func(childComplexity int, params model.VerifySignupTokenInput) int
|
||||
UpdateProfile func(childComplexity int, params model.UpdateProfileInput) int
|
||||
VerifyEmail func(childComplexity int, params model.VerifyEmailInput) int
|
||||
}
|
||||
|
||||
Query struct {
|
||||
|
@ -72,11 +73,6 @@ type ComplexityRoot struct {
|
|||
Message func(childComplexity int) int
|
||||
}
|
||||
|
||||
SignUpResponse struct {
|
||||
Message func(childComplexity int) int
|
||||
User func(childComplexity int) int
|
||||
}
|
||||
|
||||
User struct {
|
||||
CreatedAt func(childComplexity int) int
|
||||
Email func(childComplexity int) int
|
||||
|
@ -102,10 +98,11 @@ type ComplexityRoot struct {
|
|||
}
|
||||
|
||||
type MutationResolver interface {
|
||||
Signup(ctx context.Context, params model.SignUpInput) (*model.SignUpResponse, error)
|
||||
VerifySignupToken(ctx context.Context, params model.VerifySignupTokenInput) (*model.LoginResponse, error)
|
||||
Signup(ctx context.Context, params model.SignUpInput) (*model.Response, error)
|
||||
Login(ctx context.Context, params model.LoginInput) (*model.LoginResponse, error)
|
||||
Logout(ctx context.Context) (*model.Response, error)
|
||||
UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error)
|
||||
VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.LoginResponse, error)
|
||||
}
|
||||
type QueryResolver interface {
|
||||
Users(ctx context.Context) ([]*model.User, error)
|
||||
|
@ -201,17 +198,29 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Mutation.Signup(childComplexity, args["params"].(model.SignUpInput)), true
|
||||
|
||||
case "Mutation.verifySignupToken":
|
||||
if e.complexity.Mutation.VerifySignupToken == nil {
|
||||
case "Mutation.updateProfile":
|
||||
if e.complexity.Mutation.UpdateProfile == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Mutation_verifySignupToken_args(context.TODO(), rawArgs)
|
||||
args, err := ec.field_Mutation_updateProfile_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.VerifySignupToken(childComplexity, args["params"].(model.VerifySignupTokenInput)), true
|
||||
return e.complexity.Mutation.UpdateProfile(childComplexity, args["params"].(model.UpdateProfileInput)), true
|
||||
|
||||
case "Mutation.verifyEmail":
|
||||
if e.complexity.Mutation.VerifyEmail == nil {
|
||||
break
|
||||
}
|
||||
|
||||
args, err := ec.field_Mutation_verifyEmail_args(context.TODO(), rawArgs)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
return e.complexity.Mutation.VerifyEmail(childComplexity, args["params"].(model.VerifyEmailInput)), true
|
||||
|
||||
case "Query.profile":
|
||||
if e.complexity.Query.Profile == nil {
|
||||
|
@ -241,20 +250,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
|||
|
||||
return e.complexity.Response.Message(childComplexity), true
|
||||
|
||||
case "SignUpResponse.message":
|
||||
if e.complexity.SignUpResponse.Message == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SignUpResponse.Message(childComplexity), true
|
||||
|
||||
case "SignUpResponse.user":
|
||||
if e.complexity.SignUpResponse.User == nil {
|
||||
break
|
||||
}
|
||||
|
||||
return e.complexity.SignUpResponse.User(childComplexity), true
|
||||
|
||||
case "User.createdAt":
|
||||
if e.complexity.User.CreatedAt == nil {
|
||||
break
|
||||
|
@ -478,11 +473,6 @@ type LoginResponse {
|
|||
user: User
|
||||
}
|
||||
|
||||
type SignUpResponse {
|
||||
message: String!
|
||||
user: User
|
||||
}
|
||||
|
||||
type Response {
|
||||
message: String!
|
||||
}
|
||||
|
@ -501,15 +491,26 @@ input LoginInput {
|
|||
password: String!
|
||||
}
|
||||
|
||||
input VerifySignupTokenInput {
|
||||
input VerifyEmailInput {
|
||||
token: String!
|
||||
}
|
||||
|
||||
input UpdateProfileInput {
|
||||
oldPassword: String
|
||||
newPassword: String
|
||||
confirmNewPassword: String
|
||||
firstName: String
|
||||
lastName: String
|
||||
image: String
|
||||
email: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
signup(params: SignUpInput!): SignUpResponse!
|
||||
verifySignupToken(params: VerifySignupTokenInput!): LoginResponse!
|
||||
signup(params: SignUpInput!): Response!
|
||||
login(params: LoginInput!): LoginResponse!
|
||||
logout: Response!
|
||||
updateProfile(params: UpdateProfileInput!): Response!
|
||||
verifyEmail(params: VerifyEmailInput!): LoginResponse!
|
||||
}
|
||||
|
||||
type Query {
|
||||
|
@ -555,13 +556,28 @@ func (ec *executionContext) field_Mutation_signup_args(ctx context.Context, rawA
|
|||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_verifySignupToken_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
func (ec *executionContext) field_Mutation_updateProfile_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 model.VerifySignupTokenInput
|
||||
var arg0 model.UpdateProfileInput
|
||||
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)
|
||||
arg0, err = ec.unmarshalNUpdateProfileInput2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐUpdateProfileInput(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
args["params"] = arg0
|
||||
return args, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) field_Mutation_verifyEmail_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||
var err error
|
||||
args := map[string]interface{}{}
|
||||
var arg0 model.VerifyEmailInput
|
||||
if tmp, ok := rawArgs["params"]; ok {
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("params"))
|
||||
arg0, err = ec.unmarshalNVerifyEmailInput2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerifyEmailInput(ctx, tmp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -861,51 +877,9 @@ func (ec *executionContext) _Mutation_signup(ctx context.Context, field graphql.
|
|||
}
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*model.SignUpResponse)
|
||||
res := resTmp.(*model.Response)
|
||||
fc.Result = res
|
||||
return ec.marshalNSignUpResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐSignUpResponse(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.LoginResponse)
|
||||
fc.Result = res
|
||||
return ec.marshalNLoginResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐLoginResponse(ctx, field.Selections, res)
|
||||
return ec.marshalNResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_login(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
|
@ -985,6 +959,90 @@ func (ec *executionContext) _Mutation_logout(ctx context.Context, field graphql.
|
|||
return ec.marshalNResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐResponse(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Mutation_updateProfile(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_updateProfile_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().UpdateProfile(rctx, args["params"].(model.UpdateProfileInput))
|
||||
})
|
||||
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_verifyEmail(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_verifyEmail_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().VerifyEmail(rctx, args["params"].(model.VerifyEmailInput))
|
||||
})
|
||||
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.LoginResponse)
|
||||
fc.Result = res
|
||||
return ec.marshalNLoginResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐLoginResponse(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _Query_users(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
|
@ -1193,73 +1251,6 @@ func (ec *executionContext) _Response_message(ctx context.Context, field graphql
|
|||
return ec.marshalNString2string(ctx, field.Selections, res)
|
||||
}
|
||||
|
||||
func (ec *executionContext) _SignUpResponse_message(ctx context.Context, field graphql.CollectedField, obj *model.SignUpResponse) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "SignUpResponse",
|
||||
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) _SignUpResponse_user(ctx context.Context, field graphql.CollectedField, obj *model.SignUpResponse) (ret graphql.Marshaler) {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
ec.Error(ctx, ec.Recover(ctx, r))
|
||||
ret = graphql.Null
|
||||
}
|
||||
}()
|
||||
fc := &graphql.FieldContext{
|
||||
Object: "SignUpResponse",
|
||||
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.User, nil
|
||||
})
|
||||
if err != nil {
|
||||
ec.Error(ctx, err)
|
||||
return graphql.Null
|
||||
}
|
||||
if resTmp == nil {
|
||||
return graphql.Null
|
||||
}
|
||||
res := resTmp.(*model.User)
|
||||
fc.Result = res
|
||||
return ec.marshalOUser2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐUser(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 {
|
||||
|
@ -2991,8 +2982,76 @@ func (ec *executionContext) unmarshalInputSignUpInput(ctx context.Context, obj i
|
|||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputVerifySignupTokenInput(ctx context.Context, obj interface{}) (model.VerifySignupTokenInput, error) {
|
||||
var it model.VerifySignupTokenInput
|
||||
func (ec *executionContext) unmarshalInputUpdateProfileInput(ctx context.Context, obj interface{}) (model.UpdateProfileInput, error) {
|
||||
var it model.UpdateProfileInput
|
||||
var asMap = obj.(map[string]interface{})
|
||||
|
||||
for k, v := range asMap {
|
||||
switch k {
|
||||
case "oldPassword":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("oldPassword"))
|
||||
it.OldPassword, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "newPassword":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("newPassword"))
|
||||
it.NewPassword, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "confirmNewPassword":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("confirmNewPassword"))
|
||||
it.ConfirmNewPassword, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "firstName":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("firstName"))
|
||||
it.FirstName, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "lastName":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("lastName"))
|
||||
it.LastName, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "image":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("image"))
|
||||
it.Image, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
case "email":
|
||||
var err error
|
||||
|
||||
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("email"))
|
||||
it.Email, err = ec.unmarshalOString2ᚖstring(ctx, v)
|
||||
if err != nil {
|
||||
return it, err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return it, nil
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalInputVerifyEmailInput(ctx context.Context, obj interface{}) (model.VerifyEmailInput, error) {
|
||||
var it model.VerifyEmailInput
|
||||
var asMap = obj.(map[string]interface{})
|
||||
|
||||
for k, v := range asMap {
|
||||
|
@ -3104,11 +3163,6 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
|||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "verifySignupToken":
|
||||
out.Values[i] = ec._Mutation_verifySignupToken(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "login":
|
||||
out.Values[i] = ec._Mutation_login(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
|
@ -3119,6 +3173,16 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet)
|
|||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "updateProfile":
|
||||
out.Values[i] = ec._Mutation_updateProfile(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "verifyEmail":
|
||||
out.Values[i] = ec._Mutation_verifyEmail(ctx, field)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
default:
|
||||
panic("unknown field " + strconv.Quote(field.Name))
|
||||
}
|
||||
|
@ -3226,35 +3290,6 @@ func (ec *executionContext) _Response(ctx context.Context, sel ast.SelectionSet,
|
|||
return out
|
||||
}
|
||||
|
||||
var signUpResponseImplementors = []string{"SignUpResponse"}
|
||||
|
||||
func (ec *executionContext) _SignUpResponse(ctx context.Context, sel ast.SelectionSet, obj *model.SignUpResponse) graphql.Marshaler {
|
||||
fields := graphql.CollectFields(ec.OperationContext, sel, signUpResponseImplementors)
|
||||
|
||||
out := graphql.NewFieldSet(fields)
|
||||
var invalids uint32
|
||||
for i, field := range fields {
|
||||
switch field.Name {
|
||||
case "__typename":
|
||||
out.Values[i] = graphql.MarshalString("SignUpResponse")
|
||||
case "message":
|
||||
out.Values[i] = ec._SignUpResponse_message(ctx, field, obj)
|
||||
if out.Values[i] == graphql.Null {
|
||||
invalids++
|
||||
}
|
||||
case "user":
|
||||
out.Values[i] = ec._SignUpResponse_user(ctx, field, obj)
|
||||
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 {
|
||||
|
@ -3658,20 +3693,6 @@ func (ec *executionContext) unmarshalNSignUpInput2githubᚗcomᚋyauthdevᚋyaut
|
|||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNSignUpResponse2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐSignUpResponse(ctx context.Context, sel ast.SelectionSet, v model.SignUpResponse) graphql.Marshaler {
|
||||
return ec._SignUpResponse(ctx, sel, &v)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNSignUpResponse2ᚖgithubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐSignUpResponse(ctx context.Context, sel ast.SelectionSet, v *model.SignUpResponse) graphql.Marshaler {
|
||||
if v == nil {
|
||||
if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) {
|
||||
ec.Errorf(ctx, "must not be null")
|
||||
}
|
||||
return graphql.Null
|
||||
}
|
||||
return ec._SignUpResponse(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)
|
||||
|
@ -3687,6 +3708,11 @@ func (ec *executionContext) marshalNString2string(ctx context.Context, sel ast.S
|
|||
return res
|
||||
}
|
||||
|
||||
func (ec *executionContext) unmarshalNUpdateProfileInput2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐUpdateProfileInput(ctx context.Context, v interface{}) (model.UpdateProfileInput, error) {
|
||||
res, err := ec.unmarshalInputUpdateProfileInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
func (ec *executionContext) marshalNUser2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐUser(ctx context.Context, sel ast.SelectionSet, v model.User) graphql.Marshaler {
|
||||
return ec._User(ctx, sel, &v)
|
||||
}
|
||||
|
@ -3738,8 +3764,8 @@ 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)
|
||||
func (ec *executionContext) unmarshalNVerifyEmailInput2githubᚗcomᚋyauthdevᚋyauthᚋserverᚋgraphᚋmodelᚐVerifyEmailInput(ctx context.Context, v interface{}) (model.VerifyEmailInput, error) {
|
||||
res, err := ec.unmarshalInputVerifyEmailInput(ctx, v)
|
||||
return res, graphql.ErrorOnPath(ctx, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,14 @@ type SignUpInput struct {
|
|||
Image *string `json:"image"`
|
||||
}
|
||||
|
||||
type SignUpResponse struct {
|
||||
Message string `json:"message"`
|
||||
User *User `json:"user"`
|
||||
type UpdateProfileInput struct {
|
||||
OldPassword *string `json:"oldPassword"`
|
||||
NewPassword *string `json:"newPassword"`
|
||||
ConfirmNewPassword *string `json:"confirmNewPassword"`
|
||||
FirstName *string `json:"firstName"`
|
||||
LastName *string `json:"lastName"`
|
||||
Image *string `json:"image"`
|
||||
Email *string `json:"email"`
|
||||
}
|
||||
|
||||
type User struct {
|
||||
|
@ -60,6 +65,6 @@ type VerificationRequest struct {
|
|||
UpdatedAt *int64 `json:"updatedAt"`
|
||||
}
|
||||
|
||||
type VerifySignupTokenInput struct {
|
||||
type VerifyEmailInput struct {
|
||||
Token string `json:"token"`
|
||||
}
|
||||
|
|
|
@ -38,11 +38,6 @@ type LoginResponse {
|
|||
user: User
|
||||
}
|
||||
|
||||
type SignUpResponse {
|
||||
message: String!
|
||||
user: User
|
||||
}
|
||||
|
||||
type Response {
|
||||
message: String!
|
||||
}
|
||||
|
@ -61,15 +56,26 @@ input LoginInput {
|
|||
password: String!
|
||||
}
|
||||
|
||||
input VerifySignupTokenInput {
|
||||
input VerifyEmailInput {
|
||||
token: String!
|
||||
}
|
||||
|
||||
input UpdateProfileInput {
|
||||
oldPassword: String
|
||||
newPassword: String
|
||||
confirmNewPassword: String
|
||||
firstName: String
|
||||
lastName: String
|
||||
image: String
|
||||
email: String
|
||||
}
|
||||
|
||||
type Mutation {
|
||||
signup(params: SignUpInput!): SignUpResponse!
|
||||
verifySignupToken(params: VerifySignupTokenInput!): LoginResponse!
|
||||
signup(params: SignUpInput!): Response!
|
||||
login(params: LoginInput!): LoginResponse!
|
||||
logout: Response!
|
||||
updateProfile(params: UpdateProfileInput!): Response!
|
||||
verifyEmail(params: VerifyEmailInput!): LoginResponse!
|
||||
}
|
||||
|
||||
type Query {
|
||||
|
|
|
@ -11,14 +11,10 @@ import (
|
|||
"github.com/yauthdev/yauth/server/resolvers"
|
||||
)
|
||||
|
||||
func (r *mutationResolver) Signup(ctx context.Context, params model.SignUpInput) (*model.SignUpResponse, error) {
|
||||
func (r *mutationResolver) Signup(ctx context.Context, params model.SignUpInput) (*model.Response, error) {
|
||||
return resolvers.Signup(ctx, params)
|
||||
}
|
||||
|
||||
func (r *mutationResolver) VerifySignupToken(ctx context.Context, params model.VerifySignupTokenInput) (*model.LoginResponse, error) {
|
||||
return resolvers.VerifySignupToken(ctx, params)
|
||||
}
|
||||
|
||||
func (r *mutationResolver) Login(ctx context.Context, params model.LoginInput) (*model.LoginResponse, error) {
|
||||
return resolvers.Login(ctx, params)
|
||||
}
|
||||
|
@ -27,6 +23,14 @@ func (r *mutationResolver) Logout(ctx context.Context) (*model.Response, error)
|
|||
return resolvers.Logout(ctx)
|
||||
}
|
||||
|
||||
func (r *mutationResolver) UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
||||
return resolvers.UpdateProfile(ctx, params)
|
||||
}
|
||||
|
||||
func (r *mutationResolver) VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.LoginResponse, error) {
|
||||
return resolvers.VerifyEmail(ctx, params)
|
||||
}
|
||||
|
||||
func (r *queryResolver) Users(ctx context.Context) ([]*model.User, error) {
|
||||
return resolvers.Users(ctx)
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ package resolvers
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
@ -25,15 +24,15 @@ func Login(ctx context.Context, params model.LoginInput) (*model.LoginResponse,
|
|||
params.Email = strings.ToLower(params.Email)
|
||||
user, err := db.Mgr.GetUserByEmail(params.Email)
|
||||
if err != nil {
|
||||
return res, errors.New(`User with this email not found`)
|
||||
return res, fmt.Errorf(`user with this email not found`)
|
||||
}
|
||||
|
||||
if !strings.Contains(user.SignupMethod, enum.BasicAuth.String()) {
|
||||
return res, errors.New(`User has not signed up email & password`)
|
||||
return res, fmt.Errorf(`user has not signed up email & password`)
|
||||
}
|
||||
|
||||
if user.EmailVerifiedAt <= 0 {
|
||||
return res, errors.New(`Email not verified`)
|
||||
return res, fmt.Errorf(`email not verified`)
|
||||
}
|
||||
// match password
|
||||
cost, err := bcrypt.Cost([]byte(user.Password))
|
||||
|
@ -42,7 +41,7 @@ func Login(ctx context.Context, params model.LoginInput) (*model.LoginResponse,
|
|||
|
||||
if err != nil {
|
||||
log.Println("Compare password error:", err)
|
||||
return res, errors.New(`Invalid Password`)
|
||||
return res, fmt.Errorf(`invalid password`)
|
||||
}
|
||||
userIdStr := fmt.Sprintf("%d", user.ID)
|
||||
refreshToken, _, _ := utils.CreateAuthToken(utils.UserAuthInfo{
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"github.com/yauthdev/yauth/server/db"
|
||||
"github.com/yauthdev/yauth/server/graph/model"
|
||||
"github.com/yauthdev/yauth/server/session"
|
||||
"github.com/yauthdev/yauth/server/utils"
|
||||
)
|
||||
|
||||
|
@ -26,6 +27,12 @@ func Profile(ctx context.Context) (*model.User, error) {
|
|||
return res, err
|
||||
}
|
||||
|
||||
sessionToken := session.GetToken(claim.ID)
|
||||
|
||||
if sessionToken == "" {
|
||||
return res, fmt.Errorf(`unauthorized`)
|
||||
}
|
||||
|
||||
user, err := db.Mgr.GetUserByEmail(claim.Email)
|
||||
if err != nil {
|
||||
return res, err
|
||||
|
|
|
@ -2,7 +2,7 @@ package resolvers
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -13,16 +13,16 @@ import (
|
|||
"github.com/yauthdev/yauth/server/utils"
|
||||
)
|
||||
|
||||
func Signup(ctx context.Context, params model.SignUpInput) (*model.SignUpResponse, error) {
|
||||
var res *model.SignUpResponse
|
||||
func Signup(ctx context.Context, params model.SignUpInput) (*model.Response, error) {
|
||||
var res *model.Response
|
||||
if params.CofirmPassword != params.Password {
|
||||
return res, errors.New(`Passowrd and Confirm Password does not match`)
|
||||
return res, fmt.Errorf(`passowrd and confirm password does not match`)
|
||||
}
|
||||
|
||||
params.Email = strings.ToLower(params.Email)
|
||||
|
||||
if !utils.IsValidEmail(params.Email) {
|
||||
return res, errors.New(`Invalid email address`)
|
||||
return res, fmt.Errorf(`invalid email address`)
|
||||
}
|
||||
|
||||
// find user with email
|
||||
|
@ -33,7 +33,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.SignUpRespons
|
|||
|
||||
if existingUser.EmailVerifiedAt > 0 {
|
||||
// email is verified
|
||||
return res, errors.New(`You have already signed up. Please login`)
|
||||
return res, fmt.Errorf(`you have already signed up. Please login`)
|
||||
}
|
||||
user := db.User{
|
||||
Email: params.Email,
|
||||
|
@ -57,7 +57,7 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.SignUpRespons
|
|||
}
|
||||
|
||||
// insert verification request
|
||||
verificationType := enum.BasicAuth.String()
|
||||
verificationType := enum.BasicAuthSignup.String()
|
||||
token, err := utils.CreateVerificationToken(params.Email, verificationType)
|
||||
if err != nil {
|
||||
log.Println(`Error generating token`, err)
|
||||
|
@ -74,8 +74,8 @@ func Signup(ctx context.Context, params model.SignUpInput) (*model.SignUpRespons
|
|||
utils.SendVerificationMail(params.Email, token)
|
||||
}()
|
||||
|
||||
res = &model.SignUpResponse{
|
||||
Message: `Verification email sent successfully. Please check your inbox`,
|
||||
res = &model.Response{
|
||||
Message: `Verification email has been sent. Please check your inbox`,
|
||||
}
|
||||
|
||||
return res, nil
|
||||
|
|
|
@ -2,7 +2,6 @@ package resolvers
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/yauthdev/yauth/server/db"
|
||||
|
@ -36,19 +35,17 @@ func Token(ctx context.Context) (*model.LoginResponse, error) {
|
|||
sessionToken := session.GetToken(userIdStr)
|
||||
|
||||
if sessionToken == "" {
|
||||
return res, errors.New(`Unauthorized`)
|
||||
return res, fmt.Errorf(`unauthorized`)
|
||||
}
|
||||
// TODO check if session token has expired
|
||||
|
||||
if accessTokenErr != nil {
|
||||
// if access token has expired and refresh/session token is valid
|
||||
// generate new accessToken
|
||||
fmt.Println(`here... getting new accesstoken`)
|
||||
token, expiresAt, _ = utils.CreateAuthToken(utils.UserAuthInfo{
|
||||
ID: userIdStr,
|
||||
Email: user.Email,
|
||||
}, enum.AccessToken)
|
||||
|
||||
}
|
||||
utils.SetCookie(gc, token)
|
||||
res = &model.LoginResponse{
|
||||
|
|
136
server/resolvers/updateProfile.go
Normal file
136
server/resolvers/updateProfile.go
Normal file
|
@ -0,0 +1,136 @@
|
|||
package resolvers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/yauthdev/yauth/server/db"
|
||||
"github.com/yauthdev/yauth/server/enum"
|
||||
"github.com/yauthdev/yauth/server/graph/model"
|
||||
"github.com/yauthdev/yauth/server/session"
|
||||
"github.com/yauthdev/yauth/server/utils"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func UpdateProfile(ctx context.Context, params model.UpdateProfileInput) (*model.Response, error) {
|
||||
gc, err := utils.GinContextFromContext(ctx)
|
||||
var res *model.Response
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
token, err := utils.GetAuthToken(gc)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
claim, err := utils.VerifyAuthToken(token)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
sessionToken := session.GetToken(claim.ID)
|
||||
|
||||
if sessionToken == "" {
|
||||
return res, fmt.Errorf(`unauthorized`)
|
||||
}
|
||||
|
||||
// validate if all params are not empty
|
||||
if params.FirstName == nil && params.LastName == nil && params.Image == nil && params.OldPassword == nil && params.Email == nil {
|
||||
return res, fmt.Errorf("please enter atleast one param to update")
|
||||
}
|
||||
|
||||
user, err := db.Mgr.GetUserByEmail(claim.Email)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
|
||||
if params.FirstName != nil && user.FirstName != *params.FirstName {
|
||||
user.FirstName = *params.FirstName
|
||||
}
|
||||
|
||||
if params.LastName != nil && user.LastName != *params.LastName {
|
||||
user.LastName = *params.LastName
|
||||
}
|
||||
|
||||
if params.Image != nil && user.Image != *params.Image {
|
||||
user.Image = *params.Image
|
||||
}
|
||||
|
||||
if params.OldPassword != nil {
|
||||
if err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(*params.OldPassword)); err != nil {
|
||||
return res, fmt.Errorf("incorrect old password")
|
||||
}
|
||||
|
||||
if params.NewPassword == nil {
|
||||
return res, fmt.Errorf("new password is required")
|
||||
}
|
||||
|
||||
if params.ConfirmNewPassword == nil {
|
||||
return res, fmt.Errorf("confirm password is required")
|
||||
}
|
||||
|
||||
if *params.ConfirmNewPassword != *params.NewPassword {
|
||||
return res, fmt.Errorf(`password and confirm password does not match`)
|
||||
}
|
||||
|
||||
password, _ := utils.HashPassword(*params.NewPassword)
|
||||
|
||||
user.Password = password
|
||||
}
|
||||
|
||||
hasEmailChanged := false
|
||||
|
||||
if params.Email != nil && user.Email != *params.Email {
|
||||
// check if valid email
|
||||
if !utils.IsValidEmail(*params.Email) {
|
||||
return res, fmt.Errorf("invalid email address")
|
||||
}
|
||||
newEmail := strings.ToLower(*params.Email)
|
||||
// check if user with new email exists
|
||||
_, err = db.Mgr.GetUserByEmail(newEmail)
|
||||
// err = nil means user exists
|
||||
if err == nil {
|
||||
return res, fmt.Errorf("user with this email address already exists")
|
||||
}
|
||||
|
||||
session.DeleteToken(fmt.Sprintf("%d", user.ID))
|
||||
utils.DeleteCookie(gc)
|
||||
|
||||
user.Email = newEmail
|
||||
user.EmailVerifiedAt = 0
|
||||
hasEmailChanged = true
|
||||
// insert verification request
|
||||
verificationType := enum.UpdateEmail.String()
|
||||
token, err := utils.CreateVerificationToken(newEmail, verificationType)
|
||||
if err != nil {
|
||||
log.Println(`Error generating token`, err)
|
||||
}
|
||||
db.Mgr.AddVerification(db.Verification{
|
||||
Token: token,
|
||||
Identifier: verificationType,
|
||||
ExpiresAt: time.Now().Add(time.Minute * 30).Unix(),
|
||||
Email: newEmail,
|
||||
})
|
||||
|
||||
// exec it as go routin so that we can reduce the api latency
|
||||
go func() {
|
||||
utils.SendVerificationMail(newEmail, token)
|
||||
}()
|
||||
|
||||
}
|
||||
|
||||
_, err = db.Mgr.UpdateUser(user)
|
||||
message := `Profile details updated successfully.`
|
||||
if hasEmailChanged {
|
||||
message += `For the email change we have sent new verification email, please verify and continue`
|
||||
}
|
||||
res = &model.Response{
|
||||
Message: message,
|
||||
}
|
||||
|
||||
return res, nil
|
||||
}
|
|
@ -2,7 +2,6 @@ package resolvers
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
|
@ -13,7 +12,7 @@ import (
|
|||
"github.com/yauthdev/yauth/server/utils"
|
||||
)
|
||||
|
||||
func VerifySignupToken(ctx context.Context, params model.VerifySignupTokenInput) (*model.LoginResponse, error) {
|
||||
func VerifyEmail(ctx context.Context, params model.VerifyEmailInput) (*model.LoginResponse, error) {
|
||||
gc, err := utils.GinContextFromContext(ctx)
|
||||
var res *model.LoginResponse
|
||||
if err != nil {
|
||||
|
@ -22,13 +21,13 @@ func VerifySignupToken(ctx context.Context, params model.VerifySignupTokenInput)
|
|||
|
||||
_, err = db.Mgr.GetVerificationByToken(params.Token)
|
||||
if err != nil {
|
||||
return res, errors.New(`Invalid token`)
|
||||
return res, fmt.Errorf(`invalid token`)
|
||||
}
|
||||
|
||||
// verify if token exists in db
|
||||
claim, err := utils.VerifyVerificationToken(params.Token)
|
||||
if err != nil {
|
||||
return res, errors.New(`Invalid token`)
|
||||
return res, fmt.Errorf(`invalid token`)
|
||||
}
|
||||
|
||||
user, err := db.Mgr.GetUserByEmail(claim.Email)
|
|
@ -1,7 +1,7 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -56,7 +56,7 @@ func GetAuthToken(gc *gin.Context) (string, error) {
|
|||
log.Println("cookie not found checking headers")
|
||||
auth := gc.Request.Header.Get("Authorization")
|
||||
if auth == "" {
|
||||
return "", errors.New(`Unauthorized`)
|
||||
return "", fmt.Errorf(`Unauthorized`)
|
||||
}
|
||||
|
||||
token = strings.TrimPrefix(auth, "Bearer ")
|
||||
|
|
Loading…
Reference in New Issue
Block a user