RuralDatabase/apps/web/components/user/form/setting/edit-totp.vue

116 lines
2.8 KiB
Vue

<script setup lang="ts">
import { z } from 'zod'
import type { FormSubmitEvent } from '#ui/types'
const model = defineModel({
type: Boolean
})
const { data, refresh } = useAsyncData(userApi.qrTotpCode)
const user = useUserStore()
const toast = useToastHandle()
const { identityCheck } = useVerify()
const loading = ref(false)
const schema = z.object({
TotpCode: z.string({
required_error: '验证码不能为空'
}),
})
type Schema = z.output<typeof schema>
const state = reactive({
TotpCode: undefined,
})
const toggle = computed(() => {
return (!!user.userInfo.IsTotp)
})
async function onClick() {
loading.value = true
await identityCheck(async () => {
try {
if (user.userInfo.IsTotp) {
// 关闭双因素认证
await userApi.edit({ IsSafeCheck: user.userInfo.IsSafeCheck ? 2 : 1 })
user.getUserInfo()
} else {
model.value = true
}
} catch (e: any) {
toast.error(e.message)
}
})
loading.value = false
}
async function onSubmit(event: FormSubmitEvent<Schema>) {
try {
await userApi.edit({ ...event.data, TotpSecret: data.value?.TotpSecret })
await user.getUserInfo()
model.value = false
} catch (err: any) {
refresh()
toast.error(err.message)
}
}
</script>
<template>
<div class="flex justify-end gap-2 items-center">
<span class="typography-muted">
{{ user.userInfo.IsTotp ? "已绑定" : "未绑定" }}
</span>
<UToggle
v-model="toggle"
:on-icon="loading ? 'i-eos-icons-three-dots-loading' : 'i-heroicons-check-20-solid'"
:off-icon="loading ? 'i-eos-icons-three-dots-loading' : 'i-heroicons-x-mark-20-solid'"
:disabled="loading"
size="xl"
@click="onClick"
/>
</div>
<UDashboardModal v-model="model" title="身份验证器" description="使用移动设备进行身份绑定" :ui="{ width: 'sm:max-w-md' }">
<UForm ref="form" :schema="schema" :state="state" class="space-y-4 md:space-y-6" @submit="onSubmit">
<div class="flex flex-col justify-center items-center px-10">
<UTooltip text="点击刷新" class="w-full">
<NuxtImg
class="rounded overflow-hidden w-full cursor-pointer"
:src="`data:image/png;base64,${data?.Qr}`"
@click="refresh"
/>
</UTooltip>
<span class=" typography-muted">用相关设备扫一扫绑定</span>
</div>
<UFormGroup name="Code">
<UButtonGroup orientation="horizontal" class="w-full">
<UInput v-model="state.TotpCode" :maxlength="4" class="flex-1" placeholder="请输入验证码" />
</UButtonGroup>
</UFormGroup>
<div class="flex justify-end">
<UButton type="submit" class="px-4">
确认
</UButton>
</div>
</UForm>
</UDashboardModal>
</template>