Files
baron_qa_write/tests/worker-logout.test.js
root beaa2fc423
Deploy EG-BIM QA Gateway / deploy (push) Successful in 54s
feat: add account menu and redirect after Q&A logout
Add the top-right account icon with the signed-in name and logout link. Expire the Q&A session before redirecting to the configured inquiry homepage in both environments. Preserve login return URL checks and ignore request-controlled logout destinations.

Validation: 106 tests, syntax checks, and mocked Chromium desktop/mobile regressions pass, including session-cookie removal and the destination navigation request with external networking blocked.
2026-11-02 14:18:23 +09:00

45 lines
2.3 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
import worker from '../src/index.js';
const destination = 'https://test.baroncs.co.kr/ko/sw-inquiry.html';
for (const configFile of ['wrangler.toml', 'wrangler.production.toml']) {
test(configFile + ' logout expires its own session and redirects to the inquiry homepage', async () => {
const config = readFileSync(new URL('../' + configFile, import.meta.url), 'utf8');
const setting = name => config.match(new RegExp('^' + name + ' = "([^"]+)"', 'm'))[1];
const env = {
SESSION_COOKIE_NAME: setting('SESSION_COOKIE_NAME'),
AUTH_POST_LOGOUT_REDIRECT_URI: setting('AUTH_POST_LOGOUT_REDIRECT_URI')
};
const response = await worker.fetch(new Request('https://qa.example.test/auth/logout?return_url=https://untrusted.example/&redirect_uri=https://untrusted.example/', {
headers: { cookie: env.SESSION_COOKIE_NAME + '=existing-session' }
}), env);
assert.equal(response.status, 302);
assert.equal(response.headers.get('location'), destination);
const cookie = response.headers.get('set-cookie');
assert.ok(cookie.startsWith(env.SESSION_COOKIE_NAME + '=;'));
for (const attribute of ['Max-Age=0', 'Path=/', 'Secure', 'HttpOnly', 'SameSite=Lax', 'Expires=Thu, 01 Jan 1970 00:00:00 GMT']) assert.ok(cookie.includes(attribute));
assert.match(response.headers.get('cache-control'), /no-store/);
});
}
for (const [label, value, expected] of [
['no configured destination', undefined, '/'],
['same-origin relative destination', '/signed-out', '/signed-out'],
['invalid URL', 'https://[invalid', '/'],
['script URL', 'javascript:alert(1)', '/'],
['external insecure URL', 'http://untrusted.example/', '/'],
['URL containing credentials', 'https://user:pass@untrusted.example/', '/']
]) {
test('logout handles ' + label + ' while clearing the session', async () => {
const response = await worker.fetch(new Request('https://qa.example.test/auth/logout'), {
SESSION_COOKIE_NAME: 'fixture_session', AUTH_POST_LOGOUT_REDIRECT_URI: value
});
assert.equal(response.status, 302);
assert.equal(response.headers.get('location'), 'https://qa.example.test' + expected);
assert.match(response.headers.get('set-cookie'), /fixture_session=; Max-Age=0/);
});
}