The provisioned IdP client (https://auth.forgecore.work) is confidential rather than public/PKCE-only, so a client secret must never reach the browser. The frontend now only performs the Authorization Code + PKCE redirect itself (hand-rolled PKCE, oidc-client-ts dependency removed) and hands the resulting code + verifier to a new, intentionally unauthenticated POST /api/v1/auth/session endpoint, which performs the code-for-tokens exchange server-side using OIDC_CLIENT_SECRET and returns only {accessToken, expiresIn} — refresh_token/id_token are never forwarded to the client. New required backend env vars: OIDC_CLIENT_ID, OIDC_CLIENT_SECRET. Added frontend/proxy.conf.json so the Angular dev server forwards /api and /health to the local API without needing CORS.
24 lines
800 B
TypeScript
24 lines
800 B
TypeScript
import { AuthSessionController } from './auth-session.controller';
|
|
|
|
describe('AuthSessionController', () => {
|
|
it('POST /auth/session exchanges the authorization code via the token exchange service', async () => {
|
|
const tokenExchange = {
|
|
exchangeAuthorizationCode: jest
|
|
.fn()
|
|
.mockResolvedValue({ accessToken: 'at-1', expiresIn: 3600 }),
|
|
};
|
|
const controller = new AuthSessionController(tokenExchange as never);
|
|
|
|
const dto = {
|
|
code: 'code-1',
|
|
codeVerifier: 'verifier-1',
|
|
redirectUri: 'http://localhost:4200/auth/callback',
|
|
};
|
|
await expect(controller.createSession(dto)).resolves.toEqual({
|
|
accessToken: 'at-1',
|
|
expiresIn: 3600,
|
|
});
|
|
expect(tokenExchange.exchangeAuthorizationCode).toHaveBeenCalledWith(dto);
|
|
});
|
|
});
|