82 lines
2.5 KiB
TypeScript
82 lines
2.5 KiB
TypeScript
// server/api/auth/logout.post.ts
|
|
|
|
|
|
export default defineEventHandler(async (event) => {
|
|
const asString = (value: unknown): string => (typeof value === 'string' ? value : '');
|
|
|
|
const buildLogoutUrl = (idToken?: string) => {
|
|
const config = useRuntimeConfig();
|
|
const keycloakIssuer = asString(config.keycloakIssuer);
|
|
const keycloakClientId = asString(config.keycloakClientId);
|
|
const authUrl = asString(config.public.authUrl);
|
|
const baseUrl = asString(config.public.baseUrl);
|
|
const keycloakLogoutUri = asString(config.keycloakLogoutUri);
|
|
const postLogoutRedirectUriConfig = asString(config.postLogoutRedirectUri);
|
|
|
|
const logoutPath = keycloakLogoutUri || `${keycloakIssuer}/protocol/openid-connect/logout`;
|
|
const postLogoutRedirectUri = postLogoutRedirectUriConfig || baseUrl || authUrl;
|
|
|
|
const logoutUrl = new URL(logoutPath);
|
|
logoutUrl.searchParams.set('client_id', keycloakClientId);
|
|
|
|
if (postLogoutRedirectUri) {
|
|
logoutUrl.searchParams.set('post_logout_redirect_uri', postLogoutRedirectUri);
|
|
}
|
|
|
|
if (idToken) {
|
|
logoutUrl.searchParams.set('id_token_hint', idToken);
|
|
}
|
|
|
|
return logoutUrl.toString();
|
|
};
|
|
|
|
try {
|
|
// Retrieve token from the active session when available.
|
|
const sessionId = getCookie(event, 'user_session');
|
|
let idToken: string | undefined;
|
|
|
|
if (sessionId) {
|
|
try {
|
|
const { getUserSession, deleteUserSession } = await import('~/server/utils/sessionStore');
|
|
const session = getUserSession(sessionId);
|
|
|
|
if (session) {
|
|
idToken = session.idToken;
|
|
deleteUserSession(sessionId);
|
|
}
|
|
} catch {
|
|
// Ignore session-store retrieval failures; cookies are still cleared below.
|
|
}
|
|
}
|
|
|
|
// Always clear auth-related cookies.
|
|
deleteCookie(event, 'user_session');
|
|
deleteCookie(event, 'oauth_state');
|
|
deleteCookie(event, 'user_session', { path: '/' });
|
|
deleteCookie(event, 'oauth_state', { path: '/' });
|
|
|
|
const logoutUrl = buildLogoutUrl(idToken);
|
|
|
|
return {
|
|
success: true,
|
|
logoutUrl,
|
|
message: 'Session cleared successfully',
|
|
};
|
|
|
|
} catch {
|
|
let fallbackLogoutUrl = '';
|
|
|
|
try {
|
|
fallbackLogoutUrl = buildLogoutUrl();
|
|
} catch {
|
|
// Keep empty fallback URL if runtime config is not usable.
|
|
}
|
|
|
|
return {
|
|
success: false,
|
|
logoutUrl: fallbackLogoutUrl,
|
|
error: 'Logout encountered an error, but providing fallback logout URL',
|
|
message: 'Logout failed',
|
|
};
|
|
}
|
|
}); |