// routes/auth/logout.ts import { deleteCookie } from "$std/http/cookie.ts"; import { deleteStateKey, deleteUserTokenByStateId, getUserTokens, } from "../../services/userService.ts"; import { define } from "../../utils.ts"; const _redirectHome = Deno.env.get("REDIRECT_HOME")!; export const handler = define.handlers({ async GET(ctx) { const sessionData = ctx.state.data; const userId = sessionData?.user_id; const sealKey = ctx.state.sealKey; const stateId = ctx.state.stateId; // For single session logout: delete only the current session's token and state key if (userId && stateId) { try { // Delete the current session's token await deleteUserTokenByStateId(userId, stateId); // Delete the current session's state key (using sealKey, not stateId) if (sealKey) { await deleteStateKey(sealKey); } // Try to revoke Azure AD sessions for this specific session const tokens = await getUserTokens(userId); if (tokens && tokens.length > 0) { // Use any valid access token to revoke all Azure AD sessions const validToken = tokens.find((t) => t.access_token); if (validToken) { try { await fetch( "https://graph.microsoft.com/v1.0/me/revokeSignInSessions", { method: "POST", headers: { "Authorization": `Bearer ${validToken.access_token}`, }, }, ); } catch (e) { console.error("Failed to revoke Graph sessions:", e); } } } } catch (e) { console.error("Failed to delete session:", e); } } const response = new Response("", { status: 302, headers: { "Location": "/", }, }); deleteCookie(response.headers, "xx_state_id", { path: "/" }); deleteCookie(response.headers, "session", { path: "/" }); return response; }, async POST(ctx) { const sessionData = ctx.state.data; const userId = sessionData?.user_id; const sealKey = ctx.state.sealKey; const stateId = ctx.state.stateId; // For single session logout: delete only the current session's token and state key if (userId && stateId) { try { // Delete the current session's token await deleteUserTokenByStateId(userId, stateId); // Delete the current session's state key (using sealKey, not stateId) if (sealKey) { await deleteStateKey(sealKey); } // Try to revoke Azure AD sessions for this specific session const tokens = await getUserTokens(userId); if (tokens && tokens.length > 0) { // Use any valid access token to revoke all Azure AD sessions const validToken = tokens.find((t) => t.access_token); if (validToken) { try { await fetch( "https://graph.microsoft.com/v1.0/me/revokeSignInSessions", { method: "POST", headers: { "Authorization": `Bearer ${validToken.access_token}`, }, }, ); } catch (e) { console.error("Failed to revoke Graph sessions:", e); } } } } catch (e) { console.error("Failed to delete session:", e); } } const response = new Response("", { status: 302, headers: { "Location": "/", }, }); deleteCookie(response.headers, "xx_state_id", { path: "/" }); deleteCookie(response.headers, "session", { path: "/" }); return response; }, });