diff --git a/CHANGELOG.md b/CHANGELOG.md
index 188e146cdd..d90b1425c1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -16,7 +16,8 @@
- Enhance: リアクション受け入れが「いいねのみ」の場合はリアクション絵文字一覧を表示しないように
- Enhance: 設定>プラグインのページからプラグインの簡易的なログやエラーを見られるように
- 実装の都合により、プラグインは1つエラーを起こした時に即時停止するようになりました
-- Enhance: ページのデザインを変更
+- Enhance: ページのデザインを変更
+- Enhance: 2要素認証(ワンタイムパスワード)の入力欄を改善
- Fix: 一部のページ内リンクが正しく動作しない問題を修正
- Fix: 周年の実績が閏年を考慮しない問題を修正
- Fix: ローカルURLのプレビューポップアップが左上に表示される
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 70586d7a87..e1250946f3 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -4920,6 +4920,14 @@ export interface Locale extends ILocale {
* 使用しない場合は空欄にしてください
*/
"notUsePleaseLeaveBlank": string;
+ /**
+ * ワンタイムパスワードを使う
+ */
+ "useTotp": string;
+ /**
+ * バックアップコードを使う
+ */
+ "useBackupCode": string;
"_bubbleGame": {
/**
* 遊び方
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index cada6d855f..1c4df27d92 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -1226,6 +1226,8 @@ loading: "読み込み中"
surrender: "やめる"
gameRetry: "リトライ"
notUsePleaseLeaveBlank: "使用しない場合は空欄にしてください"
+useTotp: "ワンタイムパスワードを使う"
+useBackupCode: "バックアップコードを使う"
_bubbleGame:
howToPlay: "遊び方"
diff --git a/packages/frontend/src/components/MkInput.vue b/packages/frontend/src/components/MkInput.vue
index d3cddad15b..88ef4635e6 100644
--- a/packages/frontend/src/components/MkInput.vue
+++ b/packages/frontend/src/components/MkInput.vue
@@ -22,6 +22,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:autocomplete="autocomplete"
:autocapitalize="autocapitalize"
:spellcheck="spellcheck"
+ :inputmode="inputmode"
:step="step"
:list="id"
:min="min"
@@ -63,6 +64,7 @@ const props = defineProps<{
mfmAutocomplete?: boolean | SuggestionType[],
autocapitalize?: string;
spellcheck?: boolean;
+ inputmode?: 'none' | 'text' | 'search' | 'email' | 'url' | 'numeric' | 'tel' | 'decimal';
step?: any;
datalist?: string[];
min?: number;
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
{{ i18n.ts.authenticationRequiredToContinue }}
-
+
@@ -54,6 +57,7 @@ const emit = defineEmits<{
const dialog = shallowRef>();
const passwordInput = shallowRef>();
const password = ref('');
+const isBackupCode = ref(false);
const token = ref(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();
}
diff --git a/packages/frontend/src/components/MkSignin.vue b/packages/frontend/src/components/MkSignin.vue
index 852af01b5a..970aff825d 100644
--- a/packages/frontend/src/components/MkSignin.vue
+++ b/packages/frontend/src/components/MkSignin.vue
@@ -31,15 +31,15 @@ SPDX-License-Identifier: AGPL-3.0-only
-
-
{{ i18n.ts['2fa'] }}
+
{{ i18n.ts.password }}
-
- {{ i18n.ts.token }}
-
+
+ {{ i18n.ts.token }} ({{ i18n.ts['2fa'] }})
+
+
{{ signing ? i18n.ts.loggingIn : i18n.ts.login }}
@@ -70,6 +70,7 @@ const password = ref('');
const token = ref('');
const host = ref(toUnicode(configHost));
const totpLogin = ref(false);
+const isBackupCode = ref(false);
const queryingKey = ref(false);
const credentialRequest = ref
(null);
diff --git a/packages/frontend/src/pages/settings/2fa.qrdialog.vue b/packages/frontend/src/pages/settings/2fa.qrdialog.vue
index 2608560cc4..2ef664b9a3 100644
--- a/packages/frontend/src/pages/settings/2fa.qrdialog.vue
+++ b/packages/frontend/src/pages/settings/2fa.qrdialog.vue
@@ -52,7 +52,7 @@ SPDX-License-Identifier: AGPL-3.0-only
{{ i18n.ts._2fa.step3Title }}
-
+
{{ i18n.ts._2fa.step3 }}
diff --git a/packages/frontend/src/pages/settings/2fa.vue b/packages/frontend/src/pages/settings/2fa.vue
index d8c5f848fe..975f23cdd1 100644
--- a/packages/frontend/src/pages/settings/2fa.vue
+++ b/packages/frontend/src/pages/settings/2fa.vue
@@ -80,7 +80,7 @@ import MkSwitch from '@/components/MkSwitch.vue';
import FormSection from '@/components/form/section.vue';
import MkFolder from '@/components/MkFolder.vue';
import * as os from '@/os.js';
-import { signinRequired } from '@/account.js';
+import { signinRequired, updateAccount } from '@/account.js';
import { i18n } from '@/i18n.js';
const $i = signinRequired();
@@ -116,6 +116,10 @@ async function unregisterTOTP(): Promise {
os.apiWithDialog('i/2fa/unregister', {
password: auth.result.password,
token: auth.result.token,
+ }).then(res => {
+ updateAccount({
+ twoFactorEnabled: false,
+ });
}).catch(error => {
os.alert({
type: 'error',