monacousa-portal/server/api/auth/callback.get.ts

97 lines
3.0 KiB
TypeScript

export default defineEventHandler(async (event) => {
console.log('🔄 Callback endpoint called at:', new Date().toISOString());
const query = getQuery(event);
const { code, state } = query;
console.log('📝 Callback query params:', {
hasCode: !!code,
hasState: !!state,
state: state ? 'present' : 'missing'
});
if (!code || !state) {
throw createError({
statusCode: 400,
statusMessage: 'Missing authorization code or state',
});
}
// Verify state
const storedState = getCookie(event, 'oauth-state');
if (state !== storedState) {
throw createError({
statusCode: 400,
statusMessage: 'Invalid state parameter',
});
}
try {
const keycloak = createKeycloakClient();
const sessionManager = createSessionManager();
// Exchange code for tokens
const tokens = await keycloak.exchangeCodeForTokens(code as string);
// Get user info
const userInfo = await keycloak.getUserInfo(tokens.access_token);
// Use member-tiers service for proper tier determination
const { determineMemberTierByEmail, determineMemberTierFromKeycloak } = await import('~/server/utils/member-tiers');
// First try to determine tier by email (checks NocoDB and Keycloak)
const tierResult = await determineMemberTierByEmail(userInfo.email);
// Log tier determination for monitoring
console.log(`[auth-callback] Tier determination for ${userInfo.email}:`, {
tier: tierResult.tier,
source: tierResult.source,
confidence: tierResult.confidence,
reason: tierResult.reason
});
// Alert admin if tier confidence is low
if (tierResult.confidence === 'low') {
console.warn(`[auth-callback] Low confidence tier assignment for ${userInfo.email}. Manual review recommended.`);
}
// Create session
const sessionData = {
user: {
id: userInfo.sub,
email: userInfo.email,
name: userInfo.name || `${userInfo.given_name || ''} ${userInfo.family_name || ''}`.trim(),
firstName: userInfo.given_name,
lastName: userInfo.family_name,
username: userInfo.preferred_username,
tier: tierResult.tier,
tierSource: tierResult.source, // Track where tier came from
groups: userInfo.groups || ['user'],
},
tokens: {
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
expiresAt: Date.now() + (tokens.expires_in * 1000),
},
createdAt: Date.now(),
lastActivity: Date.now(),
};
const sessionCookie = sessionManager.createSession(sessionData);
// Set session cookie
setHeader(event, 'Set-Cookie', sessionCookie);
// Clear state cookie
deleteCookie(event, 'oauth-state');
return sendRedirect(event, '/dashboard');
} catch (error) {
console.error('Auth callback error:', error);
throw createError({
statusCode: 500,
statusMessage: 'Authentication failed',
});
}
});