Skip to content

Commit 4f0cbfc

Browse files
committed
更新TOTP与passkey支持
1 parent e3756f1 commit 4f0cbfc

File tree

16 files changed

+1171
-627
lines changed

16 files changed

+1171
-627
lines changed

dev-dist/sw.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ define(['./workbox-c6a197bf'], (function (workbox) { 'use strict';
8080
*/
8181
workbox.precacheAndRoute([{
8282
"url": "/index.html",
83-
"revision": "0.6p9rojc2l8"
83+
"revision": "0.40a6r5nmirg"
8484
}], {});
8585
workbox.cleanupOutdatedCaches();
8686
workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("/index.html"), {

src/components/SecurityManager.vue

Lines changed: 437 additions & 3 deletions
Large diffs are not rendered by default.

src/components/TotpDialog.vue

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<template>
2+
<v-dialog v-model="internalModel" max-width="420" persistent>
3+
<v-card>
4+
<v-card-title class="text-h6 d-flex align-center">
5+
<v-icon class="mr-2">mdi-shield-key</v-icon>
6+
{{ title }}
7+
</v-card-title>
8+
<v-card-subtitle v-if="subtitle" class="pb-0">{{ subtitle }}</v-card-subtitle>
9+
<v-card-text>
10+
<div class="mb-3 text-caption text-medium-emphasis">请输入认证器中的 6 位一次性验证码</div>
11+
<div class="d-flex justify-center mb-2">
12+
<v-otp-input
13+
v-model="otp"
14+
:length="length"
15+
:disabled="loading"
16+
type="number"
17+
18+
autofocus
19+
@finish="handleAutoFinish"
20+
/>
21+
</div>
22+
<v-alert
23+
v-if="errorMessage"
24+
type="error"
25+
variant="tonal"
26+
density="comfortable"
27+
class="mt-2"
28+
:text="errorMessage"
29+
/>
30+
</v-card-text>
31+
<v-card-actions>
32+
<v-spacer />
33+
<v-btn variant="text" @click="handleCancel" :disabled="loading">取消</v-btn>
34+
<v-btn color="primary" variant="flat" :loading="loading" :disabled="!canConfirm" @click="handleConfirm">确认</v-btn>
35+
</v-card-actions>
36+
</v-card>
37+
</v-dialog>
38+
39+
</template>
40+
41+
<script>
42+
43+
export default {
44+
name: 'TotpDialog',
45+
props: {
46+
modelValue: { type: Boolean, default: false },
47+
title: { type: String, default: 'TOTP 验证' },
48+
subtitle: { type: String, default: '' },
49+
length: { type: Number, default: 6 },
50+
loading: { type: Boolean, default: false },
51+
errorMessage: { type: String, default: '' },
52+
},
53+
emits: ['update:modelValue', 'confirm', 'cancel'],
54+
data() {
55+
return {
56+
otp: '',
57+
internalModel: this.modelValue,
58+
}
59+
},
60+
computed: {
61+
canConfirm() {
62+
return !!this.otp && this.otp.length === this.length && !this.loading
63+
},
64+
},
65+
watch: {
66+
modelValue(val) {
67+
this.internalModel = val
68+
if (val === true) this.otp = ''
69+
},
70+
internalModel(val) {
71+
this.$emit('update:modelValue', val)
72+
if (!val) this.otp = ''
73+
},
74+
},
75+
methods: {
76+
handleCancel() {
77+
this.$emit('cancel')
78+
this.internalModel = false
79+
},
80+
handleConfirm() {
81+
if (!this.canConfirm) return
82+
this.$emit('confirm', this.otp)
83+
this.internalModel = false
84+
},
85+
handleAutoFinish() {
86+
// Auto confirm when input length reached
87+
this.handleConfirm()
88+
}
89+
}
90+
}
91+
</script>
92+
93+

0 commit comments

Comments
 (0)