mirror of https://github.com/halo-dev/halo
feat: refine 2fa-related i18n (#6228)
#### What type of PR is this? /area ui /kind feature /milestone 2.17.x #### What this PR does / why we need it: 补充 2FA 相关的 i18n 定义。 #### Does this PR introduce a user-facing change? ```release-note None ```pull/6211/head
parent
2c454ccb28
commit
f3f48e2753
|
@ -1,15 +1,24 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { setFocus } from "@/formkit/utils/focus";
|
||||||
import { submitForm } from "@formkit/core";
|
import { submitForm } from "@formkit/core";
|
||||||
import { Toast, VButton } from "@halo-dev/components";
|
import { Toast, VButton } from "@halo-dev/components";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import qs from "qs";
|
import qs from "qs";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "succeed"): void;
|
(event: "succeed"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const loading = ref(false);
|
||||||
|
|
||||||
async function onSubmit({ code }: { code: string }) {
|
async function onSubmit({ code }: { code: string }) {
|
||||||
try {
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
const _csrf = document.cookie
|
const _csrf = document.cookie
|
||||||
.split("; ")
|
.split("; ")
|
||||||
.find((row) => row.startsWith("XSRF-TOKEN"))
|
.find((row) => row.startsWith("XSRF-TOKEN"))
|
||||||
|
@ -36,9 +45,15 @@ async function onSubmit({ code }: { code: string }) {
|
||||||
|
|
||||||
emit("succeed");
|
emit("succeed");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Toast.error("验证失败");
|
Toast.error(t("core.common.toast.validation_failed"));
|
||||||
|
} finally {
|
||||||
|
loading.value = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
setFocus("code");
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -54,19 +69,25 @@ async function onSubmit({ code }: { code: string }) {
|
||||||
@keyup.enter="submitForm('mfa-form')"
|
@keyup.enter="submitForm('mfa-form')"
|
||||||
>
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
|
id="code"
|
||||||
:classes="{
|
:classes="{
|
||||||
outer: '!py-0',
|
outer: '!py-0',
|
||||||
}"
|
}"
|
||||||
name="code"
|
name="code"
|
||||||
placeholder="请输入两步验证码"
|
:placeholder="$t('core.login.2fa.fields.code.placeholder')"
|
||||||
validation-label="两步验证码"
|
:validation-label="$t('core.login.2fa.fields.code.label')"
|
||||||
:autofocus="true"
|
|
||||||
type="text"
|
type="text"
|
||||||
validation="required"
|
validation="required"
|
||||||
>
|
>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
<VButton class="mt-8" block type="secondary" @click="submitForm('mfa-form')">
|
<VButton
|
||||||
验证
|
:loading="loading"
|
||||||
|
class="mt-8"
|
||||||
|
block
|
||||||
|
type="secondary"
|
||||||
|
@click="submitForm('mfa-form')"
|
||||||
|
>
|
||||||
|
{{ $t("core.common.buttons.verify") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -25,6 +25,11 @@ core:
|
||||||
button: Login
|
button: Login
|
||||||
modal:
|
modal:
|
||||||
title: Re-login
|
title: Re-login
|
||||||
|
2fa:
|
||||||
|
fields:
|
||||||
|
code:
|
||||||
|
placeholder: Two-step verification code
|
||||||
|
label: Two-step verification code
|
||||||
signup:
|
signup:
|
||||||
title: Sign up
|
title: Sign up
|
||||||
fields:
|
fields:
|
||||||
|
@ -1161,6 +1166,7 @@ core:
|
||||||
detail: Detail
|
detail: Detail
|
||||||
notification-preferences: Notification Preferences
|
notification-preferences: Notification Preferences
|
||||||
pat: Personal Access Tokens
|
pat: Personal Access Tokens
|
||||||
|
2fa: 2FA
|
||||||
devices: Devices
|
devices: Devices
|
||||||
actions:
|
actions:
|
||||||
update_profile:
|
update_profile:
|
||||||
|
@ -1194,6 +1200,49 @@ core:
|
||||||
title: Verify email
|
title: Verify email
|
||||||
email_verified:
|
email_verified:
|
||||||
tooltip: Verified
|
tooltip: Verified
|
||||||
|
2fa:
|
||||||
|
operations:
|
||||||
|
enable:
|
||||||
|
button: Enable 2FA
|
||||||
|
title: Enable 2FA
|
||||||
|
disable:
|
||||||
|
title: Disable 2FA
|
||||||
|
disable_totp:
|
||||||
|
title: Disable TOTP
|
||||||
|
password_validation_form:
|
||||||
|
fields:
|
||||||
|
password:
|
||||||
|
label: Password
|
||||||
|
help: Login password of the current account
|
||||||
|
methods:
|
||||||
|
title: Two-factor methods
|
||||||
|
totp:
|
||||||
|
title: TOTP
|
||||||
|
description: Configure two-step verification with TOTP application
|
||||||
|
fields:
|
||||||
|
status:
|
||||||
|
configured: Configured
|
||||||
|
not_configured: Not configured
|
||||||
|
operations:
|
||||||
|
reconfigure:
|
||||||
|
button: Reconfigure
|
||||||
|
configure:
|
||||||
|
button: Configure
|
||||||
|
title: TOTP configuration
|
||||||
|
fields:
|
||||||
|
code:
|
||||||
|
label: Verification code
|
||||||
|
help: >-
|
||||||
|
6-digit verification code obtained from the validator
|
||||||
|
application
|
||||||
|
password:
|
||||||
|
label: Password
|
||||||
|
help: Login password of the current account
|
||||||
|
qrcode:
|
||||||
|
label: "Use the validator application to scan the QR code below:"
|
||||||
|
manual:
|
||||||
|
label: "If you can't scan the QR code, click to view the alternative steps."
|
||||||
|
help: "Manually configure the validator application with the following code:"
|
||||||
pat:
|
pat:
|
||||||
operations:
|
operations:
|
||||||
delete:
|
delete:
|
||||||
|
@ -1707,6 +1756,8 @@ core:
|
||||||
access: Access
|
access: Access
|
||||||
schedule_publish: Schedule publish
|
schedule_publish: Schedule publish
|
||||||
revoke: Revoke
|
revoke: Revoke
|
||||||
|
disable: Disable
|
||||||
|
enable: Enable
|
||||||
radio:
|
radio:
|
||||||
"yes": "Yes"
|
"yes": "Yes"
|
||||||
"no": "No"
|
"no": "No"
|
||||||
|
@ -1739,6 +1790,8 @@ core:
|
||||||
not_found: Resource not found
|
not_found: Resource not found
|
||||||
server_internal_error: Internal server error
|
server_internal_error: Internal server error
|
||||||
unknown_error: Unknown error
|
unknown_error: Unknown error
|
||||||
|
disable_success: Disabled successfully
|
||||||
|
enable_success: Enabled successfully
|
||||||
dialog:
|
dialog:
|
||||||
titles:
|
titles:
|
||||||
tip: Tip
|
tip: Tip
|
||||||
|
|
|
@ -25,6 +25,11 @@ core:
|
||||||
button: 登录
|
button: 登录
|
||||||
modal:
|
modal:
|
||||||
title: 重新登录
|
title: 重新登录
|
||||||
|
2fa:
|
||||||
|
fields:
|
||||||
|
code:
|
||||||
|
placeholder: 请输入两步验证码
|
||||||
|
label: 两步验证码
|
||||||
signup:
|
signup:
|
||||||
title: 注册
|
title: 注册
|
||||||
fields:
|
fields:
|
||||||
|
@ -1086,6 +1091,7 @@ core:
|
||||||
detail: 详情
|
detail: 详情
|
||||||
notification-preferences: 通知配置
|
notification-preferences: 通知配置
|
||||||
pat: 个人令牌
|
pat: 个人令牌
|
||||||
|
2fa: 两步验证
|
||||||
devices: 登录设备
|
devices: 登录设备
|
||||||
actions:
|
actions:
|
||||||
update_profile:
|
update_profile:
|
||||||
|
@ -1115,6 +1121,47 @@ core:
|
||||||
description: 电子邮箱地址还未验证,点击下方按钮进行验证
|
description: 电子邮箱地址还未验证,点击下方按钮进行验证
|
||||||
email_verified:
|
email_verified:
|
||||||
tooltip: 已验证
|
tooltip: 已验证
|
||||||
|
2fa:
|
||||||
|
operations:
|
||||||
|
enable:
|
||||||
|
button: 启用两步验证
|
||||||
|
title: 启用两步验证
|
||||||
|
disable:
|
||||||
|
title: 禁用两步验证
|
||||||
|
disable_totp:
|
||||||
|
title: 停用 TOTP
|
||||||
|
password_validation_form:
|
||||||
|
fields:
|
||||||
|
password:
|
||||||
|
label: 验证密码
|
||||||
|
help: 当前账号的登录密码
|
||||||
|
methods:
|
||||||
|
title: 验证方式
|
||||||
|
totp:
|
||||||
|
title: TOTP
|
||||||
|
description: 使用 TOTP 应用程序配置两步验证
|
||||||
|
fields:
|
||||||
|
status:
|
||||||
|
configured: 已配置
|
||||||
|
not_configured: 未配置
|
||||||
|
operations:
|
||||||
|
reconfigure:
|
||||||
|
button: 重新配置
|
||||||
|
configure:
|
||||||
|
button: 配置
|
||||||
|
title: TOTP 配置
|
||||||
|
fields:
|
||||||
|
code:
|
||||||
|
label: 验证码
|
||||||
|
help: 从验证器应用获得的 6 位验证码
|
||||||
|
password:
|
||||||
|
label: 验证密码
|
||||||
|
help: 当前账号的登录密码
|
||||||
|
qrcode:
|
||||||
|
label: 使用验证器应用扫描下方二维码:
|
||||||
|
manual:
|
||||||
|
label: 如果无法扫描二维码,点击查看代替步骤
|
||||||
|
help: 使用以下代码手动配置验证器应用:
|
||||||
pat:
|
pat:
|
||||||
operations:
|
operations:
|
||||||
delete:
|
delete:
|
||||||
|
@ -1624,6 +1671,8 @@ core:
|
||||||
access: 访问
|
access: 访问
|
||||||
schedule_publish: 定时发布
|
schedule_publish: 定时发布
|
||||||
revoke: 撤销
|
revoke: 撤销
|
||||||
|
disable: 禁用
|
||||||
|
enable: 启用
|
||||||
radio:
|
radio:
|
||||||
"yes": 是
|
"yes": 是
|
||||||
"no": 否
|
"no": 否
|
||||||
|
@ -1656,6 +1705,8 @@ core:
|
||||||
not_found: 资源不存在
|
not_found: 资源不存在
|
||||||
server_internal_error: 服务器内部错误
|
server_internal_error: 服务器内部错误
|
||||||
unknown_error: 未知错误
|
unknown_error: 未知错误
|
||||||
|
disable_success: 禁用成功
|
||||||
|
enable_success: 啟用成功
|
||||||
dialog:
|
dialog:
|
||||||
titles:
|
titles:
|
||||||
tip: 提示
|
tip: 提示
|
||||||
|
|
|
@ -25,6 +25,11 @@ core:
|
||||||
button: 登入
|
button: 登入
|
||||||
modal:
|
modal:
|
||||||
title: 重新登入
|
title: 重新登入
|
||||||
|
2fa:
|
||||||
|
fields:
|
||||||
|
code:
|
||||||
|
placeholder: 請輸入兩步驟驗證碼
|
||||||
|
label: 兩步驟驗證碼
|
||||||
signup:
|
signup:
|
||||||
title: 註冊
|
title: 註冊
|
||||||
fields:
|
fields:
|
||||||
|
@ -1066,6 +1071,7 @@ core:
|
||||||
detail: 詳情
|
detail: 詳情
|
||||||
notification-preferences: 通知配置
|
notification-preferences: 通知配置
|
||||||
pat: 個人令牌
|
pat: 個人令牌
|
||||||
|
2fa: 两步验证
|
||||||
devices: 登錄設備
|
devices: 登錄設備
|
||||||
actions:
|
actions:
|
||||||
update_profile:
|
update_profile:
|
||||||
|
@ -1095,6 +1101,47 @@ core:
|
||||||
title: 驗證電子郵件信箱
|
title: 驗證電子郵件信箱
|
||||||
email_verified:
|
email_verified:
|
||||||
tooltip: 已驗證
|
tooltip: 已驗證
|
||||||
|
2fa:
|
||||||
|
operations:
|
||||||
|
enable:
|
||||||
|
button: 启用两步验证
|
||||||
|
title: 启用两步验证
|
||||||
|
disable:
|
||||||
|
title: 禁用两步验证
|
||||||
|
disable_totp:
|
||||||
|
title: 停用 TOTP
|
||||||
|
password_validation_form:
|
||||||
|
fields:
|
||||||
|
password:
|
||||||
|
label: 验证密碼
|
||||||
|
help: 目前帳號的登入密碼
|
||||||
|
methods:
|
||||||
|
title: 驗證方法
|
||||||
|
totp:
|
||||||
|
title: TOTP
|
||||||
|
description: 使用 TOTP 應用程式設定兩步驟驗證
|
||||||
|
fields:
|
||||||
|
status:
|
||||||
|
configured: 已配置
|
||||||
|
not_configured: 未配置
|
||||||
|
operations:
|
||||||
|
reconfigure:
|
||||||
|
button: 重新配置
|
||||||
|
configure:
|
||||||
|
button: 配置
|
||||||
|
title: TOTP 配置
|
||||||
|
fields:
|
||||||
|
code:
|
||||||
|
label: 驗證碼
|
||||||
|
help: 從驗證器應用程式取得的 6 位驗證碼
|
||||||
|
password:
|
||||||
|
label: 验证密碼
|
||||||
|
help: 目前帳號的登入密碼
|
||||||
|
qrcode:
|
||||||
|
label: 使用驗證器應用程式掃描下面的二維碼:
|
||||||
|
manual:
|
||||||
|
label: 如果您無法掃描二維碼,請按一下查看替代步驟。
|
||||||
|
help: 使用以下程式碼手動配置驗證器應用程式:
|
||||||
pat:
|
pat:
|
||||||
operations:
|
operations:
|
||||||
delete:
|
delete:
|
||||||
|
@ -1581,6 +1628,8 @@ core:
|
||||||
access: 訪問
|
access: 訪問
|
||||||
schedule_publish: 定時發佈
|
schedule_publish: 定時發佈
|
||||||
revoke: 撤銷
|
revoke: 撤銷
|
||||||
|
disable: 禁用
|
||||||
|
enable: 启用
|
||||||
radio:
|
radio:
|
||||||
"yes": 是
|
"yes": 是
|
||||||
"no": 否
|
"no": 否
|
||||||
|
@ -1613,6 +1662,8 @@ core:
|
||||||
not_found: 資源不存在
|
not_found: 資源不存在
|
||||||
server_internal_error: 伺服器內部錯誤
|
server_internal_error: 伺服器內部錯誤
|
||||||
unknown_error: 未知錯誤
|
unknown_error: 未知錯誤
|
||||||
|
disable_success: 禁用成功
|
||||||
|
enable_success: 啟用成功
|
||||||
dialog:
|
dialog:
|
||||||
titles:
|
titles:
|
||||||
tip: 提示
|
tip: 提示
|
||||||
|
|
|
@ -70,7 +70,7 @@ const tabs = ref<UserProfileTab[]>([
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "2fa",
|
id: "2fa",
|
||||||
label: "两步验证",
|
label: t("core.uc_profile.tabs.2fa"),
|
||||||
component: markRaw(TwoFactor),
|
component: markRaw(TwoFactor),
|
||||||
priority: 40,
|
priority: 40,
|
||||||
},
|
},
|
||||||
|
|
|
@ -51,7 +51,9 @@ const totpDeletionModalVisible = ref(false);
|
||||||
:checked="settings?.enabled"
|
:checked="settings?.enabled"
|
||||||
@change="onEnabledChange"
|
@change="onEnabledChange"
|
||||||
/>
|
/>
|
||||||
<span class="text-sm font-medium text-gray-700">启用两步验证</span>
|
<span class="text-sm font-medium text-gray-700">
|
||||||
|
{{ $t("core.uc_profile.2fa.operations.enable.button") }}
|
||||||
|
</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -63,7 +65,9 @@ const totpDeletionModalVisible = ref(false);
|
||||||
role="list"
|
role="list"
|
||||||
>
|
>
|
||||||
<li class="bg-gray-50 px-4 py-3">
|
<li class="bg-gray-50 px-4 py-3">
|
||||||
<span class="text-sm font-semibold text-gray-900">验证方式</span>
|
<span class="text-sm font-semibold text-gray-900">
|
||||||
|
{{ $t("core.uc_profile.2fa.methods.title") }}
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<VEntity>
|
<VEntity>
|
||||||
|
@ -74,20 +78,36 @@ const totpDeletionModalVisible = ref(false);
|
||||||
</template>
|
</template>
|
||||||
</VEntityField>
|
</VEntityField>
|
||||||
<VEntityField
|
<VEntityField
|
||||||
title="TOTP"
|
:title="$t('core.uc_profile.2fa.methods.totp.title')"
|
||||||
description="使用 TOTP 应用程序配置两步验证"
|
:description="$t('core.uc_profile.2fa.methods.totp.description')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template #end>
|
<template #end>
|
||||||
<StatusDotField
|
<StatusDotField
|
||||||
:state="settings?.totpConfigured ? 'success' : 'default'"
|
:state="settings?.totpConfigured ? 'success' : 'default'"
|
||||||
:text="settings?.totpConfigured ? '已配置' : '未配置'"
|
:text="
|
||||||
|
settings?.totpConfigured
|
||||||
|
? $t(
|
||||||
|
'core.uc_profile.2fa.methods.totp.fields.status.configured'
|
||||||
|
)
|
||||||
|
: $t(
|
||||||
|
'core.uc_profile.2fa.methods.totp.fields.status.not_configured'
|
||||||
|
)
|
||||||
|
"
|
||||||
></StatusDotField>
|
></StatusDotField>
|
||||||
<VEntityField>
|
<VEntityField>
|
||||||
<template #description>
|
<template #description>
|
||||||
<VSpace>
|
<VSpace>
|
||||||
<VButton size="sm" @click="totpConfigureModalVisible = true">
|
<VButton size="sm" @click="totpConfigureModalVisible = true">
|
||||||
{{ settings?.totpConfigured ? "重新配置" : "配置" }}
|
{{
|
||||||
|
settings?.totpConfigured
|
||||||
|
? $t(
|
||||||
|
"core.uc_profile.2fa.methods.totp.operations.reconfigure.button"
|
||||||
|
)
|
||||||
|
: $t(
|
||||||
|
"core.uc_profile.2fa.methods.totp.operations.configure.button"
|
||||||
|
)
|
||||||
|
}}
|
||||||
</VButton>
|
</VButton>
|
||||||
<VButton
|
<VButton
|
||||||
v-if="settings?.totpConfigured"
|
v-if="settings?.totpConfigured"
|
||||||
|
@ -95,7 +115,7 @@ const totpDeletionModalVisible = ref(false);
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="totpDeletionModalVisible = true"
|
@click="totpDeletionModalVisible = true"
|
||||||
>
|
>
|
||||||
停用
|
{{ $t("core.common.buttons.disable") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
</VSpace>
|
</VSpace>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -17,10 +17,14 @@ function onSubmit({ password }: { password: string }) {
|
||||||
>
|
>
|
||||||
<FormKit
|
<FormKit
|
||||||
type="password"
|
type="password"
|
||||||
label="验证密码"
|
:label="
|
||||||
|
$t('core.uc_profile.2fa.password_validation_form.fields.password.label')
|
||||||
|
"
|
||||||
validation="required"
|
validation="required"
|
||||||
name="password"
|
name="password"
|
||||||
help="当前账号的登录密码"
|
:help="
|
||||||
|
$t('core.uc_profile.2fa.password_validation_form.fields.password.help')
|
||||||
|
"
|
||||||
autocomplete="current-password"
|
autocomplete="current-password"
|
||||||
></FormKit>
|
></FormKit>
|
||||||
</FormKit>
|
</FormKit>
|
||||||
|
|
|
@ -5,8 +5,10 @@ import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
||||||
import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/vue-query";
|
||||||
import { useQRCode } from "@vueuse/integrations/useQRCode";
|
import { useQRCode } from "@vueuse/integrations/useQRCode";
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
|
@ -32,7 +34,7 @@ const { mutate, isLoading } = useMutation({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
Toast.success("配置成功");
|
Toast.success(t("core.common.toast.save_success"));
|
||||||
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
||||||
modal.value?.close();
|
modal.value?.close();
|
||||||
},
|
},
|
||||||
|
@ -48,20 +50,34 @@ function onSubmit(data: TotpRequest) {
|
||||||
ref="modal"
|
ref="modal"
|
||||||
:width="500"
|
:width="500"
|
||||||
:centered="false"
|
:centered="false"
|
||||||
title="TOTP 配置"
|
:title="$t('core.uc_profile.2fa.methods.totp.operations.configure.title')"
|
||||||
@close="emit('close')"
|
@close="emit('close')"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<div class="mb-4 space-y-3 border-b border-gray-100 pb-4 text-gray-900">
|
<div class="mb-4 space-y-3 border-b border-gray-100 pb-4 text-gray-900">
|
||||||
<div class="text-sm font-semibold">使用验证器应用扫描下方二维码:</div>
|
<div class="text-sm font-semibold">
|
||||||
|
{{
|
||||||
|
$t(
|
||||||
|
"core.uc_profile.2fa.methods.totp.operations.configure.fields.qrcode.label"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</div>
|
||||||
<img :src="qrcode" class="rounded-base border border-gray-100" />
|
<img :src="qrcode" class="rounded-base border border-gray-100" />
|
||||||
<details>
|
<details>
|
||||||
<summary class="cursor-pointer select-none text-sm text-gray-800">
|
<summary class="cursor-pointer select-none text-sm text-gray-800">
|
||||||
如果无法扫描二维码,点击查看代替步骤
|
{{
|
||||||
|
$t(
|
||||||
|
"core.uc_profile.2fa.methods.totp.operations.configure.fields.manual.label"
|
||||||
|
)
|
||||||
|
}}
|
||||||
</summary>
|
</summary>
|
||||||
<div class="mt-3 rounded-base border border-gray-100 p-2">
|
<div class="mt-3 rounded-base border border-gray-100 p-2">
|
||||||
<span class="text-sm text-gray-600">
|
<span class="text-sm text-gray-600">
|
||||||
使用以下代码手动配置验证器应用:
|
{{
|
||||||
|
$t(
|
||||||
|
"core.uc_profile.2fa.methods.totp.operations.configure.fields.manual.help"
|
||||||
|
)
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
<div class="mt-2">
|
<div class="mt-2">
|
||||||
<code
|
<code
|
||||||
|
@ -77,16 +93,32 @@ function onSubmit(data: TotpRequest) {
|
||||||
<FormKit
|
<FormKit
|
||||||
type="number"
|
type="number"
|
||||||
name="code"
|
name="code"
|
||||||
label="验证码"
|
:label="
|
||||||
|
$t(
|
||||||
|
'core.uc_profile.2fa.methods.totp.operations.configure.fields.code.label'
|
||||||
|
)
|
||||||
|
"
|
||||||
validation="required"
|
validation="required"
|
||||||
help="从验证器应用获得的 6 位验证码"
|
:help="
|
||||||
|
$t(
|
||||||
|
'core.uc_profile.2fa.methods.totp.operations.configure.fields.code.help'
|
||||||
|
)
|
||||||
|
"
|
||||||
></FormKit>
|
></FormKit>
|
||||||
<FormKit
|
<FormKit
|
||||||
type="password"
|
type="password"
|
||||||
label="验证密码"
|
:label="
|
||||||
|
$t(
|
||||||
|
'core.uc_profile.2fa.methods.totp.operations.configure.fields.password.label'
|
||||||
|
)
|
||||||
|
"
|
||||||
validation="required"
|
validation="required"
|
||||||
name="password"
|
name="password"
|
||||||
help="当前账号的登录密码"
|
:help="
|
||||||
|
$t(
|
||||||
|
'core.uc_profile.2fa.methods.totp.operations.configure.fields.password.help'
|
||||||
|
)
|
||||||
|
"
|
||||||
autocomplete="current-password"
|
autocomplete="current-password"
|
||||||
></FormKit>
|
></FormKit>
|
||||||
<FormKit
|
<FormKit
|
||||||
|
@ -103,9 +135,11 @@ function onSubmit(data: TotpRequest) {
|
||||||
type="secondary"
|
type="secondary"
|
||||||
@click="$formkit.submit('totp-form')"
|
@click="$formkit.submit('totp-form')"
|
||||||
>
|
>
|
||||||
完成
|
{{ $t("core.common.buttons.save") }}
|
||||||
|
</VButton>
|
||||||
|
<VButton @click="modal?.close()">
|
||||||
|
{{ $t("core.common.buttons.close") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
<VButton @click="modal?.close()">关闭</VButton>
|
|
||||||
</VSpace>
|
</VSpace>
|
||||||
</template>
|
</template>
|
||||||
</VModal>
|
</VModal>
|
||||||
|
|
|
@ -3,9 +3,11 @@ import { ucApiClient } from "@halo-dev/api-client";
|
||||||
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
import PasswordValidationForm from "./PasswordValidationForm.vue";
|
import PasswordValidationForm from "./PasswordValidationForm.vue";
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
|
@ -23,7 +25,7 @@ const { mutate, isLoading } = useMutation({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
Toast.success("停用成功");
|
Toast.success(t("core.common.toast.disable_success"));
|
||||||
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
||||||
modal.value?.close();
|
modal.value?.close();
|
||||||
},
|
},
|
||||||
|
@ -39,7 +41,7 @@ function onSubmit(password: string) {
|
||||||
ref="modal"
|
ref="modal"
|
||||||
:width="500"
|
:width="500"
|
||||||
:centered="false"
|
:centered="false"
|
||||||
title="停用 TOTP"
|
:title="$t('core.uc_profile.2fa.operations.disable_totp.title')"
|
||||||
@close="emit('close')"
|
@close="emit('close')"
|
||||||
>
|
>
|
||||||
<PasswordValidationForm @submit="onSubmit" />
|
<PasswordValidationForm @submit="onSubmit" />
|
||||||
|
@ -50,9 +52,11 @@ function onSubmit(password: string) {
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="$formkit.submit('password-validation-form')"
|
@click="$formkit.submit('password-validation-form')"
|
||||||
>
|
>
|
||||||
停用
|
{{ $t("core.common.buttons.disable") }}
|
||||||
|
</VButton>
|
||||||
|
<VButton @click="modal?.close()">
|
||||||
|
{{ $t("core.common.buttons.close") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
<VButton @click="modal?.close()">关闭</VButton>
|
|
||||||
</VSpace>
|
</VSpace>
|
||||||
</template>
|
</template>
|
||||||
</VModal>
|
</VModal>
|
||||||
|
|
|
@ -3,9 +3,11 @@ import { ucApiClient } from "@halo-dev/api-client";
|
||||||
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
import PasswordValidationForm from "./PasswordValidationForm.vue";
|
import PasswordValidationForm from "./PasswordValidationForm.vue";
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
|
@ -23,7 +25,7 @@ const { mutate, isLoading } = useMutation({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
Toast.success("停用成功");
|
Toast.success(t("core.common.toast.disable_success"));
|
||||||
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
||||||
modal.value?.close();
|
modal.value?.close();
|
||||||
},
|
},
|
||||||
|
@ -39,7 +41,7 @@ function onSubmit(password: string) {
|
||||||
ref="modal"
|
ref="modal"
|
||||||
:width="500"
|
:width="500"
|
||||||
:centered="false"
|
:centered="false"
|
||||||
title="停用两步验证"
|
:title="$t('core.uc_profile.2fa.operations.disable.title')"
|
||||||
@close="emit('close')"
|
@close="emit('close')"
|
||||||
>
|
>
|
||||||
<PasswordValidationForm @submit="onSubmit" />
|
<PasswordValidationForm @submit="onSubmit" />
|
||||||
|
@ -50,9 +52,11 @@ function onSubmit(password: string) {
|
||||||
type="danger"
|
type="danger"
|
||||||
@click="$formkit.submit('password-validation-form')"
|
@click="$formkit.submit('password-validation-form')"
|
||||||
>
|
>
|
||||||
停用
|
{{ $t("core.common.buttons.disable") }}
|
||||||
|
</VButton>
|
||||||
|
<VButton @click="modal?.close()">
|
||||||
|
{{ $t("core.common.buttons.close") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
<VButton @click="modal?.close()">关闭</VButton>
|
|
||||||
</VSpace>
|
</VSpace>
|
||||||
</template>
|
</template>
|
||||||
</VModal>
|
</VModal>
|
||||||
|
|
|
@ -3,9 +3,11 @@ import { ucApiClient } from "@halo-dev/api-client";
|
||||||
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
import { Toast, VButton, VModal, VSpace } from "@halo-dev/components";
|
||||||
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
import { useMutation, useQueryClient } from "@tanstack/vue-query";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
|
import { useI18n } from "vue-i18n";
|
||||||
import PasswordValidationForm from "./PasswordValidationForm.vue";
|
import PasswordValidationForm from "./PasswordValidationForm.vue";
|
||||||
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: "close"): void;
|
(event: "close"): void;
|
||||||
|
@ -23,7 +25,7 @@ const { mutate, isLoading } = useMutation({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
Toast.success("启用成功");
|
Toast.success(t("core.common.toast.enable_success"));
|
||||||
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
queryClient.invalidateQueries({ queryKey: ["two-factor-settings"] });
|
||||||
modal.value?.close();
|
modal.value?.close();
|
||||||
},
|
},
|
||||||
|
@ -39,7 +41,7 @@ function onSubmit(password: string) {
|
||||||
ref="modal"
|
ref="modal"
|
||||||
:width="500"
|
:width="500"
|
||||||
:centered="false"
|
:centered="false"
|
||||||
title="启用两步验证"
|
:title="$t('core.uc_profile.2fa.operations.enable.title')"
|
||||||
@close="emit('close')"
|
@close="emit('close')"
|
||||||
>
|
>
|
||||||
<PasswordValidationForm @submit="onSubmit" />
|
<PasswordValidationForm @submit="onSubmit" />
|
||||||
|
@ -50,9 +52,11 @@ function onSubmit(password: string) {
|
||||||
type="secondary"
|
type="secondary"
|
||||||
@click="$formkit.submit('password-validation-form')"
|
@click="$formkit.submit('password-validation-form')"
|
||||||
>
|
>
|
||||||
启用
|
{{ $t("core.common.buttons.enable") }}
|
||||||
|
</VButton>
|
||||||
|
<VButton @click="modal?.close()">
|
||||||
|
{{ $t("core.common.buttons.close") }}
|
||||||
</VButton>
|
</VButton>
|
||||||
<VButton @click="modal?.close()">关闭</VButton>
|
|
||||||
</VSpace>
|
</VSpace>
|
||||||
</template>
|
</template>
|
||||||
</VModal>
|
</VModal>
|
||||||
|
|
Loading…
Reference in New Issue