Public Access
The token is no longer stored; a tbp_session flag remembers the login. apiFetch renews the session once on a 401 and sends the request again. Parallel requests and other tabs share one refresh, because Auth revokes the session when a refresh token is used twice. Only a 401 from the refresh ends the session; a 502 or no network shows the normal error.
48 lines
1.5 KiB
JavaScript
48 lines
1.5 KiB
JavaScript
// @vitest-environment jsdom
|
|
import {afterEach, describe, expect, it} from 'vitest';
|
|
import {clearSession, hasSession, markSession, safeReturnPath, sessionStamp} from './auth.js';
|
|
|
|
afterEach(() => localStorage.clear());
|
|
|
|
describe('session flag', () => {
|
|
it('is set by a login and removed by clearSession', () => {
|
|
expect(hasSession()).toBe(false);
|
|
|
|
markSession();
|
|
expect(hasSession()).toBe(true);
|
|
|
|
clearSession();
|
|
expect(hasSession()).toBe(false);
|
|
});
|
|
|
|
it('removes the token of the old localStorage login', () => {
|
|
localStorage.setItem('tbp_jwt', 'old');
|
|
markSession();
|
|
expect(localStorage.getItem('tbp_jwt')).toBeNull();
|
|
|
|
localStorage.setItem('tbp_jwt', 'old');
|
|
clearSession();
|
|
expect(localStorage.getItem('tbp_jwt')).toBeNull();
|
|
});
|
|
|
|
it('gives a new stamp on every mark', async () => {
|
|
markSession();
|
|
const first = sessionStamp();
|
|
await new Promise((resolve) => setTimeout(resolve, 2));
|
|
markSession();
|
|
|
|
expect(sessionStamp()).not.toBe(first);
|
|
});
|
|
});
|
|
|
|
describe('safeReturnPath', () => {
|
|
it.each(['/library?status=PLAYING', '/library/220', '/settings'])('keeps the internal path %s', (path) => {
|
|
expect(safeReturnPath(path)).toBe(path);
|
|
});
|
|
|
|
it.each([undefined, null, '', 'library', '//evil.example', '/\\evil.example', '/\t/evil.example', '/\n/evil.example', 'https://evil.example', '/login', '/login?x=1'])(
|
|
'rejects %j', (path) => {
|
|
expect(safeReturnPath(path)).toBeNull();
|
|
});
|
|
});
|