Files
module-farmasi/server/api/auth/logout.post.ts
T
2026-03-31 11:11:39 +07:00

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',
};
}
});