diff --git a/api/src/plugins/service-bearer-auth.test.ts b/api/src/plugins/service-bearer-auth.test.ts index 500fbd1d5c6..fadaf9c8666 100644 --- a/api/src/plugins/service-bearer-auth.test.ts +++ b/api/src/plugins/service-bearer-auth.test.ts @@ -88,4 +88,56 @@ describe('service-bearer-auth plugin', () => { expect(res.statusCode).toEqual(401); expect(res.json()).toEqual({ error: 'Invalid bearer token' }); }); + + test('should return 401 when bearer token is the same length but wrong', async () => { + const sameLengthWrongToken = 'x'.repeat('test-api-secret-key'.length); + const res = await fastify.inject({ + method: 'GET', + url: '/test', + headers: { + authorization: `Bearer ${sameLengthWrongToken}` + } + }); + + expect(res.statusCode).toEqual(401); + expect(res.json()).toEqual({ error: 'Invalid bearer token' }); + }); +}); + +describe('service-bearer-auth plugin without a configured token', () => { + afterEach(() => { + vi.doUnmock('../utils/env'); + vi.resetModules(); + }); + + test('should return 500 when TPA_API_BEARER_TOKEN is not configured', async () => { + vi.resetModules(); + vi.doMock('../utils/env', async importOriginal => { + const actual = await importOriginal(); + return { ...actual, TPA_API_BEARER_TOKEN: '' }; + }); + + const { default: plugin } = await import('./service-bearer-auth.js'); + const fastify = Fastify(); + await fastify.register(plugin); + fastify.addHook('onRequest', fastify.validateBearerToken); + fastify.get('/test', (_req, reply) => { + void reply.send({ ok: true }); + }); + + const res = await fastify.inject({ + method: 'GET', + url: '/test', + headers: { + authorization: 'Bearer anything' + } + }); + + expect(res.statusCode).toEqual(500); + expect(res.json()).toEqual({ + error: 'Service authentication not configured' + }); + + await fastify.close(); + }); }); diff --git a/api/src/plugins/service-bearer-auth.ts b/api/src/plugins/service-bearer-auth.ts index 8398ee7d33f..552bd4450a4 100644 --- a/api/src/plugins/service-bearer-auth.ts +++ b/api/src/plugins/service-bearer-auth.ts @@ -38,9 +38,11 @@ const plugin: FastifyPluginCallback = (fastify, _options, done) => { } const token = authHeader.slice(7); + const tokenBuf = Buffer.from(token); + const secretBuf = Buffer.from(secret); if ( - token.length !== secret.length || - !crypto.timingSafeEqual(Buffer.from(token), Buffer.from(secret)) + tokenBuf.length !== secretBuf.length || + !crypto.timingSafeEqual(tokenBuf, secretBuf) ) { await reply.status(401).send({ error: 'Invalid bearer token' }); return; diff --git a/api/src/routes/protected/user.test.ts b/api/src/routes/protected/user.test.ts index aa96400cce8..f18542f3ae8 100644 --- a/api/src/routes/protected/user.test.ts +++ b/api/src/routes/protected/user.test.ts @@ -210,7 +210,8 @@ const sessionOnlyData = { theme: testUserData.theme, keyboardShortcuts: testUserData.keyboardShortcuts, completedChallengeCount: 3, - acceptedPrivacyTerms: testUserData.acceptedPrivacyTerms + acceptedPrivacyTerms: testUserData.acceptedPrivacyTerms, + isClassroomAccount: testUserData.isClassroomAccount ?? false }; const publicUserData = { @@ -281,7 +282,6 @@ const publicUserData = { isApisMicroservicesCert: testUserData.isApisMicroservicesCert, isBackEndCert: testUserData.isBackEndCert, isCheater: testUserData.isCheater, - isClassroomAccount: testUserData.isClassroomAccount ?? false, isCollegeAlgebraPyCertV8: testUserData.isCollegeAlgebraPyCertV8, isDataAnalysisPyCertV7: testUserData.isDataAnalysisPyCertV7, isDataVisCert: testUserData.isDataVisCert, diff --git a/api/src/routes/public/user.test.ts b/api/src/routes/public/user.test.ts index 071b84cd266..2eb4d198408 100644 --- a/api/src/routes/public/user.test.ts +++ b/api/src/routes/public/user.test.ts @@ -204,7 +204,6 @@ const publicUserData = { isApisMicroservicesCert: testUserData.isApisMicroservicesCert, isBackEndCert: testUserData.isBackEndCert, isCheater: testUserData.isCheater, - isClassroomAccount: testUserData.isClassroomAccount ?? false, isCollegeAlgebraPyCertV8: testUserData.isCollegeAlgebraPyCertV8, isDataAnalysisPyCertV7: testUserData.isDataAnalysisPyCertV7, isDataVisCert: testUserData.isDataVisCert, diff --git a/api/src/schemas/users/get-public-profile.ts b/api/src/schemas/users/get-public-profile.ts index fb963563f11..20ed3e2ec05 100644 --- a/api/src/schemas/users/get-public-profile.ts +++ b/api/src/schemas/users/get-public-profile.ts @@ -68,7 +68,6 @@ export const getPublicProfile = { isFrontEndLibsCert: Type.Boolean(), isFullStackCert: Type.Boolean(), isJavascriptCertV9: Type.Boolean(), - isClassroomAccount: Type.Boolean(), isHonest: Type.Boolean(), isInfosecCertV7: Type.Boolean(), isInfosecQaCert: Type.Boolean(),