diff --git a/src/account/kcContext/KcContext.ts b/src/account/kcContext/KcContext.ts index ca356144..1cce3b2c 100644 --- a/src/account/kcContext/KcContext.ts +++ b/src/account/kcContext/KcContext.ts @@ -138,6 +138,7 @@ export declare namespace KcContext { export type Totp = Common & { pageId: "totp.ftl"; totp: { + enabled: boolean; totpSecretEncoded: string; qrUrl: string; policy: { diff --git a/src/account/kcContext/kcContextMocks.ts b/src/account/kcContext/kcContextMocks.ts index 0c7b7c52..6f52d8d3 100644 --- a/src/account/kcContext/kcContextMocks.ts +++ b/src/account/kcContext/kcContextMocks.ts @@ -204,6 +204,7 @@ export const kcContextMocks: KcContext[] = [ ...kcContextCommonMock, "pageId": "totp.ftl", totp: { + enabled: true, totpSecretEncoded: "KVVF G2BY N4YX S6LB IUYT K2LH IFYE 4SBV", qrUrl: "#", totpSecretQrCode: diff --git a/src/account/pages/Totp.tsx b/src/account/pages/Totp.tsx index 8ce4eb15..838d0bf7 100644 --- a/src/account/pages/Totp.tsx +++ b/src/account/pages/Totp.tsx @@ -12,7 +12,7 @@ export default function Totp(props: PageProps
-

{msg("changePasswordHtmlTitle")}

+

{msg("authenticatorTitle")}

-
- {msg("allFieldsRequired")} -
-
-
    -
  1. -

    {msg("totpStep1")}

    - -
      - {totp.supportedApplications.map(app => ( -
    • {msg(app as MessageKey)}
    • - ))} -
    -
  2. - - {mode && mode == "manual" ? ( - <> -
  3. -

    {msg("totpManualStep2")}

    -

    - {totp.totpSecretEncoded} -

    -

    - - {msg("totpScanBarcode")} - -

    -
  4. -
  5. -

    {msg("totpManualStep3")}

    -

    -

      -
    • - {msg("totpType")}: {msg(`totp.${totp.policy.type}`)} -
    • -
    • - {msg("totpAlgorithm")}: {algToKeyUriAlg?.[totp.policy.algorithm] ?? totp.policy.algorithm} -
    • -
    • - {msg("totpDigits")}: {totp.policy.digits} -
    • - {totp.policy.type === "totp" ? ( -
    • - {msg("totpInterval")}: {totp.policy.period} -
    • - ) : ( -
    • - {msg("totpCounter")}: {totp.policy.initialCounter} -
    • - )} -
    -

    -
  6. - - ) : ( -
  7. -

    {msg("totpStep2")}

    - Figure: Barcode -
    -

    - - {msg("totpUnableToScan")} - -

    -
  8. - )} -
  9. -

    {msg("totpStep3")}

    -

    {msg("totpStep3DeviceName")}

    -
  10. -
- {/*
*/} - - -
-
- {" "} + {totp.otpCredentials.length === 0 && ( +
* + {msg("requiredFields")}
-
- - - {messagesPerField.existsError("totp") && ( - - {messagesPerField.get("totp")} - + )} +
+ {totp.enabled && ( + + + {totp.otpCredentials.length > 1 ? ( + + + + ) : ( + + + )} - - - {mode && } - + + + {totp.otpCredentials.map((credential, index) => ( + + + {totp.otpCredentials.length > 1 && } + + + + ))} + +
{msg("configureAuthenticators")}
{msg("configureAuthenticators")}
{msg("mobile")}{credential.id}{credential.userLabel || ""} + + + + + + +
+ )} + {!totp.enabled && ( +
+
+
    +
  1. +

    {msg("totpStep1")}

    -
    -
    - {" "} - {totp.otpCredentials.length >= 1 && *} -
    -
    - - {messagesPerField.existsError("userLabel") && ( - - {messagesPerField.get("userLabel")} - - )} -
    -
    +
      + {totp.supportedApplications.map(app => ( +
    • {msg(app as MessageKey)}
    • + ))} +
    +
  2. -
    - - +
  3. +

    {msg("totpStep3")}

    +

    {msg("totpStep3DeviceName")}

    +
  4. +
+
+
+ +
+
+ + * +
+
+ + + {messagesPerField.existsError("totp") && ( + + {messagesPerField.get("totp")} + + )} +
+ + {mode && } +
+ +
+
+ + {totp.otpCredentials.length >= 1 && *} +
+
+ + {messagesPerField.existsError("userLabel") && ( + + {messagesPerField.get("userLabel")} + + )} +
+
+ +
+
+ + +
+
+
- + )} ); diff --git a/stories/account/pages/Totp.stories.tsx b/stories/account/pages/Totp.stories.tsx index 4807f799..265d76a6 100644 --- a/stories/account/pages/Totp.stories.tsx +++ b/stories/account/pages/Totp.stories.tsx @@ -25,6 +25,68 @@ export const Default = () => ( +); + +export const WithTotpEnabled = () => ( + +); + +export const WithManualMode = () => ( +