Added "Forgot password"

Closes #38
This commit is contained in:
2022-10-14 03:15:57 +02:00
parent b2d67f6ed4
commit 643a5755c0
11 changed files with 302 additions and 35 deletions

View File

@@ -21,6 +21,22 @@ export const auth_signup = (
password: password
});
export const send_recovery_key = (
username: string
): Promise<Responses.Success | Responses.Error> =>
post<Requests.SendRecoveryKey>('/api/auth/send_key', {
username: username
});
export const reset_password = (
key: string,
password: string
): Promise<Responses.Success | Responses.Error> =>
post<Requests.ResetPassword>('/api/auth/reset', {
key: key,
password: password
});
export const refresh_token = (
token: string
): Promise<Responses.Login | Responses.Error> =>

View File

@@ -1,10 +1,5 @@
import type { Requests, Responses, UploadFile } from '@/dto';
import {
get_token,
post_token,
post_token_form,
isErrorResponse
} from './base';
import { get_token, post_token, isErrorResponse } from './base';
import axios from 'axios';
export const get_root = (

View File

@@ -32,6 +32,15 @@ export namespace Requests {
otp?: string;
}
export interface SendRecoveryKey extends Base {
username: string;
}
export interface ResetPassword extends Base {
key: string;
password: string;
}
export interface TfaSetup extends Base {
mail: boolean;
}

View File

@@ -0,0 +1,119 @@
<script setup lang="ts">
import { ref } from 'vue';
import { Auth, isErrorResponse } from '@/api';
import { useMessage, NInput, NGrid, NGi, NButton, NCard } from 'naive-ui';
import { useRouter } from 'vue-router';
import { loadingMsgWrapper } from '@/utils';
const router = useRouter();
const message = useMessage();
const email = ref('');
const code = ref('');
const password = ref('');
const password2 = ref('');
const enterCode = ref(false);
const reset = loadingMsgWrapper(message, async () => {
if (password.value !== password2.value) {
message.error("Passwords don't match");
return;
}
const res = await Auth.reset_password(code.value, password.value);
if (isErrorResponse(res)) {
message.error(`Failed to reset password: ${res.message}`);
} else {
message.success('Password reset', {
duration: 2000
});
login();
}
});
const sendKey = loadingMsgWrapper(message, async () => {
const res = await Auth.send_recovery_key(email.value);
if (isErrorResponse(res)) {
message.error(`Failed to send recovery key: ${res.message}`);
} else {
message.success('If the email is registered a mail has been sent', {
duration: 10000
});
enterCode.value = true;
}
});
function login() {
router.replace('login');
}
function onKey(event: KeyboardEvent) {
if (event.key == 'Enter') enterCode.value ? reset() : sendKey();
}
</script>
<template>
<n-card>
<n-grid cols="2" x-gap="16" y-gap="16">
<template v-if="enterCode">
<n-gi span="2">
<n-input
:key="1"
type="text"
placeholder="Recovery key"
v-model:value="code"
maxlength="10"
autofocus
@keyup="onKey"
/>
</n-gi>
<n-gi span="2">
<n-input
type="password"
placeholder="Password"
v-model:value="password"
@keyup="onKey"
/>
</n-gi>
<n-gi span="2">
<n-input
type="password"
placeholder="Repeat password"
v-model:value="password2"
@keyup="onKey"
/>
</n-gi>
<n-gi>
<n-button type="info" @click="reset">
Reset password
</n-button>
</n-gi>
<n-gi style="text-align: right">
<n-button ghost @click="login">Go to login</n-button>
</n-gi>
</template>
<template v-else>
<n-gi span="2">
<n-input
:key="2"
type="text"
placeholder="Email"
v-model:value="email"
autofocus
:input-props="{ type: 'email' }"
@keyup="onKey"
/>
</n-gi>
<n-gi>
<n-button type="info" @click="sendKey">
Send recovery key
</n-button>
</n-gi>
<n-gi style="text-align: right">
<n-button ghost @click="login">Go to login</n-button>
</n-gi>
</template>
</n-grid>
</n-card>
</template>
<style scoped></style>