sessions fix password change sign-in fix
This commit is contained in:
1 parent
63861449cf
commit
f0706432d4
20 files changed
+539
-117
No files matched your search
@@ -1,34 +1,141 @@
|
||||
<script setup lang="ts">
|
||||
import { reactive } from 'vue'
|
||||
import { computed, reactive, ref, watch } from 'vue'
|
||||
import { authClient } from '@/lib/auth-client.js'
|
||||
import { useSnackbarStore } from '@/stores/snackbar.ts'
|
||||
|
||||
const passwordData = reactive({
|
||||
const session = authClient.useSession()
|
||||
const snackbarStore = useSnackbarStore()
|
||||
|
||||
const email = computed(() => session.value.data?.user.email ?? '')
|
||||
|
||||
const err = ref('')
|
||||
const loading = ref(false)
|
||||
const reset = reactive({
|
||||
newPassword: '',
|
||||
currentPassword: '',
|
||||
OTP: '',
|
||||
showOTP: false,
|
||||
showPassword: false,
|
||||
})
|
||||
|
||||
const changePassword = async () => {
|
||||
await authClient.changePassword({
|
||||
newPassword: passwordData.newPassword,
|
||||
currentPassword: passwordData.currentPassword,
|
||||
revokeOtherSessions: true,
|
||||
const canReset = computed(() => reset.newPassword.length > 0 && reset.OTP.length === 6)
|
||||
|
||||
watch(
|
||||
() => reset.OTP,
|
||||
(val) => {
|
||||
if (val.length >= 1) err.value = ''
|
||||
},
|
||||
)
|
||||
|
||||
const sendOTP = async () => {
|
||||
if (!email.value) return
|
||||
loading.value = true
|
||||
const { data, error } = await authClient.emailOtp.requestPasswordReset({
|
||||
email: email.value,
|
||||
})
|
||||
loading.value = false
|
||||
|
||||
if (data?.success) {
|
||||
reset.showOTP = true
|
||||
err.value = ''
|
||||
}
|
||||
if (error) err.value = error.message ?? 'Failed to send code'
|
||||
}
|
||||
|
||||
const confirmPasswordReset = async () => {
|
||||
if (!canReset.value) return
|
||||
loading.value = true
|
||||
const { data, error } = await authClient.emailOtp.resetPassword({
|
||||
email: email.value,
|
||||
otp: reset.OTP,
|
||||
password: reset.newPassword,
|
||||
})
|
||||
loading.value = false
|
||||
|
||||
if (data?.success) {
|
||||
snackbarStore.add({ title: 'Password changed', text: '', color: 'success' })
|
||||
reset.newPassword = ''
|
||||
reset.OTP = ''
|
||||
reset.showOTP = false
|
||||
err.value = ''
|
||||
}
|
||||
if (error) {
|
||||
err.value = error.message ?? 'Failed to reset password'
|
||||
reset.OTP = ''
|
||||
}
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
reset.newPassword = ''
|
||||
reset.OTP = ''
|
||||
reset.showOTP = false
|
||||
err.value = ''
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<v-sheet border class="pa-4 d-flex flex-column ga-2">
|
||||
<div class="text-uppercase text-title-large">Change password</div>
|
||||
<div class="d-flex flex-column ga-2">
|
||||
<div class="d-flex ga-2 align-center justify-space-between">
|
||||
<div class="text-uppercase text-title-large">Change password</div>
|
||||
<v-chip v-if="err" size="small" variant="flat" color="error" density="compact">{{ err }}</v-chip>
|
||||
</div>
|
||||
|
||||
<div v-if="reset.showOTP" class="d-flex flex-column ga-2">
|
||||
<div class="text-body-medium">Enter the code sent to {{ email }} and a new password</div>
|
||||
<v-text-field
|
||||
class="w-50"
|
||||
clearable
|
||||
bg-color="background"
|
||||
placeholder="current password"
|
||||
v-model="passwordData.currentPassword"
|
||||
density="comfortable"
|
||||
placeholder="New password"
|
||||
prepend-inner-icon="mdi-lock"
|
||||
:type="reset.showPassword ? 'text' : 'password'"
|
||||
:append-inner-icon="reset.showPassword ? 'mdi-eye-off' : 'mdi-eye'"
|
||||
@click:append-inner="reset.showPassword = !reset.showPassword"
|
||||
v-model="reset.newPassword"
|
||||
/>
|
||||
<v-text-field clearable bg-color="background" placeholder="new password" v-model="passwordData.newPassword" />
|
||||
<div>
|
||||
<v-btn variant="tonal" prepend-icon="mdi-check" text="Update" @click="changePassword" />
|
||||
<div class="d-flex ga-2 align-center">
|
||||
<div>CODE from E-mail:</div>
|
||||
<v-otp-input
|
||||
class="justify-start pa-0"
|
||||
color="background"
|
||||
density="comfortable"
|
||||
pattern="numeric"
|
||||
v-model="reset.OTP"
|
||||
@finish="confirmPasswordReset"
|
||||
/>
|
||||
</div>
|
||||
<div class="d-flex ga-1">
|
||||
<v-btn density="comfortable" text="Cancel" @click="cancel" />
|
||||
<v-btn
|
||||
prepend-icon="mdi-autorenew"
|
||||
density="comfortable"
|
||||
text="Resend Code"
|
||||
:disabled="loading"
|
||||
@click="sendOTP"
|
||||
/>
|
||||
<v-btn
|
||||
variant="tonal"
|
||||
density="comfortable"
|
||||
prepend-icon="mdi-check-circle"
|
||||
text="Reset password"
|
||||
:loading="loading"
|
||||
:disabled="!canReset"
|
||||
@click="confirmPasswordReset"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="d-flex flex-column ga-2">
|
||||
<div class="text-body-medium">A confirmation code will be sent to {{ email }}</div>
|
||||
<div class="d-flex ga-1">
|
||||
<v-btn
|
||||
prepend-icon="mdi-email-fast-outline"
|
||||
density="comfortable"
|
||||
text="Send Code"
|
||||
:loading="loading"
|
||||
:disabled="!email"
|
||||
@click="sendOTP"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</v-sheet>
|
||||
|
||||
Reference in new issue
Block a user