Refactor email verification to use JSON responses instead of redirects
All checks were successful
Build And Push Image / docker (push) Successful in 2m54s
All checks were successful
Build And Push Image / docker (push) Successful in 2m54s
- Replace server-side redirects with JSON API responses for better error handling - Add support for partial success when Keycloak update fails but token is valid - Improve error messages with specific status codes (410 for expired, 409 for already used) - Extract email from API response instead of URL query parameters - Enable client-side navigation with proper error state management
This commit is contained in:
@@ -18,6 +18,8 @@ export default defineEventHandler(async (event) => {
|
||||
// Update user verification status in Keycloak
|
||||
const { createKeycloakAdminClient } = await import('~/server/utils/keycloak-admin');
|
||||
const keycloak = createKeycloakAdminClient();
|
||||
|
||||
let partialSuccess = false;
|
||||
|
||||
try {
|
||||
await keycloak.updateUserProfile(userId, {
|
||||
@@ -29,27 +31,38 @@ export default defineEventHandler(async (event) => {
|
||||
|
||||
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);
|
||||
partialSuccess = true;
|
||||
}
|
||||
|
||||
// Return JSON response for client-side navigation
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
userId,
|
||||
email,
|
||||
partialSuccess
|
||||
}
|
||||
};
|
||||
|
||||
} catch (error: any) {
|
||||
console.error('[verify-email] Verification failed:', error.message);
|
||||
|
||||
// Handle different error types with appropriate redirects
|
||||
// Return error response
|
||||
if (error.message?.includes('expired')) {
|
||||
return sendRedirect(event, '/auth/verify-expired', 302);
|
||||
throw createError({
|
||||
statusCode: 410,
|
||||
statusMessage: 'Verification link has expired. Please request a new one.'
|
||||
});
|
||||
} else if (error.message?.includes('already used') || error.message?.includes('not found')) {
|
||||
return sendRedirect(event, '/auth/verify-expired?reason=used', 302);
|
||||
throw createError({
|
||||
statusCode: 409,
|
||||
statusMessage: 'This verification link has already been used or is invalid.'
|
||||
});
|
||||
} else {
|
||||
// For other errors, show a generic error page
|
||||
throw createError({
|
||||
statusCode: 400,
|
||||
statusMessage: error.message || 'Invalid verification link'
|
||||
|
||||
Reference in New Issue
Block a user