[grade=B] fix(auth): generalize cross-host SSO handoff
Codex deployment review: urn:ump:sufisot7ewy33mhjude3ly6wxcjizagt42ywaicwve6qufqdtvbq Caddy path-order correction: urn:ump:o6apvvpvhynkouii4cl5ghxpprrwtilrg2dejdy2lqsupoktc6tq
This commit is contained in:
@@ -7,6 +7,23 @@ const test = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
|
||||
const source = fs.readFileSync(path.join(__dirname, '..', 'js', 'auth-gate.js'), 'utf8');
|
||||
const totpSource = fs.readFileSync(path.join(__dirname, '..', 'js', 'totp-auth.js'), 'utf8');
|
||||
|
||||
function buildHandoffTarget(returnUrl, token, tld = '.sami') {
|
||||
const start = totpSource.indexOf(' function buildSsoHandoffTarget');
|
||||
const end = totpSource.indexOf('\n\n // Setup digit input UX', start);
|
||||
assert.notEqual(start, -1, 'handoff builder must exist');
|
||||
assert.notEqual(end, -1, 'handoff builder boundary must exist');
|
||||
const functionSource = totpSource.slice(start, end);
|
||||
const context = {
|
||||
URL,
|
||||
SITE: { tld },
|
||||
window: { location: { origin: 'https://status.sami' } },
|
||||
};
|
||||
const sandbox = { ...context, input: returnUrl, token, result: undefined };
|
||||
vm.runInNewContext(`${functionSource}\nresult = buildSsoHandoffTarget(input, token);`, sandbox);
|
||||
return sandbox.result;
|
||||
}
|
||||
|
||||
function capturedRedirect(returnUrl, tld = '.sami') {
|
||||
const stored = new Map();
|
||||
@@ -59,3 +76,20 @@ test('accepts relative same-origin paths and protocol-relative HTTPS private hos
|
||||
test('normalizes a configured TLD without a leading dot', () => {
|
||||
assert.equal(capturedRedirect('https://plex.sami/web/', 'sami'), 'https://plex.sami/web/');
|
||||
});
|
||||
|
||||
test('builds the generic cross-host SSO landing URL and preserves the final path', () => {
|
||||
assert.equal(
|
||||
buildHandoffTarget('https://router.sami/config?tab=network#dns', 'one-time'),
|
||||
'https://router.sami/dashcaddy-sso?token=one-time&return=%2Fconfig%3Ftab%3Dnetwork%23dns',
|
||||
);
|
||||
});
|
||||
|
||||
test('does not create cross-host handoffs for plaintext or lookalike destinations', () => {
|
||||
assert.equal(buildHandoffTarget('http://router.sami/', 'one-time'), null);
|
||||
assert.equal(buildHandoffTarget('https://router.sami.evil.example/', 'one-time'), null);
|
||||
});
|
||||
|
||||
test('same-origin and tokenless destinations keep their direct URL', () => {
|
||||
assert.equal(buildHandoffTarget('/settings', 'one-time'), 'https://status.sami/settings');
|
||||
assert.equal(buildHandoffTarget('https://router.sami/config', ''), 'https://router.sami/config');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user