diff --git a/server/dev-server.mjs b/server/dev-server.mjs index ab19fba..ae7a7ae 100644 --- a/server/dev-server.mjs +++ b/server/dev-server.mjs @@ -136,6 +136,15 @@ app.get("/auth/callback", asyncRoute(async (req, res) => { res.redirect(pendingLogin.returnTo); })); +app.get("/auth/logged-out", (req, res) => { + const returnTo = sanitizeReturnTo(req.query.returnTo); + + res.clearCookie(sessionCookieName, clearCookieOptions()); + res.clearCookie(oidcStateCookieName, clearCookieOptions()); + setNoStore(res); + res.redirect(buildLoginRedirectUrl(returnTo, { forceLogin: true })); +}); + app.get("/auth/logout", asyncRoute(async (req, res) => { const session = getCurrentSession(req); const returnTo = sanitizeReturnTo(req.query.returnTo); @@ -156,6 +165,7 @@ app.get("/auth/logout", asyncRoute(async (req, res) => { const discovery = await getOidcDiscovery(); const endSessionEndpoint = discovery.end_session_endpoint; const loginRedirectUrl = buildLoginRedirectUrl(returnTo, { forceLogin: true }); + const postLogoutRedirectUrl = buildLoggedOutRedirectUrl(); if (!endSessionEndpoint) { setNoStore(res); @@ -165,14 +175,14 @@ app.get("/auth/logout", asyncRoute(async (req, res) => { const logoutUrl = new URL(endSessionEndpoint); logoutUrl.searchParams.set("client_id", config.clientId); - logoutUrl.searchParams.set("post_logout_redirect_uri", loginRedirectUrl); + logoutUrl.searchParams.set("post_logout_redirect_uri", postLogoutRedirectUrl); if (session?.tokenSet.idToken) { logoutUrl.searchParams.set("id_token_hint", session.tokenSet.idToken); } setNoStore(res); - res.type("html").send(renderGlobalLogoutPage(getFrontchannelLogoutUrls(), loginRedirectUrl, logoutUrl.toString())); + res.type("html").send(renderGlobalLogoutPage(getFrontchannelLogoutUrls(), logoutUrl.toString())); })); app.get("/api/me", (req, res) => { @@ -548,6 +558,7 @@ function readConfig() { clientId, clientSecret, redirectUri: process.env.LAUNCHER_OIDC_REDIRECT_URI ?? `${appBaseUrl}/auth/callback`, + loggedOutRedirectUri: process.env.LAUNCHER_OIDC_LOGGED_OUT_REDIRECT_URI ?? `${appBaseUrl}/auth/logged-out`, appBaseUrl, scope: process.env.LAUNCHER_OIDC_SCOPE ?? "openid email profile groups offline_access", cookieDomain: process.env.LAUNCHER_COOKIE_DOMAIN || undefined, @@ -919,10 +930,9 @@ function normalizeLogoutUrl(value) { } } -function renderGlobalLogoutPage(frontchannelLogoutUrls, finalRedirectUrl, identityLogoutUrl = null) { +function renderGlobalLogoutPage(frontchannelLogoutUrls, finalRedirectUrl) { const logoutUrlsJson = JSON.stringify(frontchannelLogoutUrls); const redirectUrlJson = JSON.stringify(finalRedirectUrl); - const identityLogoutUrlJson = JSON.stringify(identityLogoutUrl); return ` @@ -946,19 +956,12 @@ function renderGlobalLogoutPage(frontchannelLogoutUrls, finalRedirectUrl, identi @@ -1284,6 +1287,11 @@ function buildLoginRedirectUrl(returnTo, { forceLogin = false } = {}) { return loginUrl.toString(); } +function buildLoggedOutRedirectUrl() { + const loggedOutUrl = new URL(config.loggedOutRedirectUri); + return loggedOutUrl.toString(); +} + function randomBase64Url(size) { return randomBytes(size).toString("base64url"); }