enable switch to pw totp in account settings

This commit is contained in:
Julian Krauser 2025-05-05 17:44:03 +02:00
parent 63d97d0b83
commit ee52363bde
6 changed files with 429 additions and 56 deletions

View file

@ -6,29 +6,41 @@
</div>
</template>
<template #diffMain>
<div class="flex flex-col w-full h-full gap-2 justify-between px-7 overflow-hidden">
<div class="flex flex-col gap-2">
<img :src="image" alt="totp" class="w-56 h-56 self-center" />
<TextCopy :copyText="otp" />
<Spinner v-if="loading" class="mx-auto" />
<div v-else class="flex flex-col w-full h-full gap-2 px-7 overflow-hidden">
<div class="w-full flex flex-row gap-2 justify-center">
<p
class="w-1/2 p-0.5 pl-0 rounded-lg py-2.5 text-sm text-center font-medium leading-5 outline-hidden cursor-pointer"
:class="
tab == 'totp' ? 'bg-red-200 shadow-sm border-b-2 border-primary rounded-b-none' : ' hover:bg-red-200'
"
@click="tab = 'totp'"
>
TOTP
</p>
<p
class="w-1/2 p-0.5 rounded-lg py-2.5 text-sm text-center font-medium leading-5 outline-hidden cursor-pointer"
:class="
tab == 'password' ? 'bg-red-200 shadow-sm border-b-2 border-primary rounded-b-none' : 'hover:bg-red-200'
"
@click="tab = 'password'"
>
Passwort
</p>
</div>
<form class="flex flex-col gap-2" @submit.prevent="verify">
<div class="-space-y-px">
<div>
<input id="totp" name="totp" type="text" required placeholder="TOTP prüfen" />
</div>
</div>
<div class="flex flex-row gap-2">
<button type="submit" primary :disabled="verifyStatus == 'loading' || verifyStatus == 'success'">
TOTP prüfen
</button>
<Spinner v-if="verifyStatus == 'loading'" class="my-auto" />
<SuccessCheckmark v-else-if="verifyStatus == 'success'" />
<FailureXMark v-else-if="verifyStatus == 'failed'" />
</div>
<p v-if="verifyError" class="text-center">{{ verifyError }}</p>
</form>
<ChangeToTOTP
v-if="currentRoutine == 'password' && tab == 'totp'"
:currentRoutine="currentRoutine"
@updateCurrent="currentRoutine = 'totp'"
/>
<ChangeToPassword
v-else-if="currentRoutine == 'totp' && tab == 'password'"
:currentRoutine="currentRoutine"
@updateCurrent="currentRoutine = 'password'"
/>
<TotpCheckAndScan v-else-if="tab == 'totp'" />
<PasswordChange v-else-if="tab == 'password'" />
<p v-else>etwas ist schief gelaufen</p>
</div>
</template>
</MainTemplate>
@ -42,53 +54,34 @@ import Spinner from "@/components/Spinner.vue";
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
import FailureXMark from "@/components/FailureXMark.vue";
import TextCopy from "@/components/TextCopy.vue";
import TotpCheckAndScan from "../../components/account/TotpCheckAndScan.vue";
import PasswordChange from "../../components/account/PasswordChange.vue";
import ChangeToPassword from "../../components/account/ChangeToPassword.vue";
import ChangeToTOTP from "../../components/account/ChangeToTOTP.vue";
</script>
<script lang="ts">
export default defineComponent({
data() {
return {
verification: "loading" as "success" | "loading" | "failed",
image: undefined as undefined | string,
otp: undefined as undefined | string,
verifyStatus: undefined as undefined | "loading" | "success" | "failed",
verifyError: "" as string,
loading: false,
tab: "",
currentRoutine: "",
};
},
mounted() {
this.loading = true;
this.$http
.get(`/user/totp`)
.get(`/user/routine`)
.then((result) => {
this.verification = "success";
this.image = result.data.dataUrl;
this.otp = result.data.otp;
this.tab = result.data.routine;
this.currentRoutine = result.data.routine;
})
.catch((err) => {
this.verification = "failed";
.catch((err) => {})
.finally(() => {
this.loading = false;
});
},
methods: {
verify(e: any) {
let formData = e.target.elements;
this.verifyStatus = "loading";
this.verifyError = "";
this.$http
.post(`/user/verify`, {
totp: formData.totp.value,
})
.then((result) => {
this.verifyStatus = "success";
})
.catch((err) => {
this.verifyStatus = "failed";
this.verifyError = err.response.data;
})
.finally(() => {
setTimeout(() => {
this.verifyStatus = undefined;
}, 2000);
});
},
},
methods: {},
});
</script>