124 lines
3.7 KiB
TypeScript
Executable File
124 lines
3.7 KiB
TypeScript
Executable File
// 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;
|
|
},
|
|
});
|