Files
chat/api/server/iamConfig.spec.js
zeekayandHanzo Dev a57771c05a Name the box for what it carries, not for whose it is
The shell hands the browser its IAM identity in a global that was called
__HANZO_IAM__. Every value inside it was already correct — on lux.chat it reads
serverUrl https://lux.id, clientId lux-chat, organization lux — so the last
thing saying "Hanzo" on a Lux page was the name we picked for the container, and
it is visible in view-source on the customer's own domain.

That is the same class as a wrong mark or a wrong link, spelled as an
identifier. __IAM__ says what it holds and belongs to no brand.

Renamed at both ends in one change, because a half-rename does not degrade —
it breaks login outright: the writer would publish a name the reader never
looks up, every visitor would fall through to the bundle's compiled default,
and lux.chat would send its customers to hanzo.id as hanzo-chat with a
redirect_uri that client has never registered. There are exactly six sites and
no others: the writer, the reader, two assertions and two comments.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-10 20:37:49 -07:00

63 lines
2.2 KiB
JavaScript

const { iamConfig, injectIamConfig } = require('./iamConfig');
const HTML = '<html><head><title>t</title></head><body><script type="module" src="/a.js"></script></body></html>';
describe('iamConfig', () => {
const saved = { ...process.env };
beforeEach(() => {
delete process.env.OPENID_ISSUER;
delete process.env.OPENID_CLIENT_ID;
delete process.env.OPENID_ORG;
});
afterAll(() => {
process.env = saved;
});
/* The whole point of the per-key shape: a deployment that states nothing must
behave exactly as it did before this existed, so the compiled defaults in
the bundle stay in charge. */
it('states nothing when the environment states nothing', () => {
expect(iamConfig()).toBeNull();
expect(injectIamConfig(HTML)).toBe(HTML);
});
it('omits a key rather than emitting it empty', () => {
process.env.OPENID_ISSUER = 'https://lux.id';
expect(iamConfig()).toEqual({ serverUrl: 'https://lux.id' });
});
it('reads the same variables the backend strategy registers with', () => {
process.env.OPENID_ISSUER = 'https://lux.id';
process.env.OPENID_CLIENT_ID = 'lux-chat';
process.env.OPENID_ORG = 'lux';
expect(iamConfig()).toEqual({
serverUrl: 'https://lux.id',
clientId: 'lux-chat',
organization: 'lux',
});
});
/* Ahead of the module scripts, which are declared in <body>. OAuthCallback
reads this before any config request exists, so it cannot be a fetch. */
it('injects ahead of the module scripts', () => {
process.env.OPENID_ISSUER = 'https://lux.id';
const out = injectIamConfig(HTML);
expect(out.indexOf('__IAM__')).toBeLessThan(out.indexOf('type="module"'));
expect(out).toContain('</script></head>');
});
it('cannot close its own script element', () => {
process.env.OPENID_CLIENT_ID = 'x</script><script>alert(1)';
const out = injectIamConfig(HTML);
expect(out).not.toContain('x</script>');
expect(out).toContain('\\u003c/script');
});
it('still delivers the config when there is no head to anchor to', () => {
process.env.OPENID_ISSUER = 'https://lux.id';
expect(injectIamConfig('<body>x</body>')).toContain('__IAM__');
});
});