mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
fix(api): use generic error message if CSRF error (#55264)
This commit is contained in:
committed by
GitHub
parent
512547e76c
commit
a22e90c10d
+4
-1
@@ -105,7 +105,10 @@ export const build = async (
|
||||
// test environments)
|
||||
skipInit: !SENTRY_DSN,
|
||||
errorResponse: (error, _request, reply) => {
|
||||
if (reply.statusCode === 500) {
|
||||
const isCSRFError =
|
||||
error.code === 'FST_CSRF_INVALID_TOKEN' ||
|
||||
error.code === 'FST_CSRF_MISSING_SECRET';
|
||||
if (reply.statusCode === 500 || isCSRFError) {
|
||||
void reply.send({
|
||||
message: 'flash.generic-error',
|
||||
type: 'danger'
|
||||
|
||||
@@ -396,8 +396,7 @@ export const challengeRoutes: FastifyPluginCallbackTypebox = (
|
||||
!multifileCertProjectIds.includes(challengeId) &&
|
||||
!multifilePythonCertProjectIds.includes(challengeId)
|
||||
) {
|
||||
void reply.code(403);
|
||||
return 'That challenge type is not saveable.';
|
||||
void reply.code(403).send('That challenge type is not saveable.');
|
||||
}
|
||||
|
||||
const userSavedChallenges = saveUserChallengeData(
|
||||
@@ -413,7 +412,7 @@ export const challengeRoutes: FastifyPluginCallbackTypebox = (
|
||||
}
|
||||
});
|
||||
|
||||
return { savedChallenges: userSavedChallenges };
|
||||
void reply.send({ savedChallenges: userSavedChallenges });
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -62,10 +62,8 @@ describe('settingRoutes', () => {
|
||||
});
|
||||
|
||||
expect(response.body).toEqual({
|
||||
code: 'FST_CSRF_MISSING_SECRET',
|
||||
error: 'Forbidden',
|
||||
message: 'Missing csrf secret',
|
||||
statusCode: 403
|
||||
message: 'flash.generic-error',
|
||||
type: 'danger'
|
||||
});
|
||||
expect(response.statusCode).toEqual(403);
|
||||
});
|
||||
@@ -76,10 +74,8 @@ describe('settingRoutes', () => {
|
||||
}).set('Cookie', ['_csrf=foo', 'csrf-token=bar']);
|
||||
|
||||
expect(response.body).toEqual({
|
||||
code: 'FST_CSRF_INVALID_TOKEN',
|
||||
error: 'Forbidden',
|
||||
message: 'Invalid csrf token',
|
||||
statusCode: 403
|
||||
message: 'flash.generic-error',
|
||||
type: 'danger'
|
||||
});
|
||||
expect(response.statusCode).toEqual(403);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { Certification } from '../../../../shared/config/certification-settings';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const certSlug = {
|
||||
params: Type.Object({
|
||||
@@ -120,6 +120,6 @@ export const certSlug = {
|
||||
})
|
||||
)
|
||||
}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500, isCertMap } from '../types';
|
||||
import { genericError, isCertMap } from '../types';
|
||||
|
||||
export const certificateVerify = {
|
||||
// TODO(POST_MVP): Remove partial validation from route for schema validation
|
||||
@@ -126,7 +126,8 @@ export const certificateVerify = {
|
||||
type: Type.Literal('danger'),
|
||||
message: Type.Literal('flash.went-wrong')
|
||||
}),
|
||||
generic500
|
||||
])
|
||||
genericError
|
||||
]),
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const backendChallengeCompleted = {
|
||||
body: Type.Object({
|
||||
@@ -17,6 +17,6 @@ export const backendChallengeCompleted = {
|
||||
'That does not appear to be a valid challenge submission.'
|
||||
)
|
||||
}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const coderoadChallengeCompleted = {
|
||||
body: Type.Object({
|
||||
@@ -15,6 +15,6 @@ export const coderoadChallengeCompleted = {
|
||||
type: Type.Literal('error'),
|
||||
msg: Type.String()
|
||||
}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { examResults } from '../types';
|
||||
import { examResults, genericError } from '../types';
|
||||
|
||||
export const examChallengeCompleted = {
|
||||
body: Type.Object({
|
||||
@@ -30,9 +30,12 @@ export const examChallengeCompleted = {
|
||||
400: Type.Object({
|
||||
error: Type.String()
|
||||
}),
|
||||
403: Type.Object({
|
||||
error: Type.String()
|
||||
}),
|
||||
403: Type.Union([
|
||||
Type.Object({
|
||||
error: Type.String()
|
||||
}),
|
||||
genericError
|
||||
]),
|
||||
500: Type.Object({
|
||||
error: Type.String()
|
||||
})
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const exam = {
|
||||
params: Type.Object({
|
||||
@@ -27,9 +28,12 @@ export const exam = {
|
||||
400: Type.Object({
|
||||
error: Type.String()
|
||||
}),
|
||||
403: Type.Object({
|
||||
error: Type.String()
|
||||
}),
|
||||
403: Type.Union([
|
||||
Type.Object({
|
||||
error: Type.String()
|
||||
}),
|
||||
genericError
|
||||
]),
|
||||
500: Type.Object({
|
||||
error: Type.String()
|
||||
})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500, savedChallenge } from '../types';
|
||||
import { genericError, savedChallenge } from '../types';
|
||||
|
||||
export const modernChallengeCompleted = {
|
||||
body: Type.Object({
|
||||
@@ -30,6 +30,6 @@ export const modernChallengeCompleted = {
|
||||
'That does not appear to be a valid challenge submission.'
|
||||
)
|
||||
}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const projectCompleted = {
|
||||
body: Type.Object({
|
||||
@@ -28,15 +28,20 @@ export const projectCompleted = {
|
||||
)
|
||||
])
|
||||
}),
|
||||
403: Type.Object({
|
||||
type: Type.Literal('error'),
|
||||
message: Type.Union([
|
||||
Type.Literal(
|
||||
'You have to complete the project before you can submit a URL.'
|
||||
),
|
||||
Type.Literal('That does not appear to be a valid challenge submission.')
|
||||
])
|
||||
}),
|
||||
500: generic500
|
||||
403: Type.Union([
|
||||
Type.Object({
|
||||
type: Type.Literal('error'),
|
||||
message: Type.Union([
|
||||
Type.Literal(
|
||||
'You have to complete the project before you can submit a URL.'
|
||||
),
|
||||
Type.Literal(
|
||||
'That does not appear to be a valid challenge submission.'
|
||||
)
|
||||
])
|
||||
}),
|
||||
genericError
|
||||
]),
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { file, generic500, savedChallenge } from '../types';
|
||||
import { file, genericError, savedChallenge } from '../types';
|
||||
|
||||
export const saveChallenge = {
|
||||
body: Type.Object({
|
||||
@@ -14,7 +14,16 @@ export const saveChallenge = {
|
||||
200: Type.Object({
|
||||
savedChallenges: Type.Array(savedChallenge)
|
||||
}),
|
||||
403: Type.Literal('That challenge type is not saveable.'),
|
||||
500: generic500
|
||||
400: Type.Object({
|
||||
message: Type.Literal(
|
||||
'That does not appear to be a valid challenge submission.'
|
||||
),
|
||||
type: Type.Literal('error')
|
||||
}),
|
||||
403: Type.Union([
|
||||
Type.Literal('That challenge type is not saveable.'),
|
||||
genericError
|
||||
]),
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const updateMyClassroomMode = {
|
||||
body: Type.Object({
|
||||
@@ -9,9 +10,12 @@ export const updateMyClassroomMode = {
|
||||
message: Type.Literal('flash.classroom-mode-updated'),
|
||||
type: Type.Literal('success')
|
||||
}),
|
||||
403: Type.Object({
|
||||
message: Type.Literal('flash.wrong-updating'),
|
||||
type: Type.Literal('danger')
|
||||
})
|
||||
403: Type.Union([
|
||||
Type.Object({
|
||||
message: Type.Literal('flash.wrong-updating'),
|
||||
type: Type.Literal('danger')
|
||||
}),
|
||||
genericError
|
||||
])
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
|
||||
export const generic500 = Type.Object({
|
||||
export const genericError = Type.Object({
|
||||
message: Type.Literal('flash.generic-error'),
|
||||
type: Type.Literal('danger')
|
||||
});
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const deleteMyAccount = {
|
||||
response: {
|
||||
200: Type.Object({}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const deleteUserToken = {
|
||||
response: {
|
||||
@@ -10,6 +10,6 @@ export const deleteUserToken = {
|
||||
message: Type.Literal('userToken not found'),
|
||||
type: Type.Literal('info')
|
||||
}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const postMsUsername = {
|
||||
body: Type.Object({
|
||||
@@ -16,10 +17,13 @@ export const postMsUsername = {
|
||||
type: Type.Literal('error'),
|
||||
message: Type.Literal('flash.ms.transcript.link-err-2')
|
||||
}),
|
||||
403: Type.Object({
|
||||
type: Type.Literal('error'),
|
||||
message: Type.Literal('flash.ms.transcript.link-err-4')
|
||||
}),
|
||||
403: Type.Union([
|
||||
Type.Object({
|
||||
type: Type.Literal('error'),
|
||||
message: Type.Literal('flash.ms.transcript.link-err-4')
|
||||
}),
|
||||
genericError
|
||||
]),
|
||||
500: Type.Union([
|
||||
Type.Object({
|
||||
type: Type.Literal('error'),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const reportUser = {
|
||||
body: Type.Object({
|
||||
@@ -18,6 +18,6 @@ export const reportUser = {
|
||||
type: Type.Literal('danger'),
|
||||
message: Type.Literal('flash.provide-username')
|
||||
}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { Type } from '@fastify/type-provider-typebox';
|
||||
import { generic500 } from '../types';
|
||||
import { genericError } from '../types';
|
||||
|
||||
export const resetMyProgress = {
|
||||
response: {
|
||||
200: Type.Object({}),
|
||||
500: generic500
|
||||
default: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -34,6 +34,8 @@ export const formatProjectCompletedValidation = (
|
||||
): FormattedError => {
|
||||
const error = getError(errors);
|
||||
|
||||
// TODO: split this into two functions. There's no need for it to handle both
|
||||
// /project-completed and /save-challenge
|
||||
return error.instancePath === '' &&
|
||||
error.params.missingProperty === 'solution'
|
||||
? {
|
||||
|
||||
Reference in New Issue
Block a user