From 32fcba0f8d5731d5b47b3c986822842a0dc676ba Mon Sep 17 00:00:00 2001 From: Lakhan Samani Date: Sun, 3 Dec 2023 22:27:56 +0530 Subject: [PATCH] Fix/forgot password (#430) * fix: forgot password shown with magic link login * fix: forgot password shown with magic link login * fix is basic auth enabled --- app/package-lock.json | 25 +++-- app/package.json | 2 +- app/src/pages/login.tsx | 27 +++-- app/yarn.lock | 24 +++-- server/graph/generated/generated.go | 152 +++++++++++++++++++++++++--- server/graph/model/models_gen.go | 34 ++++--- server/graph/schema.graphqls | 2 + server/resolvers/meta.go | 42 +++++--- 8 files changed, 232 insertions(+), 76 deletions(-) diff --git a/app/package-lock.json b/app/package-lock.json index f8d8f6306..62ac19d51 100644 --- a/app/package-lock.json +++ b/app/package-lock.json @@ -9,7 +9,7 @@ "version": "1.0.0", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.15", + "@authorizerdev/authorizer-react": "^1.1.18", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", @@ -27,9 +27,9 @@ } }, "node_modules/@authorizerdev/authorizer-js": { - "version": "1.2.17", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.17.tgz", - "integrity": "sha512-aF/lu9wZR7TBRaRMAes/hy1q8cZzz5Zo60QLU9Iu09sqnhliHJCp5wSkjsVH+V4ER9i7bmJ2HNABTmOdluxj3A==", + "version": "1.2.18", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.18.tgz", + "integrity": "sha512-9j5U/4lqaaEcG78Zli+TtLJ0migSKhFwnXXunulAGTZOzQSTCJ/CSSPip5wWNa/Mkr6gdEMwk1HYfhIdk2A9Mg==", "dependencies": { "cross-fetch": "^3.1.5" }, @@ -41,11 +41,12 @@ } }, "node_modules/@authorizerdev/authorizer-react": { - "version": "1.1.15", - "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.15.tgz", - "integrity": "sha512-Y71qC4GUAHL0QCNj5mVv0Jwv1cIg4Y0yXRiOeYV21C1NMleyLRXgw4qzJ/Vk8rmXsxqSHmr8SGrwOLcSKA2oMA==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.18.tgz", + "integrity": "sha512-5SgFzG1VatmrMpl9XKwPcoVmCayA4Hn+sd2I9CwRlCWkdcna4pGJL8kYesuIGjGagS9394qp4ICRLRZ35wXj8A==", "dependencies": { - "@authorizerdev/authorizer-js": "^1.2.17" + "@authorizerdev/authorizer-js": "^1.2.18", + "validator": "^13.11.0" }, "engines": { "node": ">=10" @@ -847,6 +848,14 @@ "node": ">=4.2.0" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/value-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", diff --git a/app/package.json b/app/package.json index 5221603bf..530b65ce1 100644 --- a/app/package.json +++ b/app/package.json @@ -12,7 +12,7 @@ "author": "Lakhan Samani", "license": "ISC", "dependencies": { - "@authorizerdev/authorizer-react": "^1.1.15", + "@authorizerdev/authorizer-react": "^1.1.18", "@types/react": "^17.0.15", "@types/react-dom": "^17.0.9", "esbuild": "^0.12.17", diff --git a/app/src/pages/login.tsx b/app/src/pages/login.tsx index 3e8e4a196..d53d36c83 100644 --- a/app/src/pages/login.tsx +++ b/app/src/pages/login.tsx @@ -32,6 +32,7 @@ const FooterContent = styled.div` export default function Login({ urlProps }: { urlProps: Record }) { const { config } = useAuthorizer(); const [view, setView] = useState(VIEW_TYPES.LOGIN); + const isBasicAuth = config.is_basic_authentication_enabled; return ( {view === VIEW_TYPES.LOGIN && ( @@ -39,22 +40,26 @@ export default function Login({ urlProps }: { urlProps: Record }) {

Login


- {config.is_basic_authentication_enabled && + {(config.is_basic_authentication_enabled || + config.is_mobile_basic_authentication_enabled) && !config.is_magic_link_login_enabled && ( )} {config.is_magic_link_login_enabled && ( )} -
- setView(VIEW_TYPES.FORGOT_PASSWORD)} - style={{ marginBottom: 10 }} - > - Forgot Password? - -
+ {(config.is_basic_authentication_enabled || + config.is_mobile_basic_authentication_enabled) && ( +
+ setView(VIEW_TYPES.FORGOT_PASSWORD)} + style={{ marginBottom: 10 }} + > + Forgot Password? + +
+ )}
)} {view === VIEW_TYPES.FORGOT_PASSWORD && ( @@ -81,7 +86,7 @@ export default function Login({ urlProps }: { urlProps: Record }) { !config.is_magic_link_login_enabled && config.is_sign_up_enabled && ( - Don't have an account? Sign Up + Don't have an account?   Sign Up )} diff --git a/app/yarn.lock b/app/yarn.lock index 5e2c385da..d9fa87187 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -2,19 +2,20 @@ # yarn lockfile v1 -"@authorizerdev/authorizer-js@^1.2.17": - version "1.2.17" - resolved "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.17.tgz" - integrity sha512-aF/lu9wZR7TBRaRMAes/hy1q8cZzz5Zo60QLU9Iu09sqnhliHJCp5wSkjsVH+V4ER9i7bmJ2HNABTmOdluxj3A== +"@authorizerdev/authorizer-js@^1.2.18": + version "1.2.18" + resolved "https://registry.npmjs.org/@authorizerdev/authorizer-js/-/authorizer-js-1.2.18.tgz" + integrity sha512-9j5U/4lqaaEcG78Zli+TtLJ0migSKhFwnXXunulAGTZOzQSTCJ/CSSPip5wWNa/Mkr6gdEMwk1HYfhIdk2A9Mg== dependencies: cross-fetch "^3.1.5" -"@authorizerdev/authorizer-react@^1.1.15": - version "1.1.15" - resolved "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.15.tgz" - integrity sha512-Y71qC4GUAHL0QCNj5mVv0Jwv1cIg4Y0yXRiOeYV21C1NMleyLRXgw4qzJ/Vk8rmXsxqSHmr8SGrwOLcSKA2oMA== +"@authorizerdev/authorizer-react@^1.1.18": + version "1.1.18" + resolved "https://registry.npmjs.org/@authorizerdev/authorizer-react/-/authorizer-react-1.1.18.tgz" + integrity sha512-5SgFzG1VatmrMpl9XKwPcoVmCayA4Hn+sd2I9CwRlCWkdcna4pGJL8kYesuIGjGagS9394qp4ICRLRZ35wXj8A== dependencies: - "@authorizerdev/authorizer-js" "^1.2.17" + "@authorizerdev/authorizer-js" "^1.2.18" + validator "^13.11.0" "@babel/code-frame@^7.22.13": version "7.22.13" @@ -594,6 +595,11 @@ typescript@^4.3.5: resolved "https://registry.npmjs.org/typescript/-/typescript-4.3.5.tgz" integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +validator@^13.11.0: + version "13.11.0" + resolved "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz" + integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + value-equal@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz" diff --git a/server/graph/generated/generated.go b/server/graph/generated/generated.go index df7829ace..b0792bcb6 100644 --- a/server/graph/generated/generated.go +++ b/server/graph/generated/generated.go @@ -162,22 +162,24 @@ type ComplexityRoot struct { } Meta struct { - ClientID func(childComplexity int) int - IsAppleLoginEnabled func(childComplexity int) int - IsBasicAuthenticationEnabled func(childComplexity int) int - IsEmailVerificationEnabled func(childComplexity int) int - IsFacebookLoginEnabled func(childComplexity int) int - IsGithubLoginEnabled func(childComplexity int) int - IsGoogleLoginEnabled func(childComplexity int) int - IsLinkedinLoginEnabled func(childComplexity int) int - IsMagicLinkLoginEnabled func(childComplexity int) int - IsMicrosoftLoginEnabled func(childComplexity int) int - IsMultiFactorAuthEnabled func(childComplexity int) int - IsSignUpEnabled func(childComplexity int) int - IsStrongPasswordEnabled func(childComplexity int) int - IsTwitchLoginEnabled func(childComplexity int) int - IsTwitterLoginEnabled func(childComplexity int) int - Version func(childComplexity int) int + ClientID func(childComplexity int) int + IsAppleLoginEnabled func(childComplexity int) int + IsBasicAuthenticationEnabled func(childComplexity int) int + IsEmailVerificationEnabled func(childComplexity int) int + IsFacebookLoginEnabled func(childComplexity int) int + IsGithubLoginEnabled func(childComplexity int) int + IsGoogleLoginEnabled func(childComplexity int) int + IsLinkedinLoginEnabled func(childComplexity int) int + IsMagicLinkLoginEnabled func(childComplexity int) int + IsMicrosoftLoginEnabled func(childComplexity int) int + IsMobileBasicAuthenticationEnabled func(childComplexity int) int + IsMultiFactorAuthEnabled func(childComplexity int) int + IsPhoneVerificationEnabled func(childComplexity int) int + IsSignUpEnabled func(childComplexity int) int + IsStrongPasswordEnabled func(childComplexity int) int + IsTwitchLoginEnabled func(childComplexity int) int + IsTwitterLoginEnabled func(childComplexity int) int + Version func(childComplexity int) int } Mutation struct { @@ -1142,6 +1144,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Meta.IsMicrosoftLoginEnabled(childComplexity), true + case "Meta.is_mobile_basic_authentication_enabled": + if e.complexity.Meta.IsMobileBasicAuthenticationEnabled == nil { + break + } + + return e.complexity.Meta.IsMobileBasicAuthenticationEnabled(childComplexity), true + case "Meta.is_multi_factor_auth_enabled": if e.complexity.Meta.IsMultiFactorAuthEnabled == nil { break @@ -1149,6 +1158,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.Meta.IsMultiFactorAuthEnabled(childComplexity), true + case "Meta.is_phone_verification_enabled": + if e.complexity.Meta.IsPhoneVerificationEnabled == nil { + break + } + + return e.complexity.Meta.IsPhoneVerificationEnabled(childComplexity), true + case "Meta.is_sign_up_enabled": if e.complexity.Meta.IsSignUpEnabled == nil { break @@ -2355,6 +2371,8 @@ type Meta { is_sign_up_enabled: Boolean! is_strong_password_enabled: Boolean! is_multi_factor_auth_enabled: Boolean! + is_mobile_basic_authentication_enabled: Boolean! + is_phone_verification_enabled: Boolean! } type User { @@ -8373,6 +8391,94 @@ func (ec *executionContext) fieldContext_Meta_is_multi_factor_auth_enabled(ctx c return fc, nil } +func (ec *executionContext) _Meta_is_mobile_basic_authentication_enabled(ctx context.Context, field graphql.CollectedField, obj *model.Meta) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Meta_is_mobile_basic_authentication_enabled(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsMobileBasicAuthenticationEnabled, 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) fieldContext_Meta_is_mobile_basic_authentication_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Meta", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + +func (ec *executionContext) _Meta_is_phone_verification_enabled(ctx context.Context, field graphql.CollectedField, obj *model.Meta) (ret graphql.Marshaler) { + fc, err := ec.fieldContext_Meta_is_phone_verification_enabled(ctx, field) + if err != nil { + return graphql.Null + } + ctx = graphql.WithFieldContext(ctx, fc) + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return obj.IsPhoneVerificationEnabled, 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) fieldContext_Meta_is_phone_verification_enabled(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Meta", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return nil, errors.New("field of type Boolean does not have child fields") + }, + } + return fc, nil +} + func (ec *executionContext) _Mutation_signup(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { fc, err := ec.fieldContext_Mutation_signup(ctx, field) if err != nil { @@ -10653,6 +10759,10 @@ func (ec *executionContext) fieldContext_Query_meta(ctx context.Context, field g return ec.fieldContext_Meta_is_strong_password_enabled(ctx, field) case "is_multi_factor_auth_enabled": return ec.fieldContext_Meta_is_multi_factor_auth_enabled(ctx, field) + case "is_mobile_basic_authentication_enabled": + return ec.fieldContext_Meta_is_mobile_basic_authentication_enabled(ctx, field) + case "is_phone_verification_enabled": + return ec.fieldContext_Meta_is_phone_verification_enabled(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type Meta", field.Name) }, @@ -19594,6 +19704,16 @@ func (ec *executionContext) _Meta(ctx context.Context, sel ast.SelectionSet, obj if out.Values[i] == graphql.Null { out.Invalids++ } + case "is_mobile_basic_authentication_enabled": + out.Values[i] = ec._Meta_is_mobile_basic_authentication_enabled(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "is_phone_verification_enabled": + out.Values[i] = ec._Meta_is_phone_verification_enabled(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/server/graph/model/models_gen.go b/server/graph/model/models_gen.go index 06a93eefb..45f588973 100644 --- a/server/graph/model/models_gen.go +++ b/server/graph/model/models_gen.go @@ -191,22 +191,24 @@ type MagicLinkLoginInput struct { } type Meta struct { - Version string `json:"version"` - ClientID string `json:"client_id"` - IsGoogleLoginEnabled bool `json:"is_google_login_enabled"` - IsFacebookLoginEnabled bool `json:"is_facebook_login_enabled"` - IsGithubLoginEnabled bool `json:"is_github_login_enabled"` - IsLinkedinLoginEnabled bool `json:"is_linkedin_login_enabled"` - IsAppleLoginEnabled bool `json:"is_apple_login_enabled"` - IsTwitterLoginEnabled bool `json:"is_twitter_login_enabled"` - IsMicrosoftLoginEnabled bool `json:"is_microsoft_login_enabled"` - IsTwitchLoginEnabled bool `json:"is_twitch_login_enabled"` - IsEmailVerificationEnabled bool `json:"is_email_verification_enabled"` - IsBasicAuthenticationEnabled bool `json:"is_basic_authentication_enabled"` - IsMagicLinkLoginEnabled bool `json:"is_magic_link_login_enabled"` - IsSignUpEnabled bool `json:"is_sign_up_enabled"` - IsStrongPasswordEnabled bool `json:"is_strong_password_enabled"` - IsMultiFactorAuthEnabled bool `json:"is_multi_factor_auth_enabled"` + Version string `json:"version"` + ClientID string `json:"client_id"` + IsGoogleLoginEnabled bool `json:"is_google_login_enabled"` + IsFacebookLoginEnabled bool `json:"is_facebook_login_enabled"` + IsGithubLoginEnabled bool `json:"is_github_login_enabled"` + IsLinkedinLoginEnabled bool `json:"is_linkedin_login_enabled"` + IsAppleLoginEnabled bool `json:"is_apple_login_enabled"` + IsTwitterLoginEnabled bool `json:"is_twitter_login_enabled"` + IsMicrosoftLoginEnabled bool `json:"is_microsoft_login_enabled"` + IsTwitchLoginEnabled bool `json:"is_twitch_login_enabled"` + IsEmailVerificationEnabled bool `json:"is_email_verification_enabled"` + IsBasicAuthenticationEnabled bool `json:"is_basic_authentication_enabled"` + IsMagicLinkLoginEnabled bool `json:"is_magic_link_login_enabled"` + IsSignUpEnabled bool `json:"is_sign_up_enabled"` + IsStrongPasswordEnabled bool `json:"is_strong_password_enabled"` + IsMultiFactorAuthEnabled bool `json:"is_multi_factor_auth_enabled"` + IsMobileBasicAuthenticationEnabled bool `json:"is_mobile_basic_authentication_enabled"` + IsPhoneVerificationEnabled bool `json:"is_phone_verification_enabled"` } type MobileLoginInput struct { diff --git a/server/graph/schema.graphqls b/server/graph/schema.graphqls index 35e64597b..07d36783b 100644 --- a/server/graph/schema.graphqls +++ b/server/graph/schema.graphqls @@ -29,6 +29,8 @@ type Meta { is_sign_up_enabled: Boolean! is_strong_password_enabled: Boolean! is_multi_factor_auth_enabled: Boolean! + is_mobile_basic_authentication_enabled: Boolean! + is_phone_verification_enabled: Boolean! } type User { diff --git a/server/resolvers/meta.go b/server/resolvers/meta.go index 9290a415d..cbab1e062 100644 --- a/server/resolvers/meta.go +++ b/server/resolvers/meta.go @@ -106,6 +106,16 @@ func MetaResolver(ctx context.Context) (*model.Meta, error) { log.Debug("Failed to get Disable Basic Authentication from environment variable", err) isBasicAuthDisabled = true } + isMobileBasicAuthDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableMobileBasicAuthentication) + if err != nil { + log.Debug("Failed to get Disable Basic Authentication from environment variable", err) + isMobileBasicAuthDisabled = true + } + isMobileVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisablePhoneVerification) + if err != nil { + log.Debug("Failed to get Disable Basic Authentication from environment variable", err) + isMobileVerificationDisabled = true + } isEmailVerificationDisabled, err := memorystore.Provider.GetBoolStoreEnvVariable(constants.EnvKeyDisableEmailVerification) if err != nil { @@ -138,21 +148,23 @@ func MetaResolver(ctx context.Context) (*model.Meta, error) { } metaInfo := model.Meta{ - Version: constants.VERSION, - ClientID: clientID, - IsGoogleLoginEnabled: googleClientID != "" && googleClientSecret != "", - IsGithubLoginEnabled: githubClientID != "" && githubClientSecret != "", - IsFacebookLoginEnabled: facebookClientID != "" && facebookClientSecret != "", - IsLinkedinLoginEnabled: linkedClientID != "" && linkedInClientSecret != "", - IsAppleLoginEnabled: appleClientID != "" && appleClientSecret != "", - IsTwitterLoginEnabled: twitterClientID != "" && twitterClientSecret != "", - IsMicrosoftLoginEnabled: microsoftClientID != "" && microsoftClientSecret != "", - IsBasicAuthenticationEnabled: !isBasicAuthDisabled, - IsEmailVerificationEnabled: !isEmailVerificationDisabled, - IsMagicLinkLoginEnabled: !isMagicLinkLoginDisabled, - IsSignUpEnabled: !isSignUpDisabled, - IsStrongPasswordEnabled: !isStrongPasswordDisabled, - IsMultiFactorAuthEnabled: !isMultiFactorAuthenticationEnabled, + Version: constants.VERSION, + ClientID: clientID, + IsGoogleLoginEnabled: googleClientID != "" && googleClientSecret != "", + IsGithubLoginEnabled: githubClientID != "" && githubClientSecret != "", + IsFacebookLoginEnabled: facebookClientID != "" && facebookClientSecret != "", + IsLinkedinLoginEnabled: linkedClientID != "" && linkedInClientSecret != "", + IsAppleLoginEnabled: appleClientID != "" && appleClientSecret != "", + IsTwitterLoginEnabled: twitterClientID != "" && twitterClientSecret != "", + IsMicrosoftLoginEnabled: microsoftClientID != "" && microsoftClientSecret != "", + IsBasicAuthenticationEnabled: !isBasicAuthDisabled, + IsEmailVerificationEnabled: !isEmailVerificationDisabled, + IsMagicLinkLoginEnabled: !isMagicLinkLoginDisabled, + IsSignUpEnabled: !isSignUpDisabled, + IsStrongPasswordEnabled: !isStrongPasswordDisabled, + IsMultiFactorAuthEnabled: !isMultiFactorAuthenticationEnabled, + IsMobileBasicAuthenticationEnabled: !isMobileBasicAuthDisabled, + IsPhoneVerificationEnabled: !isMobileVerificationDisabled, } return &metaInfo, nil }