mirror of
https://github.com/bulwarkmail/webmail.git
synced 2026-10-31 16:13:15 +00:00
The startup banner printed `/setup?token=...`, so the one-hour bootstrap token that grants the setup wizard landed in reverse-proxy access logs, Referer headers and browser history. The link now carries the token in the fragment, which never leaves the browser, and the wizard removes it from the address bar as soon as it reads it. Old `?token=` links still work and are cleaned up the same way.
30 lines
1.1 KiB
TypeScript
30 lines
1.1 KiB
TypeScript
import { describe, expect, it, vi } from 'vitest';
|
|
import { takeSetupTokenFromUrl } from '@/lib/setup/url-token';
|
|
|
|
function take(href: string) {
|
|
const url = new URL(href);
|
|
const history = { state: { k: 1 }, replaceState: vi.fn() };
|
|
const token = takeSetupTokenFromUrl(url, history);
|
|
return { token, history };
|
|
}
|
|
|
|
describe('takeSetupTokenFromUrl', () => {
|
|
it('reads the token from the fragment and clears it from the address bar', () => {
|
|
const { token, history } = take('https://mail.example/setup#token=abc123');
|
|
expect(token).toBe('abc123');
|
|
expect(history.replaceState).toHaveBeenCalledWith({ k: 1 }, '', '/setup');
|
|
});
|
|
|
|
it('still accepts the legacy query parameter and keeps other parameters', () => {
|
|
const { token, history } = take('https://mail.example/setup?lang=de&token=abc123');
|
|
expect(token).toBe('abc123');
|
|
expect(history.replaceState).toHaveBeenCalledWith({ k: 1 }, '', '/setup?lang=de');
|
|
});
|
|
|
|
it('leaves a URL without a token alone', () => {
|
|
const { token, history } = take('https://mail.example/setup?lang=de');
|
|
expect(token).toBe('');
|
|
expect(history.replaceState).not.toHaveBeenCalled();
|
|
});
|
|
});
|