fixes
Build And Push Image / docker (push) Successful in 3m45s
Details
Build And Push Image / docker (push) Successful in 3m45s
Details
This commit is contained in:
parent
b833826a1e
commit
e097fb746f
|
|
@ -0,0 +1,64 @@
|
||||||
|
// server/api/admin/debug-rsvp-config.get.ts
|
||||||
|
import { createSessionManager } from '~/server/utils/session';
|
||||||
|
import { getEffectiveNocoDBConfig } from '~/server/utils/admin-config';
|
||||||
|
import { getEventTableId } from '~/server/utils/nocodb-events';
|
||||||
|
|
||||||
|
export default defineEventHandler(async (event) => {
|
||||||
|
try {
|
||||||
|
// Verify admin session
|
||||||
|
const sessionManager = createSessionManager();
|
||||||
|
const cookieHeader = getHeader(event, 'cookie');
|
||||||
|
const session = sessionManager.getSession(cookieHeader);
|
||||||
|
|
||||||
|
if (!session?.user || session.user.tier !== 'admin') {
|
||||||
|
throw createError({
|
||||||
|
statusCode: 403,
|
||||||
|
statusMessage: 'Admin access required'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('[admin/debug-rsvp-config] =========================');
|
||||||
|
console.log('[admin/debug-rsvp-config] 🔍 DEBUG: RSVP Configuration Analysis');
|
||||||
|
|
||||||
|
// Get effective config
|
||||||
|
const effectiveConfig = getEffectiveNocoDBConfig();
|
||||||
|
console.log('[admin/debug-rsvp-config] 🔍 Effective config:', JSON.stringify(effectiveConfig, null, 2));
|
||||||
|
|
||||||
|
// Test RSVP table ID retrieval
|
||||||
|
const rsvpTableId = getEventTableId('EventRSVPs');
|
||||||
|
console.log('[admin/debug-rsvp-config] 🔍 RSVP Table ID retrieved:', rsvpTableId);
|
||||||
|
|
||||||
|
// Test Events table ID retrieval
|
||||||
|
const eventsTableId = getEventTableId('Events');
|
||||||
|
console.log('[admin/debug-rsvp-config] 🔍 Events Table ID retrieved:', eventsTableId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
debug: {
|
||||||
|
effectiveConfig,
|
||||||
|
rsvpTableId,
|
||||||
|
eventsTableId,
|
||||||
|
availableTableKeys: Object.keys(effectiveConfig?.tables || {}),
|
||||||
|
rsvpTableInConfig: {
|
||||||
|
'rsvps': effectiveConfig?.tables?.['rsvps'],
|
||||||
|
'event_rsvps': effectiveConfig?.tables?.['event_rsvps'],
|
||||||
|
'EventRSVPs': effectiveConfig?.tables?.['EventRSVPs'],
|
||||||
|
'rsvp_table': effectiveConfig?.tables?.['rsvp_table'],
|
||||||
|
'RSVPs': effectiveConfig?.tables?.['RSVPs']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error('[admin/debug-rsvp-config] ❌ Error:', error);
|
||||||
|
|
||||||
|
if (error.statusCode) {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw createError({
|
||||||
|
statusCode: 500,
|
||||||
|
statusMessage: 'Failed to debug RSVP configuration'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -3,10 +3,8 @@ export default defineEventHandler(async (event) => {
|
||||||
const { token } = getQuery(event);
|
const { token } = getQuery(event);
|
||||||
|
|
||||||
if (!token || typeof token !== 'string') {
|
if (!token || typeof token !== 'string') {
|
||||||
throw createError({
|
console.log('[verify-email] Missing or invalid token, redirecting to expired page');
|
||||||
statusCode: 400,
|
return sendRedirect(event, '/auth/verify-expired?reason=invalid', 302);
|
||||||
statusMessage: 'Verification token is required'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('[verify-email] Processing verification token...');
|
console.log('[verify-email] Processing verification token...');
|
||||||
|
|
@ -35,54 +33,54 @@ export default defineEventHandler(async (event) => {
|
||||||
// ONLY consume token after successful Keycloak update
|
// ONLY consume token after successful Keycloak update
|
||||||
await consumeEmailToken(token);
|
await consumeEmailToken(token);
|
||||||
|
|
||||||
} catch (keycloakError: any) {
|
} catch (keycloakUpdateError: any) {
|
||||||
console.error('[verify-email] Keycloak update failed:', keycloakError.message);
|
console.error('[verify-email] Keycloak update failed:', keycloakUpdateError.message);
|
||||||
|
|
||||||
// Check if this is a retryable error or a permanent failure
|
// Check if this is a retryable error or a permanent failure
|
||||||
if (keycloakError.message?.includes('error-user-attribute-required')) {
|
if (keycloakUpdateError.message?.includes('error-user-attribute-required')) {
|
||||||
// This is a configuration issue - don't consume token, allow retries
|
// This is a configuration issue - don't consume token, allow retries
|
||||||
console.log('[verify-email] Keycloak configuration error - token preserved for retry');
|
console.log('[verify-email] Keycloak configuration error - token preserved for retry');
|
||||||
partialSuccess = true;
|
partialSuccess = true;
|
||||||
keycloakError = keycloakError.message;
|
keycloakError = keycloakUpdateError.message;
|
||||||
} else {
|
} else {
|
||||||
// For other errors, still consume token to prevent infinite retries
|
// For other errors, still consume token to prevent infinite retries
|
||||||
console.log('[verify-email] Consuming token despite Keycloak error to prevent loops');
|
console.log('[verify-email] Consuming token despite Keycloak error to prevent loops');
|
||||||
await consumeEmailToken(token);
|
await consumeEmailToken(token);
|
||||||
partialSuccess = true;
|
partialSuccess = true;
|
||||||
keycloakError = keycloakError.message;
|
keycloakError = keycloakUpdateError.message;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return JSON response for client-side navigation
|
// Build success redirect URL with query parameters
|
||||||
return {
|
const successUrl = new URL('/auth/verify-success', 'https://portal.monacousa.org');
|
||||||
success: true,
|
successUrl.searchParams.set('email', email);
|
||||||
data: {
|
|
||||||
userId,
|
if (partialSuccess && keycloakError) {
|
||||||
email,
|
successUrl.searchParams.set('warning', 'partial');
|
||||||
partialSuccess,
|
console.log('[verify-email] Redirecting to success page with partial warning');
|
||||||
keycloakError: keycloakError || undefined
|
} else {
|
||||||
}
|
console.log('[verify-email] Redirecting to success page - verification complete');
|
||||||
};
|
}
|
||||||
|
|
||||||
|
// Redirect to success page instead of returning JSON
|
||||||
|
return sendRedirect(event, successUrl.pathname + successUrl.search, 302);
|
||||||
|
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.error('[verify-email] Verification failed:', error.message);
|
console.error('[verify-email] Verification failed:', error.message);
|
||||||
|
|
||||||
// Return error response
|
// Redirect to appropriate error page instead of throwing errors
|
||||||
if (error.message?.includes('expired')) {
|
if (error.message?.includes('expired')) {
|
||||||
throw createError({
|
console.log('[verify-email] Token expired, redirecting to expired page');
|
||||||
statusCode: 410,
|
return sendRedirect(event, '/auth/verify-expired?reason=expired', 302);
|
||||||
statusMessage: 'Verification link has expired. Please request a new one.'
|
} else if (error.message?.includes('already used')) {
|
||||||
});
|
console.log('[verify-email] Token already used, redirecting to expired page');
|
||||||
} else if (error.message?.includes('already used') || error.message?.includes('not found')) {
|
return sendRedirect(event, '/auth/verify-expired?reason=used', 302);
|
||||||
throw createError({
|
} else if (error.message?.includes('not found')) {
|
||||||
statusCode: 409,
|
console.log('[verify-email] Token not found, redirecting to expired page');
|
||||||
statusMessage: 'This verification link has already been used or is invalid.'
|
return sendRedirect(event, '/auth/verify-expired?reason=invalid', 302);
|
||||||
});
|
|
||||||
} else {
|
} else {
|
||||||
throw createError({
|
console.log('[verify-email] Generic verification error, redirecting to expired page');
|
||||||
statusCode: 400,
|
return sendRedirect(event, '/auth/verify-expired?reason=invalid', 302);
|
||||||
statusMessage: error.message || 'Invalid verification link'
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -26,18 +26,26 @@ export enum EventTable {
|
||||||
|
|
||||||
// Dynamic table ID getter - will use configured table ID from admin panel
|
// Dynamic table ID getter - will use configured table ID from admin panel
|
||||||
export const getEventTableId = (tableName: 'Events' | 'EventRSVPs'): string => {
|
export const getEventTableId = (tableName: 'Events' | 'EventRSVPs'): string => {
|
||||||
|
console.log(`[nocodb-events] 🔍 DEBUG: Getting table ID for ${tableName}...`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Try to get effective configuration from admin config system first
|
// Try to get effective configuration from admin config system first
|
||||||
const effectiveConfig = getEffectiveNocoDBConfig();
|
const effectiveConfig = getEffectiveNocoDBConfig();
|
||||||
|
console.log(`[nocodb-events] 🔍 DEBUG: Effective config:`, JSON.stringify(effectiveConfig, null, 2));
|
||||||
|
|
||||||
if (effectiveConfig?.tables) {
|
if (effectiveConfig?.tables) {
|
||||||
|
console.log(`[nocodb-events] 🔍 DEBUG: Available table keys:`, Object.keys(effectiveConfig.tables));
|
||||||
|
|
||||||
if (tableName === 'Events') {
|
if (tableName === 'Events') {
|
||||||
// Check multiple possible keys for Events table
|
// Check multiple possible keys for Events table
|
||||||
const eventsTableId = effectiveConfig.tables['events'] ||
|
const eventsTableId = effectiveConfig.tables['events'] ||
|
||||||
effectiveConfig.tables['Events'] ||
|
effectiveConfig.tables['Events'] ||
|
||||||
effectiveConfig.tables['events_table'];
|
effectiveConfig.tables['events_table'];
|
||||||
if (eventsTableId) {
|
if (eventsTableId) {
|
||||||
console.log(`[nocodb-events] Using admin config table ID for ${tableName}:`, eventsTableId);
|
console.log(`[nocodb-events] ✅ Using admin config table ID for ${tableName}:`, eventsTableId);
|
||||||
return eventsTableId;
|
return eventsTableId;
|
||||||
|
} else {
|
||||||
|
console.log(`[nocodb-events] ⚠️ No Events table ID found in config`);
|
||||||
}
|
}
|
||||||
} else if (tableName === 'EventRSVPs') {
|
} else if (tableName === 'EventRSVPs') {
|
||||||
// Check multiple possible keys for RSVP table
|
// Check multiple possible keys for RSVP table
|
||||||
|
|
@ -47,13 +55,20 @@ export const getEventTableId = (tableName: 'Events' | 'EventRSVPs'): string => {
|
||||||
effectiveConfig.tables['rsvp_table'] ||
|
effectiveConfig.tables['rsvp_table'] ||
|
||||||
effectiveConfig.tables['RSVPs'];
|
effectiveConfig.tables['RSVPs'];
|
||||||
if (rsvpTableId) {
|
if (rsvpTableId) {
|
||||||
console.log(`[nocodb-events] Using admin config table ID for ${tableName}:`, rsvpTableId);
|
console.log(`[nocodb-events] ✅ Using admin config table ID for ${tableName}:`, rsvpTableId);
|
||||||
return rsvpTableId;
|
return rsvpTableId;
|
||||||
|
} else {
|
||||||
|
console.log(`[nocodb-events] ⚠️ No RSVP table ID found in config. Checking individual keys:`);
|
||||||
|
console.log(`[nocodb-events] 🔍 rsvps:`, effectiveConfig.tables['rsvps']);
|
||||||
|
console.log(`[nocodb-events] 🔍 event_rsvps:`, effectiveConfig.tables['event_rsvps']);
|
||||||
|
console.log(`[nocodb-events] 🔍 EventRSVPs:`, effectiveConfig.tables['EventRSVPs']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
console.log(`[nocodb-events] ⚠️ No tables configuration found in effective config`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`[nocodb-events] Admin config not available, trying fallback for ${tableName}:`, error);
|
console.log(`[nocodb-events] ❌ Admin config error for ${tableName}:`, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to get table ID from global configuration
|
// Try to get table ID from global configuration
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue