diff --git a/dashboard/package-lock.json b/dashboard/package-lock.json index c04cac0..41d31f9 100644 --- a/dashboard/package-lock.json +++ b/dashboard/package-lock.json @@ -2529,8 +2529,7 @@ "@chakra-ui/css-reset": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@chakra-ui/css-reset/-/css-reset-1.1.1.tgz", - "integrity": "sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg==", - "requires": {} + "integrity": "sha512-+KNNHL4OWqeKia5SL858K3Qbd8WxMij9mWIilBzLD4j2KFrl/+aWFw8syMKth3NmgIibrjsljo+PU3fy2o50dg==" }, "@chakra-ui/descendant": { "version": "2.1.1", @@ -3134,8 +3133,7 @@ "@graphql-typed-document-node/core": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.1.1.tgz", - "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==", - "requires": {} + "integrity": "sha512-NQ17ii0rK1b34VZonlmT2QMJFI70m0TRwbknO/ihlbatXyaktDhN/98vBiUU6kNBPljqGqyIrl2T4nY2RpFANg==" }, "@popperjs/core": { "version": "2.11.0", @@ -3845,8 +3843,7 @@ "react-icons": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.3.1.tgz", - "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==", - "requires": {} + "integrity": "sha512-cB10MXLTs3gVuXimblAdI71jrJx8njrJZmNMEMC+sQu5B/BIOmlsAjskdqpn81y8UBVEGuHODd7/ci5DvoSzTQ==" }, "react-is": { "version": "16.13.1", @@ -4032,8 +4029,7 @@ "use-callback-ref": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz", - "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==", - "requires": {} + "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==" }, "use-sidecar": { "version": "1.0.5", diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index 850c964..535821f 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -44,12 +44,13 @@ type DirectiveRoot struct { type ComplexityRoot struct { AuthResponse struct { - AccessToken func(childComplexity int) int - ExpiresIn func(childComplexity int) int - IDToken func(childComplexity int) int - Message func(childComplexity int) int - RefreshToken func(childComplexity int) int - User func(childComplexity int) int + AccessToken func(childComplexity int) int + ExpiresIn func(childComplexity int) int + IDToken func(childComplexity int) int + Message func(childComplexity int) int + RefreshToken func(childComplexity int) int + ShouldShowOtpScreen func(childComplexity int) int + User func(childComplexity int) int } EmailTemplate struct { @@ -378,6 +379,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.AuthResponse.RefreshToken(childComplexity), true + case "AuthResponse.should_show_otp_screen": + if e.complexity.AuthResponse.ShouldShowOtpScreen == nil { + break + } + + return e.complexity.AuthResponse.ShouldShowOtpScreen(childComplexity), true + case "AuthResponse.user": if e.complexity.AuthResponse.User == nil { break @@ -1890,6 +1898,7 @@ type Error { type AuthResponse { message: String! + should_show_otp_screen: Boolean access_token: String id_token: String refresh_token: String @@ -2890,6 +2899,38 @@ func (ec *executionContext) _AuthResponse_message(ctx context.Context, field gra return ec.marshalNString2string(ctx, field.Selections, res) } +func (ec *executionContext) _AuthResponse_should_show_otp_screen(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "AuthResponse", + 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.ShouldShowOtpScreen, nil + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.(*bool) + fc.Result = res + return ec.marshalOBoolean2ᚖbool(ctx, field.Selections, res) +} + func (ec *executionContext) _AuthResponse_access_token(ctx context.Context, field graphql.CollectedField, obj *model.AuthResponse) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -11761,6 +11802,8 @@ func (ec *executionContext) _AuthResponse(ctx context.Context, sel ast.Selection if out.Values[i] == graphql.Null { invalids++ } + case "should_show_otp_screen": + out.Values[i] = ec._AuthResponse_should_show_otp_screen(ctx, field, obj) case "access_token": out.Values[i] = ec._AuthResponse_access_token(ctx, field, obj) case "id_token": diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index e9addef..bbdb2f7 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -23,12 +23,13 @@ type AdminSignupInput struct { } type AuthResponse struct { - Message string `json:"message"` - AccessToken *string `json:"access_token"` - IDToken *string `json:"id_token"` - RefreshToken *string `json:"refresh_token"` - ExpiresIn *int64 `json:"expires_in"` - User *User `json:"user"` + Message string `json:"message"` + ShouldShowOtpScreen *bool `json:"should_show_otp_screen"` + AccessToken *string `json:"access_token"` + IDToken *string `json:"id_token"` + RefreshToken *string `json:"refresh_token"` + ExpiresIn *int64 `json:"expires_in"` + User *User `json:"user"` } type DeleteEmailTemplateRequest struct { diff --git a/server/graph/schema.resolvers.go b/server/graph/schema.resolvers.go index 193e1f0..e224137 100644 --- a/server/graph/schema.resolvers.go +++ b/server/graph/schema.resolvers.go @@ -177,7 +177,5 @@ func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResol // Query returns generated.QueryResolver implementation. func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } -type ( - mutationResolver struct{ *Resolver } - queryResolver struct{ *Resolver } -) +type mutationResolver struct{ *Resolver } +type queryResolver struct{ *Resolver } diff --git a/server/resolvers/login.go b/server/resolvers/login.go index e55f984..c163528 100644 --- a/server/resolvers/login.go +++ b/server/resolvers/login.go @@ -15,6 +15,7 @@ import ( "github.com/authorizerdev/authorizer/server/db/models" "github.com/authorizerdev/authorizer/server/graph/model" "github.com/authorizerdev/authorizer/server/memorystore" + "github.com/authorizerdev/authorizer/server/refs" "github.com/authorizerdev/authorizer/server/token" "github.com/authorizerdev/authorizer/server/utils" "github.com/authorizerdev/authorizer/server/validators" @@ -97,6 +98,13 @@ func LoginResolver(ctx context.Context, params model.LoginInput) (*model.AuthRes scope = params.Scope } + if refs.BoolValue(user.IsMultiFactorAuthEnabled) { + return &model.AuthResponse{ + Message: "Please check the OTP in your inbox", + ShouldShowOtpScreen: refs.NewBoolRef(true), + }, nil + } + authToken, err := token.CreateAuthToken(gc, user, roles, scope, constants.AuthRecipeMethodBasicAuth) if err != nil { log.Debug("Failed to create auth token", err)