Move the Set-Cookie parser out of login/+page.server.ts into a shared module with its own Vitest coverage (single-header, multi-header getSetCookie path, missing-header, attribute-stripping, prefix-match-rejection). An Undici or Node upgrade that changes header shape now trips its own test instead of silently breaking login. Addresses PR #612 / Felix F2. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
39 lines
1.4 KiB
TypeScript
39 lines
1.4 KiB
TypeScript
import { describe, expect, it } from 'vitest';
|
|
import { extractFaSessionId } from './cookies';
|
|
|
|
describe('extractFaSessionId', () => {
|
|
it('extracts the opaque id from a single Set-Cookie header', () => {
|
|
const headers = ['fa_session=abc123; Path=/; HttpOnly; SameSite=Strict'];
|
|
expect(extractFaSessionId(headers)).toBe('abc123');
|
|
});
|
|
|
|
it('extracts the value when multiple Set-Cookie headers are present (getSetCookie path)', () => {
|
|
const headers = [
|
|
'JSESSIONID=legacy; Path=/',
|
|
'fa_session=xyz789; Path=/; Max-Age=28800; HttpOnly',
|
|
'XSRF-TOKEN=ignored; Path=/'
|
|
];
|
|
expect(extractFaSessionId(headers)).toBe('xyz789');
|
|
});
|
|
|
|
it('returns null when no header carries fa_session', () => {
|
|
expect(extractFaSessionId(['Other=foo; Path=/'])).toBeNull();
|
|
});
|
|
|
|
it('returns null for an empty header list', () => {
|
|
expect(extractFaSessionId([])).toBeNull();
|
|
});
|
|
|
|
it('strips all attributes after the first semicolon', () => {
|
|
const headers = ['fa_session=opaque-token-with.dots_and-dashes; Path=/; Secure; HttpOnly'];
|
|
expect(extractFaSessionId(headers)).toBe('opaque-token-with.dots_and-dashes');
|
|
});
|
|
|
|
it('only matches a cookie whose name is exactly fa_session', () => {
|
|
// A different cookie name that happens to contain "fa_session" as a substring
|
|
// must not match — anchored to start of header.
|
|
const headers = ['xfa_session=should-not-match; Path=/'];
|
|
expect(extractFaSessionId(headers)).toBeNull();
|
|
});
|
|
});
|