bfg-common 1.5.831 → 1.5.833
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/localization/local_be.json +2 -1
- package/assets/localization/local_en.json +2 -1
- package/assets/localization/local_hy.json +2 -1
- package/assets/localization/local_kk.json +2 -1
- package/assets/localization/local_ru.json +4 -2
- package/assets/localization/local_zh.json +2 -1
- package/components/common/layout/theHeader/userMenu/modals/preferences/Old.vue +156 -136
- package/components/common/layout/theHeader/userMenu/modals/preferences/security/Old.vue +196 -184
- package/components/common/layout/theHeader/userMenu/modals/preferences/security/Security.vue +2 -0
- package/components/common/layout/topNotification/TopNotification.vue +5 -1
- package/components/common/layout/topNotification/lib/models/enums.ts +2 -0
- package/package.json +1 -1
|
@@ -3915,7 +3915,8 @@
|
|
|
3915
3915
|
"backToLogin": "Вярнуцца да ўваходу",
|
|
3916
3916
|
"qrcodeDescription": "Скануйце гэты QR-код з дапамогай праграмы-аўтэнтыфікатара альбо ўвядзіце адзін з гэтых кодаў уручную. Пасля гэтага пацвердзіце дзеянне, увёўшы аднаразовы код ніжэй.",
|
|
3917
3917
|
"showNotification": "Паказваць апавяшчэнне",
|
|
3918
|
-
"showNotificationDescription": "Паказваць апавяшчэнне, калі нешта ідзе не так"
|
|
3918
|
+
"showNotificationDescription": "Паказваць апавяшчэнне, калі нешта ідзе не так",
|
|
3919
|
+
"twoFactorMustBeEnabled": "Неабходна падключыць двухфактарную аўтэнтыфікацыю (2FA), інакш ваш акаўнт будзе заблакаваны."
|
|
3919
3920
|
},
|
|
3920
3921
|
"ssoConfiguration": {
|
|
3921
3922
|
"twoFactorPolicy": "Палітыка двухфактарнай аўтэнтыфікацыі",
|
|
@@ -3919,7 +3919,8 @@
|
|
|
3919
3919
|
"backToLogin": "Back to Login",
|
|
3920
3920
|
"qrcodeDescription": "Scan this QR code with your authenticator app, or enter one of these codes manually. After that, confirm the action by entering the one-time code below.",
|
|
3921
3921
|
"showNotification": "Show a notification",
|
|
3922
|
-
"showNotificationDescription": "Show a notification when something goes wrong"
|
|
3922
|
+
"showNotificationDescription": "Show a notification when something goes wrong",
|
|
3923
|
+
"twoFactorMustBeEnabled": "Two-factor authentication (2FA) must be enabled, otherwise your account will be blocked."
|
|
3923
3924
|
},
|
|
3924
3925
|
"ssoConfiguration": {
|
|
3925
3926
|
"twoFactorPolicy": "Two-factor policy",
|
|
@@ -3919,7 +3919,8 @@
|
|
|
3919
3919
|
"backToLogin": "Վերադառնալ մուտքի էջ",
|
|
3920
3920
|
"qrcodeDescription": "Սկանավորեք այս QR կոդը ձեր նույնականացման հավելվածով կամ մուտքագրեք այս կոդերից մեկը ձեռքով: Դրանից հետո հաստատեք գործողությունը՝ ներքևում մուտքագրելով միանգամյա կոդը:",
|
|
3921
3921
|
"showNotification": "Ցուցադրել ծանուցում",
|
|
3922
|
-
"showNotificationDescription": "Ցուցադրել ծանուցում, երբ ինչ-որ բան սխալ է ընթանում"
|
|
3922
|
+
"showNotificationDescription": "Ցուցադրել ծանուցում, երբ ինչ-որ բան սխալ է ընթանում",
|
|
3923
|
+
"twoFactorMustBeEnabled": "Անհրաժեշտ է միացնել երկգործոն նույնականացում (2FA), հակառակ դեպքում ձեր հաշիվը կարգելափակվի:"
|
|
3923
3924
|
},
|
|
3924
3925
|
"ssoConfiguration": {
|
|
3925
3926
|
"twoFactorPolicy": "Երկու գործոնի քաղաքականություն",
|
|
@@ -3919,7 +3919,8 @@
|
|
|
3919
3919
|
"backToLogin": "Кіру бетіне оралу",
|
|
3920
3920
|
"qrcodeDescription": "Бұл QR-кодты аутентификатор қолданбасымен сканерлеңіз немесе осы кодтардың бірін қолмен енгізіңіз. Содан кейін әрекетті төмендегі бір реттік кодты енгізу арқылы растаңыз.",
|
|
3921
3921
|
"showNotification": "Хабарландыруды көрсету",
|
|
3922
|
-
"showNotificationDescription": "Бірдеңе дұрыс емес болған кезде хабарландыруды көрсету"
|
|
3922
|
+
"showNotificationDescription": "Бірдеңе дұрыс емес болған кезде хабарландыруды көрсету",
|
|
3923
|
+
"twoFactorMustBeEnabled": "Екі факторлы аутентификацияны (2FA) қосу қажет, әйтпесе сіздің аккаунтыңыз бұғатталады."
|
|
3923
3924
|
},
|
|
3924
3925
|
"ssoConfiguration": {
|
|
3925
3926
|
"twoFactorPolicy": "Екі факторлы саясат",
|
|
@@ -2603,7 +2603,7 @@
|
|
|
2603
2603
|
"loginErrorText": "Неверное имя пользователя или пароль",
|
|
2604
2604
|
"loginAccessErrorText": "У вас нет доступа для входа в систему",
|
|
2605
2605
|
"tooManyLoginAttempts": "Слишком много неуспешных попыток авторизации. Попробуйте позже.",
|
|
2606
|
-
"passwordLifeWarning": "Ваш пароль истечёт через {0}
|
|
2606
|
+
"passwordLifeWarning": "Ваш пароль истечёт через {0} {1}",
|
|
2607
2607
|
"theUserIsLocked": "Пользователь заблокирован"
|
|
2608
2608
|
},
|
|
2609
2609
|
"home": {
|
|
@@ -3918,7 +3918,9 @@
|
|
|
3918
3918
|
"backToLogin": "Вернуться ко входу",
|
|
3919
3919
|
"qrcodeDescription": "Отсканируйте этот QR-код с помощью приложения-аутентификатора или введите один из этих кодов вручную. После этого подтвердите действие, введя одноразовый код ниже.",
|
|
3920
3920
|
"showNotification": "Показывать уведомление",
|
|
3921
|
-
"showNotificationDescription": "Показывать уведомление, когда что-то идёт не так"
|
|
3921
|
+
"showNotificationDescription": "Показывать уведомление, когда что-то идёт не так",
|
|
3922
|
+
"twoFactorMustBeEnabled": "Необходимо подключить двухфакторную аутентификацию (2FA), иначе ваш аккаунт будет заблокирован.",
|
|
3923
|
+
"twoFactorMustWarning": "Вам осталось {0} {1}, чтобы подключить двухфакторную аутентификацию (2FA), иначе ваш аккаунт будет заблокирован (отключён)."
|
|
3922
3924
|
},
|
|
3923
3925
|
"ssoConfiguration": {
|
|
3924
3926
|
"twoFactorPolicy": "Политика двухфакторной аутентификации",
|
|
@@ -3916,7 +3916,8 @@
|
|
|
3916
3916
|
"backToLogin": "返回登录",
|
|
3917
3917
|
"qrcodeDescription": "使用您的身份验证器应用程序扫描此QR码,或手动输入其中一个代码。然后,通过输入下面的一次性代码来确认操作。",
|
|
3918
3918
|
"showNotification": "显示通知",
|
|
3919
|
-
"showNotificationDescription": "当出现问题时显示通知"
|
|
3919
|
+
"showNotificationDescription": "当出现问题时显示通知",
|
|
3920
|
+
"twoFactorMustBeEnabled": "必须启用双因素认证(2FA),否则您的账户将被锁定。"
|
|
3920
3921
|
},
|
|
3921
3922
|
"ssoConfiguration": {
|
|
3922
3923
|
"twoFactorPolicy": "双因素策略",
|
|
@@ -1,136 +1,156 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<atoms-modal
|
|
3
|
-
:title="localization.common.preferences"
|
|
4
|
-
:modal-loading="isLoading || props.securityLoader"
|
|
5
|
-
test-id="user-preferences-modal"
|
|
6
|
-
width="580px"
|
|
7
|
-
height="420px"
|
|
8
|
-
show
|
|
9
|
-
@hide="onHide"
|
|
10
|
-
>
|
|
11
|
-
<template #modalBody>
|
|
12
|
-
<atoms-nav-bar
|
|
13
|
-
v-model="selectedTab"
|
|
14
|
-
:items="tabsItems"
|
|
15
|
-
test-id="user-preferences-nav-bar"
|
|
16
|
-
/>
|
|
17
|
-
|
|
18
|
-
<common-layout-the-header-user-menu-modals-preferences-time-format
|
|
19
|
-
v-if="selectedTab === 'time-tab'"
|
|
20
|
-
v-model:time-format="timeFormat"
|
|
21
|
-
:new-view="props.newView"
|
|
22
|
-
/>
|
|
23
|
-
|
|
24
|
-
<common-layout-the-header-user-menu-modals-preferences-change-language
|
|
25
|
-
v-if="selectedTab === 'language-tab'"
|
|
26
|
-
:new-view="props.newView"
|
|
27
|
-
:selected-type="props.selectedLanguageType"
|
|
28
|
-
:selected-language="props.selectedLanguage"
|
|
29
|
-
@update-language="emits('update-language', $event)"
|
|
30
|
-
@update-is-browser="emits('update-is-browser', $event)"
|
|
31
|
-
/>
|
|
32
|
-
|
|
33
|
-
<common-layout-the-header-user-menu-modals-preferences-inventory
|
|
34
|
-
v-if="selectedTab === 'inventory-tab' && isSphere"
|
|
35
|
-
v-model="vmInHostsClusters"
|
|
36
|
-
:new-view="props.newView"
|
|
37
|
-
/>
|
|
38
|
-
|
|
39
|
-
<common-layout-the-header-user-menu-modals-preferences-default-console
|
|
40
|
-
v-if="selectedTab === 'console-tab' && isSphere"
|
|
41
|
-
v-model="consoleValue"
|
|
42
|
-
:new-view="props.newView"
|
|
43
|
-
/>
|
|
44
|
-
|
|
45
|
-
<common-layout-the-header-user-menu-modals-preferences-security
|
|
46
|
-
v-if="selectedTab === 'security-tab'"
|
|
47
|
-
v-model:security="security"
|
|
48
|
-
:recovery="props.recovery"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
v-
|
|
55
|
-
v-model:
|
|
56
|
-
:
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
</
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
import type {
|
|
84
|
-
import type {
|
|
85
|
-
import type {
|
|
86
|
-
import type {
|
|
87
|
-
import type {
|
|
88
|
-
import {
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
const
|
|
95
|
-
const
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
(event: '
|
|
109
|
-
(event: '
|
|
110
|
-
(event: '
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
const
|
|
121
|
-
|
|
122
|
-
)
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<atoms-modal
|
|
3
|
+
:title="localization.common.preferences"
|
|
4
|
+
:modal-loading="isLoading || props.securityLoader"
|
|
5
|
+
test-id="user-preferences-modal"
|
|
6
|
+
width="580px"
|
|
7
|
+
height="420px"
|
|
8
|
+
show
|
|
9
|
+
@hide="onHide"
|
|
10
|
+
>
|
|
11
|
+
<template #modalBody>
|
|
12
|
+
<atoms-nav-bar
|
|
13
|
+
v-model="selectedTab"
|
|
14
|
+
:items="tabsItems"
|
|
15
|
+
test-id="user-preferences-nav-bar"
|
|
16
|
+
/>
|
|
17
|
+
|
|
18
|
+
<common-layout-the-header-user-menu-modals-preferences-time-format
|
|
19
|
+
v-if="selectedTab === 'time-tab'"
|
|
20
|
+
v-model:time-format="timeFormat"
|
|
21
|
+
:new-view="props.newView"
|
|
22
|
+
/>
|
|
23
|
+
|
|
24
|
+
<common-layout-the-header-user-menu-modals-preferences-change-language
|
|
25
|
+
v-if="selectedTab === 'language-tab'"
|
|
26
|
+
:new-view="props.newView"
|
|
27
|
+
:selected-type="props.selectedLanguageType"
|
|
28
|
+
:selected-language="props.selectedLanguage"
|
|
29
|
+
@update-language="emits('update-language', $event)"
|
|
30
|
+
@update-is-browser="emits('update-is-browser', $event)"
|
|
31
|
+
/>
|
|
32
|
+
|
|
33
|
+
<common-layout-the-header-user-menu-modals-preferences-inventory
|
|
34
|
+
v-if="selectedTab === 'inventory-tab' && isSphere"
|
|
35
|
+
v-model="vmInHostsClusters"
|
|
36
|
+
:new-view="props.newView"
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<common-layout-the-header-user-menu-modals-preferences-default-console
|
|
40
|
+
v-if="selectedTab === 'console-tab' && isSphere"
|
|
41
|
+
v-model="consoleValue"
|
|
42
|
+
:new-view="props.newView"
|
|
43
|
+
/>
|
|
44
|
+
|
|
45
|
+
<common-layout-the-header-user-menu-modals-preferences-security
|
|
46
|
+
v-if="selectedTab === 'security-tab'"
|
|
47
|
+
v-model:security="security"
|
|
48
|
+
:recovery="props.recovery"
|
|
49
|
+
:is-on-fa-important="isOn2FaImportant"
|
|
50
|
+
@confirm="emits('security-confirm', $event)"
|
|
51
|
+
/>
|
|
52
|
+
|
|
53
|
+
<common-layout-the-header-user-menu-modals-preferences-view
|
|
54
|
+
v-if="selectedTab === 'view-tab'"
|
|
55
|
+
v-model:new-view-local="newViewLocal"
|
|
56
|
+
v-model:is-show-notification="isShowNotification"
|
|
57
|
+
:new-view="props.newView"
|
|
58
|
+
/>
|
|
59
|
+
</template>
|
|
60
|
+
|
|
61
|
+
<template #modalFooter>
|
|
62
|
+
<button
|
|
63
|
+
id="user-preferences-cancel-button"
|
|
64
|
+
data-id="user-preferences-cancel-button"
|
|
65
|
+
class="btn btn-outline"
|
|
66
|
+
@click="onHide"
|
|
67
|
+
>
|
|
68
|
+
{{ localization.common.cancel }}
|
|
69
|
+
</button>
|
|
70
|
+
<button
|
|
71
|
+
id="user-preferences-apply-button"
|
|
72
|
+
data-id="user-preferences-apply-button"
|
|
73
|
+
class="btn btn-primary"
|
|
74
|
+
@click="onSubmit"
|
|
75
|
+
>
|
|
76
|
+
{{ localization.common.save }}
|
|
77
|
+
</button>
|
|
78
|
+
</template>
|
|
79
|
+
</atoms-modal>
|
|
80
|
+
</template>
|
|
81
|
+
|
|
82
|
+
<script setup lang="ts">
|
|
83
|
+
import type { UI_I_CollapseNavItem } from '~/components/atoms/collapse/lib/models/interfaces'
|
|
84
|
+
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
85
|
+
import type { UI_T_LangValue, UI_T_Project } from '~/lib/models/types'
|
|
86
|
+
import type { UI_T_UserPreferenceTab } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/models/types'
|
|
87
|
+
import type { UI_T_TimeValue } from '~/components/common/layout/theHeader/userMenu/modals/preferences/timeFormat/lib/models/types'
|
|
88
|
+
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
89
|
+
import { UI_E_TopNotificationActionId } from '~/components/common/layout/topNotification/lib/models/enums'
|
|
90
|
+
import { preferencesTabs } from '~/components/common/layout/theHeader/userMenu/modals/preferences/lib/config/preferencesTabs'
|
|
91
|
+
|
|
92
|
+
const security = defineModel<boolean>('security')
|
|
93
|
+
const isShowNotification = defineModel<boolean>('isShowNotification')
|
|
94
|
+
const newViewLocal = defineModel<boolean>('newViewLocal')
|
|
95
|
+
const timeFormat = defineModel<UI_T_TimeValue>('timeFormat')
|
|
96
|
+
const consoleValue = defineModel<string>('consoleValue')
|
|
97
|
+
const vmInHostsClusters = defineModel<boolean>('vmInHostsClusters')
|
|
98
|
+
|
|
99
|
+
const props = defineProps<{
|
|
100
|
+
project: UI_T_Project
|
|
101
|
+
selectedLanguage: UI_T_LangValue
|
|
102
|
+
selectedLanguageType: UI_T_LangValue
|
|
103
|
+
newView: boolean
|
|
104
|
+
securityLoader: boolean // для Сферы
|
|
105
|
+
recovery: UI_I_Recovery | null // для Сферы
|
|
106
|
+
}>()
|
|
107
|
+
const emits = defineEmits<{
|
|
108
|
+
(event: 'hide'): void
|
|
109
|
+
(event: 'update-language', value: string): void
|
|
110
|
+
(event: 'update-is-browser', value: string): void
|
|
111
|
+
(event: 'security-confirm', value: boolean): void
|
|
112
|
+
(event: 'submit'): void
|
|
113
|
+
}>()
|
|
114
|
+
|
|
115
|
+
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
116
|
+
|
|
117
|
+
const isLoading = ref<boolean>(false)
|
|
118
|
+
|
|
119
|
+
const isSphere = ref<boolean>(props.project === 'sphere')
|
|
120
|
+
const selectedTab = ref<UI_T_UserPreferenceTab>('time-tab')
|
|
121
|
+
|
|
122
|
+
const tabsItems = computed<UI_I_CollapseNavItem[]>(() =>
|
|
123
|
+
preferencesTabs(localization.value, props.project)
|
|
124
|
+
)
|
|
125
|
+
|
|
126
|
+
const onSubmit = (): void => {
|
|
127
|
+
isLoading.value = true
|
|
128
|
+
emits('submit')
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const onHide = (): void => {
|
|
132
|
+
emits('hide')
|
|
133
|
+
|
|
134
|
+
if (isSphere.value) {
|
|
135
|
+
selectedTab.value = 'time-tab'
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// TODO refactoring
|
|
140
|
+
const { $store }: any = useNuxtApp()
|
|
141
|
+
const topNotifications = computed<number>(
|
|
142
|
+
() => $store.getters['main/getTopNotificationActionId']
|
|
143
|
+
)
|
|
144
|
+
const isOn2FaImportant = ref<boolean>(false)
|
|
145
|
+
watch(
|
|
146
|
+
topNotifications,
|
|
147
|
+
(newValue) => {
|
|
148
|
+
if (newValue === UI_E_TopNotificationActionId.on2Fa || newValue === UI_E_TopNotificationActionId.on2FaImportant) {
|
|
149
|
+
isOn2FaImportant.value = newValue === UI_E_TopNotificationActionId.on2FaImportant
|
|
150
|
+
selectedTab.value = 'security-tab'
|
|
151
|
+
$store.dispatch('main/A_SET_TOP_NOTIFICATION_ACTION_ID', -1)
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{ immediate: true }
|
|
155
|
+
)
|
|
156
|
+
</script>
|
|
@@ -1,184 +1,196 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<form id="security-form" class="compact" @submit.prevent>
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</div>
|
|
13
|
-
|
|
14
|
-
<div
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
<
|
|
44
|
-
<
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
{{
|
|
50
|
-
</
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
<
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<form id="security-form" class="compact" @submit.prevent>
|
|
3
|
+
<!-- TODO new view-->
|
|
4
|
+
<div v-if="props.isOnFaImportant">
|
|
5
|
+
<atoms-alert
|
|
6
|
+
:hide-close-icon="true"
|
|
7
|
+
:items="[localization.myPreferences.twoFactorMustBeEnabled]"
|
|
8
|
+
status="alert-warning"
|
|
9
|
+
class="mb-1"
|
|
10
|
+
test-id="on-2-fa-alert"
|
|
11
|
+
/>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<div class="description">
|
|
15
|
+
{{ localization.myPreferences.twoFactorAuthentication }}
|
|
16
|
+
</div>
|
|
17
|
+
|
|
18
|
+
<div class="flex-align-center">
|
|
19
|
+
<label for="security">{{
|
|
20
|
+
localization.myPreferences.securityLabel
|
|
21
|
+
}}</label>
|
|
22
|
+
<input id="security" v-model="security" type="checkbox" class="switch" />
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div
|
|
26
|
+
v-if="
|
|
27
|
+
props.recovery &&
|
|
28
|
+
security &&
|
|
29
|
+
!props.initialSecurity &&
|
|
30
|
+
!props.otpEnabledSuccess
|
|
31
|
+
"
|
|
32
|
+
class="recovery-codes-wrap"
|
|
33
|
+
>
|
|
34
|
+
<p>
|
|
35
|
+
{{ localization.myPreferences.enterOtpForEnabled }}
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
<div class="recovery-codes">
|
|
39
|
+
<common-qr :qr-code-url="props.recovery.qr_code_url" />
|
|
40
|
+
|
|
41
|
+
<span>{{ localization.common.or }}</span>
|
|
42
|
+
|
|
43
|
+
<ul class="recovery-codes-list">
|
|
44
|
+
<li
|
|
45
|
+
v-for="item in props.recovery.recovery_codes"
|
|
46
|
+
:key="item"
|
|
47
|
+
class="recovery-codes-list-item"
|
|
48
|
+
>
|
|
49
|
+
{{ item }}
|
|
50
|
+
</li>
|
|
51
|
+
</ul>
|
|
52
|
+
</div>
|
|
53
|
+
<section class="form-block">
|
|
54
|
+
<div class="form-group">
|
|
55
|
+
<label for="otp">{{
|
|
56
|
+
localization.myPreferences.enterOtpForEnabled
|
|
57
|
+
}}</label>
|
|
58
|
+
<input id="otp" v-model="otp" type="text" />
|
|
59
|
+
<button class="btn btn-sm btn-primary" @click="emits('confirm')">
|
|
60
|
+
{{ localization.common.confirm }}
|
|
61
|
+
</button>
|
|
62
|
+
<atoms-loader
|
|
63
|
+
v-if="props.isOtpLoading"
|
|
64
|
+
test-id="2fa-enabled-loader"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
</section>
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
<div v-if="!security && props.initialSecurity && !props.otpDisabledSuccess">
|
|
71
|
+
<section class="form-block">
|
|
72
|
+
<div class="form-group">
|
|
73
|
+
<label for="otp">{{
|
|
74
|
+
localization.myPreferences.enterOtpForDisabled
|
|
75
|
+
}}</label>
|
|
76
|
+
<input id="otp" v-model="otp" type="text" />
|
|
77
|
+
<button class="btn btn-sm btn-primary" @click="emits('disabled')">
|
|
78
|
+
{{ localization.common.confirm }}
|
|
79
|
+
</button>
|
|
80
|
+
<atoms-loader
|
|
81
|
+
v-if="props.isOtpLoading"
|
|
82
|
+
test-id="2fa-disabled-loader"
|
|
83
|
+
/>
|
|
84
|
+
</div>
|
|
85
|
+
</section>
|
|
86
|
+
</div>
|
|
87
|
+
</form>
|
|
88
|
+
</template>
|
|
89
|
+
|
|
90
|
+
<script setup lang="ts">
|
|
91
|
+
import type { UI_I_Localization } from '~/lib/models/interfaces'
|
|
92
|
+
import type { UI_I_Recovery } from '~/components/common/layout/theHeader/userMenu/modals/preferences/security/lib/models/interfaces'
|
|
93
|
+
|
|
94
|
+
const security = defineModel<boolean>('security')
|
|
95
|
+
const otp = defineModel<string>('otp')
|
|
96
|
+
|
|
97
|
+
const props = defineProps<{
|
|
98
|
+
initialSecurity: boolean
|
|
99
|
+
isOtpLoading: boolean
|
|
100
|
+
otpEnabledSuccess: boolean
|
|
101
|
+
otpDisabledSuccess: boolean
|
|
102
|
+
recovery: UI_I_Recovery | null
|
|
103
|
+
isOnFaImportant: boolean
|
|
104
|
+
}>()
|
|
105
|
+
const emits = defineEmits<{
|
|
106
|
+
(event: 'confirm'): void
|
|
107
|
+
(event: 'disabled'): void
|
|
108
|
+
}>()
|
|
109
|
+
|
|
110
|
+
const localization = computed<UI_I_Localization>(() => useLocal())
|
|
111
|
+
</script>
|
|
112
|
+
|
|
113
|
+
<style lang="scss" scoped>
|
|
114
|
+
.description {
|
|
115
|
+
margin-bottom: 10px;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.recovery-codes-wrap {
|
|
119
|
+
margin: 10px 0;
|
|
120
|
+
|
|
121
|
+
.recovery-codes {
|
|
122
|
+
display: flex;
|
|
123
|
+
align-items: center;
|
|
124
|
+
justify-content: space-evenly;
|
|
125
|
+
|
|
126
|
+
.recovery-codes-list-item {
|
|
127
|
+
font-size: 12px;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
label {
|
|
133
|
+
margin-right: 6px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// TODO повторяется в ../view, необходимо вынести глобально
|
|
137
|
+
input[type='checkbox'] {
|
|
138
|
+
--active: var(--checkbox-value-active-color);
|
|
139
|
+
--active-inner: var(--checkbox-mark-color);
|
|
140
|
+
--border: var(--checkbox-mark-color);
|
|
141
|
+
--background: var(--checkbox-mark-background-color);
|
|
142
|
+
-webkit-appearance: none;
|
|
143
|
+
-moz-appearance: none;
|
|
144
|
+
height: 20px;
|
|
145
|
+
outline: none;
|
|
146
|
+
display: inline-block;
|
|
147
|
+
vertical-align: top;
|
|
148
|
+
position: relative;
|
|
149
|
+
margin: 0;
|
|
150
|
+
cursor: pointer;
|
|
151
|
+
border: 1px solid var(--bc, var(--border));
|
|
152
|
+
background: var(--b, var(--background));
|
|
153
|
+
transition: background 0.3s, border-color 0.3s, box-shadow 0.2s;
|
|
154
|
+
&:after {
|
|
155
|
+
content: '';
|
|
156
|
+
display: block;
|
|
157
|
+
left: 0;
|
|
158
|
+
top: 0;
|
|
159
|
+
position: absolute;
|
|
160
|
+
transition: transform var(--d-t, 0.3s) var(--d-t-e, ease),
|
|
161
|
+
opacity var(--d-o, 0.2s);
|
|
162
|
+
}
|
|
163
|
+
&:checked {
|
|
164
|
+
--b: var(--active);
|
|
165
|
+
--bc: var(--active);
|
|
166
|
+
--d-o: 0.3s;
|
|
167
|
+
--d-t: 0.6s;
|
|
168
|
+
--d-t-e: cubic-bezier(0.2, 0.85, 0.32, 1.2);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
input[type='checkbox'] {
|
|
172
|
+
&.switch {
|
|
173
|
+
width: 35px;
|
|
174
|
+
border-radius: 11px;
|
|
175
|
+
&:after {
|
|
176
|
+
left: 2px;
|
|
177
|
+
top: 2px;
|
|
178
|
+
bottom: 2px;
|
|
179
|
+
border-radius: 50%;
|
|
180
|
+
width: 14px;
|
|
181
|
+
height: 14px;
|
|
182
|
+
border: 1px solid var(--bc, var(--border));
|
|
183
|
+
background: var(--ab, var(--border));
|
|
184
|
+
transform: translateX(var(--x, 0));
|
|
185
|
+
}
|
|
186
|
+
&:checked {
|
|
187
|
+
--ab: var(--active-inner);
|
|
188
|
+
--x: 14px;
|
|
189
|
+
}
|
|
190
|
+
&:disabled {
|
|
191
|
+
cursor: not-allowed;
|
|
192
|
+
opacity: 0.5;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
</style>
|
package/components/common/layout/theHeader/userMenu/modals/preferences/security/Security.vue
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
:recovery="props.recovery"
|
|
11
11
|
:otp-error-api-text="otpErrorApiText"
|
|
12
12
|
:otp-disabled-error-api-text="otpDisabledErrorApiText"
|
|
13
|
+
:is-on-fa-important="props.isOnFaImportant"
|
|
13
14
|
@confirm="onConfirm"
|
|
14
15
|
@disabled="onDisabled"
|
|
15
16
|
/>
|
|
@@ -22,6 +23,7 @@ const security = defineModel<boolean>('security')
|
|
|
22
23
|
|
|
23
24
|
const props = defineProps<{
|
|
24
25
|
recovery: UI_I_Recovery | null
|
|
26
|
+
isOnFaImportant: boolean
|
|
25
27
|
}>()
|
|
26
28
|
|
|
27
29
|
const emits = defineEmits<{
|