fix(api): handle unauthenticated users in get-session-user endpoint (#65652)

This commit is contained in:
Sem Bauke
2026-02-27 21:25:55 +01:00
committed by GitHub
parent 946b96c089
commit 75917df14a
3 changed files with 32 additions and 12 deletions

View File

@@ -191,13 +191,6 @@ export const build = async (
await fastify.register(protectedRoutes.userRoutes);
});
// CSRF protection disabled:
await fastify.register(async function (fastify, _opts) {
fastify.addHook('onRequest', fastify.send401IfNoUser);
await fastify.register(protectedRoutes.userGetRoutes);
});
// Routes that redirect if access is denied:
await fastify.register(async function (fastify, _opts) {
fastify.addHook('onRequest', fastify.redirectIfNoUser);
@@ -209,6 +202,14 @@ export const build = async (
// TODO: The route should not handle its own AuthZ
await fastify.register(protectedRoutes.challengeTokenRoutes);
// CSRF protection disabled:
// Routes that work for both authenticated and unauthenticated users:
void fastify.register(async function (fastify) {
fastify.addHook('onRequest', fastify.authorize);
await fastify.register(protectedRoutes.userGetRoutes);
});
// Routes for signed out users:
void fastify.register(async function (fastify) {
fastify.addHook('onRequest', fastify.authorize);

View File

@@ -1607,7 +1607,6 @@ Thanks and regards,
{ path: `/users/${otherUserId}`, method: 'DELETE' },
{ path: '/account/delete', method: 'POST' },
{ path: '/account/reset-progress', method: 'POST' },
{ path: '/user/get-session-user', method: 'GET' },
{ path: '/user/user-token', method: 'DELETE' },
{ path: '/user/user-token', method: 'POST' },
{ path: '/user/ms-username', method: 'DELETE' },
@@ -1625,6 +1624,18 @@ Thanks and regards,
expect(response.statusCode).toBe(401);
});
});
describe('/user/get-session-user', () => {
test('GET returns 200 with empty user object for unauthenticated users', async () => {
const response = await superRequest('/user/get-session-user', {
method: 'GET',
setCookies
});
expect(response.statusCode).toBe(200);
expect(response.body).toStrictEqual({ user: {}, result: '' });
});
});
});
});

View File

@@ -661,13 +661,21 @@ export const userGetRoutes: FastifyPluginCallbackTypebox = (
// This is one of the most requested routes. To avoid spamming the logs
// with this route, we'll log requests at the debug level.
logger.debug({ userId: req.user?.id });
// Handle unauthenticated users - this is not an error, it's how the client
// determines if they are signed in or not
if (!req.user?.id) {
logger.debug('Unauthenticated user requested session');
return { user: {}, result: '' };
}
try {
const userTokenP = fastify.prisma.userToken.findFirst({
where: { userId: req.user!.id }
where: { userId: req.user.id }
});
const userP = fastify.prisma.user.findUnique({
where: { id: req.user!.id },
where: { id: req.user.id },
select: {
about: true,
acceptedPrivacyTerms: true,
@@ -738,11 +746,11 @@ export const userGetRoutes: FastifyPluginCallbackTypebox = (
});
const completedSurveysP = fastify.prisma.survey.findMany({
where: { userId: req.user!.id }
where: { userId: req.user.id }
});
const msUsernameP = fastify.prisma.msUsername.findFirst({
where: { userId: req.user?.id }
where: { userId: req.user.id }
});
const [userToken, user, completedSurveys, msUsername] =