How the freeCodeCamp User Reporting System Handles Blocked Users
The freeCodeCamp user reporting system prevents blocked entities from submitting abuse reports by rejecting automated scripts at the routing layer with HTTP 400 errors and intercepting suspended accounts at the authentication layer via Auth0 redirects.
The freeCodeCamp open-source platform maintains strict access controls to prevent abuse of its reporting infrastructure. According to the freeCodeCamp/freeCodeCamp source code, the user reporting system handles blocked users through two distinct defense mechanisms that operate before any protected endpoint logic executes.
Two Layers of Blocking Protection
The platform implements complementary blocking strategies at different architectural layers to ensure neither automated scripts nor suspended human accounts can file reports.
Blocking Automated User Agents at the API Layer
Before any authentication occurs, the public API routes filter out known automation tools. In api/src/routes/public/user.ts (lines 95–118), the system inspects the incoming request's User-Agent header against a blocklist:
blockedUserAgentParts = ['python', 'google-apps-script', 'curl']
If the user agent string contains any of these substrings, the route immediately returns HTTP 400 and terminates the request. This prevents scripted attacks from ever reaching the reporting logic or consuming authentication resources.
Suspending Accounts via Auth0 Authentication
For human accounts disabled by the moderation team, the blocking occurs during the authentication phase. The Auth0 plugin located in api/src/plugins/auth0.ts (lines 113–119) validates the user's status during the JWT verification process.
If the account is marked as blocked in Auth0, the plugin executes:
reply.redirect(`${HOME_LOCATION}/blocked`)
This redirects the browser to the /blocked page before issuing a valid token. Because the reporting endpoint requires authentication, a suspended user cannot obtain the necessary JWT to reach the protected route.
End-to-End Reporting Flow for Legitimate Users
When a reporter passes both blocking layers, the system processes their submission through a coordinated client-server flow.
Client-Side Report Initiation
The reporting process begins in the React/Redux client layer. The UI dispatches the reportUser action defined in client/src/redux/actions.ts (lines 82–84). The createReportUserSaga in client/src/redux/report-user-saga.js (lines 8–16) intercepts this action and executes postReportUser:
function* createReportUserSaga({ payload }) {
try {
yield call(postReportUser, payload);
yield put(createFlashMessage({ type: 'success', message: 'flash.report-sent' }));
} catch (e) {
yield put(handleError(e));
}
}
On success, the saga triggers a flash message confirming the report was sent.
Server-Side Validation and Processing
The protected endpoint at /user/report-user in api/src/routes/protected/user.ts handles the actual submission. The route first validates the payload against schemas.reportUser defined in api/src/schemas/user/report-user.ts (lines 4–27), which enforces required fields like username and reason.
The handler logic (lines 74–124) then:
- Looks up the reported user by username, returning 404 if not found
- Composes an email to
support@freecodecamp.orgCC'ing the reporter - Returns the
flash.report-sentpayload to confirm receipt
Summary
- Blocked user agents (Python scripts, curl, Google Apps Script) receive an immediate HTTP 400 rejection at the public route level in
api/src/routes/public/user.ts - Blocked accounts are redirected to
/blockedby the Auth0 plugin inapi/src/plugins/auth0.tsbefore obtaining authentication tokens - Legitimate users flow through Redux sagas to a protected endpoint that validates input, verifies the target user exists, and emails support@freecodecamp.org
- The architecture ensures reporting capabilities are inaccessible to both automated tools and suspended human accounts
Frequently Asked Questions
What happens if a blocked user tries to access the reporting endpoint directly?
A blocked user cannot successfully call the reporting endpoint. Automated tools are rejected at the network layer by user agent filtering in api/src/routes/public/user.ts, while suspended accounts are intercepted by the Auth0 plugin in api/src/plugins/auth0.ts and redirected to /blocked before receiving a valid JWT.
Which specific user agents are blocked from accessing freeCodeCamp's API?
The system blocks requests containing python, google-apps-script, or curl in their User-Agent header. This blocklist is defined in api/src/routes/public/user.ts and returns HTTP 400 for any matching request.
How does the system validate report submissions from legitimate users?
Legitimate submissions are validated against the schemas.reportUser schema in api/src/schemas/user/report-user.ts, which enforces required fields and data types. The protected route handler in api/src/routes/protected/user.ts also verifies that the reported username exists in the database before processing.
Where does the report data go once a legitimate user submits it?
The system sends an email to support@freecodecamp.org with the abuse details, CC'ing the reporter's email address. The client receives a flash.report-sent confirmation message via the Redux saga in client/src/redux/report-user-saga.js.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →