aboutsummaryrefslogtreecommitdiff
path: root/front-end/src/views/Account/components/settings/TotpSettings.vue
diff options
context:
space:
mode:
Diffstat (limited to 'front-end/src/views/Account/components/settings/TotpSettings.vue')
-rw-r--r--front-end/src/views/Account/components/settings/TotpSettings.vue232
1 files changed, 116 insertions, 116 deletions
diff --git a/front-end/src/views/Account/components/settings/TotpSettings.vue b/front-end/src/views/Account/components/settings/TotpSettings.vue
index 0fcfe31..04a261b 100644
--- a/front-end/src/views/Account/components/settings/TotpSettings.vue
+++ b/front-end/src/views/Account/components/settings/TotpSettings.vue
@@ -1,99 +1,11 @@
-<template>
- <div id="totp-settings">
-
- <div v-if="!isLocalAccount" class="flex flex-row justify-between">
- <h6 class="block">
- TOTP Authenticator App
- </h6>
- <div class="text-red-500">
- Unavailable for external auth
- </div>
- </div>
-
- <div v-else-if="showTotpCode" class="w-full py-2 text-center">
- <h5 class="text-center" />
- <p class="py-2">
- Scan the QR code with your TOTP authenticator app.
- </p>
-
- <div class="flex">
- <VueQrcode class="m-auto" :value="qrCode" />
- </div>
-
- <p class="py-2">
- Your secret, if your application requires it.
- </p>
-
- <p class="flex flex-row flex-wrap justify-center p-2 bg-gray-200 border border-gray-300 dark:bg-dark-800 dark:border-dark-500">
- <span v-for="code in secretSegments" :key="code" class="px-2 font-mono tracking-wider" >
- {{ code }}
- </span>
- </p>
-
- <p class="py-2 text-color-background">
- Please enter your code from your authenticator app to continue.
- </p>
-
- <div class="m-auto w-min">
- <VOtpInput
- class="otp-input"
- input-type="letter-numeric"
- separator=""
- :is-disabled="showSubmitButton"
- input-classes="primary input rounded"
- :num-inputs="6"
- @on-change="onInput"
- @on-complete="VerifyTotp"
- />
- </div>
-
- <div v-if="showSubmitButton" class="flex flex-row justify-end my-2">
- <button class="btn primary" @click.prevent="CloseQrWindow">
- Complete
- </button>
- </div>
- </div>
-
- <div v-else class="flex flex-row flex-wrap justify-between">
- <h6>TOTP Authenticator App</h6>
-
- <div v-if="totpEnabled" class="button-group">
- <button class="btn xs" @click.prevent="regenTotp">
- <fa-icon icon="sync" />
- <span class="pl-2">Regenerate</span>
- </button>
- <button class="btn red xs" @click.prevent="disable">
- <fa-icon icon="minus-circle" />
- <span class="pl-2">Disable</span>
- </button>
- </div>
-
- <div v-else>
- <button class="btn primary xs" @click.prevent="configTotp">
- <fa-icon icon="plus" />
- <span class="pl-2">Setup</span>
- </button>
- </div>
- <p class="p-1 pt-3 text-sm text-color-background">
- TOTP is a time based one time password. You can use it as a form of Multi Factor Authentication when
- using another device such as a smart phone or TOTP hardware device. You can use TOTP with your smart
- phone
- using apps like Google Authenticator, Authy, or Duo. Read more on
- <a class="link" href="https://en.wikipedia.org/wiki/Time-based_one-time_password" target="_blank">
- Wikipedia.
- </a>
- </p>
- </div>
-
- </div>
-</template>
-
<script setup lang="ts">
import { isNil, chunk, defaultTo, includes, map, join } from 'lodash-es'
import { TOTP } from 'otpauth'
-import { computed, ref, defineAsyncComponent } from 'vue'
import base32Encode from 'base32-encode'
-import {
+import QrCodeVue from 'qrcode.vue'
+import VOtpInput from "vue3-otp-input";
+import { computed, ref } from 'vue'
+import {
useSession,
useMessage,
useConfirm,
@@ -104,26 +16,23 @@ import {
import { useStore } from '../../../../store';
import { storeToRefs } from 'pinia';
-const VueQrcode = defineAsyncComponent(() => import('@chenfengyuan/vue-qrcode'))
-const VOtpInput = defineAsyncComponent(() => import('vue3-otp-input'));
-
-interface TotpConfig{
- secret: string;
- readonly issuer: string;
- readonly algorithm: string;
- readonly digits?: number;
- readonly period?: number;
+interface TotpConfig {
+ secret: string;
+ readonly issuer: string;
+ readonly algorithm: string;
+ readonly digits?: number;
+ readonly period?: number;
}
const store = useStore();
-const { userName, isLocalAccount, mfaEndabledMethods } = storeToRefs(store);
+const { isLocalAccount } = storeToRefs(store);
const { KeyStore } = useSession()
const { reveal } = useConfirm()
const { elevatedApiCall } = usePassConfirm()
const { onInput, setMessage } = useMessage()
-const totpEnabled = computed(() => includes(mfaEndabledMethods.value, MfaMethod.TOTP))
+const totpEnabled = computed(() => includes(store.mfa.enabledMethods, MfaMethod.TOTP))
const totpMessage = ref<TotpConfig>()
const showSubmitButton = ref(false)
@@ -152,7 +61,7 @@ const qrCode = computed(() => {
params.append('algorithm', m.algorithm)
params.append('digits', defaultTo(m.digits, 6).toString())
params.append('period', defaultTo(m.period, 30).toString())
- const url = `otpauth://totp/${m.issuer}:${userName.value}?${params.toString()}`
+ const url = `otpauth://totp/${m.issuer}:${store.userName}?${params.toString()}`
return url
})
@@ -160,7 +69,7 @@ const ProcessAddOrUpdate = async () => {
await elevatedApiCall(async ({ password }) => {
// Init or update the totp method and get the encrypted totp message
- const res = await store.mfaConfig.initOrUpdateMethod<TotpConfig>(MfaMethod.TOTP, password);
+ const res = await store.mfa.initOrUpdateMethod<TotpConfig>(MfaMethod.TOTP, password);
//Get the encrypted totp message
const totp = res.getResultOrThrow()
@@ -181,7 +90,7 @@ const configTotp = async () => {
text: 'Are you sure you understand TOTP multi factor and wish to enable it?',
})
- if(!isCanceled){
+ if (!isCanceled) {
ProcessAddOrUpdate()
}
}
@@ -197,7 +106,7 @@ const regenTotp = async () => {
text: 'If you continue your previous TOTP authenticator and recovery codes will no longer be valid.'
})
- if(!isCanceled){
+ if (!isCanceled) {
ProcessAddOrUpdate()
}
}
@@ -214,16 +123,15 @@ const disable = async () => {
}
await elevatedApiCall(async ({ password }) => {
-
// Disable the totp method
- const res = await store.mfaConfig.disableMethod(MfaMethod.TOTP, password)
+ const res = await store.mfa.disableMethod(MfaMethod.TOTP, password)
res.getResultOrThrow()
-
- store.mfaRefreshMethods()
+
+ store.mfa.refresh()
})
}
-const VerifyTotp = async (code : string) => {
+const VerifyTotp = async (code: string) => {
// Create a new TOTP instance from the current message
const totp = new TOTP(totpMessage.value)
@@ -231,10 +139,11 @@ const VerifyTotp = async (code : string) => {
const valid = totp.validate({ token: code, window: 4 })
if (valid) {
- showSubmitButton.value = true
+ showSubmitButton.value = true;
+
toaster.success({
title: 'Success',
- text: 'Your TOTP code is valid and your account is now verified.'
+ text: 'Your TOTP code is valid and is now enabled'
})
} else {
setMessage('Your TOTP code is not valid.')
@@ -244,12 +153,103 @@ const VerifyTotp = async (code : string) => {
const CloseQrWindow = () => {
showSubmitButton.value = false
totpMessage.value = undefined
-
+
//Fresh methods
- store.mfaRefreshMethods()
+ store.mfa.refresh()
}
</script>
+<template>
+ <div id="totp-settings">
+
+ <div v-if="!isLocalAccount" class="flex flex-row justify-between">
+ <h6 class="block">
+ TOTP Authenticator App
+ </h6>
+ <div class="text-red-500">
+ Unavailable for external auth
+ </div>
+ </div>
+
+ <div v-else-if="showTotpCode" class="w-full py-2 text-center">
+ <h5 class="text-center" />
+ <p class="py-2">
+ Scan the QR code with your TOTP authenticator app.
+ </p>
+
+ <div class="flex">
+ <QrCodeVue class="m-auto" :size="180" render-as="svg" level="Q" :value="qrCode" />
+ </div>
+
+ <p class="py-2">
+ Your secret, if your application requires it.
+ </p>
+
+ <p class="flex flex-row flex-wrap justify-center p-2 bg-gray-200 border border-gray-300 dark:bg-dark-800 dark:border-dark-500">
+ <span v-for="code in secretSegments" :key="code" class="px-2 font-mono tracking-wider" >
+ {{ code }}
+ </span>
+ </p>
+
+ <p class="py-2 text-color-background">
+ Please enter your code from your authenticator app to continue.
+ </p>
+
+ <div class="m-auto w-min">
+ <VOtpInput
+ class="otp-input"
+ input-type="letter-numeric"
+ separator=""
+ value=""
+ :is-disabled="showSubmitButton"
+ input-classes="primary input rounded"
+ :num-inputs="6"
+ @on-change="onInput"
+ @on-complete="VerifyTotp"
+ />
+ </div>
+
+ <div v-if="showSubmitButton" class="flex flex-row justify-end my-2">
+ <button class="btn primary" @click.prevent="CloseQrWindow">
+ Complete
+ </button>
+ </div>
+ </div>
+
+ <div v-else class="flex flex-row flex-wrap justify-between">
+ <h6>TOTP Authenticator App</h6>
+
+ <div v-if="totpEnabled" class="button-group">
+ <button class="btn xs" @click.prevent="regenTotp">
+ <fa-icon icon="sync" />
+ <span class="pl-2">Regenerate</span>
+ </button>
+ <button class="btn red xs" @click.prevent="disable">
+ <fa-icon icon="minus-circle" />
+ <span class="pl-2">Disable</span>
+ </button>
+ </div>
+
+ <div v-else>
+ <button class="btn primary xs" @click.prevent="configTotp">
+ <fa-icon icon="plus" />
+ <span class="pl-2">Setup</span>
+ </button>
+ </div>
+ <p class="p-1 pt-3 text-sm text-color-background">
+ TOTP is a time based one time password. You can use it as a form of Multi Factor Authentication when
+ using another device such as a smart phone or TOTP hardware device. You can use TOTP with your smart
+ phone
+ using apps like Google Authenticator, Authy, or Duo. Read more on
+ <a class="link" href="https://en.wikipedia.org/wiki/Time-based_one-time_password" target="_blank">
+ Wikipedia.
+ </a>
+ </p>
+ </div>
+
+ </div>
+</template>
+
<style>