password recovery flow

This commit is contained in:
Michael Dausmann
2023-05-06 18:31:00 +10:00
parent fe0f68087c
commit c6b48f05c1
4 changed files with 95 additions and 3 deletions

38
pages/forgotpassword.vue Normal file
View File

@@ -0,0 +1,38 @@
<script setup lang="ts">
const supabase = useSupabaseAuthClient();
const config = useRuntimeConfig();
const loading = ref(false)
const email = ref('')
const sendResetPasswordLink = async () => {
try {
loading.value = true
const { data, error } = await supabase.auth.resetPasswordForEmail(email.value, {
redirectTo: `${config.public.siteRootUrl}/resetpassword`,
})
if (error) throw error
else alert('Password Reset link sent, check your email.');
} catch (error) {
alert(error)
} finally {
loading.value = false
}
}
</script>
<template>
<div class="flex flex-col items-center justify-center h-screen bg-gray-100">
<div class="w-full max-w-md p-6 space-y-6 bg-white rounded-lg shadow-lg">
<h1 class="text-3xl font-bold text-center">Forgot Pasword</h1>
<form @submit.prevent="sendResetPasswordLink" class="space-y-4">
<div>
<label for="email" class="block mb-2 font-bold">Email</label>
<input v-model="email" id="email" type="email" class="w-full p-2 border border-gray-400 rounded-md"
placeholder="Enter your email" required>
</div>
<button :disabled="loading || email === ''" type="submit"
class="w-full py-2 text-white bg-indigo-600 rounded-md hover:bg-indigo-700">Send Reset Password Link</button>
</form>
</div>
</div>
</template>

46
pages/resetpassword.vue Normal file
View File

@@ -0,0 +1,46 @@
<script setup lang="ts">
const supabase = useSupabaseAuthClient();
const loading = ref(false)
const password = ref('')
const confirmPassword = ref('')
const changePassword = async () => {
try {
loading.value = true
const { data, error } = await supabase.auth.updateUser({
password: password.value
});
if (error) throw error
else {
alert('password changed');
navigateTo('/signin', {replace: true}); // navigate to signin because it is best practice although the auth session seems to be valid so it immediately redirects to dashboard
}
} catch (error) {
alert(error)
} finally {
loading.value = false
}
}
</script>
<template>
<div class="flex flex-col items-center justify-center h-screen bg-gray-100">
<div class="w-full max-w-md p-6 space-y-6 bg-white rounded-lg shadow-lg">
<h1 class="text-3xl font-bold text-center">Forgot Pasword</h1>
<form @submit.prevent="changePassword" class="space-y-4">
<div>
<label for="password" class="block mb-2 font-bold">New Password</label>
<input v-model="password" id="password" type="password" class="w-full p-2 border border-gray-400 rounded-md"
placeholder="Enter your new password" required>
</div>
<div>
<label for="confirmPassword" class="block mb-2 font-bold">Confirm New Password</label>
<input v-model="confirmPassword" id="confirmPassword" type="password" class="w-full p-2 border border-gray-400 rounded-md"
placeholder="Confirm new password" required>
</div>
<button :disabled="loading || password === '' || (confirmPassword !== password)" type="submit"
class="w-full py-2 text-white bg-indigo-600 rounded-md hover:bg-indigo-700">Change Password</button>
</form>
</div>
</div>
</template>

View File

@@ -57,6 +57,7 @@
<input v-model="password" id="password" type="password" class="w-full p-2 border border-gray-400 rounded-md"
placeholder="Enter your password" required>
</div>
<NuxtLink id="forgotPasswordLink" to="/forgotpassword" class="text-right block">Forgot your password?</NuxtLink>
<button :disabled="loading || password === ''" type="submit"
class="w-full py-2 text-white bg-indigo-600 rounded-md hover:bg-indigo-700">Sign in</button>
</form>