From c9c6424205f1d05813735a8f9c0e53a1ccc35e0e Mon Sep 17 00:00:00 2001
From: かっこかり <67428053+kakkokari-gtyih@users.noreply.github.com>
Date: Fri, 22 Mar 2024 15:03:21 +0900
Subject: enhance(frontend): TOTPの入力ダイアログを改良 (#13607)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* enhance(frontend): TOTPの入力ダイアログを改良

* Update Changelog
---
 .../frontend/src/components/MkPasswordDialog.vue   | 26 +++++++++++++---------
 1 file changed, 15 insertions(+), 11 deletions(-)

(limited to 'packages/frontend/src/components/MkPasswordDialog.vue')

diff --git a/packages/frontend/src/components/MkPasswordDialog.vue b/packages/frontend/src/components/MkPasswordDialog.vue
index c49526d8e2..e749725fea 100644
--- a/packages/frontend/src/components/MkPasswordDialog.vue
+++ b/packages/frontend/src/components/MkPasswordDialog.vue
@@ -19,18 +19,21 @@ SPDX-License-Identifier: AGPL-3.0-only
 			<div style="margin-top: 16px;">{{ i18n.ts.authenticationRequiredToContinue }}</div>
 		</div>
 
-		<div class="_gaps">
-			<MkInput ref="passwordInput" v-model="password" :placeholder="i18n.ts.password" type="password" autocomplete="current-password webauthn" :withPasswordToggle="true">
-				<template #prefix><i class="ti ti-password"></i></template>
-			</MkInput>
+		<form @submit.prevent="done">
+			<div class="_gaps">
+				<MkInput ref="passwordInput" v-model="password" :placeholder="i18n.ts.password" type="password" autocomplete="current-password webauthn" required :withPasswordToggle="true">
+					<template #prefix><i class="ti ti-password"></i></template>
+				</MkInput>
 
-			<MkInput v-if="$i.twoFactorEnabled" v-model="token" type="text" pattern="^([0-9]{6}|[A-Z0-9]{32})$" autocomplete="one-time-code" :spellcheck="false">
-				<template #label>{{ i18n.ts.token }} ({{ i18n.ts['2fa'] }})</template>
-				<template #prefix><i class="ti ti-123"></i></template>
-			</MkInput>
+				<MkInput v-if="$i.twoFactorEnabled" v-model="token" type="text" :pattern="isBackupCode ? '^[A-Z0-9]{32}$' :'^[0-9]{6}$'" autocomplete="one-time-code" required :spellcheck="false" :inputmode="isBackupCode ? undefined : 'numeric'">
+					<template #label>{{ i18n.ts.token }} ({{ i18n.ts['2fa'] }})</template>
+					<template #prefix><i v-if="isBackupCode" class="ti ti-key"></i><i v-else class="ti ti-123"></i></template>
+					<template #caption><button class="_textButton" type="button" @click="isBackupCode = !isBackupCode">{{ isBackupCode ? i18n.ts.useTotp : i18n.ts.useBackupCode }}</button></template>
+				</MkInput>
 
-			<MkButton :disabled="(password ?? '') == '' || ($i.twoFactorEnabled && (token ?? '') == '')" primary rounded style="margin: 0 auto;" @click="done"><i class="ti ti-lock-open"></i> {{ i18n.ts.continue }}</MkButton>
-		</div>
+				<MkButton :disabled="(password ?? '') == '' || ($i.twoFactorEnabled && (token ?? '') == '')" type="submit" primary rounded style="margin: 0 auto;"><i class="ti ti-lock-open"></i> {{ i18n.ts.continue }}</MkButton>
+			</div>
+		</form>
 	</MkSpacer>
 </MkModalWindow>
 </template>
@@ -54,6 +57,7 @@ const emit = defineEmits<{
 const dialog = shallowRef<InstanceType<typeof MkModalWindow>>();
 const passwordInput = shallowRef<InstanceType<typeof MkInput>>();
 const password = ref('');
+const isBackupCode = ref(false);
 const token = ref<string | null>(null);
 
 function onClose() {
@@ -61,7 +65,7 @@ function onClose() {
 	if (dialog.value) dialog.value.close();
 }
 
-function done(res) {
+function done() {
 	emit('done', { password: password.value, token: token.value });
 	if (dialog.value) dialog.value.close();
 }
-- 
cgit v1.2.3-freya

