Files
crewli/apps/app/src/pages/verify-email-change.vue
bert.hausmans 836cffa232 feat: password reset, email change with verification, and password change
Password reset: multi-app support with custom notification linking to correct
frontend (app/portal/admin). Email change: self-service with password
confirmation and admin-initiated, both sending verification to new address
with 24h expiry. Confirmation sent to old email on completion. Password
change: authenticated endpoint revoking other sessions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-14 15:38:54 +02:00

117 lines
3.0 KiB
Vue

<script setup lang="ts">
import { VNodeRenderer } from '@layouts/components/VNodeRenderer'
import { themeConfig } from '@themeConfig'
import { apiClient } from '@/lib/axios'
import { useAuthStore } from '@/stores/useAuthStore'
definePage({
meta: {
layout: 'blank',
public: true,
},
})
const route = useRoute()
const authStore = useAuthStore()
const isVerifying = ref(true)
const success = ref(false)
const errorMessage = ref('')
onMounted(async () => {
const token = route.query.token as string
if (!token) {
errorMessage.value = 'Geen verificatietoken gevonden.'
isVerifying.value = false
return
}
try {
await apiClient.post('/verify-email-change', { token })
success.value = true
authStore.logout()
}
catch (error: unknown) {
const ax = error as { response?: { data?: { errors?: Record<string, string[]>; message?: string } } }
errorMessage.value = ax.response?.data?.errors?.token?.[0]
?? ax.response?.data?.errors?.new_email?.[0]
?? ax.response?.data?.message
?? 'Er is een fout opgetreden bij de verificatie.'
}
finally {
isVerifying.value = false
}
})
</script>
<template>
<div class="auth-wrapper d-flex align-center justify-center pa-4 bg-surface" style="min-height: 100vh;">
<div class="auth-logo d-flex align-center gap-x-3 position-absolute" style="inset-block-start: 2rem; inset-inline-start: 2.5rem;">
<VNodeRenderer :nodes="themeConfig.app.logo" />
<h1 class="auth-title">
{{ themeConfig.app.title }}
</h1>
</div>
<VCard
flat
:max-width="450"
width="100%"
class="pa-6"
>
<VCardText class="text-center">
<template v-if="isVerifying">
<VProgressCircular
indeterminate
color="primary"
class="mb-4"
/>
<p>E-mailadres wordt geverifieerd...</p>
</template>
<template v-else-if="success">
<VIcon
size="64"
color="success"
class="mb-4"
>
tabler-circle-check
</VIcon>
<h4 class="text-h5 mb-2">
E-mailadres gewijzigd!
</h4>
<p class="text-body-2 text-medium-emphasis mb-4">
Je e-mailadres is succesvol gewijzigd.
Log opnieuw in met je nieuwe e-mailadres.
</p>
<VBtn
color="primary"
:to="{ name: 'login' }"
>
Ga naar inloggen
</VBtn>
</template>
<template v-else>
<VIcon
size="64"
color="error"
class="mb-4"
>
tabler-circle-x
</VIcon>
<h4 class="text-h5 mb-2">
Verificatie mislukt
</h4>
<p class="text-body-2 text-medium-emphasis">
{{ errorMessage }}
</p>
</template>
</VCardText>
</VCard>
</div>
</template>
<style lang="scss">
@use "@core/scss/template/pages/page-auth";
</style>