From 00dc55281baa42dd97b698ec8a5484db4898bd50 Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Wed, 11 Sep 2024 10:07:49 +0900
Subject: [PATCH 01/26] feat(my-page): apply base mark-up at mfa (#4688)
* chore: update translation
Signed-off-by: NaYeong,Kim
* chore: changed section position
Signed-off-by: NaYeong,Kim
* feat: changed base role data
Signed-off-by: NaYeong,Kim
* feat: apply mark-up at mfa section
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
.../components/UserAccountBaseInformation.vue | 15 +-
.../components/UserAccountMultiFactorAuth.vue | 222 ++++--------------
.../UserAccountMultiFactorAuthItems.vue | 89 +++++++
.../my-page/pages/UserAccountPage.vue | 2 +-
.../console-translation-2.8.babel | 126 ++++++++++
packages/language-pack/en.json | 6 +
packages/language-pack/ja.json | 6 +
packages/language-pack/ko.json | 6 +
8 files changed, 285 insertions(+), 187 deletions(-)
create mode 100644 apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
diff --git a/apps/web/src/services/my-page/components/UserAccountBaseInformation.vue b/apps/web/src/services/my-page/components/UserAccountBaseInformation.vue
index d4b76e2210..2a5deb5a8e 100644
--- a/apps/web/src/services/my-page/components/UserAccountBaseInformation.vue
+++ b/apps/web/src/services/my-page/components/UserAccountBaseInformation.vue
@@ -9,6 +9,8 @@ import {
import type { MenuItem } from '@cloudforet/mirinae/types/inputs/context-menu/type';
import type { SelectDropdownMenuItem } from '@cloudforet/mirinae/types/inputs/dropdown/select-dropdown/type';
+import { ROLE_TYPE } from '@/schema/identity/role/constant';
+import type { RoleType } from '@/schema/identity/role/type';
import { store } from '@/store';
import { i18n } from '@/translations';
@@ -22,16 +24,19 @@ import ErrorHandler from '@/common/composables/error/errorHandler';
import UserAccountModuleContainer
from '@/services/my-page/components/UserAccountModuleContainer.vue';
-
const state = reactive({
userId: computed(() => store.state.user.userId),
- userRole: computed(() => store.getters['user/getCurrentRoleInfo']?.roleType || 'USER'),
+ userRole: computed(() => store.state.user.roleType),
languages: map(languages, (d, k) => ({
type: 'item', label: k === 'en' ? `${d} (default)` : d, name: k,
})) as MenuItem[],
timezones: map(timezoneList, (d) => ({
type: 'item', label: d === 'UTC' ? `${d} (default)` : d, name: d,
})) as SelectDropdownMenuItem[],
+ roleType: computed(() => {
+ if (state.userRole === ROLE_TYPE.DOMAIN_ADMIN) return 'Admin';
+ return 'User';
+ }),
});
const formState = reactive({
userName: '' as string | undefined,
@@ -113,12 +118,12 @@ watch(() => store.state.user.language, (language) => {
-
import {
- computed, reactive, watch,
+ computed, reactive,
} from 'vue';
-import {
- PI, PTextInput, PFieldGroup, PToggleButton, PSelectDropdown, PFieldTitle,
-} from '@cloudforet/mirinae';
-
import { store } from '@/store';
-import { i18n } from '@/translations';
-
-import { postEnableMfa } from '@/lib/helper/multi-factor-auth-helper';
-import { emailValidator } from '@/lib/helper/user-validation-helper';
-
-import { useFormValidator } from '@/common/composables/form-validator';
-import VerifyButton from '@/common/modules/button/verify-button/VerifyButton.vue';
import UserAccountModuleContainer from '@/services/my-page/components/UserAccountModuleContainer.vue';
+import UserAccountMultiFactorAuthItems from '@/services/my-page/components/UserAccountMultiFactorAuthItems.vue';
import UserAccountMultiFactorAuthModal from '@/services/my-page/components/UserAccountMultiFactorAuthModal.vue';
-// Currently, only email is supported.
-const contextMenuItems = [
- { label: 'Email', name: 'EMAIL' },
-];
-
const state = reactive({
- loading: false,
userId: computed(() => store.state.user.userId),
- //
mfa: computed(() => store.state.user.mfa || undefined),
isVerified: computed(() => state.mfa?.state === 'ENABLED'),
- enableMfa: false,
- // Currently, only email is supported.
- selectedItem: contextMenuItems[0].name,
});
const modalState = reactive({
isModalVisible: false,
- modalType: '' as 'verify' | 'disabled' | 'change' | 'new',
+ modalType: '' as 'confirm' | 'form',
});
-/* Components */
-const handleSelectDropdownItem = (selected: string) => {
- state.selectedItem = selected;
-};
-const initState = () => {
- state.enableMfa = state.mfa?.state === 'ENABLED';
-};
-
-/* API */
-const handleChangeToggle = async () => {
- if (state.isVerified && !state.enableMfa) {
- modalState.isModalVisible = true;
- modalState.modalType = 'disabled';
- }
-};
-const handleClickVerifyButton = async () => {
- if (state.isVerified) {
- modalState.modalType = 'change';
- } else {
- state.loading = true;
- try {
- await postEnableMfa({
- mfa_type: state.selectedItem,
- options: {
- email: email.value,
- },
- }, true);
- modalState.modalType = 'verify';
- } finally {
- state.loading = false;
- }
- }
- modalState.isModalVisible = true;
-};
-
-const {
- forms: {
- email,
- },
- setForm,
- invalidState,
- invalidTexts,
-} = useFormValidator({
- email: '',
-}, {
- email(value: string) { return !emailValidator(value) ? '' : i18n.t('MY_PAGE.NOTIFICATION_EMAIL.EMAIL_INVALID'); },
-});
-
-/* Watcher */
-watch(() => state.mfa, (mfa) => {
- setForm('email', mfa?.options?.email || '');
-}, { immediate: true });
-
-(() => {
- initState();
-})();
+// const handleClickVerifyButton = async () => {
+// if (state.isVerified) {
+// modalState.modalType = 'change';
+// } else {
+// state.loading = true;
+// try {
+// await postEnableMfa({
+// mfa_type: state.selectedItem,
+// options: {
+// email: email.value,
+// },
+// }, true);
+// modalState.modalType = 'verify';
+// } finally {
+// state.loading = false;
+// }
+// }
+// modalState.isModalVisible = true;
+// };
+
+// const {
+// forms: {
+// email,
+// },
+// setForm,
+// invalidState,
+// invalidTexts,
+// } = useFormValidator({
+// email: '',
+// }, {
+// email(value: string) { return !emailValidator(value) ? '' : i18n.t('MY_PAGE.NOTIFICATION_EMAIL.EMAIL_INVALID'); },
+// });
+//
+// /* Watcher */
+// watch(() => state.mfa, (mfa) => {
+// setForm('email', mfa?.options?.email || '');
+// }, { immediate: true });
@@ -108,83 +69,14 @@ watch(() => state.mfa, (mfa) => {
{{ $t('MY_PAGE.MFA.TITLE') }}
-
-
-
-
- {{ $t('MY_PAGE.MFA.STATE_VERIFIED') }}
-
-
-
- {{ $t('MY_PAGE.MFA.STATE_NOT_VERIFIED') }}
-
-
-
-
- {{ $t('MY_PAGE.MFA.ENABLE_MFA') }}
-
-
-
-
+
@@ -200,38 +92,6 @@ watch(() => state.mfa, (mfa) => {
@apply text-display-md;
margin-bottom: 0;
}
- .verify-status-wrapper {
- margin-left: 0.5rem;
- .verified {
- @apply flex items-center text-label-md text-green-600;
- gap: 0.25rem;
- }
- .not-verified {
- @apply bg-yellow-200 text-label-sm;
- padding: 0.15rem 0.5rem;
- border-radius: 6.25rem;
- }
- }
- }
- .enable-toggle {
- @apply flex items-center;
- gap: 1rem;
- }
- .enable-mfa-wrapper {
- @apply flex items-end;
- max-width: 47.5rem;
- margin-bottom: 1rem;
- .type-dropdown {
- min-width: 13rem;
- }
- .email-input {
- flex: 1;
- margin-left: 1rem;
- }
- }
-
- .verify-button {
- @apply flex items-end;
}
}
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
new file mode 100644
index 0000000000..c4f2b72d29
--- /dev/null
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+
+
+
+ {{ item.title }}
+
+
+ {{ $t('MY_PAGE.MFA.SYNC') }}
+
+
+
+ {{ item.desc }}
+
+
+
+
+
+
+
diff --git a/apps/web/src/services/my-page/pages/UserAccountPage.vue b/apps/web/src/services/my-page/pages/UserAccountPage.vue
index 89fd2d4988..d599b47b7f 100644
--- a/apps/web/src/services/my-page/pages/UserAccountPage.vue
+++ b/apps/web/src/services/my-page/pages/UserAccountPage.vue
@@ -70,9 +70,9 @@ const state = reactive({
+
-
diff --git a/packages/language-pack/console-translation-2.8.babel b/packages/language-pack/console-translation-2.8.babel
index 867d960626..b9b7b028db 100644
--- a/packages/language-pack/console-translation-2.8.babel
+++ b/packages/language-pack/console-translation-2.8.babel
@@ -73024,6 +73024,27 @@
+
+ ADMIN_ROLE
+ false
+
+
+
+
+
+ en-US
+ true
+
+
+ ja-JP
+ true
+
+
+ ko-KR
+ true
+
+
+
BASE_INFORMATION
false
@@ -73155,6 +73176,48 @@
+
+ EMAIL
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ EMAIL_DESC
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
ENABLE_MFA
false
@@ -73176,6 +73239,48 @@
+
+ MS_DESC
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ MS_TITLE
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
STATE_NOT_VERIFIED
false
@@ -73218,6 +73323,27 @@
+
+ SYNC
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
TITLE
false
diff --git a/packages/language-pack/en.json b/packages/language-pack/en.json
index 3a1a6a0cdd..0a14aa0f81 100644
--- a/packages/language-pack/en.json
+++ b/packages/language-pack/en.json
@@ -4027,6 +4027,7 @@
"MY_PAGE": {
"ACCOUNT": {
"ACCOUNT_N_PROFILE": "Account & Profile",
+ "ADMIN_ROLE": "Admin Role",
"BASE_INFORMATION": "Base Information",
"SAVE_CHANGES": "Save Changes",
"TIMEZONE_INVALID": "The time zone is set incorrectly."
@@ -4035,9 +4036,14 @@
"MFA": {
"BTN_CHANGE": "Change",
"BTN_SEND_MAIL": "Send Verification Code",
+ "EMAIL": "Email",
+ "EMAIL_DESC": "Receive a code by Email",
"ENABLE_MFA": "Enable MFA",
+ "MS_DESC": "Receive a code with the Microsoft Authenticator app",
+ "MS_TITLE": "Microsoft Authenticator App",
"STATE_NOT_VERIFIED": "Not Verified",
"STATE_VERIFIED": "Verified",
+ "SYNC": "In-Sync",
"TITLE": "Multi-factor Authentication",
"TYPE": "MFA Type"
},
diff --git a/packages/language-pack/ja.json b/packages/language-pack/ja.json
index c81790f8fd..3927150fdf 100644
--- a/packages/language-pack/ja.json
+++ b/packages/language-pack/ja.json
@@ -4027,6 +4027,7 @@
"MY_PAGE": {
"ACCOUNT": {
"ACCOUNT_N_PROFILE": "アカウント&情報",
+ "ADMIN_ROLE": "Admin役割",
"BASE_INFORMATION": "基本情報",
"SAVE_CHANGES": "変更事項を保存",
"TIMEZONE_INVALID": "タイムゾーンが正しく設定されました。"
@@ -4035,9 +4036,14 @@
"MFA": {
"BTN_CHANGE": "変更",
"BTN_SEND_MAIL": "認証コード送信",
+ "EMAIL": "",
+ "EMAIL_DESC": "",
"ENABLE_MFA": "MFA有効化",
+ "MS_DESC": "",
+ "MS_TITLE": "",
"STATE_NOT_VERIFIED": "認証されていません",
"STATE_VERIFIED": "認証済みです",
+ "SYNC": "",
"TITLE": "マルチファクタ認証",
"TYPE": "MFAタイプ"
},
diff --git a/packages/language-pack/ko.json b/packages/language-pack/ko.json
index ad76151680..c5e12c56d7 100644
--- a/packages/language-pack/ko.json
+++ b/packages/language-pack/ko.json
@@ -4027,6 +4027,7 @@
"MY_PAGE": {
"ACCOUNT": {
"ACCOUNT_N_PROFILE": "계정 & 프로필",
+ "ADMIN_ROLE": "Admin 역할(Role)",
"BASE_INFORMATION": "기본 정보",
"SAVE_CHANGES": "변경사항 저장 ",
"TIMEZONE_INVALID": "타임존이 잘못 설정되었습니다."
@@ -4035,9 +4036,14 @@
"MFA": {
"BTN_CHANGE": "변경",
"BTN_SEND_MAIL": "인증 코드 전송",
+ "EMAIL": "",
+ "EMAIL_DESC": "",
"ENABLE_MFA": "MFA 활성화",
+ "MS_DESC": "",
+ "MS_TITLE": "",
"STATE_NOT_VERIFIED": "인증되지 않음",
"STATE_VERIFIED": "인증됨",
+ "SYNC": "",
"TITLE": "멀티 팩터 인증",
"TYPE": "MFA 타입"
},
From 9afab66696e295946220412e1ace556d4488e3e7 Mon Sep 17 00:00:00 2001
From: HeeYoung Anna <73812528+heeyoung1332@users.noreply.github.com>
Date: Wed, 11 Sep 2024 14:00:14 +0900
Subject: [PATCH 02/26] upload 'ic_microsoft_auth' (#4692)
upload 'ic_microsoft_auth'
Signed-off-by: HeeYoung Anna <73812528+heeyoung1332@users.noreply.github.com>
---
.../foundation/icons/icon-assets/ic_microsoft_auth.svg | 9 +++++++++
1 file changed, 9 insertions(+)
create mode 100644 packages/mirinae/src/foundation/icons/icon-assets/ic_microsoft_auth.svg
diff --git a/packages/mirinae/src/foundation/icons/icon-assets/ic_microsoft_auth.svg b/packages/mirinae/src/foundation/icons/icon-assets/ic_microsoft_auth.svg
new file mode 100644
index 0000000000..29fe2b97e6
--- /dev/null
+++ b/packages/mirinae/src/foundation/icons/icon-assets/ic_microsoft_auth.svg
@@ -0,0 +1,9 @@
+
From c1d3bdc357a9c5863fe5ad3ea2a354b6e7fcd4f7 Mon Sep 17 00:00:00 2001
From: HeeYoung Anna <73812528+heeyoung1332@users.noreply.github.com>
Date: Wed, 11 Sep 2024 14:02:58 +0900
Subject: [PATCH 03/26] upload 'ic_notification-protocol_envelope' (#4693)
upload 'ic_notification-protocol_envelope'
Signed-off-by: HeeYoung Anna <73812528+heeyoung1332@users.noreply.github.com>
---
.../icons/icon-assets/ic_notification-protocol_envelope.svg | 3 +++
1 file changed, 3 insertions(+)
create mode 100644 packages/mirinae/src/foundation/icons/icon-assets/ic_notification-protocol_envelope.svg
diff --git a/packages/mirinae/src/foundation/icons/icon-assets/ic_notification-protocol_envelope.svg b/packages/mirinae/src/foundation/icons/icon-assets/ic_notification-protocol_envelope.svg
new file mode 100644
index 0000000000..aa7e9fbbf5
--- /dev/null
+++ b/packages/mirinae/src/foundation/icons/icon-assets/ic_notification-protocol_envelope.svg
@@ -0,0 +1,3 @@
+
From a4ebb50c49b3b150032cce6fd34f223fecbb0121 Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Mon, 23 Sep 2024 10:44:35 +0900
Subject: [PATCH 04/26] feat: update package.json/ translations/ icon (#4727)
* feat: install useQRCode / update jwt-decode
Signed-off-by: NaYeong,Kim
* chore: run icon
Signed-off-by: NaYeong,Kim
* chore: update translations
Signed-off-by: NaYeong,Kim
* chore: update translations
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
apps/web/package.json | 6 +-
apps/web/src/router/helpers/route-helper.ts | 2 +-
.../src/services/auth/pages/PasswordPage.vue | 2 +-
apps/web/src/store/modules/user/actions.ts | 2 +-
package-lock.json | 490 ++++++++++++++++--
packages/core-lib/package.json | 2 +-
.../core-lib/src/space-connector/token-api.ts | 2 +-
.../console-translation-2.8.babel | 116 ++++-
packages/language-pack/en.json | 10 +-
packages/language-pack/ja.json | 10 +-
packages/language-pack/ko.json | 10 +-
.../icons/p-icons/ic_microsoft_auth.js | 12 +
.../ic_notification-protocol_envelope.js | 12 +
.../src/foundation/icons/p-icons/index.js | 2 +
14 files changed, 616 insertions(+), 62 deletions(-)
create mode 100644 packages/mirinae/src/foundation/icons/p-icons/ic_microsoft_auth.js
create mode 100644 packages/mirinae/src/foundation/icons/p-icons/ic_notification-protocol_envelope.js
diff --git a/apps/web/package.json b/apps/web/package.json
index d8b52d0a28..5735c7e63a 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -40,6 +40,7 @@
"@vercel/edge-config": "^0.2.1",
"@vueuse/components": "^9.0.2",
"@vueuse/core": "^10.7.2",
+ "@vueuse/integrations": "^11.1.0",
"@vvo/tzdb": "^6.4.1",
"animated-number-vue": "^1.0.0",
"axios": "^1.7.4",
@@ -57,7 +58,7 @@
"html-to-image": "^1.9.0",
"js-yaml": "^4.1.0",
"jsonwebtoken": "^9.0.0",
- "jwt-decode": "^3.1.2",
+ "jwt-decode": "^4.0.0",
"keycloak-js": "^10.0.2",
"lodash": "^4.17.21",
"numeral": "^2.0.6",
@@ -80,7 +81,8 @@
"vue-selecto": "^1.6.4",
"vuedraggable": "^2.24.3",
"vuex": "^3.6.2",
- "webfontloader": "^1.6.28"
+ "webfontloader": "^1.6.28",
+ "qrcode": "^1.5.4"
},
"devDependencies": {
"@babel/preset-env": "^7.21.4",
diff --git a/apps/web/src/router/helpers/route-helper.ts b/apps/web/src/router/helpers/route-helper.ts
index c4cee27e16..0bd39dc297 100644
--- a/apps/web/src/router/helpers/route-helper.ts
+++ b/apps/web/src/router/helpers/route-helper.ts
@@ -1,7 +1,7 @@
import type { Route, NavigationGuardNext } from 'vue-router';
import type { JwtPayload } from 'jwt-decode';
-import jwtDecode from 'jwt-decode';
+import { jwtDecode } from 'jwt-decode';
import { SpaceConnector } from '@cloudforet/core-lib/space-connector';
diff --git a/apps/web/src/services/auth/pages/PasswordPage.vue b/apps/web/src/services/auth/pages/PasswordPage.vue
index cb11e2af6d..bd61279500 100644
--- a/apps/web/src/services/auth/pages/PasswordPage.vue
+++ b/apps/web/src/services/auth/pages/PasswordPage.vue
@@ -94,7 +94,7 @@ import type { Vue } from 'vue/types/vue';
import dayjs from 'dayjs';
import type { JwtPayload } from 'jwt-decode';
-import jwtDecode from 'jwt-decode';
+import { jwtDecode } from 'jwt-decode';
import { SpaceConnector } from '@cloudforet/core-lib/space-connector';
import { PButton, PDataLoader, PIconButton } from '@cloudforet/mirinae';
diff --git a/apps/web/src/store/modules/user/actions.ts b/apps/web/src/store/modules/user/actions.ts
index c150a35f8f..26e4540b4a 100644
--- a/apps/web/src/store/modules/user/actions.ts
+++ b/apps/web/src/store/modules/user/actions.ts
@@ -1,6 +1,6 @@
import type { Action } from 'vuex';
-import jwtDecode from 'jwt-decode';
+import { jwtDecode } from 'jwt-decode';
import { SpaceConnector } from '@cloudforet/core-lib/space-connector';
import { getCancellableFetcher } from '@cloudforet/core-lib/space-connector/cancallable-fetcher';
diff --git a/package-lock.json b/package-lock.json
index 086d328361..fbed7191d0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -188,6 +188,7 @@
"@vercel/edge-config": "^0.2.1",
"@vueuse/components": "^9.0.2",
"@vueuse/core": "^10.7.2",
+ "@vueuse/integrations": "^11.1.0",
"@vvo/tzdb": "^6.4.1",
"animated-number-vue": "^1.0.0",
"axios": "^1.7.4",
@@ -205,7 +206,7 @@
"html-to-image": "^1.9.0",
"js-yaml": "^4.1.0",
"jsonwebtoken": "^9.0.0",
- "jwt-decode": "^3.1.2",
+ "jwt-decode": "^4.0.0",
"keycloak-js": "^10.0.2",
"lodash": "^4.17.21",
"numeral": "^2.0.6",
@@ -216,6 +217,7 @@
"prosemirror-state": "^1.4.3",
"prosemirror-transform": "^1.7.3",
"prosemirror-view": "^1.31.5",
+ "qrcode": "^1.5.4",
"uuid": "^8.3.2",
"v-click-outside": "^3.0.1",
"v-tooltip": "^2.0.3",
@@ -886,6 +888,129 @@
}
}
},
+ "apps/web/node_modules/@vueuse/integrations": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.1.0.tgz",
+ "integrity": "sha512-O2ZgrAGPy0qAjpoI2YR3egNgyEqwG85fxfwmA9BshRIGjV4G6yu6CfOPpMHAOoCD+UfsIl7Vb1bXJ6ifrHYDDA==",
+ "dependencies": {
+ "@vueuse/core": "11.1.0",
+ "@vueuse/shared": "11.1.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "async-validator": "^4",
+ "axios": "^1",
+ "change-case": "^5",
+ "drauu": "^0.4",
+ "focus-trap": "^7",
+ "fuse.js": "^7",
+ "idb-keyval": "^6",
+ "jwt-decode": "^4",
+ "nprogress": "^0.2",
+ "qrcode": "^1.5",
+ "sortablejs": "^1",
+ "universal-cookie": "^7"
+ },
+ "peerDependenciesMeta": {
+ "async-validator": {
+ "optional": true
+ },
+ "axios": {
+ "optional": true
+ },
+ "change-case": {
+ "optional": true
+ },
+ "drauu": {
+ "optional": true
+ },
+ "focus-trap": {
+ "optional": true
+ },
+ "fuse.js": {
+ "optional": true
+ },
+ "idb-keyval": {
+ "optional": true
+ },
+ "jwt-decode": {
+ "optional": true
+ },
+ "nprogress": {
+ "optional": true
+ },
+ "qrcode": {
+ "optional": true
+ },
+ "sortablejs": {
+ "optional": true
+ },
+ "universal-cookie": {
+ "optional": true
+ }
+ }
+ },
+ "apps/web/node_modules/@vueuse/integrations/node_modules/@vueuse/core": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.1.0.tgz",
+ "integrity": "sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==",
+ "dependencies": {
+ "@types/web-bluetooth": "^0.0.20",
+ "@vueuse/metadata": "11.1.0",
+ "@vueuse/shared": "11.1.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "apps/web/node_modules/@vueuse/integrations/node_modules/@vueuse/metadata": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.1.0.tgz",
+ "integrity": "sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "apps/web/node_modules/@vueuse/integrations/node_modules/@vueuse/shared": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.1.0.tgz",
+ "integrity": "sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==",
+ "dependencies": {
+ "vue-demi": ">=0.14.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "apps/web/node_modules/@vueuse/integrations/node_modules/vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "hasInstallScript": true,
+ "bin": {
+ "vue-demi-fix": "bin/vue-demi-fix.js",
+ "vue-demi-switch": "bin/vue-demi-switch.js"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ },
+ "peerDependencies": {
+ "@vue/composition-api": "^1.0.0-rc.1",
+ "vue": "^3.0.0-0 || ^2.6.0"
+ },
+ "peerDependenciesMeta": {
+ "@vue/composition-api": {
+ "optional": true
+ }
+ }
+ },
"apps/web/node_modules/@vueuse/metadata": {
"version": "10.7.2",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.2.tgz",
@@ -1003,6 +1128,16 @@
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
}
},
+ "apps/web/node_modules/fuse.js": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
+ "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
+ "optional": true,
+ "peer": true,
+ "engines": {
+ "node": ">=10"
+ }
+ },
"apps/web/node_modules/istanbul-lib-instrument": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.0.tgz",
@@ -12487,7 +12622,6 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -16349,6 +16483,11 @@
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
+ "node_modules/dijkstrajs": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
+ "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
+ },
"node_modules/dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -19076,7 +19215,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
@@ -21455,9 +21593,12 @@
}
},
"node_modules/jwt-decode": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
- "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
+ "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
+ "engines": {
+ "node": ">=18"
+ }
},
"node_modules/keycloak-js": {
"version": "10.0.2",
@@ -25276,7 +25417,6 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -25554,6 +25694,14 @@
"resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz",
"integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g=="
},
+ "node_modules/pngjs": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
+ "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==",
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
"node_modules/polished": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/polished/-/polished-4.2.2.tgz",
@@ -28657,6 +28805,136 @@
"teleport": ">=0.2.0"
}
},
+ "node_modules/qrcode": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
+ "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
+ "dependencies": {
+ "dijkstrajs": "^1.0.1",
+ "pngjs": "^5.0.0",
+ "yargs": "^15.3.1"
+ },
+ "bin": {
+ "qrcode": "bin/qrcode"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/qrcode/node_modules/cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "node_modules/qrcode/node_modules/find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dependencies": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "dependencies": {
+ "p-locate": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "dependencies": {
+ "p-try": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/qrcode/node_modules/p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "dependencies": {
+ "p-limit": "^2.2.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+ },
+ "node_modules/qrcode/node_modules/wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+ },
+ "node_modules/qrcode/node_modules/yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "dependencies": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/qrcode/node_modules/yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "dependencies": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/qs": {
"version": "6.12.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz",
@@ -31310,7 +31588,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@@ -31353,14 +31630,12 @@
"node_modules/string-width/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"node_modules/string-width/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -31450,7 +31725,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"dependencies": {
"ansi-regex": "^5.0.1"
},
@@ -35277,7 +35551,7 @@
"axios-auth-refresh": "^3.2.2",
"bytes": "^3.1.2",
"dayjs": "^1.10.7",
- "jwt-decode": "^3.1.2",
+ "jwt-decode": "^4.0.0",
"lodash": "^4.17.21"
},
"devDependencies": {
@@ -37777,7 +38051,7 @@
"cross-env": "^7.0.3",
"dayjs": "^1.10.7",
"eslint-config-custom": "*",
- "jwt-decode": "^3.1.2",
+ "jwt-decode": "^4.0.0",
"lodash": "^4.17.21",
"rimraf": "^3.0.2",
"tsc-alias": "^1.6.11",
@@ -44507,8 +44781,7 @@
"ansi-regex": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
},
"ansi-styles": {
"version": "4.3.0",
@@ -47433,6 +47706,11 @@
"integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==",
"dev": true
},
+ "dijkstrajs": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/dijkstrajs/-/dijkstrajs-1.0.3.tgz",
+ "integrity": "sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA=="
+ },
"dir-glob": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
@@ -49516,8 +49794,7 @@
"get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="
},
"get-func-name": {
"version": "2.0.2",
@@ -51230,9 +51507,9 @@
}
},
"jwt-decode": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
- "integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
+ "integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA=="
},
"keycloak-js": {
"version": "10.0.2",
@@ -53969,8 +54246,7 @@
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
},
"path-is-absolute": {
"version": "1.0.1",
@@ -54181,6 +54457,11 @@
"resolved": "https://registry.npmjs.org/png-js/-/png-js-1.0.0.tgz",
"integrity": "sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g=="
},
+ "pngjs": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz",
+ "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw=="
+ },
"polished": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/polished/-/polished-4.2.2.tgz",
@@ -56743,6 +57024,108 @@
"resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
"integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw=="
},
+ "qrcode": {
+ "version": "1.5.4",
+ "resolved": "https://registry.npmjs.org/qrcode/-/qrcode-1.5.4.tgz",
+ "integrity": "sha512-1ca71Zgiu6ORjHqFBDpnSMTR2ReToX4l1Au1VFLyVeBTFavzQnv5JxMFr3ukHVKpSrSA2MCk0lNJSykjUfz7Zg==",
+ "requires": {
+ "dijkstrajs": "^1.0.1",
+ "pngjs": "^5.0.0",
+ "yargs": "^15.3.1"
+ },
+ "dependencies": {
+ "cliui": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+ "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "requires": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^6.2.0"
+ }
+ },
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+ "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz",
+ "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==",
+ "requires": {
+ "p-try": "^2.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+ "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "require-main-filename": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg=="
+ },
+ "wrap-ansi": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+ "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+ "requires": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ }
+ },
+ "y18n": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
+ "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
+ },
+ "yargs": {
+ "version": "15.4.1",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
+ "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "requires": {
+ "cliui": "^6.0.0",
+ "decamelize": "^1.2.0",
+ "find-up": "^4.1.0",
+ "get-caller-file": "^2.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^2.0.0",
+ "set-blocking": "^2.0.0",
+ "string-width": "^4.2.0",
+ "which-module": "^2.0.0",
+ "y18n": "^4.0.0",
+ "yargs-parser": "^18.1.2"
+ }
+ },
+ "yargs-parser": {
+ "version": "18.1.3",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+ "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+ "requires": {
+ "camelcase": "^5.0.0",
+ "decamelize": "^1.2.0"
+ }
+ }
+ }
+ },
"qs": {
"version": "6.12.3",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz",
@@ -58910,7 +59293,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
"requires": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
@@ -58920,14 +59302,12 @@
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
}
}
},
@@ -59019,7 +59399,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
"requires": {
"ansi-regex": "^5.0.1"
}
@@ -61485,6 +61864,7 @@
"@vue/test-utils": "^1.3.3",
"@vueuse/components": "^9.0.2",
"@vueuse/core": "^10.7.2",
+ "@vueuse/integrations": "^11.1.0",
"@vvo/tzdb": "^6.4.1",
"animated-number-vue": "^1.0.0",
"axios": "^1.7.4",
@@ -61506,7 +61886,7 @@
"js-yaml": "^4.1.0",
"jsdom": "^20.0.1",
"jsonwebtoken": "^9.0.0",
- "jwt-decode": "^3.1.2",
+ "jwt-decode": "^4.0.0",
"keycloak-js": "^10.0.2",
"lodash": "^4.17.21",
"numeral": "^2.0.6",
@@ -61519,6 +61899,7 @@
"prosemirror-state": "^1.4.3",
"prosemirror-transform": "^1.7.3",
"prosemirror-view": "^1.31.5",
+ "qrcode": "^1.5.4",
"rollup-plugin-visualizer": "^5.9.0",
"tsconfig": "*",
"uuid": "^8.3.2",
@@ -61846,6 +62227,48 @@
}
}
},
+ "@vueuse/integrations": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/integrations/-/integrations-11.1.0.tgz",
+ "integrity": "sha512-O2ZgrAGPy0qAjpoI2YR3egNgyEqwG85fxfwmA9BshRIGjV4G6yu6CfOPpMHAOoCD+UfsIl7Vb1bXJ6ifrHYDDA==",
+ "requires": {
+ "@vueuse/core": "11.1.0",
+ "@vueuse/shared": "11.1.0",
+ "vue-demi": ">=0.14.10"
+ },
+ "dependencies": {
+ "@vueuse/core": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/core/-/core-11.1.0.tgz",
+ "integrity": "sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==",
+ "requires": {
+ "@types/web-bluetooth": "^0.0.20",
+ "@vueuse/metadata": "11.1.0",
+ "@vueuse/shared": "11.1.0",
+ "vue-demi": ">=0.14.10"
+ }
+ },
+ "@vueuse/metadata": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-11.1.0.tgz",
+ "integrity": "sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg=="
+ },
+ "@vueuse/shared": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-11.1.0.tgz",
+ "integrity": "sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==",
+ "requires": {
+ "vue-demi": ">=0.14.10"
+ }
+ },
+ "vue-demi": {
+ "version": "0.14.10",
+ "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.10.tgz",
+ "integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
+ "requires": {}
+ }
+ }
+ },
"@vueuse/metadata": {
"version": "10.7.2",
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-10.7.2.tgz",
@@ -61917,6 +62340,13 @@
"dev": true,
"optional": true
},
+ "fuse.js": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.0.0.tgz",
+ "integrity": "sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==",
+ "optional": true,
+ "peer": true
+ },
"istanbul-lib-instrument": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.0.tgz",
diff --git a/packages/core-lib/package.json b/packages/core-lib/package.json
index 59689cd1a7..5488ca5190 100644
--- a/packages/core-lib/package.json
+++ b/packages/core-lib/package.json
@@ -21,7 +21,7 @@
"axios-auth-refresh": "^3.2.2",
"bytes": "^3.1.2",
"dayjs": "^1.10.7",
- "jwt-decode": "^3.1.2",
+ "jwt-decode": "^4.0.0",
"lodash": "^4.17.21"
},
"devDependencies": {
diff --git a/packages/core-lib/src/space-connector/token-api.ts b/packages/core-lib/src/space-connector/token-api.ts
index fef1a060cb..5bf8dd29fa 100644
--- a/packages/core-lib/src/space-connector/token-api.ts
+++ b/packages/core-lib/src/space-connector/token-api.ts
@@ -3,7 +3,7 @@ import type {
} from 'axios';
import axios from 'axios';
import type { JwtPayload } from 'jwt-decode';
-import jwtDecode from 'jwt-decode';
+import { jwtDecode } from 'jwt-decode';
import { LocalStorageAccessor } from '@/local-storage-accessor';
import type {
diff --git a/packages/language-pack/console-translation-2.8.babel b/packages/language-pack/console-translation-2.8.babel
index b9b7b028db..b272fe4847 100644
--- a/packages/language-pack/console-translation-2.8.babel
+++ b/packages/language-pack/console-translation-2.8.babel
@@ -21770,15 +21770,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -73033,15 +73033,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -73177,7 +73177,7 @@
- EMAIL
+ EMAIL_DESC
false
@@ -73198,7 +73198,28 @@
- EMAIL_DESC
+ ENABLE_MFA
+ false
+
+
+
+
+
+ en-US
+ true
+
+
+ ja-JP
+ true
+
+
+ ko-KR
+ true
+
+
+
+
+ MS_DESC
false
@@ -73219,7 +73240,49 @@
- ENABLE_MFA
+ RESYNC_DESC
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ RESYNC_TITLE
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ STATE_NOT_VERIFIED
false
@@ -73240,7 +73303,28 @@
- MS_DESC
+ STATE_VERIFIED
+ false
+
+
+
+
+
+ en-US
+ true
+
+
+ ja-JP
+ true
+
+
+ ko-KR
+ true
+
+
+
+
+ STEP1
false
@@ -73261,7 +73345,7 @@
- MS_TITLE
+ STEP2
false
@@ -73282,7 +73366,7 @@
- STATE_NOT_VERIFIED
+ STEP3
false
@@ -73290,20 +73374,20 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
- STATE_VERIFIED
+ STEP_DESC
false
diff --git a/packages/language-pack/en.json b/packages/language-pack/en.json
index 0a14aa0f81..6940e46e67 100644
--- a/packages/language-pack/en.json
+++ b/packages/language-pack/en.json
@@ -1230,7 +1230,7 @@
"SEND_NEW_CODE": "Send new code",
"SENT_DESC": "A verification code has been sent to",
"SUCCESS": "A verification code has been sent to your notification email.",
- "TITLE": "Verify your Email Address",
+ "TITLE": "Set up {type}",
"VERIFICATION_CODE": "Verification Code",
"VERIFY": "Verify"
},
@@ -4036,13 +4036,17 @@
"MFA": {
"BTN_CHANGE": "Change",
"BTN_SEND_MAIL": "Send Verification Code",
- "EMAIL": "Email",
"EMAIL_DESC": "Receive a code by Email",
"ENABLE_MFA": "Enable MFA",
"MS_DESC": "Receive a code with the Microsoft Authenticator app",
- "MS_TITLE": "Microsoft Authenticator App",
+ "RESYNC_DESC": "To re-sync, your existing authentication records will be deleted.",
+ "RESYNC_TITLE": "Are you sure you want to resync this multi-factor authentication?",
"STATE_NOT_VERIFIED": "Not Verified",
"STATE_VERIFIED": "Verified",
+ "STEP1": "Download the Microsoft Authenticator app to your phone.",
+ "STEP2": "Scan this QR code or Enter the secret key with the Microsoft Authenticator app.",
+ "STEP3": "Enter the code below that the Microsoft Authenticator app generated.",
+ "STEP_DESC": "To set up two-step verification using {type}",
"SYNC": "In-Sync",
"TITLE": "Multi-factor Authentication",
"TYPE": "MFA Type"
diff --git a/packages/language-pack/ja.json b/packages/language-pack/ja.json
index 3927150fdf..4ebbe0e418 100644
--- a/packages/language-pack/ja.json
+++ b/packages/language-pack/ja.json
@@ -1230,7 +1230,7 @@
"SEND_NEW_CODE": "再送信",
"SENT_DESC": "認証コードが入力したメールアドレスに送信されました:",
"SUCCESS": "確認コードが通知メールに送信されました。",
- "TITLE": "メールアドレス認証",
+ "TITLE": "",
"VERIFICATION_CODE": "認証コード",
"VERIFY": "認証"
},
@@ -4036,13 +4036,17 @@
"MFA": {
"BTN_CHANGE": "変更",
"BTN_SEND_MAIL": "認証コード送信",
- "EMAIL": "",
"EMAIL_DESC": "",
"ENABLE_MFA": "MFA有効化",
"MS_DESC": "",
- "MS_TITLE": "",
+ "RESYNC_DESC": "",
+ "RESYNC_TITLE": "",
"STATE_NOT_VERIFIED": "認証されていません",
"STATE_VERIFIED": "認証済みです",
+ "STEP1": "",
+ "STEP2": "",
+ "STEP3": "",
+ "STEP_DESC": "",
"SYNC": "",
"TITLE": "マルチファクタ認証",
"TYPE": "MFAタイプ"
diff --git a/packages/language-pack/ko.json b/packages/language-pack/ko.json
index c5e12c56d7..98f1b47d0b 100644
--- a/packages/language-pack/ko.json
+++ b/packages/language-pack/ko.json
@@ -1230,7 +1230,7 @@
"SEND_NEW_CODE": "인증 코드 재전송",
"SENT_DESC": "인증코드가 입력한 이메일로 발송 되었습니다: ",
"SUCCESS": "인증 코드가 알림 이메일로 전송되었습니다.",
- "TITLE": "이메일 주소 인증",
+ "TITLE": "",
"VERIFICATION_CODE": "인증 코드",
"VERIFY": "인증"
},
@@ -4036,13 +4036,17 @@
"MFA": {
"BTN_CHANGE": "변경",
"BTN_SEND_MAIL": "인증 코드 전송",
- "EMAIL": "",
"EMAIL_DESC": "",
"ENABLE_MFA": "MFA 활성화",
"MS_DESC": "",
- "MS_TITLE": "",
+ "RESYNC_DESC": "",
+ "RESYNC_TITLE": "",
"STATE_NOT_VERIFIED": "인증되지 않음",
"STATE_VERIFIED": "인증됨",
+ "STEP1": "",
+ "STEP2": "",
+ "STEP3": "",
+ "STEP_DESC": "",
"SYNC": "",
"TITLE": "멀티 팩터 인증",
"TYPE": "MFA 타입"
diff --git a/packages/mirinae/src/foundation/icons/p-icons/ic_microsoft_auth.js b/packages/mirinae/src/foundation/icons/p-icons/ic_microsoft_auth.js
new file mode 100644
index 0000000000..cdb13ae941
--- /dev/null
+++ b/packages/mirinae/src/foundation/icons/p-icons/ic_microsoft_auth.js
@@ -0,0 +1,12 @@
+/* eslint-disable */
+/* tslint:disable */
+// @ts-ignore
+import icon from 'vue-svgicon'
+icon.register({
+ 'ic_microsoft_auth': {
+ width: 32,
+ height: 32,
+ viewBox: '0 0 32 32',
+ data: ''
+ }
+})
diff --git a/packages/mirinae/src/foundation/icons/p-icons/ic_notification-protocol_envelope.js b/packages/mirinae/src/foundation/icons/p-icons/ic_notification-protocol_envelope.js
new file mode 100644
index 0000000000..e749f75abf
--- /dev/null
+++ b/packages/mirinae/src/foundation/icons/p-icons/ic_notification-protocol_envelope.js
@@ -0,0 +1,12 @@
+/* eslint-disable */
+/* tslint:disable */
+// @ts-ignore
+import icon from 'vue-svgicon'
+icon.register({
+ 'ic_notification-protocol_envelope': {
+ width: 32,
+ height: 32,
+ viewBox: '0 0 32 32',
+ data: ''
+ }
+})
diff --git a/packages/mirinae/src/foundation/icons/p-icons/index.js b/packages/mirinae/src/foundation/icons/p-icons/index.js
index b495add1ec..9de70f112b 100644
--- a/packages/mirinae/src/foundation/icons/p-icons/index.js
+++ b/packages/mirinae/src/foundation/icons/p-icons/index.js
@@ -159,6 +159,7 @@ import './ic_main-filled'
import './ic_marketplace'
import './ic_megaphone-filled'
import './ic_member'
+import './ic_microsoft_auth'
import './ic_minus_circle'
import './ic_minus'
import './ic_money-bag'
@@ -168,6 +169,7 @@ import './ic_my-page_account-and-profile'
import './ic_my-page_notifications-channel'
import './ic_no-edit'
import './ic_no-image'
+import './ic_notification-protocol_envelope'
import './ic_paper-airplane'
import './ic_peacock-gradient-circle'
import './ic_performance-filled'
From 3ac3d1d06cd3a523095eab1e02df655ee7c2ee9d Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Mon, 23 Sep 2024 11:07:35 +0900
Subject: [PATCH 05/26] feat: add mfa type (MS) - only Mark up (#4735)
* chore: add type
Signed-off-by: NaYeong,Kim
* feat: changed mfa section
Signed-off-by: NaYeong,Kim
* feat: chaged mfa modal
Signed-off-by: NaYeong,Kim
* chore: changed function name
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
.../components/UserAccountMultiFactorAuth.vue | 53 ++---
.../UserAccountMultiFactorAuthItems.vue | 63 ++++--
.../UserAccountMultiFactorAuthModal.vue | 208 +++++++++---------
...erAccountMultiFactorAuthModalEmailInfo.vue | 49 +----
...UserAccountMultiFactorAuthModalFolding.vue | 11 +-
.../my-page/types/multi-factor-auth-type.ts | 31 +++
6 files changed, 206 insertions(+), 209 deletions(-)
create mode 100644 apps/web/src/services/my-page/types/multi-factor-auth-type.ts
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
index 9ddc32ec9c..a17a0649c5 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
@@ -8,6 +8,8 @@ import { store } from '@/store';
import UserAccountModuleContainer from '@/services/my-page/components/UserAccountModuleContainer.vue';
import UserAccountMultiFactorAuthItems from '@/services/my-page/components/UserAccountMultiFactorAuthItems.vue';
import UserAccountMultiFactorAuthModal from '@/services/my-page/components/UserAccountMultiFactorAuthModal.vue';
+import type { MultiFactorAuthModalType } from '@/services/my-page/types/multi-factor-auth-type';
+import { MULTI_FACTOR_AUTH_MODAL_TYPE } from '@/services/my-page/types/multi-factor-auth-type';
const state = reactive({
userId: computed(() => store.state.user.userId),
@@ -17,46 +19,17 @@ const state = reactive({
const modalState = reactive({
isModalVisible: false,
- modalType: '' as 'confirm' | 'form',
+ modalType: MULTI_FACTOR_AUTH_MODAL_TYPE.EMAIL as MultiFactorAuthModalType,
});
-// const handleClickVerifyButton = async () => {
-// if (state.isVerified) {
-// modalState.modalType = 'change';
-// } else {
-// state.loading = true;
-// try {
-// await postEnableMfa({
-// mfa_type: state.selectedItem,
-// options: {
-// email: email.value,
-// },
-// }, true);
-// modalState.modalType = 'verify';
-// } finally {
-// state.loading = false;
-// }
-// }
-// modalState.isModalVisible = true;
-// };
-
-// const {
-// forms: {
-// email,
-// },
-// setForm,
-// invalidState,
-// invalidTexts,
-// } = useFormValidator({
-// email: '',
-// }, {
-// email(value: string) { return !emailValidator(value) ? '' : i18n.t('MY_PAGE.NOTIFICATION_EMAIL.EMAIL_INVALID'); },
-// });
-//
-// /* Watcher */
-// watch(() => state.mfa, (mfa) => {
-// setForm('email', mfa?.options?.email || '');
-// }, { immediate: true });
+const handleChangeToggle = (type: MultiFactorAuthModalType, value: boolean) => {
+ modalState.isModalVisible = true;
+ if (!value) {
+ modalState.modalType = MULTI_FACTOR_AUTH_MODAL_TYPE.DISABLED;
+ } else {
+ modalState.modalType = type;
+ }
+};
@@ -71,7 +44,9 @@ const modalState = reactive({
-
+
-import { reactive } from 'vue';
+import { computed, reactive, watch } from 'vue';
+
+import { keyBy, mapValues } from 'lodash';
import { PI, PToggleButton, PBadge } from '@cloudforet/mirinae';
-import { i18n } from '@/translations';
+import { store } from '@/store';
+
+import type { MultiFactorAuthType } from '@/services/my-page/types/multi-factor-auth-type';
+import { MULTI_FACTOR_AUTH_ITEMS } from '@/services/my-page/types/multi-factor-auth-type';
-const MULTI_FACTOR_AUTH_ITEMS = [
- {
- id: 'ms',
- icon: 'microsoft',
- title: i18n.t('MY_PAGE.MFA.MS_TITLE'),
- desc: i18n.t('MY_PAGE.MFA.MS_DESC'),
- },
- {
- id: 'email',
- icon: 'ic_notification-protocol_envelope',
- title: i18n.t('MY_PAGE.MFA.EMAIL'),
- desc: i18n.t('MY_PAGE.MFA.EMAIL_DESC'),
- },
-];
+interface Props {
+ modalVisible: boolean;
+}
+
+const props = withDefaults(defineProps(), {
+ modalVisible: false,
+});
+const emit = defineEmits<{(e: 'change-toggle', type: string, value: boolean): void }>();
+const storeState = reactive({
+ mfa: computed(() => store.state.user.mfa || undefined),
+});
const state = reactive({
- enableMfa: {
- ms: false,
- email: false,
- },
+ enableMfa: mapValues(keyBy(MULTI_FACTOR_AUTH_ITEMS, 'type'), () => false) as Record,
+ isVerified: computed(() => storeState.mfa?.state === 'ENABLED'),
+ type: computed(() => storeState.mfa?.type),
+ selectedType: '',
});
+
+const handleChangeToggle = (type: string, value: boolean) => {
+ state.selectedType = type;
+ state.enableMfa[type] = value;
+ emit('change-toggle', type, value);
+};
+
+watch(() => props.modalVisible, (modalVisible) => {
+ if (!modalVisible) {
+ state.enableMfa[state.selectedType] = state.type === state.selectedType ? state.isVerified : false;
+ state.selectedType = '';
+ }
+}, { immediate: true });
-
+
{{ item.title }}
@@ -68,7 +85,7 @@ const state = reactive({
@apply flex items-center border border-gray-200;
padding: 1rem;
border-radius: 0.375rem;
- gap: 0.375rem;
+ gap: 1rem;
.title-wrapper {
@apply flex flex-col;
gap: 0.5rem;
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
index 4730d10154..3bcff6b79e 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
@@ -1,15 +1,16 @@
@@ -45,12 +32,11 @@ const handleChangeToggle = (type: MultiFactorAuthModalType, value: boolean) => {
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
index a27f7b6dc1..ce57e6f909 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
@@ -3,12 +3,19 @@ import { computed, reactive, watch } from 'vue';
import { keyBy, mapValues } from 'lodash';
-import { PI, PToggleButton, PBadge } from '@cloudforet/mirinae';
+import {
+ PI, PToggleButton, PBadge, PButton,
+} from '@cloudforet/mirinae';
import { store } from '@/store';
-import type { MultiFactorAuthType } from '@/services/my-page/types/multi-factor-auth-type';
-import { MULTI_FACTOR_AUTH_ITEMS } from '@/services/my-page/types/multi-factor-auth-type';
+import type {
+ MultiFactorAuthType,
+ MultiFactorAuthModalDataType,
+} from '@/services/my-page/types/multi-factor-auth-type';
+import {
+ MULTI_FACTOR_AUTH_ITEMS,
+} from '@/services/my-page/types/multi-factor-auth-type';
interface Props {
modalVisible: boolean;
@@ -17,7 +24,9 @@ interface Props {
const props = withDefaults(defineProps
(), {
modalVisible: false,
});
-const emit = defineEmits<{(e: 'change-toggle', type: string, value: boolean): void }>();
+const emit = defineEmits<
+ {(e: 'handle-modal', data: MultiFactorAuthModalDataType): void}
+>();
const storeState = reactive({
mfa: computed(() => store.state.user.mfa || undefined),
@@ -25,16 +34,32 @@ const storeState = reactive({
const state = reactive({
enableMfa: mapValues(keyBy(MULTI_FACTOR_AUTH_ITEMS, 'type'), () => false) as Record,
isVerified: computed(() => storeState.mfa?.state === 'ENABLED'),
- type: computed(() => storeState.mfa?.type),
+ type: computed(() => storeState.mfa?.mfa_type),
selectedType: '',
});
-const handleChangeToggle = (type: string, value: boolean) => {
+const handleChangeToggle = (type: MultiFactorAuthType, value: boolean) => {
state.selectedType = type;
state.enableMfa[type] = value;
- emit('change-toggle', type, value);
+ emit('handle-modal', {
+ type,
+ state: value,
+ });
+};
+const handleClickReSyncButton = (type: MultiFactorAuthType) => {
+ emit('handle-modal', {
+ type,
+ isReSync: true,
+ });
};
+watch(() => storeState.mfa.mfa_type, (mfa_type) => {
+ if (mfa_type) {
+ state.enableMfa[mfa_type] = storeState.mfa.state === 'ENABLED';
+ } else {
+ state.enableMfa = mapValues(keyBy(MULTI_FACTOR_AUTH_ITEMS, 'type'), () => false) as Record;
+ }
+}, { immediate: true });
watch(() => props.modalVisible, (modalVisible) => {
if (!modalVisible) {
state.enableMfa[state.selectedType] = state.type === state.selectedType ? state.isVerified : false;
@@ -62,7 +87,8 @@ watch(() => props.modalVisible, (modalVisible) => {
{{ item.title }}
-
@@ -73,6 +99,14 @@ watch(() => props.modalVisible, (modalVisible) => {
{{ item.desc }}
+
+ {{ $t('MY_PAGE.MFA.RESYNC') }}
+
@@ -101,6 +135,9 @@ watch(() => props.modalVisible, (modalVisible) => {
@apply text-label-md text-gray-600;
}
}
+ .re-sync-button {
+ margin-left: auto;
+ }
}
}
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
index 3bcff6b79e..d5246f4637 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
@@ -1,12 +1,11 @@
@@ -122,7 +124,7 @@ watch(() => state.userId, (userId) => {
:header-title="modalState.title"
class="mfa-modal-wrapper"
size="sm"
- :theme-color="props.type === MULTI_FACTOR_AUTH_MODAL_TYPE.DISABLED? 'alert' : 'primary'"
+ :theme-color="state.isDisabledModal? 'alert' : 'primary'"
:disabled="validationState.verificationCode === '' || !state.isSentCode"
:loading="state.loading"
@confirm="handleClickVerifyButton"
@@ -130,56 +132,25 @@ watch(() => state.userId, (userId) => {
@close="handleClickCancel"
>
-
-
+ {{ $t('MY_PAGE.MFA.RESYNC_DESC') }}
+
+
+
{{ $t('COMMON.MFA_MODAL.ALT.DESC') }}
-
-
-
-
-
-
- Microsoft Authenticator App
-
-
-
-
-
- - {{ $t('MY_PAGE.MFA.STEP1') }}
- - {{ $t('MY_PAGE.MFA.STEP2') }}
-
-
-
-
- - {{ $t('MY_PAGE.MFA.STEP3') }}
-
-
+
-
-
-
+
+
{{ $t('COMMON.MFA_MODAL.ALT.DISABLED') }}
- {{ $t('COMMON.MFA_MODAL.VERIFY') }}
@@ -217,33 +189,8 @@ watch(() => state.userId, (userId) => {
margin-top: 1.625rem;
margin-bottom: 1rem;
}
- .set-up-desc-wrapper {
- @apply flex flex-col text-paragraph-md;
- margin-bottom: 0.5rem;
- .set-up-desc {
- list-style: decimal;
- padding-left: 1rem;
- }
- }
- .qrcode {
- width: 6.25rem;
- height: 6.25rem;
- margin: 1rem auto;
- }
- .passkey-wrapper {
- @apply flex;
- margin-bottom: 0.5rem;
- gap: 0.5rem;
-
- /* custom design-system component - p-text-input */
- :deep(.p-text-input) {
- .input-container.disabled {
- background-color: white;
- }
- }
- .refresh-btn {
- border-radius: 0.25rem;
- }
+ .re-sync-desc {
+ margin-top: 1rem;
}
.validation-code-form {
@apply flex items-end;
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
index a8f906570e..c52a58f75b 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
@@ -14,29 +14,29 @@ import { emailValidator } from '@/lib/helper/user-validation-helper';
import { useFormValidator } from '@/common/composables/form-validator';
import { useProxyValue } from '@/common/composables/proxy-state';
-import type { UserListItemType } from '@/services/iam/types/user-type';
-import { MULTI_FACTOR_AUTH_MODAL_TYPE } from '@/services/my-page/types/multi-factor-auth-type';
-
interface Props {
- email?: string
- type?: string
+ mfaType?: string
+ isDisabledModal?: boolean
isSentCode?: boolean
}
const props = withDefaults(defineProps(), {
- email: '',
- type: '',
+ mfaType: '',
+ isDisabledModal: false,
isSentCode: false,
});
const emit = defineEmits<{(e: 'update:is-sent-code'): void }>();
+const storeState = reactive({
+ email: computed(() => store.state.user.mfa?.options?.email || undefined),
+});
const state = reactive({
loading: false,
- data: {} as UserListItemType,
- userId: computed(() => store.state.user.userId),
+ userEmail: computed(() => store.state.user.email),
+ userId: computed(() => store.state.user.userId),
proxyIsSentCode: useProxyValue('isSentCode', props, emit),
- originEmail: props.email,
+ originEmail: storeState.email,
});
const {
@@ -55,19 +55,16 @@ const {
const handleClickSendCodeButton = async () => {
state.loading = true;
try {
- if (props.type === MULTI_FACTOR_AUTH_MODAL_TYPE.EMAIL) {
- state.data = await postEnableMfa({
- mfa_type: props.type,
+ if (!props.isDisabledModal) {
+ await postEnableMfa({
+ mfa_type: props.mfaType,
options: {
email: email.value,
},
- }, false) as UserListItemType;
- await store.dispatch('user/setUser', {
- email: state.data.email,
- });
+ }, false);
+ await store.dispatch('user/setUser', { mfa: { options: { email: email.value } } });
} else {
- const response = await postUserProfileDisableMfa();
- await store.dispatch('user/setUser', response);
+ await postUserProfileDisableMfa();
}
state.proxyIsSentCode = true;
} finally {
@@ -78,7 +75,7 @@ const handleClickSendCodeButton = async () => {
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
index 2d6594de5a..1370e6ed49 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
@@ -9,20 +9,25 @@ import { postUserProfileDisableMfa, postEnableMfa } from '@/lib/helper/multi-fac
import { useProxyValue } from '@/common/composables/proxy-state';
+import {
+ MULTI_FACTOR_AUTH_TYPE,
+} from '@/services/my-page/types/multi-factor-auth-type';
+
interface Props {
- mfaType?: string
- type: string
- isSentCode?: boolean
+ isDisabledModal: boolean
+ isSentCode: boolean
}
const props = withDefaults(defineProps(), {
- mfaType: '',
- type: '',
+ isDisabledModal: false,
isSentCode: false,
});
const emit = defineEmits<{(e: 'update:is-sent-code'): void }>();
+const storeState = reactive({
+ email: computed(() => store.state.user.mfa?.options?.email || undefined),
+});
const state = reactive({
isCollapsed: true,
userId: computed(() => store.state.user.userId),
@@ -31,16 +36,15 @@ const state = reactive({
});
const handleClickSendEmailButton = async () => {
- if (props.type === 'disabled' || props.type === 'change') {
- const response = await postUserProfileDisableMfa();
- await store.dispatch('user/setUser', response);
+ if (props.isDisabledModal) {
+ await postUserProfileDisableMfa();
} else {
await postEnableMfa({
- mfa_type: props.mfaType,
+ mfa_type: MULTI_FACTOR_AUTH_TYPE.EMAIL,
options: {
- email: state.userEmail,
+ email: storeState.email,
},
- }, true);
+ }, false);
}
state.proxyIsSentCode = true;
};
@@ -59,7 +63,7 @@ const handleClickSendEmailButton = async () => {
{{ $t('COMMON.MFA_MODAL.COLLAPSE_DESC') }}
{{ $t('COMMON.MFA_MODAL.SEND_NEW_CODE') }}
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue
new file mode 100644
index 0000000000..41199d5c5c
--- /dev/null
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+ Microsoft Authenticator App
+
+
+
+
+
+ - {{ $t('MY_PAGE.MFA.STEP1') }}
+ - {{ $t('MY_PAGE.MFA.STEP2') }}
+
+
+
+
+ - {{ $t('MY_PAGE.MFA.STEP3') }}
+
+
+
+
+
diff --git a/apps/web/src/services/my-page/types/multi-factor-auth-type.ts b/apps/web/src/services/my-page/types/multi-factor-auth-type.ts
index 38632b7551..437777941b 100644
--- a/apps/web/src/services/my-page/types/multi-factor-auth-type.ts
+++ b/apps/web/src/services/my-page/types/multi-factor-auth-type.ts
@@ -1,3 +1,5 @@
+import type { RoleType } from '@/schema/identity/role/type';
+import type { UserModel } from '@/schema/identity/user/model';
import { i18n } from '@/translations';
export const MULTI_FACTOR_AUTH_TYPE = {
@@ -22,10 +24,17 @@ export const MULTI_FACTOR_AUTH_ITEMS = [
},
];
-export const MULTI_FACTOR_AUTH_MODAL_TYPE = {
- MS: MULTI_FACTOR_AUTH_TYPE.MS,
- EMAIL: MULTI_FACTOR_AUTH_TYPE.EMAIL,
- DISABLED: 'disabled',
-} as const;
+export type MultiFactorAuthModalDataType = {
+ type: MultiFactorAuthType,
+ state?: boolean,
+ isReSync?: boolean,
+};
+
+type RoleBindingType = {
+ type: RoleType;
+ name: string;
+};
-export type MultiFactorAuthModalType = typeof MULTI_FACTOR_AUTH_MODAL_TYPE[keyof typeof MULTI_FACTOR_AUTH_MODAL_TYPE];
+export type UserInfoType = Partial & {
+ role_binding?: RoleBindingType
+};
diff --git a/packages/language-pack/console-translation-2.8.babel b/packages/language-pack/console-translation-2.8.babel
index b272fe4847..9e25f3b113 100644
--- a/packages/language-pack/console-translation-2.8.babel
+++ b/packages/language-pack/console-translation-2.8.babel
@@ -73239,6 +73239,27 @@
+
+ RESYNC
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
RESYNC_DESC
false
diff --git a/packages/language-pack/en.json b/packages/language-pack/en.json
index 6940e46e67..d4e9b1ec9c 100644
--- a/packages/language-pack/en.json
+++ b/packages/language-pack/en.json
@@ -4039,6 +4039,7 @@
"EMAIL_DESC": "Receive a code by Email",
"ENABLE_MFA": "Enable MFA",
"MS_DESC": "Receive a code with the Microsoft Authenticator app",
+ "RESYNC": "Re-Sync",
"RESYNC_DESC": "To re-sync, your existing authentication records will be deleted.",
"RESYNC_TITLE": "Are you sure you want to resync this multi-factor authentication?",
"STATE_NOT_VERIFIED": "Not Verified",
diff --git a/packages/language-pack/ja.json b/packages/language-pack/ja.json
index 4ebbe0e418..35bfd6aeb4 100644
--- a/packages/language-pack/ja.json
+++ b/packages/language-pack/ja.json
@@ -4039,6 +4039,7 @@
"EMAIL_DESC": "",
"ENABLE_MFA": "MFA有効化",
"MS_DESC": "",
+ "RESYNC": "",
"RESYNC_DESC": "",
"RESYNC_TITLE": "",
"STATE_NOT_VERIFIED": "認証されていません",
diff --git a/packages/language-pack/ko.json b/packages/language-pack/ko.json
index 98f1b47d0b..14c2797672 100644
--- a/packages/language-pack/ko.json
+++ b/packages/language-pack/ko.json
@@ -4039,6 +4039,7 @@
"EMAIL_DESC": "",
"ENABLE_MFA": "MFA 활성화",
"MS_DESC": "",
+ "RESYNC": "",
"RESYNC_DESC": "",
"RESYNC_TITLE": "",
"STATE_NOT_VERIFIED": "인증되지 않음",
From a9d094d8dedcb64a14751d304142e78ea84c82c3 Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Mon, 14 Oct 2024 08:34:33 +0900
Subject: [PATCH 07/26] feat: apply changed design at mfa page (UI only)
(#4793)
* feat: apply changed design at mfa page
Signed-off-by: NaYeong,Kim
* chore: update translations
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
.../auth/components/SignInContainer.vue | 15 +-
.../auth/pages/MultiFactorAuthPage.vue | 155 +++++++++---------
apps/web/src/services/auth/routes/routes.ts | 1 +
.../console-translation-2.8.babel | 27 ++-
packages/language-pack/en.json | 3 +-
packages/language-pack/ja.json | 3 +-
packages/language-pack/ko.json | 3 +-
7 files changed, 117 insertions(+), 90 deletions(-)
diff --git a/apps/web/src/services/auth/components/SignInContainer.vue b/apps/web/src/services/auth/components/SignInContainer.vue
index 3e5ee29a36..1bee4081f3 100644
--- a/apps/web/src/services/auth/components/SignInContainer.vue
+++ b/apps/web/src/services/auth/components/SignInContainer.vue
@@ -1,17 +1,19 @@
@@ -19,8 +21,10 @@ const state = reactive({
-
@@ -29,12 +33,15 @@ const state = reactive({
diff --git a/apps/web/src/services/my-page/components/UserAccountChangePassword.vue b/apps/web/src/services/my-page/components/UserAccountChangePassword.vue
index 24d02f658e..72977b6171 100644
--- a/apps/web/src/services/my-page/components/UserAccountChangePassword.vue
+++ b/apps/web/src/services/my-page/components/UserAccountChangePassword.vue
@@ -3,8 +3,9 @@ import { computed, reactive } from 'vue';
import type { TranslateResult } from 'vue-i18n';
import { SpaceConnector } from '@cloudforet/core-lib/space-connector';
-import { PButton, PFieldGroup, PTextInput } from '@cloudforet/mirinae';
-
+import {
+ PButton, PFieldGroup, PTextInput, PFieldTitle,
+} from '@cloudforet/mirinae';
import type { TokenIssueParameters } from '@/schema/identity/token/api-verbs/issue';
import type { TokenIssueModel } from '@/schema/identity/token/model';
@@ -122,95 +123,105 @@ const updateUser = async (userParam: UpdateUserRequest) => {
-
diff --git a/apps/web/src/services/my-page/components/UserAccountModuleContainer.vue b/apps/web/src/services/my-page/components/UserAccountModuleContainer.vue
index b621ff83c9..9434955602 100644
--- a/apps/web/src/services/my-page/components/UserAccountModuleContainer.vue
+++ b/apps/web/src/services/my-page/components/UserAccountModuleContainer.vue
@@ -24,10 +24,13 @@ const props = withDefaults(defineProps
(), {
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
index 0ae30ab920..bb289dee1d 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
@@ -20,7 +20,7 @@ const handleModalType = (data: MultiFactorAuthModalDataType) => {
-
+
@@ -43,15 +43,17 @@ const handleModalType = (data: MultiFactorAuthModalDataType) => {
diff --git a/apps/web/src/services/my-page/components/UserAccountNotificationEmail.vue b/apps/web/src/services/my-page/components/UserAccountNotificationEmail.vue
index 5fffae5b32..84503d3bfc 100644
--- a/apps/web/src/services/my-page/components/UserAccountNotificationEmail.vue
+++ b/apps/web/src/services/my-page/components/UserAccountNotificationEmail.vue
@@ -3,7 +3,9 @@ import {
computed, reactive, watch,
} from 'vue';
-import { PI, PTextInput, PFieldGroup } from '@cloudforet/mirinae';
+import {
+ PI, PTextInput, PFieldGroup, PButton, PBadge,
+} from '@cloudforet/mirinae';
import { store } from '@/store';
import { i18n } from '@/translations';
@@ -13,12 +15,11 @@ import { postUserProfileValidationEmail } from '@/lib/helper/verify-email-helper
import ErrorHandler from '@/common/composables/error/errorHandler';
import { useFormValidator } from '@/common/composables/form-validator';
-import VerifyButton from '@/common/modules/button/verify-button/VerifyButton.vue';
import NotificationEmailModal from '@/common/modules/modals/notification-email-modal/NotificationEmailModal.vue';
+import { MODAL_TYPE } from '@/common/modules/modals/notification-email-modal/type';
import UserAccountModuleContainer from '@/services/my-page/components/UserAccountModuleContainer.vue';
-
const state = reactive({
authType: computed(() => store.state.user.authType),
verified: computed(() => store.state.user.emailVerified),
@@ -84,24 +85,20 @@ watch(() => store.state.user.email, (value) => {
{{ $t('IDENTITY.USER.NOTIFICATION_EMAIL.TITLE') }}
-
-
-
- {{ $t('IDENTITY.USER.NOTIFICATION_EMAIL.VERIFIED') }}
-
-
-
{{ $t('IDENTITY.USER.NOTIFICATION_EMAIL.VERIFIED') }}
+
+
- {{ $t('IDENTITY.USER.NOTIFICATION_EMAIL.NOT_VERIFIED') }}
-
+ {{ $t('IDENTITY.USER.NOTIFICATION_EMAIL.NOT_VERIFIED') }}
+
@@ -125,20 +122,38 @@ watch(() => store.state.user.email, (value) => {
@update:value="setForm('notificationEmail', $event)"
/>
-
-
-
+
+
@@ -153,22 +168,13 @@ watch(() => store.state.user.email, (value) => {
}
.verify-status-wrapper {
margin-left: 0.5rem;
- .verified {
- @apply flex items-center text-label-md text-green-600;
- gap: 0.25rem;
- }
- .not-verified {
- @apply bg-yellow-200 text-label-sm;
- padding: 0.15rem 0.5rem;
- border-radius: 6.25rem;
- }
}
}
.help-text {
@apply text-paragraph-md;
}
.form {
- @apply flex;
+ @apply flex items-start;
max-width: 33.625rem;
margin-top: 1rem;
@@ -191,5 +197,10 @@ watch(() => store.state.user.email, (value) => {
}
}
}
+
+ .verify-button {
+ margin-top: 0.25rem;
+ margin-left: 0.5rem;
+ }
}
diff --git a/packages/language-pack/console-translation-2.8.babel b/packages/language-pack/console-translation-2.8.babel
index 1ef1dbdc28..f8626e88f6 100644
--- a/packages/language-pack/console-translation-2.8.babel
+++ b/packages/language-pack/console-translation-2.8.babel
@@ -10636,15 +10636,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -22614,15 +22614,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -22635,15 +22635,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -22656,15 +22656,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -22677,15 +22677,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -22788,6 +22788,27 @@
+
+ CONFIRM_PASSWORD
+ false
+
+
+
+
+
+ en-US
+ true
+
+
+ ja-JP
+ true
+
+
+ ko-KR
+ true
+
+
+
CURRENT_PASSWORD
false
@@ -25921,15 +25942,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -25942,15 +25963,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -25963,15 +25984,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -25984,15 +26005,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26740,15 +26761,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26761,15 +26782,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26782,15 +26803,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26803,15 +26824,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26824,15 +26845,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26845,15 +26866,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26866,15 +26887,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26887,15 +26908,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26908,15 +26929,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26929,15 +26950,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -26950,15 +26971,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -27099,15 +27120,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -27120,15 +27141,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -27489,15 +27510,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28517,15 +28538,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28538,15 +28559,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28559,15 +28580,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28601,15 +28622,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28622,15 +28643,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28690,15 +28711,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28711,15 +28732,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -28732,15 +28753,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30463,15 +30484,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30510,15 +30531,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30531,15 +30552,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30552,15 +30573,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30594,15 +30615,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30615,15 +30636,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30636,15 +30657,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30683,15 +30704,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -30704,15 +30725,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -31396,15 +31417,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -39877,15 +39898,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -40276,15 +40297,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
@@ -50003,15 +50024,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -50024,15 +50045,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61371,15 +61392,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61560,15 +61581,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61581,15 +61602,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61602,15 +61623,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61623,15 +61644,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61644,15 +61665,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61665,15 +61686,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61686,15 +61707,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61707,15 +61728,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61728,15 +61749,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -61749,15 +61770,15 @@
en-US
- true
+ false
ja-JP
- true
+ false
ko-KR
- true
+ false
@@ -75996,15 +76017,15 @@
en-US
- false
+ true
ja-JP
- false
+ true
ko-KR
- false
+ true
diff --git a/packages/language-pack/en.json b/packages/language-pack/en.json
index 1be0598e59..2c979f754d 100644
--- a/packages/language-pack/en.json
+++ b/packages/language-pack/en.json
@@ -1293,6 +1293,7 @@
"PROFILE": {
"ALT_E_UPDATE": "Failed to Update Profile",
"ALT_S_UPDATE": "Profile successfully updated ",
+ "CONFIRM_PASSWORD": "Confirm Password",
"CURRENT_PASSWORD": "Current Password",
"EMAIL": "E-mail",
"EMAIL_REQUIRED": "Please enter email",
diff --git a/packages/language-pack/ja.json b/packages/language-pack/ja.json
index efb33c698b..7d0eb3d2f7 100644
--- a/packages/language-pack/ja.json
+++ b/packages/language-pack/ja.json
@@ -1293,6 +1293,7 @@
"PROFILE": {
"ALT_E_UPDATE": "個人情報編集に失敗",
"ALT_S_UPDATE": "個人情報編集完了",
+ "CONFIRM_PASSWORD": "パスワード確認",
"CURRENT_PASSWORD": "現在のパスワード",
"EMAIL": "メールアドレス",
"EMAIL_REQUIRED": "メールアドレスを入力してください",
diff --git a/packages/language-pack/ko.json b/packages/language-pack/ko.json
index cf618510e1..7158d3c05b 100644
--- a/packages/language-pack/ko.json
+++ b/packages/language-pack/ko.json
@@ -1293,6 +1293,7 @@
"PROFILE": {
"ALT_E_UPDATE": "개인 정보 수정 실패",
"ALT_S_UPDATE": "개인 정보 수정 완료",
+ "CONFIRM_PASSWORD": "비밀번호 확인",
"CURRENT_PASSWORD": "현재 비밀번호",
"EMAIL": "이메일",
"EMAIL_REQUIRED": "이메일을 입력해주세요.",
From 11c489488a4648ef3061b73962eb71d0b338bfc8 Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Wed, 16 Oct 2024 10:56:42 +0900
Subject: [PATCH 10/26] refactor: change to a state store usage approach
(#4852)
* chore: changed file name
Signed-off-by: NaYeong,Kim
* feat: apply disabled case and changed style
Signed-off-by: NaYeong,Kim
* refactor: change to a state store usage approach
Signed-off-by: NaYeong,Kim
* chore: remove unnecessary code
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
.../components/UserAccountMultiFactorAuth.vue | 75 ++++++-------------
...> UserAccountMultiFactorAuthFormModal.vue} | 72 ++++++++----------
.../UserAccountMultiFactorAuthItems.vue | 75 +++++++++++--------
...erAccountMultiFactorAuthModalEmailInfo.vue | 10 +--
...UserAccountMultiFactorAuthModalFolding.vue | 2 -
.../multi-factor-authentication-store.ts | 40 ++++++++++
6 files changed, 141 insertions(+), 133 deletions(-)
rename apps/web/src/services/my-page/components/{UserAccountMultiFactorAuthModal.vue => UserAccountMultiFactorAuthFormModal.vue} (75%)
create mode 100644 apps/web/src/services/my-page/stores/multi-factor-authentication-store.ts
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
index bb289dee1d..ae04d73e53 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
@@ -1,71 +1,44 @@
-
-
-
-
-
- {{ $t('MY_PAGE.MFA.TITLE') }}
-
-
-
-
-
-
-
+
+
+
+
+ {{ $t('MY_PAGE.MFA.TITLE') }}
+
+
+
+
+
+
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
similarity index 75%
rename from apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
rename to apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
index d5246f4637..470bcb3a6b 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModal.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
@@ -13,54 +13,44 @@ import { i18n as _i18n } from '@/translations';
import { postValidationMfaCode } from '@/lib/helper/multi-factor-auth-helper';
-import { useProxyValue } from '@/common/composables/proxy-state';
import UserAccountMultiFactorAuthModalEmailInfo from '@/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue';
import UserAccountMultiFactorAuthModalFolding from '@/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue';
import UserAccountMultiFactorAuthModalMSInfo
from '@/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue';
+import { useMultiFactorAuthenticationStore } from '@/services/my-page/stores/multi-factor-authentication-store';
import type {
- MultiFactorAuthModalDataType,
- MultiFactorAuthType,
UserInfoType,
} from '@/services/my-page/types/multi-factor-auth-type';
import { MULTI_FACTOR_AUTH_TYPE } from '@/services/my-page/types/multi-factor-auth-type';
-interface Props {
- data: MultiFactorAuthModalDataType
- visible: boolean
-}
-
-const props = withDefaults(defineProps(), {
- data: undefined,
- visible: false,
-});
+const multiFactorAuthenticationStore = useMultiFactorAuthenticationStore();
+const multiFactorAuthenticationState = multiFactorAuthenticationStore.state;
const emit = defineEmits<{(e: 'refresh'): void }>();
const storeState = reactive({
userId: computed(() => store.state.user.userId),
+ selectedType: computed(() => multiFactorAuthenticationState.selectedType),
+ isReSyncModal: computed(() => multiFactorAuthenticationState.modalType === 'RE_SYNC'),
+ isDisabledModal: computed(() => multiFactorAuthenticationState.modalType === 'DISABLED'),
});
const state = reactive({
loading: false,
- mfaType: computed(() => props.data?.type),
- isReSyncModal: computed(() => props.data.isReSync || false),
- isDisabledModal: computed(() => !state.isReSyncModal && !props.data.state),
userInfo: {} as UserInfoType,
isCollapsed: true,
isSentCode: false,
});
const modalState = reactive({
- proxyVisible: useProxyValue('visible', props, emit),
title: computed(() => {
- if (state.isReSyncModal) {
+ if (storeState.isReSyncModal) {
return _i18n.t('MY_PAGE.MFA.RESYNC_TITLE');
}
- if (state.isDisabledModal) {
+ if (storeState.isDisabledModal) {
return _i18n.t('COMMON.MFA_MODAL.ALT.TITLE');
}
- const type = state.mfaType.toLowerCase()
+ const type = storeState.selectedType?.toLowerCase()
.replace(/_/g, ' ')
.replace(/\b\w/g, (char) => char.toUpperCase());
return _i18n.t('COMMON.MFA_MODAL.TITLE', { type });
@@ -83,7 +73,7 @@ const handleChangeInput = (value: string) => {
validationState.verificationCode = value;
};
const handleClickCancel = async () => {
- modalState.proxyVisible = false;
+ multiFactorAuthenticationStore.setModalVisible(false);
await resetFormData();
if (storeState.userId === state.userInfo.user_id) {
await store.dispatch('user/setUser', state.userInfo);
@@ -100,7 +90,7 @@ const handleClickVerifyButton = async () => {
if (storeState.userId === state.userInfo.user_id) {
await store.dispatch('user/setUser', state.userInfo);
}
- modalState.proxyVisible = false;
+ multiFactorAuthenticationStore.setModalVisible(false);
resetFormData();
} catch (e: any) {
validationState.isValidationCodeValid = false;
@@ -119,20 +109,19 @@ watch(() => storeState.userId, (userId) => {
-
-
{{ $t('MY_PAGE.MFA.RESYNC_DESC') }}
@@ -140,17 +129,16 @@ watch(() => storeState.userId, (userId) => {
-
{{ $t('COMMON.MFA_MODAL.ALT.DESC') }}
-
-
+
-
-
-
+
{{ $t('COMMON.MFA_MODAL.ALT.DISABLED') }}
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
index ce57e6f909..32afb89343 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
@@ -1,7 +1,7 @@
@@ -73,6 +75,7 @@ watch(() => props.modalVisible, (modalVisible) => {
props.modalVisible, (modalVisible) => {
@@ -138,6 +142,11 @@ watch(() => props.modalVisible, (modalVisible) => {
.re-sync-button {
margin-left: auto;
}
+ &.disabled {
+ .title {
+ @apply text-gray-400;
+ }
+ }
}
}
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
index c52a58f75b..bd4c2def47 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
@@ -15,13 +15,11 @@ import { useFormValidator } from '@/common/composables/form-validator';
import { useProxyValue } from '@/common/composables/proxy-state';
interface Props {
- mfaType?: string
isDisabledModal?: boolean
isSentCode?: boolean
}
const props = withDefaults(defineProps(), {
- mfaType: '',
isDisabledModal: false,
isSentCode: false,
});
@@ -33,8 +31,6 @@ const storeState = reactive({
});
const state = reactive({
loading: false,
- userEmail: computed(() => store.state.user.email),
- userId: computed(() => store.state.user.userId),
proxyIsSentCode: useProxyValue('isSentCode', props, emit),
originEmail: storeState.email,
});
@@ -94,6 +90,7 @@ const handleClickSendCodeButton = async () => {
/>
{
.email-info-wrapper {
margin-bottom: 1.25rem;
.email-form-wrapper {
- @apply flex items-end;
+ @apply flex items-start;
gap: 1rem;
.input-form {
flex: 1;
}
+ .send-code-button {
+ margin-top: 1.45rem;
+ }
}
.email-view-wrapper {
@apply flex flex-col bg-gray-100 rounded text-label-md text-gray-700;
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
index 1370e6ed49..144dfd49e5 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
@@ -30,8 +30,6 @@ const storeState = reactive({
});
const state = reactive({
isCollapsed: true,
- userId: computed(() => store.state.user.userId),
- userEmail: computed(() => store.state.user.email),
proxyIsSentCode: useProxyValue('is-sent-code', props, emit),
});
diff --git a/apps/web/src/services/my-page/stores/multi-factor-authentication-store.ts b/apps/web/src/services/my-page/stores/multi-factor-authentication-store.ts
new file mode 100644
index 0000000000..15e7180b40
--- /dev/null
+++ b/apps/web/src/services/my-page/stores/multi-factor-authentication-store.ts
@@ -0,0 +1,40 @@
+import { reactive } from 'vue';
+
+import { defineStore } from 'pinia';
+
+
+type modelType = 'FORM'|'RE_SYNC'|'DISABLED';
+interface userAccountPageStoreState {
+ selectedType: string,
+ modalVisible: boolean,
+ modalLoading: boolean,
+ modalType: modelType,
+}
+export const useMultiFactorAuthenticationStore = defineStore('multi-factor-authentication-store', () => {
+ const state = reactive({
+ selectedType: '',
+ modalVisible: false,
+ modalLoading: false,
+ modalType: 'FORM',
+ });
+
+ const mutations = {
+ setSelectedType: (type: string) => {
+ state.selectedType = type;
+ },
+ setModalVisible: (value: boolean) => {
+ state.modalVisible = value;
+ },
+ setModalLoading: (value: boolean) => {
+ state.modalLoading = value;
+ },
+ setModalType: (value: modelType) => {
+ state.modalType = value;
+ },
+ };
+
+ return {
+ state,
+ ...mutations,
+ };
+});
From 5b39cf3bc3e67a7dc33169a6958aa4a84f1ed07a Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Wed, 16 Oct 2024 15:38:09 +0900
Subject: [PATCH 11/26] feat: apply re-sync function (#4855)
* chore: changed store name
Signed-off-by: NaYeong,Kim
* feat: apply re-sync function
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
.../components/UserAccountMultiFactorAuth.vue | 8 ++--
.../UserAccountMultiFactorAuthFormModal.vue | 45 +++++++++++--------
.../UserAccountMultiFactorAuthItems.vue | 30 +++++++------
...erAccountMultiFactorAuthModalEmailInfo.vue | 14 +++---
...on-store.ts => multi-factor-auth-store.ts} | 6 +--
5 files changed, 59 insertions(+), 44 deletions(-)
rename apps/web/src/services/my-page/stores/{multi-factor-authentication-store.ts => multi-factor-auth-store.ts} (80%)
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
index ae04d73e53..20021f91bd 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuth.vue
@@ -2,10 +2,10 @@
import UserAccountModuleContainer from '@/services/my-page/components/UserAccountModuleContainer.vue';
import UserAccountMultiFactorAuthFormModal from '@/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue';
import UserAccountMultiFactorAuthItems from '@/services/my-page/components/UserAccountMultiFactorAuthItems.vue';
-import { useMultiFactorAuthenticationStore } from '@/services/my-page/stores/multi-factor-authentication-store';
+import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
-const multiFactorAuthenticationStore = useMultiFactorAuthenticationStore();
-const multiFactorAuthenticationState = multiFactorAuthenticationStore.state;
+const multiFactorAuthStore = useMultiFactorAuthStore();
+const multiFactorAuthState = multiFactorAuthStore.state;
@@ -20,7 +20,7 @@ const multiFactorAuthenticationState = multiFactorAuthenticationStore.state;
-
+
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
index 470bcb3a6b..48cd245b18 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
@@ -18,22 +18,22 @@ import UserAccountMultiFactorAuthModalEmailInfo from '@/services/my-page/compone
import UserAccountMultiFactorAuthModalFolding from '@/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue';
import UserAccountMultiFactorAuthModalMSInfo
from '@/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue';
-import { useMultiFactorAuthenticationStore } from '@/services/my-page/stores/multi-factor-authentication-store';
+import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
import type {
UserInfoType,
} from '@/services/my-page/types/multi-factor-auth-type';
import { MULTI_FACTOR_AUTH_TYPE } from '@/services/my-page/types/multi-factor-auth-type';
-const multiFactorAuthenticationStore = useMultiFactorAuthenticationStore();
-const multiFactorAuthenticationState = multiFactorAuthenticationStore.state;
+const multiFactorAuthStore = useMultiFactorAuthStore();
+const multiFactorAuthState = multiFactorAuthStore.state;
const emit = defineEmits<{(e: 'refresh'): void }>();
const storeState = reactive({
userId: computed
(() => store.state.user.userId),
- selectedType: computed(() => multiFactorAuthenticationState.selectedType),
- isReSyncModal: computed(() => multiFactorAuthenticationState.modalType === 'RE_SYNC'),
- isDisabledModal: computed(() => multiFactorAuthenticationState.modalType === 'DISABLED'),
+ selectedType: computed(() => multiFactorAuthState.selectedType),
+ isReSyncModal: computed(() => multiFactorAuthState.modalType === 'RE_SYNC'),
+ isDisabledModal: computed(() => multiFactorAuthState.modalType === 'DISABLED'),
});
const state = reactive({
loading: false,
@@ -71,9 +71,11 @@ const resetFormData = () => {
};
const handleChangeInput = (value: string) => {
validationState.verificationCode = value;
+ validationState.isValidationCodeValid = true;
+ validationState.validationCodeInvalidText = '';
};
const handleClickCancel = async () => {
- multiFactorAuthenticationStore.setModalVisible(false);
+ multiFactorAuthStore.setModalVisible(false);
await resetFormData();
if (storeState.userId === state.userInfo.user_id) {
await store.dispatch('user/setUser', state.userInfo);
@@ -90,8 +92,12 @@ const handleClickVerifyButton = async () => {
if (storeState.userId === state.userInfo.user_id) {
await store.dispatch('user/setUser', state.userInfo);
}
- multiFactorAuthenticationStore.setModalVisible(false);
resetFormData();
+ if (storeState.isReSyncModal) {
+ multiFactorAuthStore.setModalType('FORM');
+ } else {
+ multiFactorAuthStore.setModalVisible(false);
+ }
} catch (e: any) {
validationState.isValidationCodeValid = false;
validationState.validationCodeInvalidText = _i18n.t('COMMON.MFA_MODAL.INVALID_CODE');
@@ -106,10 +112,15 @@ watch(() => storeState.userId, (userId) => {
state.userInfo = store.state.user;
}
}, { immediate: true });
+watch(() => multiFactorAuthState.modalType, () => {
+ state.isSentCode = false;
+ validationState.isValidationCodeValid = true;
+ validationState.validationCodeInvalidText = '';
+});
- storeState.userId, (userId) => {
@close="handleClickCancel"
>
-
- {{ $t('MY_PAGE.MFA.RESYNC_DESC') }}
-
-
+
+
+ {{ $t('MY_PAGE.MFA.RESYNC_DESC') }}
+
{{ $t('COMMON.MFA_MODAL.ALT.DESC') }}
@@ -179,6 +187,7 @@ watch(() => storeState.userId, (userId) => {
}
.re-sync-desc {
margin-top: 1rem;
+ margin-bottom: 1rem;
}
.validation-code-form {
@apply flex items-end;
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
index 32afb89343..77e6cc4cdf 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
@@ -13,17 +13,17 @@ import { store } from '@/store';
import ErrorHandler from '@/common/composables/error/errorHandler';
-import { useMultiFactorAuthenticationStore } from '@/services/my-page/stores/multi-factor-authentication-store';
+import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
import {
MULTI_FACTOR_AUTH_ITEMS, MULTI_FACTOR_AUTH_TYPE,
} from '@/services/my-page/types/multi-factor-auth-type';
-const multiFactorAuthenticationStore = useMultiFactorAuthenticationStore();
-const multiFactorAuthenticationState = multiFactorAuthenticationStore.state;
+const multiFactorAuthStore = useMultiFactorAuthStore();
+const multiFactorAuthState = multiFactorAuthStore.state;
const storeState = reactive({
mfa: computed(() => store.state.user.mfa || undefined),
- selectedType: computed
(() => multiFactorAuthenticationState.selectedType),
+ selectedType: computed(() => multiFactorAuthState.selectedType),
});
const state = reactive({
enableMfa: mapValues(MULTI_FACTOR_AUTH_TYPE, () => false),
@@ -32,13 +32,14 @@ const state = reactive({
});
const handleChangeToggle = async (type: string, value: boolean) => {
- multiFactorAuthenticationStore.setSelectedType(type);
- multiFactorAuthenticationStore.setModalVisible(value);
+ multiFactorAuthStore.setSelectedType(type);
+ multiFactorAuthStore.setModalType(value ? 'FORM' : 'DISABLED');
+ multiFactorAuthStore.setModalVisible(true);
state.enableMfa[type] = value;
if (storeState.selectedType !== MULTI_FACTOR_AUTH_TYPE.MS) return;
- multiFactorAuthenticationStore.setModalLoading(true);
+ multiFactorAuthStore.setModalLoading(true);
try {
// await postEnableMfa({
// mfa_type: 'OTP',
@@ -47,12 +48,13 @@ const handleChangeToggle = async (type: string, value: boolean) => {
} catch (e) {
ErrorHandler.handleError(e);
} finally {
- multiFactorAuthenticationStore.setModalLoading(false);
+ multiFactorAuthStore.setModalLoading(false);
}
};
const handleClickReSyncButton = (type: string) => {
- multiFactorAuthenticationStore.setSelectedType(type);
- multiFactorAuthenticationStore.setModalType('RE_SYNC');
+ multiFactorAuthStore.setSelectedType(type);
+ multiFactorAuthStore.setModalVisible(true);
+ multiFactorAuthStore.setModalType('RE_SYNC');
};
watch(() => storeState.mfa.mfa_type, (mfa_type) => {
@@ -62,10 +64,10 @@ watch(() => storeState.mfa.mfa_type, (mfa_type) => {
state.enableMfa = mapValues(MULTI_FACTOR_AUTH_TYPE, () => false);
}
}, { immediate: true });
-watch(() => multiFactorAuthenticationState.modalVisible, (modalVisible) => {
+watch(() => multiFactorAuthState.modalVisible, (modalVisible) => {
if (!modalVisible) {
state.enableMfa[storeState.selectedType] = state.type === storeState.selectedType ? state.isVerified : false;
- multiFactorAuthenticationStore.setSelectedType('');
+ multiFactorAuthStore.setSelectedType('');
}
}, { immediate: true });
@@ -75,7 +77,7 @@ watch(() => multiFactorAuthenticationState.modalVisible, (modalVisible) => {
multiFactorAuthenticationState.modalVisible, (modalVisible) => {
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
index bd4c2def47..0c96c997c2 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
@@ -14,20 +14,24 @@ import { emailValidator } from '@/lib/helper/user-validation-helper';
import { useFormValidator } from '@/common/composables/form-validator';
import { useProxyValue } from '@/common/composables/proxy-state';
+import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
+
interface Props {
- isDisabledModal?: boolean
isSentCode?: boolean
}
const props = withDefaults(defineProps(), {
- isDisabledModal: false,
isSentCode: false,
});
+const multiFactorAuthStore = useMultiFactorAuthStore();
+const multiFactorAuthState = multiFactorAuthStore.state;
+
const emit = defineEmits<{(e: 'update:is-sent-code'): void }>();
const storeState = reactive({
email: computed(() => store.state.user.mfa?.options?.email || undefined),
+ isFormModal: computed(() => multiFactorAuthState.modalType === 'FORM'),
});
const state = reactive({
loading: false,
@@ -51,9 +55,9 @@ const {
const handleClickSendCodeButton = async () => {
state.loading = true;
try {
- if (!props.isDisabledModal) {
+ if (storeState.isFormModal) {
await postEnableMfa({
- mfa_type: props.mfaType,
+ mfa_type: 'EMAIL',
options: {
email: email.value,
},
@@ -71,7 +75,7 @@ const handleClickSendCodeButton = async () => {
diff --git a/apps/web/src/services/auth/pages/ValidationEmailPage.vue b/apps/web/src/services/auth/pages/ValidationEmailPage.vue
index 3f8baa7539..7929c06dc5 100644
--- a/apps/web/src/services/auth/pages/ValidationEmailPage.vue
+++ b/apps/web/src/services/auth/pages/ValidationEmailPage.vue
@@ -74,9 +74,9 @@
>
{{ $t('AUTH.PASSWORD.RESET.EMAIL.DONE.COLLAPSED') }}
-
@@ -113,7 +113,7 @@ import { useDomainStore } from '@/store/domain/domain-store';
import ErrorHandler from '@/common/composables/error/errorHandler';
-import CollapsibleContents from '@/services/auth/components/CollapsibleContents.vue';
+import CollapsibleContentsEmail from '@/services/auth/components/CollapsibleContentsEmail.vue';
import { AUTH_ROUTE } from '@/services/auth/routes/route-constant';
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
index cc1a33ccd0..431c01ba24 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthFormModal.vue
@@ -8,6 +8,7 @@ import {
PButtonModal, PFieldGroup, PTextInput,
} from '@cloudforet/mirinae';
+import { MULTI_FACTOR_AUTH_TYPE } from '@/schema/identity/user-profile/constant';
import { store } from '@/store';
import { i18n as _i18n } from '@/translations';
@@ -17,9 +18,7 @@ import UserAccountMultiFactorAuthModalEmailInfo from '@/services/my-page/compone
import UserAccountMultiFactorAuthModalFolding from '@/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue';
import UserAccountMultiFactorAuthModalMSInfo
from '@/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue';
-import {
- MULTI_FACTOR_AUTH_ITEMS, MULTI_FACTOR_AUTH_TYPE,
-} from '@/services/my-page/constants/multi-factor-auth-constants';
+import { MULTI_FACTOR_AUTH_ITEMS } from '@/services/my-page/constants/multi-factor-auth-constants';
import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
import type {
UserInfoType,
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
index bcdf04250e..9ecf5a9c65 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
@@ -5,14 +5,12 @@ import {
PI, PToggleButton, PBadge, PButton,
} from '@cloudforet/mirinae';
+import { MULTI_FACTOR_AUTH_TYPE } from '@/schema/identity/user-profile/constant';
import { store } from '@/store';
import { postUserProfileDisableMfa } from '@/lib/helper/multi-factor-auth-helper';
-import {
- MULTI_FACTOR_AUTH_ITEMS,
- MULTI_FACTOR_AUTH_TYPE,
-} from '@/services/my-page/constants/multi-factor-auth-constants';
+import { MULTI_FACTOR_AUTH_ITEMS } from '@/services/my-page/constants/multi-factor-auth-constants';
import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
const multiFactorAuthStore = useMultiFactorAuthStore();
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
index 39b7df1259..030276e044 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalEmailInfo.vue
@@ -5,6 +5,7 @@ import {
PI, PButton, PTextInput, PFieldGroup,
} from '@cloudforet/mirinae';
+import { MULTI_FACTOR_AUTH_TYPE } from '@/schema/identity/user-profile/constant';
import { store } from '@/store';
import { i18n } from '@/translations';
@@ -14,7 +15,6 @@ import { emailValidator } from '@/lib/helper/user-validation-helper';
import { useFormValidator } from '@/common/composables/form-validator';
import { useProxyValue } from '@/common/composables/proxy-state';
-import { MULTI_FACTOR_AUTH_TYPE } from '@/services/my-page/constants/multi-factor-auth-constants';
import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
interface Props {
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
index bbdad3a6fd..33a5dfef09 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalFolding.vue
@@ -3,14 +3,13 @@ import { computed, reactive } from 'vue';
import { PTextButton, PCollapsibleToggle } from '@cloudforet/mirinae';
+import { MULTI_FACTOR_AUTH_TYPE } from '@/schema/identity/user-profile/constant';
import { store } from '@/store';
import { postUserProfileDisableMfa, postEnableMfa } from '@/lib/helper/multi-factor-auth-helper';
import { useProxyValue } from '@/common/composables/proxy-state';
-import { MULTI_FACTOR_AUTH_TYPE } from '@/services/my-page/constants/multi-factor-auth-constants';
-
interface Props {
isDisabledModal: boolean
isSentCode: boolean
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue
index c41a8af943..8ecc1fcfb6 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthModalMSInfo.vue
@@ -6,11 +6,12 @@ import {
PTextInput, PIconButton, PSpinner,
} from '@cloudforet/mirinae';
+import { MULTI_FACTOR_AUTH_TYPE } from '@/schema/identity/user-profile/constant';
+
import { postEnableMfa } from '@/lib/helper/multi-factor-auth-helper';
import ErrorHandler from '@/common/composables/error/errorHandler';
-import { MULTI_FACTOR_AUTH_TYPE } from '@/services/my-page/constants/multi-factor-auth-constants';
import { useMultiFactorAuthStore } from '@/services/my-page/stores/multi-factor-auth-store';
const multiFactorAuthStore = useMultiFactorAuthStore();
diff --git a/apps/web/src/services/my-page/constants/multi-factor-auth-constants.ts b/apps/web/src/services/my-page/constants/multi-factor-auth-constants.ts
index a4c3904103..4b0bcd773d 100644
--- a/apps/web/src/services/my-page/constants/multi-factor-auth-constants.ts
+++ b/apps/web/src/services/my-page/constants/multi-factor-auth-constants.ts
@@ -1,10 +1,6 @@
+import { MULTI_FACTOR_AUTH_TYPE } from '@/schema/identity/user-profile/constant';
import { i18n } from '@/translations';
-export const MULTI_FACTOR_AUTH_TYPE = {
- OTP: 'OTP',
- EMAIL: 'EMAIL',
-} as const;
-
export const MULTI_FACTOR_AUTH_ITEMS = [
{
type: MULTI_FACTOR_AUTH_TYPE.OTP,
From d4ee95b3475a2516ada5f1e38f9352a44f17e5e0 Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Tue, 22 Oct 2024 10:46:39 +0900
Subject: [PATCH 15/26] feat: apply page after OTP user login (#4885)
* feat: apply page after OTP user login
Signed-off-by: NaYeong,Kim
* chore: update translations
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
.../GOOGLE_OAUTH2/template/GOOGLE_OAUTH2.vue | 5 +-
.../authenticator/local/template/ID_PW.vue | 5 +-
.../components/CollapsibleContentsOTP.vue | 83 ++++++++++
.../src/services/auth/pages/KeycloakPage.vue | 5 +-
.../auth/pages/MultiFactorAuthPage.vue | 51 ++++--
.../console-translation-2.8.babel | 147 ++++++++++++++++++
packages/language-pack/en.json | 9 +-
packages/language-pack/ja.json | 9 +-
packages/language-pack/ko.json | 9 +-
9 files changed, 297 insertions(+), 26 deletions(-)
create mode 100644 apps/web/src/services/auth/components/CollapsibleContentsOTP.vue
diff --git a/apps/web/src/services/auth/authenticator/external/GOOGLE_OAUTH2/template/GOOGLE_OAUTH2.vue b/apps/web/src/services/auth/authenticator/external/GOOGLE_OAUTH2/template/GOOGLE_OAUTH2.vue
index 6daac8a1cf..d49a219683 100644
--- a/apps/web/src/services/auth/authenticator/external/GOOGLE_OAUTH2/template/GOOGLE_OAUTH2.vue
+++ b/apps/web/src/services/auth/authenticator/external/GOOGLE_OAUTH2/template/GOOGLE_OAUTH2.vue
@@ -48,12 +48,13 @@ const onErrorSignIn = (e, token) => {
state.token = token;
if (e.message.includes('MFA')) {
const emailRegex = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g;
- const userEmail = e.message.match(emailRegex);
+ const mfaTypeRegex = /mfa_type\s*=\s*(\w+)/;
router.push({
name: AUTH_ROUTE.SIGN_IN.MULTI_FACTOR_AUTH._NAME,
params: {
accessToken: state.token,
- mfaEmail: userEmail[0],
+ mfaEmail: e.message.match(emailRegex)[0],
+ mfaType: e.message.match(mfaTypeRegex)[1],
userId: state.userId?.trim() as string,
},
});
diff --git a/apps/web/src/services/auth/authenticator/local/template/ID_PW.vue b/apps/web/src/services/auth/authenticator/local/template/ID_PW.vue
index 41eddb4708..61263c2ead 100644
--- a/apps/web/src/services/auth/authenticator/local/template/ID_PW.vue
+++ b/apps/web/src/services/auth/authenticator/local/template/ID_PW.vue
@@ -85,12 +85,13 @@ const signIn = async () => {
} catch (e: any) {
if (e.message.includes('MFA')) {
const emailRegex = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g;
- const userEmail = e.message.match(emailRegex);
+ const mfaTypeRegex = /mfa_type\s*=\s*(\w+)/;
await router.push({
name: AUTH_ROUTE.SIGN_IN.MULTI_FACTOR_AUTH._NAME,
params: {
password: credentials.password,
- mfaEmail: userEmail[0],
+ mfaEmail: e.message.match(emailRegex)[0],
+ mfaType: e.message.match(mfaTypeRegex)[1],
userId: state.userId?.trim() as string,
},
});
diff --git a/apps/web/src/services/auth/components/CollapsibleContentsOTP.vue b/apps/web/src/services/auth/components/CollapsibleContentsOTP.vue
new file mode 100644
index 0000000000..c5b8680027
--- /dev/null
+++ b/apps/web/src/services/auth/components/CollapsibleContentsOTP.vue
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+ {{ $t('AUTH.COLLAPSED.OTP_EXTENSION_TITLE_1') }}
+
+
+ - {{ $t('AUTH.COLLAPSED.OTP_EXTENSION_REASON_1') }}
+ - {{ $t('AUTH.COLLAPSED.OTP_EXTENSION_REASON_2') }}
+
+
+
+
+ {{ $t('AUTH.COLLAPSED.OTP_EXTENSION_TITLE_2') }}
+
+
+
+
+
+
+
+
+ {{ $t('AUTH.COLLAPSED.EXTENSION_CONTACT') }}
+
+
+
+
+
+
+
+
+
diff --git a/apps/web/src/services/auth/pages/KeycloakPage.vue b/apps/web/src/services/auth/pages/KeycloakPage.vue
index 1d2ccfb80d..b30a85a806 100644
--- a/apps/web/src/services/auth/pages/KeycloakPage.vue
+++ b/apps/web/src/services/auth/pages/KeycloakPage.vue
@@ -95,12 +95,13 @@ const onErrorSignIn = (e, token) => {
state.token = token;
if (e.message.includes('MFA')) {
const emailRegex = /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g;
- const userEmail = e.message.match(emailRegex);
+ const mfaTypeRegex = /mfa_type\s*=\s*(\w+)/;
router.push({
name: AUTH_ROUTE.SIGN_IN.MULTI_FACTOR_AUTH._NAME,
params: {
accessToken: state.token,
- mfaEmail: userEmail[0],
+ mfaEmail: e.message.match(emailRegex)[0],
+ mfaType: e.message.match(mfaTypeRegex)[1],
userId: state.beforeUser,
},
});
diff --git a/apps/web/src/services/auth/pages/MultiFactorAuthPage.vue b/apps/web/src/services/auth/pages/MultiFactorAuthPage.vue
index 9c84c43e98..fe0d86f570 100644
--- a/apps/web/src/services/auth/pages/MultiFactorAuthPage.vue
+++ b/apps/web/src/services/auth/pages/MultiFactorAuthPage.vue
@@ -7,8 +7,8 @@ import {
PButton, PIconButton, PFieldGroup, PI, PTextInput, PTextButton,
} from '@cloudforet/mirinae';
+import { MULTI_FACTOR_AUTH_TYPE } from '@/schema/identity/user-profile/constant';
import { store } from '@/store';
-// CAUTION: To prevent the issue of i18n imported in the template not being applied in the 'script setup' structure.
import { i18n as _i18n } from '@/translations';
import { useUserWorkspaceStore } from '@/store/app-context/workspace/user-workspace-store';
@@ -19,24 +19,30 @@ import ErrorHandler from '@/common/composables/error/errorHandler';
import { loadAuth } from '@/services/auth/authenticator/loader';
import CollapsibleContentsEmail from '@/services/auth/components/CollapsibleContentsEmail.vue';
+import CollapsibleContentsOTP from '@/services/auth/components/CollapsibleContentsOTP.vue';
import { getDefaultRouteAfterSignIn } from '@/services/auth/helpers/default-route-helper';
import { AUTH_ROUTE } from '@/services/auth/routes/route-constant';
+type TitleType = {
+ icon: string;
+ title: string;
+ desc: TranslateResult;
+};
const route = useRoute();
const router = useRouter();
const userWorkspaceStore = useUserWorkspaceStore();
const {
- password, userId, mfaEmail, accessToken,
+ password, userId, mfaEmail, accessToken, mfaType,
} = route.params;
const state = reactive({
loading: false,
- isLocalLogin: computed(() => userId && !accessToken),
+ isLocalLogin: computed(() => (userId && !accessToken) || false),
confirmLoading: false,
isCollapsed: true,
- credentials: computed(() => {
+ credentials: computed>(() => {
if (!accessToken) {
return {
user_id: userId,
@@ -47,6 +53,20 @@ const state = reactive({
access_token: accessToken,
};
}),
+ titleInfo: computed(() => {
+ if (mfaType === MULTI_FACTOR_AUTH_TYPE.EMAIL) {
+ return {
+ icon: 'ic_notification-protocol_envelope',
+ title: 'EMAIL',
+ desc: _i18n.t('AUTH.MFA.EMAIL_INFO'),
+ };
+ }
+ return {
+ icon: 'ic_microsoft_auth',
+ title: 'Microsoft Authenticator App',
+ desc: _i18n.t('AUTH.MFA.OTP_INFO'),
+ };
+ }),
});
const validationState = reactive({
@@ -123,22 +143,17 @@ onMounted(() => {
@@ -216,7 +234,6 @@ onMounted(() => {
.email-info-wrapper {
.email-info-desc {
@apply block text-label-md;
- margin-bottom: 0.5rem;
}
.email-text {
@apply text-violet-600 font-medium;
diff --git a/packages/language-pack/console-translation-2.8.babel b/packages/language-pack/console-translation-2.8.babel
index 33540bd3ba..f9312cc3c4 100644
--- a/packages/language-pack/console-translation-2.8.babel
+++ b/packages/language-pack/console-translation-2.8.babel
@@ -682,6 +682,132 @@
+
+ GOOGLE_GUIDE
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ OTP_EXTENSION_DESC_1
+ false
+
+
+
+
+
+ en-US
+ true
+
+
+ ja-JP
+ true
+
+
+ ko-KR
+ true
+
+
+
+
+ OTP_EXTENSION_REASON_1
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ OTP_EXTENSION_REASON_2
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ OTP_EXTENSION_TITLE_1
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
+
+ OTP_EXTENSION_TITLE_2
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
@@ -813,6 +939,27 @@
+
+ OTP_INFO
+ false
+
+
+
+
+
+ en-US
+ false
+
+
+ ja-JP
+ false
+
+
+ ko-KR
+ false
+
+
+
PROBLEM_TITLE
false
diff --git a/packages/language-pack/en.json b/packages/language-pack/en.json
index c1ed11ad84..25c629f1b8 100644
--- a/packages/language-pack/en.json
+++ b/packages/language-pack/en.json
@@ -42,7 +42,13 @@
"EXTENSION_REASON_2": "Check your spam.",
"EXTENSION_REASON_3": "to re-send the email.",
"EXTENSION_TITLE_1": "Didn't receive an email?",
- "EXTENSION_TITLE_2": "Still having trouble?"
+ "EXTENSION_TITLE_2": "Still having trouble?",
+ "GOOGLE_GUIDE": "Google’s verification guide",
+ "OTP_EXTENSION_DESC_1": "If you are still experiencing problems with {guide}, follow Google’s verification guide. If the problem only exists across SpaceONE, {contact}. ",
+ "OTP_EXTENSION_REASON_1": "Make sure you have adequate internet connection when trying to send/receive codes.",
+ "OTP_EXTENSION_REASON_2": "Your time may not be correctly synced on your authenticator app. To set the correct time, go to your Google Authenticator app Settings > Time correction for codes > Sync now.",
+ "OTP_EXTENSION_TITLE_1": "Didn’t recieve a push notification in your Google Authenticator app?",
+ "OTP_EXTENSION_TITLE_2": "Still having problems?"
},
"MFA": {
"AUTHENTICATION_CODE": "Authentication code",
@@ -51,6 +57,7 @@
"EMAIL_INFO": "allows multi-factor authentication(MFA) for account logins. A MFA code has been sent to an email address:",
"ENTER_CODE": "Enter Code",
"GO_BACK": "Back to Sign in",
+ "OTP_INFO": "allows multi-factor authentication(MFA) for account logins. Enter the code that you see in the app.",
"PROBLEM_TITLE": "Having problems?",
"SUB_TITLE": "Your account required to verify with email MFA.",
"TITLE": "Multi-factor\nauthentication"
diff --git a/packages/language-pack/ja.json b/packages/language-pack/ja.json
index f308cffdaa..c54a7d58ab 100644
--- a/packages/language-pack/ja.json
+++ b/packages/language-pack/ja.json
@@ -42,7 +42,13 @@
"EXTENSION_REASON_2": "迷惑メールボックスを含めてご確認下さい。",
"EXTENSION_REASON_3": "をクリックして、メールを再送信してください。",
"EXTENSION_TITLE_1": "メールが届かない場合は、",
- "EXTENSION_TITLE_2": "まだメールを受け取っていないですか?"
+ "EXTENSION_TITLE_2": "まだメールを受け取っていないですか?",
+ "GOOGLE_GUIDE": "",
+ "OTP_EXTENSION_DESC_1": "",
+ "OTP_EXTENSION_REASON_1": "",
+ "OTP_EXTENSION_REASON_2": "",
+ "OTP_EXTENSION_TITLE_1": "",
+ "OTP_EXTENSION_TITLE_2": ""
},
"MFA": {
"AUTHENTICATION_CODE": "認証コード",
@@ -51,6 +57,7 @@
"EMAIL_INFO": "",
"ENTER_CODE": "コードを入力",
"GO_BACK": "ログインする",
+ "OTP_INFO": "",
"PROBLEM_TITLE": "",
"SUB_TITLE": "マルチファクタ認証を使用してアカウントを確認する必要があります。",
"TITLE": "マルチファクタ\n認証"
diff --git a/packages/language-pack/ko.json b/packages/language-pack/ko.json
index e93fc9131b..a75039c8b3 100644
--- a/packages/language-pack/ko.json
+++ b/packages/language-pack/ko.json
@@ -42,7 +42,13 @@
"EXTENSION_REASON_2": "스팸 메일을 확인해주세요. ",
"EXTENSION_REASON_3": "을 클릭하여, 이메일을 재전송을 시도하세요. ",
"EXTENSION_TITLE_1": "이메일을 받지 못하셨나요?",
- "EXTENSION_TITLE_2": "아직도 이메일을 받지 못하셨나요? "
+ "EXTENSION_TITLE_2": "아직도 이메일을 받지 못하셨나요? ",
+ "GOOGLE_GUIDE": "",
+ "OTP_EXTENSION_DESC_1": "",
+ "OTP_EXTENSION_REASON_1": "",
+ "OTP_EXTENSION_REASON_2": "",
+ "OTP_EXTENSION_TITLE_1": "",
+ "OTP_EXTENSION_TITLE_2": ""
},
"MFA": {
"AUTHENTICATION_CODE": "인증 코드",
@@ -51,6 +57,7 @@
"EMAIL_INFO": "",
"ENTER_CODE": "코드 입력",
"GO_BACK": "로그인 하러 가기",
+ "OTP_INFO": "",
"PROBLEM_TITLE": "",
"SUB_TITLE": "멀티 팩터 인증을 사용하여 계정 확인이 필요합니다.",
"TITLE": "멀티 팩터\n인증"
From ba56f2f9890435cdec1f335282ce32000ac6a818 Mon Sep 17 00:00:00 2001
From: "NaYeong,Kim"
Date: Tue, 22 Oct 2024 15:11:26 +0900
Subject: [PATCH 16/26] feat: apply mfa type toggle button at user edit modal
(#4889)
* fix: fixed selected user type bug
Signed-off-by: NaYeong,Kim
* feat: apply mfa type toggle button at user edit modal
Signed-off-by: NaYeong,Kim
---------
Signed-off-by: NaYeong,Kim
---
.../UserManagementFormMultiFactorAuth.vue | 64 ++++++++++++-------
...serManagementFormNotificationEmailForm.vue | 5 +-
.../services/iam/constants/user-constant.ts | 13 ++++
3 files changed, 57 insertions(+), 25 deletions(-)
diff --git a/apps/web/src/services/iam/components/UserManagementFormMultiFactorAuth.vue b/apps/web/src/services/iam/components/UserManagementFormMultiFactorAuth.vue
index 389657e4b6..03fbd960ad 100644
--- a/apps/web/src/services/iam/components/UserManagementFormMultiFactorAuth.vue
+++ b/apps/web/src/services/iam/components/UserManagementFormMultiFactorAuth.vue
@@ -1,14 +1,17 @@
@@ -55,27 +56,44 @@ watch(() => state.data.mfa?.state, (value) => {
/>
-
+
diff --git a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
index d6ccbde2bf..080faef503 100644
--- a/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
+++ b/apps/web/src/services/my-page/components/UserAccountMultiFactorAuthItems.vue
@@ -1,5 +1,9 @@
-