diff --git a/api/openapi.yml b/api/openapi.yml
index 35136362d..10ec36b9d 100644
--- a/api/openapi.yml
+++ b/api/openapi.yml
@@ -44,6 +44,20 @@ paths:
description: Forbidden
security:
- authelia_auth: []
+ /api/configuration/password-policy:
+ get:
+ tags:
+ - State
+ summary: Password Policy Configuration
+ description: >
+ The password policy configuration endpoint provides a password policy for resetting passwords.
+ responses:
+ "200":
+ description: Successful Operation
+ content:
+ application/json:
+ schema:
+ $ref: '#/components/schemas/handlers.configuration.PasswordPolicyConfigurationBody'
/api/health:
get:
tags:
@@ -694,6 +708,43 @@ components:
- "webauthn"
- "mobile_push"
example: [totp, webauthn, mobile_push]
+ handlers.configuration.PasswordPolicyConfigurationBody:
+ type: object
+ properties:
+ status:
+ type: string
+ example: OK
+ data:
+ type: object
+ properties:
+ mode:
+ type: string
+ description: The password policy mode.
+ enum:
+ - "disabled"
+ - "standard"
+ - "zxcvbn"
+ min_length:
+ type: integer
+ description: The minimum password length when using the standard mode.
+ max_length:
+ type: integer
+ description: The maximum password length when using the standard mode.
+ min_score:
+ type: integer
+ description: The minimum password score when using the zxcvbn mode.
+ require_uppercase:
+ type: boolean
+ description: If uppercase characters are required when using the standard mode.
+ require_lowercase:
+ type: boolean
+ description: If uppercase characters are required when using the standard mode.
+ require_number:
+ type: boolean
+ description: If numeric characters are required when using the standard mode.
+ require_special:
+ type: boolean
+ description: If special characters are required when using the standard mode.
handlers.DuoDeviceBody:
required:
- device
diff --git a/config.template.yml b/config.template.yml
index 04afa858d..1292632ae 100644
--- a/config.template.yml
+++ b/config.template.yml
@@ -329,16 +329,29 @@ password_policy:
## The standard policy allows you to tune individual settings manually.
standard:
enabled: false
+
+ ## Require a minimum length for passwords.
min_length: 8
+
+ ## Require a maximum length for passwords.
max_length: 0
+
+ ## Require uppercase characters.
require_uppercase: true
+
+ ## Require lowercase characters.
require_lowercase: true
+
+ ## Require numeric characters.
require_number: true
+
+ ## Require special characters.
require_special: true
## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings.
zxcvbn:
enabled: false
+ min_score: 0
##
## Access Control Configuration
diff --git a/docs/configuration/password_policy.md b/docs/configuration/password_policy.md
index d05b3eb4e..0661d7222 100644
--- a/docs/configuration/password_policy.md
+++ b/docs/configuration/password_policy.md
@@ -17,10 +17,10 @@ password_policy:
enabled: false
min_length: 8
max_length: 0
- require_uppercase: true
- require_lowercase: true
- require_number: true
- require_special: true
+ require_uppercase: false
+ require_lowercase: false
+ require_number: false
+ require_special: false
zxcvbn:
enabled: false
```
@@ -30,7 +30,7 @@ password_policy:
### standard
type: list
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
@@ -40,7 +40,7 @@ This section allows you to enable standard security policies.
#### enabled
type: bool
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
@@ -50,7 +50,9 @@ Enables standard password policy.
#### min_length
type: integer
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
+default: 8
+{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
@@ -60,7 +62,9 @@ Determines the minimum allowed password length.
#### max_length
type: integer
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
+default: 0
+{: .label .label-config .label-blue }
required: no
{: .label .label-config .label-green }
@@ -70,7 +74,7 @@ Determines the maximum allowed password length.
#### require_uppercase
type: bool
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
@@ -80,7 +84,7 @@ Indicates that at least one UPPERCASE letter must be provided as part of the pas
#### require_lowercase
type: bool
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
@@ -90,7 +94,7 @@ Indicates that at least one lowercase letter must be provided as part of the pas
#### require_number
type: bool
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
@@ -100,7 +104,7 @@ Indicates that at least one number must be provided as part of the password.
#### require_special
type: bool
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
@@ -117,7 +121,7 @@ password is.
#### enabled
type: bool
-{: .label .label-config .label-purple }
+{: .label .label-config .label-purple }
required: no
{: .label .label-config .label-green }
diff --git a/internal/configuration/config.template.yml b/internal/configuration/config.template.yml
index 04afa858d..1292632ae 100644
--- a/internal/configuration/config.template.yml
+++ b/internal/configuration/config.template.yml
@@ -329,16 +329,29 @@ password_policy:
## The standard policy allows you to tune individual settings manually.
standard:
enabled: false
+
+ ## Require a minimum length for passwords.
min_length: 8
+
+ ## Require a maximum length for passwords.
max_length: 0
+
+ ## Require uppercase characters.
require_uppercase: true
+
+ ## Require lowercase characters.
require_lowercase: true
+
+ ## Require numeric characters.
require_number: true
+
+ ## Require special characters.
require_special: true
## zxcvbn is a well known and used password strength algorithm. It does not have tunable settings.
zxcvbn:
enabled: false
+ min_score: 0
##
## Access Control Configuration
diff --git a/internal/configuration/schema/password_policy.go b/internal/configuration/schema/password_policy.go
index 9c24815e3..a87627f0f 100644
--- a/internal/configuration/schema/password_policy.go
+++ b/internal/configuration/schema/password_policy.go
@@ -2,7 +2,7 @@ package schema
// PasswordPolicyStandardParams represents the configuration related to standard parameters of password policy.
type PasswordPolicyStandardParams struct {
- Enabled bool
+ Enabled bool `koanf:"enabled"`
MinLength int `koanf:"min_length"`
MaxLength int `koanf:"max_length"`
RequireUppercase bool `koanf:"require_uppercase"`
@@ -13,8 +13,8 @@ type PasswordPolicyStandardParams struct {
// PasswordPolicyZxcvbnParams represents the configuration related to zxcvbn parameters of password policy.
type PasswordPolicyZxcvbnParams struct {
- Enabled bool
- MinScore int `koanf:"min_score"`
+ Enabled bool `koanf:"enabled"`
+ MinScore int `koanf:"min_score"`
}
// PasswordPolicyConfiguration represents the configuration related to password policy.
@@ -26,15 +26,12 @@ type PasswordPolicyConfiguration struct {
// DefaultPasswordPolicyConfiguration is the default password policy configuration.
var DefaultPasswordPolicyConfiguration = PasswordPolicyConfiguration{
Standard: PasswordPolicyStandardParams{
- Enabled: false,
- MinLength: 8,
- MaxLength: 0,
- RequireUppercase: true,
- RequireLowercase: true,
- RequireNumber: true,
- RequireSpecial: true,
+ Enabled: false,
+ MinLength: 8,
+ MaxLength: 0,
},
Zxcvbn: PasswordPolicyZxcvbnParams{
- Enabled: false,
+ Enabled: false,
+ MinScore: 0,
},
}
diff --git a/internal/handlers/handler_configuration_password_policy.go b/internal/handlers/handler_configuration_password_policy.go
new file mode 100644
index 000000000..1840a2ad5
--- /dev/null
+++ b/internal/handlers/handler_configuration_password_policy.go
@@ -0,0 +1,31 @@
+package handlers
+
+import (
+ "github.com/authelia/authelia/v4/internal/middlewares"
+)
+
+// PasswordPolicyConfigurationGet get the password policy configuration.
+func PasswordPolicyConfigurationGet(ctx *middlewares.AutheliaCtx) {
+ policyResponse := PassworPolicyBody{
+ Mode: "disabled",
+ }
+
+ if ctx.Configuration.PasswordPolicy.Standard.Enabled {
+ policyResponse.Mode = "standard"
+ policyResponse.MinLength = ctx.Configuration.PasswordPolicy.Standard.MinLength
+ policyResponse.MaxLength = ctx.Configuration.PasswordPolicy.Standard.MaxLength
+ policyResponse.RequireLowercase = ctx.Configuration.PasswordPolicy.Standard.RequireLowercase
+ policyResponse.RequireUppercase = ctx.Configuration.PasswordPolicy.Standard.RequireUppercase
+ policyResponse.RequireNumber = ctx.Configuration.PasswordPolicy.Standard.RequireNumber
+ policyResponse.RequireSpecial = ctx.Configuration.PasswordPolicy.Standard.RequireSpecial
+ } else if ctx.Configuration.PasswordPolicy.Zxcvbn.Enabled {
+ policyResponse.Mode = "zxcvbn"
+ policyResponse.MinScore = ctx.Configuration.PasswordPolicy.Zxcvbn.MinScore
+ }
+
+ var err error
+
+ if err = ctx.SetJSONBody(policyResponse); err != nil {
+ ctx.Logger.Errorf("Unable to send password Policy: %s", err)
+ }
+}
diff --git a/internal/handlers/handler_reset_password_step1.go b/internal/handlers/handler_reset_password_step1.go
index b7cc9a352..75cff5f0e 100644
--- a/internal/handlers/handler_reset_password_step1.go
+++ b/internal/handlers/handler_reset_password_step1.go
@@ -53,28 +53,7 @@ func resetPasswordIdentityFinish(ctx *middlewares.AutheliaCtx, username string)
ctx.Logger.Errorf("Unable to clear password reset flag in session for user %s: %s", userSession.Username, err)
}
- mode := ""
- if ctx.Configuration.PasswordPolicy.Standard.Enabled {
- mode = "standard"
- } else if ctx.Configuration.PasswordPolicy.Zxcvbn.Enabled {
- mode = "zxcvbn"
- }
-
- policyResponse := PassworPolicyBody{
- Mode: mode,
- MinLength: ctx.Configuration.PasswordPolicy.Standard.MinLength,
- MaxLength: ctx.Configuration.PasswordPolicy.Standard.MaxLength,
- RequireLowercase: ctx.Configuration.PasswordPolicy.Standard.RequireLowercase,
- RequireUppercase: ctx.Configuration.PasswordPolicy.Standard.RequireUppercase,
- RequireNumber: ctx.Configuration.PasswordPolicy.Standard.RequireNumber,
- RequireSpecial: ctx.Configuration.PasswordPolicy.Standard.RequireSpecial,
- MinScore: ctx.Configuration.PasswordPolicy.Zxcvbn.MinScore,
- }
-
- err = ctx.SetJSONBody(policyResponse)
- if err != nil {
- ctx.Logger.Errorf("Unable to send password Policy: %s", err)
- }
+ ctx.ReplyOK()
}
// ResetPasswordIdentityFinish the handler for finishing the identity validation.
diff --git a/internal/server/server.go b/internal/server/server.go
index 204804d14..f5195322c 100644
--- a/internal/server/server.go
+++ b/internal/server/server.go
@@ -65,6 +65,8 @@ func registerRoutes(configuration schema.Configuration, providers middlewares.Pr
r.GET("/api/configuration", autheliaMiddleware(
middlewares.RequireFirstFactor(handlers.ConfigurationGet)))
+ r.GET("/api/configuration/password-policy", autheliaMiddleware(handlers.PasswordPolicyConfigurationGet))
+
r.GET("/api/verify", autheliaMiddleware(handlers.VerifyGet(configuration.AuthenticationBackend)))
r.HEAD("/api/verify", autheliaMiddleware(handlers.VerifyGet(configuration.AuthenticationBackend)))
diff --git a/web/package.json b/web/package.json
index fb26e9b9f..516020586 100644
--- a/web/package.json
+++ b/web/package.json
@@ -133,6 +133,7 @@
"@types/qrcode.react": "1.0.2",
"@types/react": "17.0.43",
"@types/react-dom": "17.0.14",
+ "@types/zxcvbn": "4.4.1",
"@typescript-eslint/eslint-plugin": "5.17.0",
"@typescript-eslint/parser": "5.17.0",
"@vitejs/plugin-react": "1.3.0",
diff --git a/web/pnpm-lock.yaml b/web/pnpm-lock.yaml
index 2b6322fb2..2f2f9dd42 100644
--- a/web/pnpm-lock.yaml
+++ b/web/pnpm-lock.yaml
@@ -16,6 +16,7 @@ specifiers:
'@types/qrcode.react': 1.0.2
'@types/react': 17.0.43
'@types/react-dom': 17.0.14
+ '@types/zxcvbn': 4.4.1
'@typescript-eslint/eslint-plugin': 5.17.0
'@typescript-eslint/parser': 5.17.0
'@vitejs/plugin-react': 1.3.0
@@ -91,6 +92,7 @@ devDependencies:
'@types/qrcode.react': 1.0.2
'@types/react': 17.0.43
'@types/react-dom': 17.0.14
+ '@types/zxcvbn': 4.4.1
'@typescript-eslint/eslint-plugin': 5.17.0_4ad50a0fa85b91f236c35644695e4e45
'@typescript-eslint/parser': 5.17.0_typescript@4.6.3
'@vitejs/plugin-react': 1.3.0
@@ -2517,6 +2519,10 @@ packages:
'@types/yargs-parser': 21.0.0
dev: true
+ /@types/zxcvbn/4.4.1:
+ resolution: {integrity: sha512-3NoqvZC2W5gAC5DZbTpCeJ251vGQmgcWIHQJGq2J240HY6ErQ9aWKkwfoKJlHLx+A83WPNTZ9+3cd2ILxbvr1w==}
+ dev: true
+
/@typescript-eslint/eslint-plugin/5.17.0_4ad50a0fa85b91f236c35644695e4e45:
resolution: {integrity: sha512-qVstvQilEd89HJk3qcbKt/zZrfBZ+9h2ynpAGlWjWiizA7m/MtLT9RoX6gjtpE500vfIg8jogAkDzdCxbsFASQ==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
diff --git a/web/src/components/PasswordMeter.test.tsx b/web/src/components/PasswordMeter.test.tsx
index e3e3bcba6..790ddd6f3 100644
--- a/web/src/components/PasswordMeter.test.tsx
+++ b/web/src/components/PasswordMeter.test.tsx
@@ -3,11 +3,40 @@ import React from "react";
import { render } from "@testing-library/react";
import PasswordMeter from "@components/PasswordMeter";
+import { PasswordPolicyMode } from "@models/PasswordPolicy";
it("renders without crashing", () => {
- render();
+ render(
+ ,
+ );
});
it("renders adjusted height without crashing", () => {
- render();
+ render(
+ ,
+ );
});
diff --git a/web/src/components/PasswordMeter.tsx b/web/src/components/PasswordMeter.tsx
index 359df648c..71b5fb740 100644
--- a/web/src/components/PasswordMeter.tsx
+++ b/web/src/components/PasswordMeter.tsx
@@ -1,24 +1,15 @@
-import React, { useState, useEffect } from "react";
+import React, { useEffect, useState } from "react";
import { makeStyles } from "@material-ui/core";
import classnames from "classnames";
import { useTranslation } from "react-i18next";
import zxcvbn from "zxcvbn";
+import { PasswordPolicyConfiguration, PasswordPolicyMode } from "@models/PasswordPolicy";
+
export interface Props {
value: string;
- /**
- * mode password meter mode
- * classic: classic mode (checks lowercase, uppercase, specials and numbers)
- * zxcvbn: uses zxcvbn package to get the password strength
- **/
- mode: string;
- minLength: number;
- maxLength: number;
- requireLowerCase: boolean;
- requireUpperCase: boolean;
- requireNumber: boolean;
- requireSpecial: boolean;
+ policy: PasswordPolicyConfiguration;
}
const PasswordMeter = function (props: Props) {
@@ -39,17 +30,21 @@ const PasswordMeter = function (props: Props) {
useEffect(() => {
const password = props.value;
- if (props.mode === "standard") {
+ if (props.policy.mode === PasswordPolicyMode.Standard) {
//use mode mode
setMaxScores(4);
- if (password.length < props.minLength) {
+ if (password.length < props.policy.min_length) {
setPasswordScore(0);
- setFeedback(translate("Must be at least {{len}} characters in length", { len: props.minLength }));
+ setFeedback(
+ translate("Must be at least {{len}} characters in length", { len: props.policy.min_length }),
+ );
return;
}
- if (password.length > props.maxLength) {
+ if (props.policy.max_length !== 0 && password.length > props.policy.max_length) {
setPasswordScore(0);
- setFeedback(translate("Must not be more than {{len}} characters in length", { len: props.maxLength }));
+ setFeedback(
+ translate("Must not be more than {{len}} characters in length", { len: props.policy.max_length }),
+ );
return;
}
setFeedback("");
@@ -57,7 +52,7 @@ const PasswordMeter = function (props: Props) {
let required = 0;
let hits = 0;
let warning = "";
- if (props.requireLowerCase) {
+ if (props.policy.require_lowercase) {
required++;
const hasLowercase = /[a-z]/.test(password);
if (hasLowercase) {
@@ -67,7 +62,7 @@ const PasswordMeter = function (props: Props) {
}
}
- if (props.requireUpperCase) {
+ if (props.policy.require_uppercase) {
required++;
const hasUppercase = /[A-Z]/.test(password);
if (hasUppercase) {
@@ -77,7 +72,7 @@ const PasswordMeter = function (props: Props) {
}
}
- if (props.requireNumber) {
+ if (props.policy.require_number) {
required++;
const hasNumber = /[0-9]/.test(password);
if (hasNumber) {
@@ -87,7 +82,7 @@ const PasswordMeter = function (props: Props) {
}
}
- if (props.requireSpecial) {
+ if (props.policy.require_special) {
required++;
const hasSpecial = /[^0-9\w]/i.test(password);
if (hasSpecial) {
@@ -102,7 +97,7 @@ const PasswordMeter = function (props: Props) {
setFeedback(translate("The password does not meet the password policy") + ":\n" + warning);
}
setPasswordScore(score);
- } else if (props.mode === "zxcvbn") {
+ } else if (props.policy.mode === PasswordPolicyMode.ZXCVBN) {
//use zxcvbn mode
setMaxScores(5);
const { score, feedback } = zxcvbn(password);
@@ -111,14 +106,8 @@ const PasswordMeter = function (props: Props) {
}
}, [props, translate]);
- if (props.mode === "" || props.mode === "none") return ;
-
return (
-
+
);
};
diff --git a/web/src/models/PasswordPolicy.ts b/web/src/models/PasswordPolicy.ts
new file mode 100644
index 000000000..32bec62f3
--- /dev/null
+++ b/web/src/models/PasswordPolicy.ts
@@ -0,0 +1,16 @@
+export enum PasswordPolicyMode {
+ Disabled = 0,
+ Standard = 1,
+ ZXCVBN = 2,
+}
+
+export interface PasswordPolicyConfiguration {
+ mode: PasswordPolicyMode;
+ min_length: number;
+ max_length: number;
+ min_score: number;
+ require_uppercase: boolean;
+ require_lowercase: boolean;
+ require_number: boolean;
+ require_special: boolean;
+}
diff --git a/web/src/services/Api.ts b/web/src/services/Api.ts
index 938132d77..03bb4e1ce 100644
--- a/web/src/services/Api.ts
+++ b/web/src/services/Api.ts
@@ -25,6 +25,7 @@ export const CompleteTOTPSignInPath = basePath + "/api/secondfactor/totp";
export const InitiateResetPasswordPath = basePath + "/api/reset-password/identity/start";
export const CompleteResetPasswordPath = basePath + "/api/reset-password/identity/finish";
+
// Do the password reset during completion.
export const ResetPasswordPath = basePath + "/api/reset-password";
export const ChecksSafeRedirectionPath = basePath + "/api/checks/safe-redirection";
@@ -36,6 +37,7 @@ export const UserInfo2FAMethodPath = basePath + "/api/user/info/2fa_method";
export const UserInfoTOTPConfigurationPath = basePath + "/api/user/info/totp";
export const ConfigurationPath = basePath + "/api/configuration";
+export const PasswordPolicyConfigurationPath = basePath + "/api/configuration/password-policy";
export interface ErrorResponse {
status: "KO";
diff --git a/web/src/services/PasswordPolicyConfiguration.ts b/web/src/services/PasswordPolicyConfiguration.ts
new file mode 100644
index 000000000..6b979c74d
--- /dev/null
+++ b/web/src/services/PasswordPolicyConfiguration.ts
@@ -0,0 +1,33 @@
+import { PasswordPolicyConfiguration, PasswordPolicyMode } from "@models/PasswordPolicy";
+import { PasswordPolicyConfigurationPath } from "@services/Api";
+import { Get } from "@services/Client";
+
+interface PasswordPolicyConfigurationPayload {
+ mode: ModePasswordPolicy;
+ min_length: number;
+ max_length: number;
+ min_score: number;
+ require_uppercase: boolean;
+ require_lowercase: boolean;
+ require_number: boolean;
+ require_special: boolean;
+}
+
+export type ModePasswordPolicy = "disabled" | "standard" | "zxcvbn";
+
+export function toEnum(method: ModePasswordPolicy): PasswordPolicyMode {
+ switch (method) {
+ case "disabled":
+ return PasswordPolicyMode.Disabled;
+ case "standard":
+ return PasswordPolicyMode.Standard;
+ case "zxcvbn":
+ return PasswordPolicyMode.ZXCVBN;
+ }
+}
+
+export async function getPasswordPolicyConfiguration(): Promise
{
+ const config = await Get(PasswordPolicyConfigurationPath);
+
+ return { ...config, mode: toEnum(config.mode) };
+}
diff --git a/web/src/views/ResetPassword/ResetPasswordStep2.tsx b/web/src/views/ResetPassword/ResetPasswordStep2.tsx
index 12c8cce56..b308bc9d3 100644
--- a/web/src/views/ResetPassword/ResetPasswordStep2.tsx
+++ b/web/src/views/ResetPassword/ResetPasswordStep2.tsx
@@ -1,6 +1,6 @@
-import React, { useState, useCallback, useEffect } from "react";
+import React, { useCallback, useEffect, useState } from "react";
-import { Grid, Button, makeStyles, InputAdornment, IconButton } from "@material-ui/core";
+import { Button, Grid, IconButton, InputAdornment, makeStyles } from "@material-ui/core";
import { Visibility, VisibilityOff } from "@material-ui/icons";
import classnames from "classnames";
import { useTranslation } from "react-i18next";
@@ -11,6 +11,8 @@ import PasswordMeter from "@components/PasswordMeter";
import { IndexRoute } from "@constants/Routes";
import { useNotifications } from "@hooks/NotificationsContext";
import LoginLayout from "@layouts/LoginLayout";
+import { PasswordPolicyConfiguration, PasswordPolicyMode } from "@models/PasswordPolicy";
+import { getPasswordPolicyConfiguration } from "@services/PasswordPolicyConfiguration";
import { completeResetPasswordProcess, resetPassword } from "@services/ResetPassword";
import { extractIdentityToken } from "@utils/IdentityToken";
@@ -26,13 +28,17 @@ const ResetPasswordStep2 = function () {
const { t: translate } = useTranslation("Portal");
const navigate = useNavigate();
const [showPassword, setShowPassword] = useState(false);
- const [pPolicyMode, setPPolicyMode] = useState("none");
- const [pPolicyMinLength, setPPolicyMinLength] = useState(0);
- const [pPolicyMaxLength, setPPolicyMaxLength] = useState(0);
- const [pPolicyRequireUpperCase, setPPolicyRequireUpperCase] = useState(false);
- const [pPolicyRequireLowerCase, setPPolicyRequireLowerCase] = useState(false);
- const [pPolicyRequireNumber, setPPolicyRequireNumber] = useState(false);
- const [pPolicyRequireSpecial, setPPolicyRequireSpecial] = useState(false);
+
+ const [pPolicy, setPPolicy] = useState({
+ max_length: 0,
+ min_length: 8,
+ min_score: 0,
+ require_lowercase: false,
+ require_number: false,
+ require_special: false,
+ require_uppercase: false,
+ mode: PasswordPolicyMode.Disabled,
+ });
// Get the token from the query param to give it back to the API when requesting
// the secret for OTP.
@@ -47,22 +53,9 @@ const ResetPasswordStep2 = function () {
try {
setFormDisabled(true);
- const {
- mode,
- min_length,
- max_length,
- require_uppercase,
- require_lowercase,
- require_number,
- require_special,
- } = await completeResetPasswordProcess(processToken);
- setPPolicyMode(mode);
- setPPolicyMinLength(min_length);
- setPPolicyMaxLength(max_length);
- setPPolicyRequireLowerCase(require_lowercase);
- setPPolicyRequireUpperCase(require_uppercase);
- setPPolicyRequireNumber(require_number);
- setPPolicyRequireSpecial(require_special);
+ await completeResetPasswordProcess(processToken);
+ const policy = await getPasswordPolicyConfiguration();
+ setPPolicy(policy);
setFormDisabled(false);
} catch (err) {
console.error(err);
@@ -144,16 +137,9 @@ const ResetPasswordStep2 = function () {
),
}}
/>
-
+ {pPolicy.mode === PasswordPolicyMode.Disabled ? null : (
+
+ )}