mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat(api): add user id to user report (#59816)
This commit is contained in:
@@ -13,7 +13,8 @@ import {
|
||||
devLogin,
|
||||
setupServer,
|
||||
superRequest,
|
||||
createSuperRequest
|
||||
createSuperRequest,
|
||||
defaultUsername
|
||||
} from '../../../jest.utils';
|
||||
import { JWT_SECRET } from '../../utils/env';
|
||||
import {
|
||||
@@ -802,29 +803,25 @@ describe('userRoutes', () => {
|
||||
reportDescription: 'Test Report'
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(400);
|
||||
expect(response.statusCode).toBe(404);
|
||||
expect(response.body).toStrictEqual({
|
||||
type: 'danger',
|
||||
message: 'flash.provide-username'
|
||||
message: 'flash.report-error'
|
||||
});
|
||||
});
|
||||
|
||||
test('POST returns 400 for empty report', async () => {
|
||||
const response = await superPost('/user/report-user').send({
|
||||
username: 'darth-vader',
|
||||
username: testUserData.username,
|
||||
reportDescription: ''
|
||||
});
|
||||
|
||||
expect(response.statusCode).toBe(400);
|
||||
expect(response.body).toStrictEqual({
|
||||
type: 'danger',
|
||||
message: 'flash.provide-username'
|
||||
});
|
||||
});
|
||||
|
||||
test('POST sanitises report description', async () => {
|
||||
await superPost('/user/report-user').send({
|
||||
username: 'darth-vader',
|
||||
username: defaultUsername,
|
||||
reportDescription:
|
||||
'<script>const breath = "loud"</script>Luke, I am your father'
|
||||
});
|
||||
@@ -846,7 +843,7 @@ describe('userRoutes', () => {
|
||||
}
|
||||
);
|
||||
const response = await superPost('/user/report-user').send({
|
||||
username: 'darth-vader',
|
||||
username: testUser.username,
|
||||
reportDescription: 'Luke, I am your father'
|
||||
});
|
||||
|
||||
@@ -855,11 +852,11 @@ describe('userRoutes', () => {
|
||||
from: 'team@freecodecamp.org',
|
||||
to: 'support@freecodecamp.org',
|
||||
cc: 'foo@bar.com',
|
||||
subject: "Abuse Report : Reporting darth-vader's profile.",
|
||||
subject: `Abuse Report : Reporting ${testUser.username}'s profile.`,
|
||||
text: `
|
||||
Hello Team,
|
||||
|
||||
This is to report the profile of darth-vader.
|
||||
This is to report the profile of ${testUser.username}. ID: ${defaultUserId}.
|
||||
|
||||
Report Details:
|
||||
|
||||
@@ -867,6 +864,7 @@ Luke, I am your father
|
||||
|
||||
|
||||
Reported by:
|
||||
ID: ${testUser.id}
|
||||
Username: ${testUser.username}
|
||||
Name:
|
||||
Email: foo@bar.com
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
normalizeTwitter,
|
||||
removeNulls
|
||||
} from '../../utils/normalize';
|
||||
import type { UpdateReqType } from '../../utils';
|
||||
import { mapErr, type UpdateReqType } from '../../utils';
|
||||
import {
|
||||
getCalendar,
|
||||
getPoints,
|
||||
@@ -176,21 +176,45 @@ export const userRoutes: FastifyPluginCallbackTypebox = (
|
||||
});
|
||||
const { username, reportDescription: report } = req.body;
|
||||
|
||||
if (!username || !report) {
|
||||
logger.warn('Missing username or reportDescription');
|
||||
void reply.code(400);
|
||||
// TODO: `findUnique` once db migration forces unique usernames
|
||||
const maybeReportedUsers = await mapErr(
|
||||
fastify.prisma.user.findMany({
|
||||
where: { username }
|
||||
})
|
||||
);
|
||||
|
||||
if (maybeReportedUsers.hasError) {
|
||||
logger.error(
|
||||
{ error: maybeReportedUsers.error, username },
|
||||
'Error finding reported user.'
|
||||
);
|
||||
fastify.Sentry.captureException(maybeReportedUsers.error);
|
||||
void reply.code(500);
|
||||
return {
|
||||
type: 'danger',
|
||||
message: 'flash.provide-username'
|
||||
message: 'flash.generic-error'
|
||||
} as const;
|
||||
}
|
||||
|
||||
const reportedUsers = maybeReportedUsers.data;
|
||||
|
||||
if (reportedUsers.length !== 1) {
|
||||
logger.warn({ username }, 'Reported user not found');
|
||||
void reply.code(404);
|
||||
return {
|
||||
type: 'danger',
|
||||
message: 'flash.report-error'
|
||||
} as const;
|
||||
}
|
||||
|
||||
const reportedUser = reportedUsers[0]!;
|
||||
|
||||
await fastify.sendEmail({
|
||||
from: 'team@freecodecamp.org',
|
||||
to: 'support@freecodecamp.org',
|
||||
cc: user.email,
|
||||
subject: `Abuse Report : Reporting ${username}'s profile.`,
|
||||
text: generateReportEmail(user, username, report)
|
||||
subject: `Abuse Report : Reporting ${reportedUser.username}'s profile.`,
|
||||
text: generateReportEmail(user, reportedUser, report)
|
||||
});
|
||||
|
||||
return {
|
||||
|
||||
@@ -4,7 +4,7 @@ import { genericError } from '../types';
|
||||
export const reportUser = {
|
||||
body: Type.Object({
|
||||
username: Type.String(),
|
||||
reportDescription: Type.String()
|
||||
reportDescription: Type.String({ minLength: 1 })
|
||||
}),
|
||||
response: {
|
||||
200: Type.Object({
|
||||
@@ -14,10 +14,10 @@ export const reportUser = {
|
||||
email: Type.String()
|
||||
})
|
||||
}),
|
||||
400: Type.Object({
|
||||
404: Type.Object({
|
||||
type: Type.Literal('danger'),
|
||||
message: Type.Literal('flash.provide-username')
|
||||
message: Type.Literal('flash.report-error')
|
||||
}),
|
||||
default: genericError
|
||||
500: genericError
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,13 +9,13 @@ import { user } from '@prisma/client';
|
||||
*/
|
||||
export const generateReportEmail = (
|
||||
reporter: user,
|
||||
abuser: string,
|
||||
abuser: user,
|
||||
reportDesc: string
|
||||
) => {
|
||||
return `
|
||||
Hello Team,
|
||||
|
||||
This is to report the profile of ${abuser}.
|
||||
This is to report the profile of ${abuser.username}. ID: ${abuser.id}.
|
||||
|
||||
Report Details:
|
||||
|
||||
@@ -23,10 +23,11 @@ ${reportDesc}
|
||||
|
||||
|
||||
Reported by:
|
||||
ID: ${reporter.id}
|
||||
Username: ${reporter.username}
|
||||
Name:${reporter.name ? ' ' + reporter.name : ''}
|
||||
Email: ${reporter.email}
|
||||
|
||||
Thanks and regards,
|
||||
${reporter.name ?? ''}`;
|
||||
${reporter.name ?? reporter.username}`;
|
||||
};
|
||||
|
||||
@@ -905,6 +905,7 @@
|
||||
"unlink-success": "You've successfully unlinked your {{website}}",
|
||||
"provide-username": "Check if you have provided a username and a report",
|
||||
"report-sent": "A report was sent to the team with {{email}} in copy",
|
||||
"report-error": "Unable to report this user at this time.",
|
||||
"certificate-missing": "The certification you tried to view does not exist",
|
||||
"create-token-err": "An error occurred while creating your user token",
|
||||
"delete-token-err": "An error occurred while deleting your user token",
|
||||
|
||||
Reference in New Issue
Block a user