Compare commits

..

2 Commits

Author SHA1 Message Date
Julien Gautier 986c3acea1 fix(portal-bff): add portal-admin :4300 to CORS_ALLOWED_ORIGINS in .env.example
CI / commits (pull_request) Successful in 2m51s
CI / scan (pull_request) Successful in 3m0s
CI / check (pull_request) Successful in 3m9s
CI / a11y (pull_request) Successful in 3m2s
CI / perf (pull_request) Successful in 6m19s
Caught while reviewing the previous port-correction commit on this
branch. The CORS section still pointed to "Add :4201 once portal-admin
grows its own dev server" — but portal-admin has its dev server (on
:4300, not :4201), and the SPA will hit the BFF with credentials as
soon as the admin auth flow lands. Without the origin in the allowlist
the browser blocks the call and the developer chases a CORS error
instead of getting to work.

Updates the example to list both dev origins and points at
`apps/<app>/project.json` `serve.options.port` as the source of truth
so future readers don't have to grep for it.

Local `.env` is on the developer to update — this only touches
`.env.example`. Behaviour change is opt-in.
2026-05-14 15:37:04 +02:00
Julien Gautier 2604ed3efd fix(portal-bff): use the real portal-admin dev port (4300) in admin-flow references
PR #129 baked `4201` into a few comments and test fixtures as the
admin SPA's dev port. The actual port wired in
`apps/portal-admin/project.json` `serve.options.port` is `4300` — the
Nx serve target listens on 4300 in dev. Aligning the references so a
contributor reading `.env.example` or the test fixtures sees the same
number their browser is hitting.

Touched:
- `apps/portal-bff/.env.example` — `ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI`
  default + the surrounding comment.
- `apps/portal-bff/src/config/check-cors-allowlist.ts` — stale
  doc-comment that pre-dated the portal-admin scaffolding.
- `auth.module.spec.ts`, `auth.controller.spec.ts`,
  `auth.service.spec.ts`, `admin-auth.controller.spec.ts`,
  `check-entra-config.spec.ts` — fixture `adminPostLogoutRedirectUri`
  values. Tests don't depend on the port; aligned for clarity only.

