mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-06-03 10:01:47 -04:00
fix(api): byte-safe bearer auth, hide classroom flag
This commit is contained in:
@@ -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<typeof import('../utils/env.js')>();
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(),
|
||||
|
||||
Reference in New Issue
Block a user