From 87c274a9ef170218b88e9b6a1ddd030f9c64de2d Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Wed, 25 Jun 2025 08:30:24 +0200 Subject: [PATCH] feat(api): allow HOME_LOCATION origin in development (#61003) --- api/src/plugins/auth0.test.ts | 4 ++-- api/src/routes/public/signout.test.ts | 6 ++---- api/src/utils/allowed-origins.ts | 9 ++++++++- api/src/utils/redirection.test.ts | 8 ++++---- e2e/signout-modal.spec.ts | 4 ++-- 5 files changed, 18 insertions(+), 13 deletions(-) diff --git a/api/src/plugins/auth0.test.ts b/api/src/plugins/auth0.test.ts index 23a1466218c..0f7631b70f2 100644 --- a/api/src/plugins/auth0.test.ts +++ b/api/src/plugins/auth0.test.ts @@ -107,7 +107,7 @@ describe('auth0 plugin', () => { }); expect(res.headers.location).toMatch( - `${HOME_LOCATION}/learn?${formatMessage({ type: 'danger', content: 'flash.generic-error' })}` + `${HOME_LOCATION}/?${formatMessage({ type: 'danger', content: 'flash.generic-error' })}` ); expect(res.statusCode).toBe(302); }); @@ -119,7 +119,7 @@ describe('auth0 plugin', () => { }); expect(res.headers.location).toMatch( - `${HOME_LOCATION}/learn?${formatMessage({ type: 'danger', content: 'flash.generic-error' })}` + `${HOME_LOCATION}/?${formatMessage({ type: 'danger', content: 'flash.generic-error' })}` ); expect(res.statusCode).toBe(302); }); diff --git a/api/src/routes/public/signout.test.ts b/api/src/routes/public/signout.test.ts index 0079be4593e..6234432ac55 100644 --- a/api/src/routes/public/signout.test.ts +++ b/api/src/routes/public/signout.test.ts @@ -31,11 +31,9 @@ describe('GET /signout', () => { it('should redirect to / on the client by default', async () => { const res = await superRequest('/signout', { method: 'GET' }); - // This happens because localhost:8000 is not an allowed origin and so - // normalizeParams rejects it and sets the returnTo to /learn. TODO: - // separate the validation and normalization logic. + // TODO: separate the validation and normalization logic. // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access - expect(res.headers.location).toBe(`${HOME_LOCATION}/learn`); + expect(res.headers.location).toBe(`${HOME_LOCATION}/`); expect(res.status).toBe(302); }); }); diff --git a/api/src/utils/allowed-origins.ts b/api/src/utils/allowed-origins.ts index cc5b86e1fc5..e8f2e4ab404 100644 --- a/api/src/utils/allowed-origins.ts +++ b/api/src/utils/allowed-origins.ts @@ -1,4 +1,6 @@ -export const allowedOrigins = [ +import { HOME_LOCATION, FREECODECAMP_NODE_ENV } from './env'; + +const ALLOWED_ORIGINS = [ 'https://www.freecodecamp.dev', 'https://www.freecodecamp.org', // pretty sure the rest of these can go? @@ -7,3 +9,8 @@ export const allowedOrigins = [ 'https://chinese.freecodecamp.dev', 'https://chinese.freecodecamp.org' ]; + +export const allowedOrigins = + FREECODECAMP_NODE_ENV === 'development' + ? [...ALLOWED_ORIGINS, HOME_LOCATION] + : ALLOWED_ORIGINS; diff --git a/api/src/utils/redirection.test.ts b/api/src/utils/redirection.test.ts index 9b05982cc0a..6a3a0dadb69 100644 --- a/api/src/utils/redirection.test.ts +++ b/api/src/utils/redirection.test.ts @@ -182,13 +182,13 @@ describe('redirection', () => { expect(result).toEqual(expectedReturn); }); - it('should use HOME_LOCATION with missing referer', () => { + it('should returnTo the origin if the referer is missing', () => { const req = { headers: {} }; const expectedReturn = { - returnTo: `${HOME_LOCATION}/learn`, + returnTo: `${HOME_LOCATION}/`, origin: HOME_LOCATION, pathPrefix: '' }; @@ -197,7 +197,7 @@ describe('redirection', () => { expect(result).toEqual(expectedReturn); }); - it('should use HOME_LOCATION with invalid referrer', () => { + it('should returnTo the origin if the referrer is invalid', () => { const req = { headers: { referer: 'invalid-url' @@ -205,7 +205,7 @@ describe('redirection', () => { }; const expectedReturn = { - returnTo: `${HOME_LOCATION}/learn`, + returnTo: `${HOME_LOCATION}/`, origin: HOME_LOCATION, pathPrefix: '' }; diff --git a/e2e/signout-modal.spec.ts b/e2e/signout-modal.spec.ts index 4c90cc8542c..ee3d0b96e58 100644 --- a/e2e/signout-modal.spec.ts +++ b/e2e/signout-modal.spec.ts @@ -31,7 +31,7 @@ test.describe('Signout Modal component', () => { ).toBeVisible(); }); - test('signs out and redirects to /learn after user confirms they want to sign out', async ({ + test('signs out and redirects to / after user confirms they want to sign out', async ({ page }) => { await page.getByRole('button', { name: translations.buttons.menu }).click(); @@ -50,7 +50,7 @@ test.describe('Signout Modal component', () => { await expect( page.getByRole('dialog', { name: translations.signout.heading }) ).not.toBeVisible(); - await expect(page).toHaveURL(allowTrailingSlash('/learn')); + await expect(page).toHaveURL(allowTrailingSlash('')); }); test('closes modal after user cancels signing out', async ({ page }) => {