mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
fix(api): skip picture validation when unchanged (#64868)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> Co-authored-by: Shaun Hamilton <shauhami020@gmail.com>
This commit is contained in:
@@ -991,6 +991,75 @@ Happy coding!
|
||||
expect(response.body).toEqual(updateErrorResponse);
|
||||
expect(response.statusCode).toEqual(400);
|
||||
});
|
||||
|
||||
test('PUT allows updating location/about when picture is unchanged (even without extension)', async () => {
|
||||
// Simulate a user who already has a GitHub avatar URL saved (e.g., from before strict validation)
|
||||
const githubAvatarUrl =
|
||||
'https://avatars0.githubusercontent.com/u/34585031?v=4';
|
||||
await fastifyTestInstance.prisma.user.update({
|
||||
where: { id: defaultUserId },
|
||||
data: {
|
||||
picture: githubAvatarUrl,
|
||||
about: 'Initial about',
|
||||
name: 'Test User',
|
||||
location: 'Initial Location'
|
||||
}
|
||||
});
|
||||
|
||||
// Now update only location and about, keeping the same picture (no extension)
|
||||
const updateResponse = await superPut('/update-my-about').send({
|
||||
about: 'Updated about text',
|
||||
name: 'Test User',
|
||||
location: 'New Location',
|
||||
picture: githubAvatarUrl // Same URL, no extension - should skip validation
|
||||
});
|
||||
|
||||
expect(updateResponse.body).toEqual({
|
||||
message: 'flash.updated-about-me',
|
||||
type: 'success'
|
||||
});
|
||||
expect(updateResponse.statusCode).toEqual(200);
|
||||
|
||||
const user = await fastifyTestInstance?.prisma.user.findFirst({
|
||||
where: { email: 'foo@bar.com' }
|
||||
});
|
||||
|
||||
expect(user?.about).toEqual('Updated about text');
|
||||
expect(user?.location).toEqual('New Location');
|
||||
expect(user?.picture).toEqual(githubAvatarUrl);
|
||||
});
|
||||
|
||||
test('PUT still validates picture when it is actually changed', async () => {
|
||||
// Set initial valid picture
|
||||
const validPictureUrl = 'https://example.com/avatar.png';
|
||||
await superPut('/update-my-about').send({
|
||||
about: 'Initial',
|
||||
name: 'Test',
|
||||
location: 'Location',
|
||||
picture: validPictureUrl
|
||||
});
|
||||
|
||||
// Try to change picture to invalid URL (no extension)
|
||||
const updateResponse = await superPut('/update-my-about').send({
|
||||
about: 'Initial',
|
||||
name: 'Test',
|
||||
location: 'Location',
|
||||
picture: 'https://example.com/new-avatar' // Changed but invalid
|
||||
});
|
||||
|
||||
expect(updateResponse.statusCode).toEqual(400);
|
||||
expect(updateResponse.body).toEqual({
|
||||
message: 'flash.wrong-updating',
|
||||
type: 'danger'
|
||||
});
|
||||
|
||||
// Verify picture wasn't updated
|
||||
const user = await fastifyTestInstance?.prisma.user.findFirst({
|
||||
where: { email: 'foo@bar.com' }
|
||||
});
|
||||
|
||||
expect(user?.picture).toEqual(validPictureUrl);
|
||||
});
|
||||
});
|
||||
|
||||
describe('/update-my-honesty', () => {
|
||||
|
||||
@@ -523,11 +523,16 @@ ${isLinkSentWithinLimitTTL}`
|
||||
},
|
||||
async (req, reply) => {
|
||||
const logger = fastify.log.child({ req, res: reply });
|
||||
const pictureIsValid = isValidPictureUrl(req.body.picture);
|
||||
if (!pictureIsValid) {
|
||||
logger.warn(`Invalid picture URL: ${req.body.picture}`);
|
||||
void reply.code(400);
|
||||
return { message: 'flash.wrong-updating', type: 'danger' } as const;
|
||||
|
||||
// No need to validate if picture is being deleted.
|
||||
if (req.body.picture) {
|
||||
if (req.body.picture !== req.user!.picture) {
|
||||
if (!isValidPictureUrl(req.body.picture)) {
|
||||
logger.warn(`Invalid picture URL: ${req.body.picture}`);
|
||||
void reply.code(400);
|
||||
return { message: 'flash.wrong-updating', type: 'danger' } as const;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user