aboutsummaryrefslogtreecommitdiff
path: root/src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue
diff options
context:
space:
mode:
authorGravatar Corentin Thomasset <corentin.thomasset74@gmail.com> 2023-05-28 23:13:24 +0200
committerGravatar Corentin THOMASSET <corentin.thomasset74@gmail.com> 2023-05-28 23:29:14 +0200
commit33c9b6643f58a6930043f460d5bfdca4bc1f7222 (patch)
treef313935e30f7b90ea16e564e7171e2e72319ce29 /src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue
parent4d2b037dbe4e78aa90a4a6d9c7315dcf0a51fed9 (diff)
downloadit-tools-33c9b6643f58a6930043f460d5bfdca4bc1f7222.tar.gz
it-tools-33c9b6643f58a6930043f460d5bfdca4bc1f7222.tar.zst
it-tools-33c9b6643f58a6930043f460d5bfdca4bc1f7222.zip
chore(lint): switched to a better lint config
Diffstat (limited to 'src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue')
-rw-r--r--src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue128
1 files changed, 66 insertions, 62 deletions
diff --git a/src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue b/src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue
index 95527d0..f3534eb 100644
--- a/src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue
+++ b/src/tools/otp-code-generator-and-validator/otp-code-generator-and-validator.vue
@@ -1,3 +1,57 @@
+<script setup lang="ts">
+import { computed, ref } from 'vue';
+import { useTimestamp } from '@vueuse/core';
+import { useThemeVars } from 'naive-ui';
+import { useQRCode } from '../qr-code-generator/useQRCode';
+import { base32toHex, buildKeyUri, generateSecret, generateTOTP, getCounterFromTime } from './otp.service';
+import TokenDisplay from './token-display.vue';
+import { useStyleStore } from '@/stores/style.store';
+import InputCopyable from '@/components/InputCopyable.vue';
+import { computedRefreshable } from '@/composable/computedRefreshable';
+
+const now = useTimestamp();
+const interval = computed(() => (now.value / 1000) % 30);
+const theme = useThemeVars();
+const styleStore = useStyleStore();
+
+const secret = ref(generateSecret());
+
+function refreshSecret() {
+ secret.value = generateSecret();
+}
+
+const [tokens] = computedRefreshable(
+ () => ({
+ previous: generateTOTP({ key: secret.value, now: now.value - 30000 }),
+ current: generateTOTP({ key: secret.value, now: now.value }),
+ next: generateTOTP({ key: secret.value, now: now.value + 30000 }),
+ }),
+ { throttle: 500 },
+);
+
+const keyUri = computed(() => buildKeyUri({ secret: secret.value }));
+
+const { qrcode } = useQRCode({
+ text: keyUri,
+ color: {
+ background: computed(() => (styleStore.isDarkTheme ? '#ffffff' : '#00000000')),
+ foreground: '#000000',
+ },
+ options: { width: 210 },
+});
+
+const secretValidationRules = [
+ {
+ message: 'Secret should be a base32 string',
+ validator: (value: string) => value.toUpperCase().match(/^[A-Z234567]+$/),
+ },
+ {
+ message: 'Please set a secret',
+ validator: (value: string) => value !== '',
+ },
+];
+</script>
+
<template>
<div style="max-width: 350px">
<c-input-text
@@ -20,18 +74,22 @@
</c-input-text>
<div>
- <token-display :tokens="tokens" style="margin-top: 2px" />
+ <TokenDisplay :tokens="tokens" style="margin-top: 2px" />
<n-progress :percentage="(100 * interval) / 30" :color="theme.primaryColor" :show-indicator="false" />
- <div style="text-align: center">Next in {{ String(Math.floor(30 - interval)).padStart(2, '0') }}s</div>
+ <div style="text-align: center">
+ Next in {{ String(Math.floor(30 - interval)).padStart(2, '0') }}s
+ </div>
</div>
<div mt-4 flex flex-col items-center justify-center gap-3>
- <n-image :src="qrcode"></n-image>
- <c-button :href="keyUri" target="_blank">Open Key URI in new tab</c-button>
+ <n-image :src="qrcode" />
+ <c-button :href="keyUri" target="_blank">
+ Open Key URI in new tab
+ </c-button>
</div>
</div>
<div style="max-width: 350px">
- <input-copyable
+ <InputCopyable
label="Secret in hexadecimal"
:value="base32toHex(secret)"
readonly
@@ -39,7 +97,7 @@
mb-5
/>
- <input-copyable
+ <InputCopyable
label="Epoch"
:value="Math.floor(now / 1000).toString()"
readonly
@@ -49,7 +107,7 @@
<p>Iteration</p>
- <input-copyable
+ <InputCopyable
:value="String(getCounterFromTime({ now, timeStep: 30 }))"
readonly
label="Count:"
@@ -59,7 +117,7 @@
placeholder="Iteration count will be displayed here"
/>
- <input-copyable
+ <InputCopyable
:value="getCounterFromTime({ now, timeStep: 30 }).toString(16).padStart(16, '0')"
readonly
placeholder="Iteration count in hex will be displayed here"
@@ -71,60 +129,6 @@
</div>
</template>
-<script setup lang="ts">
-import { computed, ref } from 'vue';
-import { useTimestamp } from '@vueuse/core';
-import { useThemeVars } from 'naive-ui';
-import { useStyleStore } from '@/stores/style.store';
-import InputCopyable from '@/components/InputCopyable.vue';
-import { computedRefreshable } from '@/composable/computedRefreshable';
-import { generateTOTP, buildKeyUri, generateSecret, base32toHex, getCounterFromTime } from './otp.service';
-import { useQRCode } from '../qr-code-generator/useQRCode';
-import TokenDisplay from './token-display.vue';
-
-const now = useTimestamp();
-const interval = computed(() => (now.value / 1000) % 30);
-const theme = useThemeVars();
-const styleStore = useStyleStore();
-
-const secret = ref(generateSecret());
-
-function refreshSecret() {
- secret.value = generateSecret();
-}
-
-const [tokens] = computedRefreshable(
- () => ({
- previous: generateTOTP({ key: secret.value, now: now.value - 30000 }),
- current: generateTOTP({ key: secret.value, now: now.value }),
- next: generateTOTP({ key: secret.value, now: now.value + 30000 }),
- }),
- { throttle: 500 },
-);
-
-const keyUri = computed(() => buildKeyUri({ secret: secret.value }));
-
-const { qrcode } = useQRCode({
- text: keyUri,
- color: {
- background: computed(() => (styleStore.isDarkTheme ? '#ffffff' : '#00000000')),
- foreground: '#000000',
- },
- options: { width: 210 },
-});
-
-const secretValidationRules = [
- {
- message: 'Secret should be a base32 string',
- validator: (value: string) => value.toUpperCase().match(/^[A-Z234567]+$/),
- },
- {
- message: 'Please set a secret',
- validator: (value: string) => value !== '',
- },
-];
-</script>
-
<style lang="less" scoped>
.n-progress {
margin-top: 10px;