4c6b1e38b1
theta42/proxy fronts an arbitrary number of hosts behind SSO, each with its own callback URL (https://<host>/__proxy_auth/callback) — proxy's own code comment already assumed "a wildcard redirect URI covers all", but no wildcard matching existed here, so every proxied host's callback had to be registered on the shared OAuth client individually or /oauth/authorize would reject it with InvalidRedirectURI. Add `*` (one hostname label) / `**` (any number of labels) wildcard support to redirect_uri matching, e.g. `https://**.example.com/__proxy_auth/callback` now covers every host proxy fronts under example.com. Exact matches still work exactly as before. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
67 lines
2.2 KiB
JavaScript
67 lines
2.2 KiB
JavaScript
'use strict';
|
|
|
|
const { redirectUriAllowed } = require('../routes/oauth');
|
|
|
|
// Pure logic, no LDAP/Redis needed -- regression coverage for the bug where
|
|
// theta42/proxy's per-host SSO callback (a different URL per proxied host,
|
|
// e.g. https://site.example.com/__proxy_auth/callback) could never match a
|
|
// single OAuth client's redirect_uris list without registering every host's
|
|
// callback individually. `*`/`**` wildcard support lets one registered
|
|
// pattern (e.g. https://*.example.com/__proxy_auth/callback) cover a whole
|
|
// domain's worth of proxied hosts.
|
|
describe('redirectUriAllowed', () => {
|
|
test('exact match still works with no wildcard present', () => {
|
|
expect(redirectUriAllowed(
|
|
['https://app.example.com/cb'],
|
|
'https://app.example.com/cb'
|
|
)).toBe(true);
|
|
});
|
|
|
|
test('rejects a uri that is not registered', () => {
|
|
expect(redirectUriAllowed(
|
|
['https://app.example.com/cb'],
|
|
'https://app.example.com/cb2'
|
|
)).toBe(false);
|
|
});
|
|
|
|
test('* matches exactly one hostname label', () => {
|
|
expect(redirectUriAllowed(
|
|
['https://*.example.com/__proxy_auth/callback'],
|
|
'https://site.example.com/__proxy_auth/callback'
|
|
)).toBe(true);
|
|
});
|
|
|
|
test('* does not span multiple labels', () => {
|
|
expect(redirectUriAllowed(
|
|
['https://*.example.com/__proxy_auth/callback'],
|
|
'https://site.nl.example.com/__proxy_auth/callback'
|
|
)).toBe(false);
|
|
});
|
|
|
|
test('** spans multiple labels', () => {
|
|
expect(redirectUriAllowed(
|
|
['https://**.example.com/__proxy_auth/callback'],
|
|
'https://site.nl.example.com/__proxy_auth/callback'
|
|
)).toBe(true);
|
|
});
|
|
|
|
test('scheme mismatch is not allowed even with a wildcard', () => {
|
|
expect(redirectUriAllowed(
|
|
['https://*.example.com/__proxy_auth/callback'],
|
|
'http://site.example.com/__proxy_auth/callback'
|
|
)).toBe(false);
|
|
});
|
|
|
|
test('a wildcard pattern does not match an unrelated domain', () => {
|
|
expect(redirectUriAllowed(
|
|
['https://**.example.com/__proxy_auth/callback'],
|
|
'https://evil.com/__proxy_auth/callback'
|
|
)).toBe(false);
|
|
});
|
|
|
|
test('empty/missing patterns list rejects everything', () => {
|
|
expect(redirectUriAllowed([], 'https://app.example.com/cb')).toBe(false);
|
|
expect(redirectUriAllowed(undefined, 'https://app.example.com/cb')).toBe(false);
|
|
});
|
|
});
|