summaryrefslogtreecommitdiff
path: root/packages/frontend/src/components/MkSignin.totp.vue
blob: 670b8057c2afcae9828f3227f5d9dbd307f082bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
<!--
SPDX-FileCopyrightText: syuilo and misskey-project
SPDX-License-Identifier: AGPL-3.0-only
-->

<template>
<div :class="$style.wrapper">
	<div class="_gaps" :class="$style.root">
		<div class="_gaps_s">
			<div :class="$style.totpIcon">
				<i class="ti ti-key"></i>
			</div>
			<div :class="$style.totpDescription">{{ i18n.ts['2fa'] }}</div>
		</div>

		<!-- totp入力 -->
		<form class="_gaps_s" @submit.prevent="emit('totpSubmitted', token)">
			<MkInput v-model="token" type="text" :pattern="isBackupCode ? '^[A-Z0-9]{32}$' :'^[0-9]{6}$'" autocomplete="one-time-code" required autofocus :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 type="submit" large primary rounded style="margin: 0 auto;">{{ i18n.ts.continue }} <i class="ti ti-arrow-right"></i></MkButton>
		</form>
	</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';

import { i18n } from '@/i18n.js';

import MkButton from '@/components/MkButton.vue';
import MkInput from '@/components/MkInput.vue';

const emit = defineEmits<{
	(ev: 'totpSubmitted', token: string): void;
}>();

const token = ref('');
const isBackupCode = ref(false);
</script>

<style lang="scss" module>
.wrapper {
	display: flex;
	align-items: center;
	width: 100%;
	min-height: 336px;

	> .root {
		width: 100%;
	}
}

.totpIcon {
	margin: 0 auto;
	background-color: var(--MI_THEME-accentedBg);
	color: var(--MI_THEME-accent);
	text-align: center;
	height: 64px;
	width: 64px;
	font-size: 24px;
	line-height: 64px;
	border-radius: 50%;
}

.totpDescription {
	text-align: center;
	font-size: 1.1em;
}
</style>