mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-04-28 22:00:47 -04:00
feat(api): add :email unsubscribe/:email to the deprecated (#50497)
Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com>
This commit is contained in:
@@ -32,6 +32,8 @@ export const getCsrfToken = (setCookies: string[]): string | undefined => {
|
||||
return csrfToken;
|
||||
};
|
||||
|
||||
export const ORIGIN = 'https://www.freecodecamp.org';
|
||||
|
||||
export function superRequest(
|
||||
resource: string,
|
||||
config: {
|
||||
@@ -43,10 +45,7 @@ export function superRequest(
|
||||
const { method, setCookies } = config;
|
||||
const { sendCSRFToken = true } = options ?? {};
|
||||
|
||||
const req = requests[method](resource).set(
|
||||
'Origin',
|
||||
'https://www.freecodecamp.org'
|
||||
);
|
||||
const req = requests[method](resource).set('Origin', ORIGIN);
|
||||
|
||||
if (setCookies) {
|
||||
void req.set('Cookie', setCookies);
|
||||
|
||||
@@ -21,6 +21,7 @@ import cors from './plugins/cors';
|
||||
import jwtAuthz from './plugins/fastify-jwt-authz';
|
||||
import security from './plugins/security';
|
||||
import sessionAuth from './plugins/session-auth';
|
||||
import redirectWithMessage from './plugins/redirect-with-message';
|
||||
import { settingRoutes } from './routes/settings';
|
||||
import { deprecatedEndpoints } from './routes/deprecated-endpoints';
|
||||
import { auth0Routes, devLoginCallback } from './routes/auth';
|
||||
@@ -42,6 +43,7 @@ import {
|
||||
import { userRoutes } from './routes/user';
|
||||
import { donateRoutes } from './routes/donate';
|
||||
import { statusRoute } from './routes/status';
|
||||
import { unsubscribeDeprecated } from './routes/deprecated-unsubscribe';
|
||||
|
||||
export type FastifyInstanceWithTypeProvider = FastifyInstance<
|
||||
RawServerDefault,
|
||||
@@ -172,6 +174,8 @@ export const build = async (
|
||||
void fastify.register(userRoutes);
|
||||
void fastify.register(deprecatedEndpoints);
|
||||
void fastify.register(statusRoute);
|
||||
void fastify.register(unsubscribeDeprecated);
|
||||
void fastify.register(redirectWithMessage);
|
||||
|
||||
return fastify;
|
||||
};
|
||||
|
||||
@@ -1,23 +1,14 @@
|
||||
import request from 'supertest';
|
||||
|
||||
import { build } from '../app';
|
||||
import { setupServer } from '../../jest.utils';
|
||||
import { endpoints } from './deprecated-endpoints';
|
||||
|
||||
describe('Deprecated endpoints', () => {
|
||||
let fastify: undefined | Awaited<ReturnType<typeof build>>;
|
||||
|
||||
beforeAll(async () => {
|
||||
fastify = await build();
|
||||
await fastify.ready();
|
||||
}, 20000);
|
||||
|
||||
afterAll(async () => {
|
||||
await fastify?.close();
|
||||
});
|
||||
setupServer();
|
||||
|
||||
endpoints.forEach(([endpoint, method]) => {
|
||||
test(`${method} ${endpoint} returns 410 status code with "info" message`, async () => {
|
||||
const response = await request(fastify?.server)[
|
||||
const response = await request(fastifyTestInstance.server)[
|
||||
method.toLowerCase() as 'get' | 'post'
|
||||
](endpoint);
|
||||
|
||||
|
||||
25
api/src/routes/deprecated-unsubscribe.test.ts
Normal file
25
api/src/routes/deprecated-unsubscribe.test.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { setupServer, superRequest } from '../../jest.utils';
|
||||
|
||||
import { unsubscribeEndpoints } from './deprecated-unsubscribe';
|
||||
|
||||
const urlEncodedMessage =
|
||||
'?messages=info%5B0%5D%3DWe%2520are%2520no%2520longer%2520able%2520to%2520process%2520this%2520unsubscription%2520request.%2520Please%2520go%2520to%2520your%2520settings%2520to%2520update%2520your%2520email%2520preferences';
|
||||
|
||||
describe('Deprecated unsubscribeEndpoints', () => {
|
||||
setupServer();
|
||||
|
||||
unsubscribeEndpoints.forEach(([endpoint, method]) => {
|
||||
test(`${method} ${endpoint} redirects to referer with "info" message`, async () => {
|
||||
const response = await superRequest(endpoint, { method }).set(
|
||||
'Referer',
|
||||
'https://www.freecodecamp.org/settings'
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
expect(response.headers.location).toStrictEqual(
|
||||
'https://www.freecodecamp.org/settings' + urlEncodedMessage
|
||||
);
|
||||
expect(response.status).toBe(302);
|
||||
});
|
||||
});
|
||||
});
|
||||
34
api/src/routes/deprecated-unsubscribe.ts
Normal file
34
api/src/routes/deprecated-unsubscribe.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { FastifyPluginCallbackTypebox } from '@fastify/type-provider-typebox';
|
||||
import { HOME_LOCATION } from '../utils/env';
|
||||
|
||||
type Endpoint = [string, 'GET' | 'POST'];
|
||||
|
||||
export const unsubscribeEndpoints: Endpoint[] = [
|
||||
['/u/:email', 'GET'],
|
||||
['/unsubscribe/:email', 'GET']
|
||||
];
|
||||
|
||||
export const unsubscribeDeprecated: FastifyPluginCallbackTypebox = (
|
||||
fastify,
|
||||
_options,
|
||||
done
|
||||
) => {
|
||||
unsubscribeEndpoints.forEach(([endpoint, method]) => {
|
||||
fastify.route({
|
||||
method,
|
||||
url: endpoint,
|
||||
handler: async (req, reply) => {
|
||||
// TODO: port over getRedirectParams from api-server anduser that
|
||||
const origin = req.headers.referer ?? HOME_LOCATION;
|
||||
void reply.redirectWithMessage(origin, {
|
||||
type: 'info',
|
||||
content:
|
||||
'We are no longer able to process this unsubscription request. ' +
|
||||
'Please go to your settings to update your email preferences'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
done();
|
||||
};
|
||||
Reference in New Issue
Block a user