No behaviour change. 278 specs still pass.
2026-05-14 15:28:32 +02:00
7 changed files with 15 additions and 12 deletions
+7 -5
View File
@@ -67,9 +67,10 @@ ENTRA_POST_LOGOUT_REDIRECT_URI=http://localhost:4200/
# session. Both `ENTRA_REDIRECT_URI` and `ENTRA_ADMIN_REDIRECT_URI` # session. Both `ENTRA_REDIRECT_URI` and `ENTRA_ADMIN_REDIRECT_URI`
# must be registered in the same Entra app registration's # must be registered in the same Entra app registration's
# "Redirect URIs" list. Distinct post-logout URL routes admin # "Redirect URIs" list. Distinct post-logout URL routes admin
# sign-outs to the admin SPA's landing page (port 4201 in dev). # sign-outs to the admin SPA's landing page (port 4300 in dev — see
# apps/portal-admin/project.json `serve.options.port`).
ENTRA_ADMIN_REDIRECT_URI=http://localhost:3000/api/admin/auth/callback ENTRA_ADMIN_REDIRECT_URI=http://localhost:3000/api/admin/auth/callback
ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI=http://localhost:4201/ ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI=http://localhost:4300/
# Cookie signing secret (per ADR-0009 §"Cookies"). Used to sign the # Cookie signing secret (per ADR-0009 §"Cookies"). Used to sign the
# transient pre-auth cookie that carries the OIDC `state` + PKCE # transient pre-auth cookie that carries the OIDC `state` + PKCE
@@ -132,9 +133,10 @@ LOG_USER_ID_SALT=replace_with_32_random_bytes_base64url
# defaulting to localhost is the classic "works in dev, breaks in # defaulting to localhost is the classic "works in dev, breaks in
# prod" trap. # prod" trap.
# #
# Local dev: the portal-shell dev server on :4200. Add :4201 once # Local dev: portal-shell on :4200 and portal-admin on :4300 — both
# portal-admin grows its own dev server. # call the BFF with credentials. Source of truth for the ports:
CORS_ALLOWED_ORIGINS=http://localhost:4200 # `apps/<app>/project.json` `serve.options.port`.
CORS_ALLOWED_ORIGINS=http://localhost:4200,http://localhost:4300
# Rate limiting (per ADR-0015 §"DoS mitigation"). Both optional # Rate limiting (per ADR-0015 §"DoS mitigation"). Both optional
# with conservative defaults; override per environment when traffic # with conservative defaults; override per environment when traffic
@@ -16,7 +16,7 @@ const ENTRA: EntraConfig = {
redirectUri: 'http://localhost:3000/api/auth/callback', redirectUri: 'http://localhost:3000/api/auth/callback',
postLogoutRedirectUri: 'http://localhost:4200/', postLogoutRedirectUri: 'http://localhost:4200/',
adminRedirectUri: 'http://localhost:3000/api/admin/auth/callback', adminRedirectUri: 'http://localhost:3000/api/admin/auth/callback',
adminPostLogoutRedirectUri: 'http://localhost:4201/', adminPostLogoutRedirectUri: 'http://localhost:4300/',
authority: 'https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', authority: 'https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
}; };
@@ -17,7 +17,7 @@ const ENTRA: EntraConfig = {
redirectUri: 'http://localhost:3000/api/auth/callback', redirectUri: 'http://localhost:3000/api/auth/callback',
postLogoutRedirectUri: 'http://localhost:4200/', postLogoutRedirectUri: 'http://localhost:4200/',
adminRedirectUri: 'http://localhost:3000/api/admin/auth/callback', adminRedirectUri: 'http://localhost:3000/api/admin/auth/callback',
adminPostLogoutRedirectUri: 'http://localhost:4201/', adminPostLogoutRedirectUri: 'http://localhost:4300/',
authority: 'https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', authority: 'https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
}; };
+1 -1
View File
@@ -43,7 +43,7 @@ const VALID = {
ENTRA_REDIRECT_URI: 'http://localhost:3000/api/auth/callback', ENTRA_REDIRECT_URI: 'http://localhost:3000/api/auth/callback',
ENTRA_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4200/', ENTRA_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4200/',
ENTRA_ADMIN_REDIRECT_URI: 'http://localhost:3000/api/admin/auth/callback', ENTRA_ADMIN_REDIRECT_URI: 'http://localhost:3000/api/admin/auth/callback',
ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4201/', ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4300/',
// Well-formed but unreachable Redis URL — `ioredis` opens the // Well-formed but unreachable Redis URL — `ioredis` opens the
// socket lazily so the module compiles without any network access. // socket lazily so the module compiles without any network access.
REDIS_URL: 'redis://default:test-pass@127.0.0.1:65535/0', REDIS_URL: 'redis://default:test-pass@127.0.0.1:65535/0',
@@ -12,7 +12,7 @@ const ENTRA: EntraConfig = {
redirectUri: 'http://localhost:3000/api/auth/callback', redirectUri: 'http://localhost:3000/api/auth/callback',
postLogoutRedirectUri: 'http://localhost:4200/', postLogoutRedirectUri: 'http://localhost:4200/',
adminRedirectUri: 'http://localhost:3000/api/admin/auth/callback', adminRedirectUri: 'http://localhost:3000/api/admin/auth/callback',
adminPostLogoutRedirectUri: 'http://localhost:4201/', adminPostLogoutRedirectUri: 'http://localhost:4300/',
authority: 'https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee', authority: 'https://login.microsoftonline.com/aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
}; };
@@ -21,8 +21,9 @@
* Production should set `CORS_ALLOWED_ORIGINS` to the SPA / admin * Production should set `CORS_ALLOWED_ORIGINS` to the SPA / admin
* SPA's deploy origins (e.g. * SPA's deploy origins (e.g.
* `https://portal.apf.example,https://admin.portal.apf.example`). * `https://portal.apf.example,https://admin.portal.apf.example`).
* Dev `.env` lists `http://localhost:4200` (and 4201 once * Dev `.env` lists `http://localhost:4200` (portal-shell) and
* portal-admin grows a dev server). * `http://localhost:4300` (portal-admin) — see
* apps/portal-admin/project.json `serve.options.port`.
*/ */
export function readCorsAllowlist(): readonly string[] { export function readCorsAllowlist(): readonly string[] {
const raw = process.env['CORS_ALLOWED_ORIGINS']; const raw = process.env['CORS_ALLOWED_ORIGINS'];
@@ -8,7 +8,7 @@ const VALID = {
ENTRA_REDIRECT_URI: 'http://localhost:3000/api/auth/callback', ENTRA_REDIRECT_URI: 'http://localhost:3000/api/auth/callback',
ENTRA_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4200/', ENTRA_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4200/',
ENTRA_ADMIN_REDIRECT_URI: 'http://localhost:3000/api/admin/auth/callback', ENTRA_ADMIN_REDIRECT_URI: 'http://localhost:3000/api/admin/auth/callback',
ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4201/', ENTRA_ADMIN_POST_LOGOUT_REDIRECT_URI: 'http://localhost:4300/',
}; };
describe('assertEntraConfig', () => { describe('assertEntraConfig', () => {