diff --git a/index.js b/index.js index 13531af..e76af45 100644 --- a/index.js +++ b/index.js @@ -415,11 +415,21 @@ app.get('/CollabCentral/:app/user/:scope/:action', (req, res) => { } else { res.status(401) } }) -// Standard options for the session cookies set after a successful OAuth round-trip. +// Options for the session cookies set after a successful OAuth round-trip. +// +// httpOnly is deliberately false: js/app.js reads `id` (to decide whether to +// redirect to OAuth) and `displayName` (to render the user chip in the header) +// via document.cookie. Enabling httpOnly here hides the cookies from JS, which +// causes an infinite auth loop where every page load thinks the user is not +// signed in and kicks off a fresh OAuth exchange — burning Webex tokens until +// the CTS token limit is reached. +// +// sameSite is 'lax' rather than 'strict' so the cookie survives the OAuth +// redirect chain webexapis.com -> /oauth -> /sendMessage.html on all browsers. const SESSION_COOKIE_OPTIONS = { - httpOnly: true, + httpOnly: false, secure: true, - sameSite: 'strict', + sameSite: 'lax', maxAge: 24 * 60 * 60 * 1000 }; @@ -467,14 +477,14 @@ app.get(`/CollabCentral/:app/oauth`, async function (req, res) { } logger("oauth", whoami.displayName + " successfully authed for " + appName + "."); + // Only the two cookies that the server (req.cookies.id, .displayName) and + // the client (getCookie('id'), getCookie('displayName')) actually read. + // Access/refresh tokens deliberately stay out of the browser: they never + // need to leave the server, and putting them in cookies would expose them + // to any XSS that might slip in later. res - .cookie('displayName', whoami.displayName, SESSION_COOKIE_OPTIONS) .cookie('id', whoami.id, SESSION_COOKIE_OPTIONS) - .cookie('avatar', whoami.avatar, SESSION_COOKIE_OPTIONS) - .cookie('email', whoami.userName, SESSION_COOKIE_OPTIONS) - .cookie('orgId', whoami.orgId, SESSION_COOKIE_OPTIONS) - .cookie('access_token', jsonData.access_token, SESSION_COOKIE_OPTIONS) - .cookie('refresh_token', jsonData.refresh_token, SESSION_COOKIE_OPTIONS) + .cookie('displayName', whoami.displayName, SESSION_COOKIE_OPTIONS) .redirect(301, '/CollabCentral/' + appName + '/sendMessage.html'); });