feat: ✨ 2FA input dialog
This commit is contained in:
parent
c5ad1d9580
commit
7220fede8c
@ -87,6 +87,7 @@
|
|||||||
"vue-isyourpasswordsafe": "^2.0.0",
|
"vue-isyourpasswordsafe": "^2.0.0",
|
||||||
"vue-plyr": "^7.0.0",
|
"vue-plyr": "^7.0.0",
|
||||||
"vue-prism-editor": "2.0.0-alpha.2",
|
"vue-prism-editor": "2.0.0-alpha.2",
|
||||||
|
"vue3-otp-input": "^0.4.1",
|
||||||
"vuedraggable": "4.1.0"
|
"vuedraggable": "4.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,18 +99,15 @@
|
|||||||
><i class="ph-lock ph-bold ph-lg"></i
|
><i class="ph-lock ph-bold ph-lg"></i
|
||||||
></template>
|
></template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkInput
|
<vue3-otp-input
|
||||||
|
input-classes="otp-input"
|
||||||
|
inputType="number"
|
||||||
|
:num-inputs="6"
|
||||||
v-model="token"
|
v-model="token"
|
||||||
type="text"
|
:should-auto-focus="true"
|
||||||
pattern="^[0-9]{6}$"
|
@on-complete="onSubmit"
|
||||||
autocomplete="one-time-code"
|
|
||||||
:spellcheck="false"
|
|
||||||
required
|
required
|
||||||
>
|
/>
|
||||||
<template #prefix>
|
|
||||||
<i class="ph-poker-chip ph-bold ph-lg"></i>
|
|
||||||
</template>
|
|
||||||
</MkInput>
|
|
||||||
<MkButton
|
<MkButton
|
||||||
type="submit"
|
type="submit"
|
||||||
:disabled="signing"
|
:disabled="signing"
|
||||||
@ -159,6 +156,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import Vue3OtpInput from "vue3-otp-input";
|
||||||
import { defineAsyncComponent } from "vue";
|
import { defineAsyncComponent } from "vue";
|
||||||
import { toUnicode } from "punycode/";
|
import { toUnicode } from "punycode/";
|
||||||
import MkButton from "@/components/MkButton.vue";
|
import MkButton from "@/components/MkButton.vue";
|
||||||
@ -392,4 +390,27 @@ function showSuspendedDialog() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.otp-input {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
padding: 5px;
|
||||||
|
margin: 0 10px;
|
||||||
|
font-size: 20px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 2px solid var(--accent);
|
||||||
|
background-color: var(--accentedBg);
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.otp-input.is-complete {
|
||||||
|
border-color: var(--success) !important;
|
||||||
|
}
|
||||||
|
.otp-input.error {
|
||||||
|
border-color: var(--error) !important;
|
||||||
|
}
|
||||||
|
.otp-input::-webkit-inner-spin-button,
|
||||||
|
.otp-input::-webkit-outer-spin-button {
|
||||||
|
-webkit-appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -94,5 +94,7 @@ const ok = () => {
|
|||||||
.qr {
|
.qr {
|
||||||
width: 20em;
|
width: 20em;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 3px solid var(--accent);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -5,7 +5,10 @@
|
|||||||
<div v-if="$i" class="_gaps_s">
|
<div v-if="$i" class="_gaps_s">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon
|
<template #icon
|
||||||
><i class="ph-shield-check ph-bold ph-lg"></i
|
><i
|
||||||
|
class="ph-shield-check ph-bold ph-lg"
|
||||||
|
style="margin-right: 0.5rem"
|
||||||
|
></i
|
||||||
></template>
|
></template>
|
||||||
<template #label>{{ i18n.ts.totp }}</template>
|
<template #label>{{ i18n.ts.totp }}</template>
|
||||||
<template #caption>{{ i18n.ts.totpDescription }}</template>
|
<template #caption>{{ i18n.ts.totpDescription }}</template>
|
||||||
@ -13,13 +16,19 @@
|
|||||||
<div v-text="i18n.ts._2fa.alreadyRegistered" />
|
<div v-text="i18n.ts._2fa.alreadyRegistered" />
|
||||||
<template v-if="$i.securityKeysList.length > 0">
|
<template v-if="$i.securityKeysList.length > 0">
|
||||||
<MkButton @click="renewTOTP"
|
<MkButton @click="renewTOTP"
|
||||||
><i class="ph-shield-check ph-bold ph-lg"></i
|
><i
|
||||||
|
class="ph-shield-check ph-bold ph-lg"
|
||||||
|
style="margin-right: 0.5rem"
|
||||||
|
></i
|
||||||
>{{ i18n.ts._2fa.renewTOTP }}</MkButton
|
>{{ i18n.ts._2fa.renewTOTP }}</MkButton
|
||||||
>
|
>
|
||||||
<MkInfo>{{ i18n.ts._2fa.whyTOTPOnlyRenew }}</MkInfo>
|
<MkInfo>{{ i18n.ts._2fa.whyTOTPOnlyRenew }}</MkInfo>
|
||||||
</template>
|
</template>
|
||||||
<MkButton v-else @click="unregisterTOTP"
|
<MkButton v-else @click="unregisterTOTP"
|
||||||
><i class="ph-shield-slash ph-bold ph-lg"></i
|
><i
|
||||||
|
class="ph-shield-slash ph-bold ph-lg"
|
||||||
|
style="margin-right: 0.5rem"
|
||||||
|
></i
|
||||||
>{{ i18n.ts.unregister }}</MkButton
|
>{{ i18n.ts.unregister }}</MkButton
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -32,7 +41,12 @@
|
|||||||
</MkFolder>
|
</MkFolder>
|
||||||
|
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #icon><i class="ph-key ph-bold ph-lg"></i></template>
|
<template #icon
|
||||||
|
><i
|
||||||
|
class="ph-key ph-bold ph-lg"
|
||||||
|
style="margin-right: 0.5rem"
|
||||||
|
></i
|
||||||
|
></template>
|
||||||
<template #label>{{ i18n.ts.securityKeyAndPasskey }}</template>
|
<template #label>{{ i18n.ts.securityKeyAndPasskey }}</template>
|
||||||
<div class="_gaps_s">
|
<div class="_gaps_s">
|
||||||
<MkInfo>
|
<MkInfo>
|
||||||
@ -54,7 +68,10 @@
|
|||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<MkButton primary @click="addSecurityKey"
|
<MkButton primary @click="addSecurityKey"
|
||||||
><i class="ph-key ph-bold ph-lg"></i
|
><i
|
||||||
|
class="ph-key ph-bold ph-lg"
|
||||||
|
style="margin-right: 0.5rem"
|
||||||
|
></i
|
||||||
>{{ i18n.ts._2fa.registerSecurityKey }}</MkButton
|
>{{ i18n.ts._2fa.registerSecurityKey }}</MkButton
|
||||||
>
|
>
|
||||||
<MkFolder
|
<MkFolder
|
||||||
|
@ -906,6 +906,9 @@ importers:
|
|||||||
vue-prism-editor:
|
vue-prism-editor:
|
||||||
specifier: 2.0.0-alpha.2
|
specifier: 2.0.0-alpha.2
|
||||||
version: 2.0.0-alpha.2(vue@3.3.4)
|
version: 2.0.0-alpha.2(vue@3.3.4)
|
||||||
|
vue3-otp-input:
|
||||||
|
specifier: ^0.4.1
|
||||||
|
version: 0.4.1(vue@3.3.4)
|
||||||
vuedraggable:
|
vuedraggable:
|
||||||
specifier: 4.1.0
|
specifier: 4.1.0
|
||||||
version: 4.1.0(vue@3.3.4)
|
version: 4.1.0(vue@3.3.4)
|
||||||
@ -15213,6 +15216,15 @@ packages:
|
|||||||
vue: 3.3.4
|
vue: 3.3.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/vue3-otp-input@0.4.1(vue@3.3.4):
|
||||||
|
resolution: {integrity: sha512-wVl9i3DcWlO0C7fBI9V+RIP3crm/1tY72fuhvb3YM2JfbLoYofB96aPl5AgFhA0Cse5bQEMYtIvOeiqW3rfbAw==}
|
||||||
|
engines: {node: '>=16.0.0', npm: '>=8.0.0'}
|
||||||
|
peerDependencies:
|
||||||
|
vue: ^3.0.*
|
||||||
|
dependencies:
|
||||||
|
vue: 3.3.4
|
||||||
|
dev: true
|
||||||
|
|
||||||
/vue@2.7.14:
|
/vue@2.7.14:
|
||||||
resolution: {integrity: sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==}
|
resolution: {integrity: sha512-b2qkFyOM0kwqWFuQmgd4o+uHGU7T+2z3T+WQp8UBjADfEv2n4FEMffzBmCKNP0IGzOEEfYjvtcC62xaSKeQDrQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
Loading…
Reference in New Issue
Block a user