From fcacbbbcc82e302df01935d93833d881cdea113a Mon Sep 17 00:00:00 2001 From: Xiao Yijun Date: Wed, 13 Sep 2023 15:14:59 +0800 Subject: [PATCH] feat(console): implement mfa config page (#4492) * feat(console): implement mfa config page * test(console): add ui tests for mfa configuration * chore(console): remove unused eslint command comment --- .../src/assets/icons/factor-backup-code.svg | 3 + .../console/src/assets/icons/factor-totp.svg | 3 + .../src/assets/icons/factor-webauthn.svg | 19 ++ .../src/assets/icons/security-lock.svg | 3 + packages/console/src/consts/env.ts | 1 - .../ConsoleContent/Sidebar/hook.tsx | 5 + .../src/containers/ConsoleContent/index.tsx | 4 +- .../ds-components/Switch/index.module.scss | 8 + .../src/ds-components/Switch/index.tsx | 6 +- .../Mfa/MfaForm/FactorLabel/index.module.scss | 20 +++ .../pages/Mfa/MfaForm/FactorLabel/index.tsx | 28 +++ .../PolicyOptionTitle/index.module.scss | 12 ++ .../Mfa/MfaForm/PolicyOptionTitle/index.tsx | 25 +++ .../src/pages/Mfa/MfaForm/constants.ts | 14 ++ .../src/pages/Mfa/MfaForm/index.module.scss | 31 ++++ .../console/src/pages/Mfa/MfaForm/index.tsx | 162 ++++++++++++++++++ .../console/src/pages/Mfa/MfaForm/utils.ts | 31 ++++ .../pages/Mfa/PageWrapper/index.module.scss | 12 ++ .../src/pages/Mfa/PageWrapper/index.tsx | 22 +++ .../src/pages/Mfa/Skeleton/index.module.scss | 7 + .../console/src/pages/Mfa/Skeleton/index.tsx | 14 ++ packages/console/src/pages/Mfa/index.tsx | 47 +++++ packages/console/src/pages/Mfa/types.ts | 10 ++ .../src/tests/console/mfa/helpers.ts | 15 ++ .../src/tests/console/mfa/index.test.ts | 63 +++++++ .../integration-tests/src/ui-helpers/index.ts | 17 +- .../de/translation/admin-console/index.ts | 2 + .../de/translation/admin-console/mfa.ts | 35 ++++ .../de/translation/admin-console/tabs.ts | 2 + .../en/translation/admin-console/index.ts | 2 + .../en/translation/admin-console/mfa.ts | 32 ++++ .../en/translation/admin-console/tabs.ts | 1 + .../es/translation/admin-console/index.ts | 2 + .../es/translation/admin-console/mfa.ts | 36 ++++ .../es/translation/admin-console/tabs.ts | 2 + .../fr/translation/admin-console/index.ts | 2 + .../fr/translation/admin-console/mfa.ts | 37 ++++ .../fr/translation/admin-console/tabs.ts | 2 + .../it/translation/admin-console/index.ts | 2 + .../it/translation/admin-console/mfa.ts | 36 ++++ .../it/translation/admin-console/tabs.ts | 2 + .../ja/translation/admin-console/index.ts | 2 + .../ja/translation/admin-console/mfa.ts | 32 ++++ .../ja/translation/admin-console/tabs.ts | 2 + .../ko/translation/admin-console/index.ts | 2 + .../ko/translation/admin-console/mfa.ts | 31 ++++ .../ko/translation/admin-console/tabs.ts | 2 + .../pl-pl/translation/admin-console/index.ts | 2 + .../pl-pl/translation/admin-console/mfa.ts | 36 ++++ .../pl-pl/translation/admin-console/tabs.ts | 2 + .../pt-br/translation/admin-console/index.ts | 2 + .../pt-br/translation/admin-console/mfa.ts | 35 ++++ .../pt-br/translation/admin-console/tabs.ts | 2 + .../pt-pt/translation/admin-console/index.ts | 2 + .../pt-pt/translation/admin-console/mfa.ts | 35 ++++ .../pt-pt/translation/admin-console/tabs.ts | 2 + .../ru/translation/admin-console/index.ts | 2 + .../ru/translation/admin-console/mfa.ts | 35 ++++ .../ru/translation/admin-console/tabs.ts | 2 + .../tr-tr/translation/admin-console/index.ts | 2 + .../tr-tr/translation/admin-console/mfa.ts | 36 ++++ .../tr-tr/translation/admin-console/tabs.ts | 2 + .../zh-cn/translation/admin-console/index.ts | 2 + .../zh-cn/translation/admin-console/mfa.ts | 27 +++ .../zh-cn/translation/admin-console/tabs.ts | 2 + .../zh-hk/translation/admin-console/index.ts | 2 + .../zh-hk/translation/admin-console/mfa.ts | 27 +++ .../zh-hk/translation/admin-console/tabs.ts | 2 + .../zh-tw/translation/admin-console/index.ts | 2 + .../zh-tw/translation/admin-console/mfa.ts | 27 +++ .../zh-tw/translation/admin-console/tabs.ts | 2 + 71 files changed, 1127 insertions(+), 11 deletions(-) create mode 100644 packages/console/src/assets/icons/factor-backup-code.svg create mode 100644 packages/console/src/assets/icons/factor-totp.svg create mode 100644 packages/console/src/assets/icons/factor-webauthn.svg create mode 100644 packages/console/src/assets/icons/security-lock.svg create mode 100644 packages/console/src/pages/Mfa/MfaForm/FactorLabel/index.module.scss create mode 100644 packages/console/src/pages/Mfa/MfaForm/FactorLabel/index.tsx create mode 100644 packages/console/src/pages/Mfa/MfaForm/PolicyOptionTitle/index.module.scss create mode 100644 packages/console/src/pages/Mfa/MfaForm/PolicyOptionTitle/index.tsx create mode 100644 packages/console/src/pages/Mfa/MfaForm/constants.ts create mode 100644 packages/console/src/pages/Mfa/MfaForm/index.module.scss create mode 100644 packages/console/src/pages/Mfa/MfaForm/index.tsx create mode 100644 packages/console/src/pages/Mfa/MfaForm/utils.ts create mode 100644 packages/console/src/pages/Mfa/PageWrapper/index.module.scss create mode 100644 packages/console/src/pages/Mfa/PageWrapper/index.tsx create mode 100644 packages/console/src/pages/Mfa/Skeleton/index.module.scss create mode 100644 packages/console/src/pages/Mfa/Skeleton/index.tsx create mode 100644 packages/console/src/pages/Mfa/index.tsx create mode 100644 packages/console/src/pages/Mfa/types.ts create mode 100644 packages/integration-tests/src/tests/console/mfa/helpers.ts create mode 100644 packages/integration-tests/src/tests/console/mfa/index.test.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/en/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/es/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/fr/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/it/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/ja/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/ko/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/pl-pl/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/pt-br/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/pt-pt/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/ru/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/tr-tr/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/zh-cn/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/zh-hk/translation/admin-console/mfa.ts create mode 100644 packages/phrases/src/locales/zh-tw/translation/admin-console/mfa.ts diff --git a/packages/console/src/assets/icons/factor-backup-code.svg b/packages/console/src/assets/icons/factor-backup-code.svg new file mode 100644 index 000000000..3f32f449e --- /dev/null +++ b/packages/console/src/assets/icons/factor-backup-code.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/console/src/assets/icons/factor-totp.svg b/packages/console/src/assets/icons/factor-totp.svg new file mode 100644 index 000000000..826eb5eaf --- /dev/null +++ b/packages/console/src/assets/icons/factor-totp.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/console/src/assets/icons/factor-webauthn.svg b/packages/console/src/assets/icons/factor-webauthn.svg new file mode 100644 index 000000000..8f9d92c1f --- /dev/null +++ b/packages/console/src/assets/icons/factor-webauthn.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packages/console/src/assets/icons/security-lock.svg b/packages/console/src/assets/icons/security-lock.svg new file mode 100644 index 000000000..be9137b46 --- /dev/null +++ b/packages/console/src/assets/icons/security-lock.svg @@ -0,0 +1,3 @@ + + + diff --git a/packages/console/src/consts/env.ts b/packages/console/src/consts/env.ts index 8ceda539e..147fa6d25 100644 --- a/packages/console/src/consts/env.ts +++ b/packages/console/src/consts/env.ts @@ -1,6 +1,5 @@ import { yes } from '@silverhand/essentials'; -// eslint-disable-next-line import/no-unused-modules export const isProduction = process.env.NODE_ENV === 'production'; export const isCloud = yes(process.env.IS_CLOUD); export const adminEndpoint = process.env.ADMIN_ENDPOINT; diff --git a/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx b/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx index daeec0002..5293a2bb8 100644 --- a/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx +++ b/packages/console/src/containers/ConsoleContent/Sidebar/hook.tsx @@ -12,6 +12,7 @@ import List from '@/assets/icons/list.svg'; import UserProfile from '@/assets/icons/profile.svg'; import ResourceIcon from '@/assets/icons/resource.svg'; import Role from '@/assets/icons/role.svg'; +import SecurityLock from '@/assets/icons/security-lock.svg'; import Web from '@/assets/icons/web.svg'; import { isCloud } from '@/consts/env'; import useUserPreferences from '@/hooks/use-user-preferences'; @@ -78,6 +79,10 @@ export const useSidebarMenuItems = (): { Icon: Web, title: 'sign_in_experience', }, + { + Icon: SecurityLock, + title: 'mfa', + }, { Icon: Connection, title: 'connectors', diff --git a/packages/console/src/containers/ConsoleContent/index.tsx b/packages/console/src/containers/ConsoleContent/index.tsx index fb780366a..46a71c78c 100644 --- a/packages/console/src/containers/ConsoleContent/index.tsx +++ b/packages/console/src/containers/ConsoleContent/index.tsx @@ -9,7 +9,7 @@ import { TenantSettingsTabs, ApplicationDetailsTabs, } from '@/consts'; -import { isCloud } from '@/consts/env'; +import { isCloud, isProduction } from '@/consts/env'; import OverlayScrollbar from '@/ds-components/OverlayScrollbar'; import useUserPreferences from '@/hooks/use-user-preferences'; import ApiResourceDetails from '@/pages/ApiResourceDetails'; @@ -24,6 +24,7 @@ import ConnectorDetails from '@/pages/ConnectorDetails'; import Connectors from '@/pages/Connectors'; import Dashboard from '@/pages/Dashboard'; import GetStarted from '@/pages/GetStarted'; +import Mfa from '@/pages/Mfa'; import NotFound from '@/pages/NotFound'; import Profile from '@/pages/Profile'; import ChangePasswordModal from '@/pages/Profile/containers/ChangePasswordModal'; @@ -97,6 +98,7 @@ function ConsoleContent() { } /> } /> + {!isProduction && } />} } /> } /> diff --git a/packages/console/src/ds-components/Switch/index.module.scss b/packages/console/src/ds-components/Switch/index.module.scss index 8fd171d4d..2605536d2 100644 --- a/packages/console/src/ds-components/Switch/index.module.scss +++ b/packages/console/src/ds-components/Switch/index.module.scss @@ -58,4 +58,12 @@ margin-right: _.unit(2); font: var(--font-body-2); } + + &.error { + border-color: var(--color-error); + + &:focus-within { + outline-color: var(--color-danger-focused); + } + } } diff --git a/packages/console/src/ds-components/Switch/index.tsx b/packages/console/src/ds-components/Switch/index.tsx index 094d6fdd8..4342e65ee 100644 --- a/packages/console/src/ds-components/Switch/index.tsx +++ b/packages/console/src/ds-components/Switch/index.tsx @@ -1,3 +1,4 @@ +import classNames from 'classnames'; import type { HTMLProps, ReactNode, Ref } from 'react'; import { forwardRef } from 'react'; @@ -5,11 +6,12 @@ import * as styles from './index.module.scss'; type Props = Omit, 'label'> & { label?: ReactNode; + hasError?: boolean; }; -function Switch({ label, ...rest }: Props, ref?: Ref) { +function Switch({ label, hasError, ...rest }: Props, ref?: Ref) { return ( -
+
{label}