60 lines
2.1 KiB
TypeScript
60 lines
2.1 KiB
TypeScript
export default defineEventHandler(async (event) => {
|
|
try {
|
|
const { token } = getQuery(event);
|
|
|
|
if (!token || typeof token !== 'string') {
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: 'Verification token is required'
|
|
});
|
|
}
|
|
|
|
console.log('[verify-email] Processing verification token...');
|
|
|
|
// Verify the token
|
|
const { verifyEmailToken } = await import('~/server/utils/email-tokens');
|
|
const { userId, email } = await verifyEmailToken(token);
|
|
|
|
// Update user verification status in Keycloak
|
|
const { createKeycloakAdminClient } = await import('~/server/utils/keycloak-admin');
|
|
const keycloak = createKeycloakAdminClient();
|
|
|
|
try {
|
|
await keycloak.updateUserProfile(userId, {
|
|
emailVerified: true,
|
|
attributes: {
|
|
lastLoginDate: new Date().toISOString()
|
|
}
|
|
});
|
|
|
|
console.log('[verify-email] Successfully verified user:', userId, 'email:', email);
|
|
|
|
// Redirect to success page
|
|
return sendRedirect(event, '/auth/verify-success?email=' + encodeURIComponent(email), 302);
|
|
|
|
} catch (keycloakError: any) {
|
|
console.error('[verify-email] Keycloak update failed:', keycloakError.message);
|
|
|
|
// Even if Keycloak update fails, consider verification successful if token was valid
|
|
// This prevents user frustration due to backend issues
|
|
return sendRedirect(event, '/auth/verify-success?email=' + encodeURIComponent(email) + '&warning=partial', 302);
|
|
}
|
|
|
|
} catch (error: any) {
|
|
console.error('[verify-email] Verification failed:', error.message);
|
|
|
|
// Handle different error types with appropriate redirects
|
|
if (error.message?.includes('expired')) {
|
|
return sendRedirect(event, '/auth/verify-expired', 302);
|
|
} else if (error.message?.includes('already used') || error.message?.includes('not found')) {
|
|
return sendRedirect(event, '/auth/verify-expired?reason=used', 302);
|
|
} else {
|
|
// For other errors, show a generic error page
|
|
throw createError({
|
|
statusCode: 400,
|
|
statusMessage: error.message || 'Invalid verification link'
|
|
});
|
|
}
|
|
}
|
|
});
|