openvibers/openvibe.wiki Commits

A guest's session probe answers 200, not 401 (browser check, WS-Q task 3): GET /auth/me with no session credential at all answers { user: null }, which the shared navbar reads as signed out. It asks on every page view, and the 401 logged a console error on each. A credential that is present but invalid or expired still answers 401. Test: auth.test.js (the guest case used to expect 401)

OP OpenVibers committed 26 Sept 2026 · 9409f51d30 · 2 files, +14 −3


Changes

ddiff --git a/server/auth/session.js b/server/auth/session.js
iindex c7be570..1b0d89e 100644
---- a/server/auth/session.js
++++ b/server/auth/session.js
@@@ -7,7 +7,7 @@
* GET /auth/callback → server-side code exchange, sets the cookies
* POST /auth/fedcm → the shared navbar's FedCM assertion (nonce checked here, signature by the Network)
* GET /auth/logout → clears the cookies (best-effort refresh revoke)
-- * GET /auth/me → the signed-in profile (offline JWT verification)
++ * GET /auth/me → the signed-in profile (offline JWT verification); a guest gets 200 { user: null }
* POST /auth/refresh → rotates tokens with the refresh token
*
* Cookies (host-only): ov_token (access JWT, JS-readable for the navbar), ov_refresh (httpOnly,
@@@ -175,9 +175,14 @@ function createSessionRoutes({ config, viewers, fetchImpl = globalThis.fetch, lo
});
router.get('/me', async (req, res) => {
++ res.set('Cache-Control', 'private, no-store');
++ // No credential at all (a guest) is signed out, not an error: the shared navbar asks this on every
++ // page view, and a 401 logged a console error on each (browser check, OpenVibe.Host). A credential
++ // that is present but invalid or expired still answers 401.
++ if (!(req.cookies && req.cookies[ACCESS_COOKIE]) && !req.get('authorization')) return res.json({ user: null });
const actor = await viewers.resolve(req, { services: false }).catch(() => null);
if (!actor || actor.kind !== 'user') return res.status(401).json({ error: 'Not authenticated' });
-- res.set('Cache-Control', 'private, no-store').json({ user: actor.user });
++ res.json({ user: actor.user });
});
router.post('/refresh', async (req, res) => {
ddiff --git a/test/auth.test.js b/test/auth.test.js
iindex 929e2bd..54ffb85 100644
---- a/test/auth.test.js
++++ b/test/auth.test.js
@@@ -55,7 +55,13 @@ const { sanitizeNext } = require('../server/auth/session');
r = await H.req(h, 'GET', '/auth/me', { cookie: `ov_token=${token}` });
assert.strictEqual(r.status, 200);
assert.strictEqual(r.json.user.username, 'ana');
-- assert.strictEqual((await H.req(h, 'GET', '/auth/me')).status, 401);
++ // A guest (no cookie, no token at all) is signed out, not an error; a bad credential is still 401.
++ r = await H.req(h, 'GET', '/auth/me');
++ assert.strictEqual(r.status, 200);
++ assert.deepStrictEqual(r.json, { user: null });
++ assert.strictEqual(r.headers.get('cache-control'), 'private, no-store');
++ assert.strictEqual((await H.req(h, 'GET', '/auth/me', { cookie: 'ov_token=expired.or.forged' })).status, 401);
++ assert.strictEqual((await H.req(h, 'GET', '/auth/me', { cookie: `ov_token=${H.userToken({ exp: -120 })}` })).status, 401, 'an expired cookie');
// An expired cookie is simply signed out on pages.
r = await H.req(h, 'GET', '/', { cookie: `ov_token=${H.userToken({ exp: -120 })}` });
assert.strictEqual(r.status, 200);