Add single-user local authentication
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import { test } from 'node:test';
|
||||
import { emit, field, find, install, nodes, server, settle } from './flow-helpers.mjs';
|
||||
|
||||
const ui = install();
|
||||
const { api, setUnauthorizedHandler } = await import('../../bindery/static/js/lib.js');
|
||||
const { stopPolling } = await import('../../bindery/static/js/jobs.js');
|
||||
|
||||
test('local login, retry, session expiry and logout use the existing form', async (t) => {
|
||||
t.mock.timers.enable({ apis: ['setTimeout'] });
|
||||
const backend = server(t);
|
||||
let auth = { authenticated: false, mode: 'local', user: null };
|
||||
backend.on('GET', 'auth/check', () => auth);
|
||||
backend.on('GET', 'config', { metadata_fields: {}, mode_labels: {}, library_available: false });
|
||||
backend.on('GET', 'stories', []);
|
||||
backend.on('GET', 'jobs', []);
|
||||
backend.on('GET', 'expired', { error: 'Session ended' }, 401);
|
||||
backend.on('POST', 'auth/logout', () => { auth = { ...auth, authenticated: false, user: null }; return {}; });
|
||||
t.after(() => { stopPolling(); setUnauthorizedHandler(() => {}); });
|
||||
await import('../../bindery/static/js/main.js');
|
||||
await settle();
|
||||
assert.match(ui.app.textContent, /Log in with your Bindery account/);
|
||||
assert.doesNotMatch(ui.app.textContent, /CWA account/);
|
||||
assert.equal(document.activeElement, field(ui.app, 'username'));
|
||||
assert.equal(backend.sent('GET', 'config').length, 0);
|
||||
const form = () => nodes(ui.app).find((el) => el.tagName === 'form');
|
||||
field(ui.app, 'username').value = 'reader';
|
||||
field(ui.app, 'password').value = 'wrong';
|
||||
backend.on('POST', 'auth/login', { error: 'Wrong user name or password' }, 401);
|
||||
await emit(form(), 'submit');
|
||||
assert.match(ui.app.textContent, /Wrong user name or password/);
|
||||
assert.equal(find(ui.app, 'button', 'Log in').disabled, false);
|
||||
assert.deepEqual(backend.sent('POST', 'auth/login')[0].body, { username: 'reader', password: 'wrong', remember: true });
|
||||
field(ui.app, 'password').value = 'correct';
|
||||
nodes(form()).find((el) => el.attributes.type === 'checkbox').checked = false;
|
||||
backend.on('POST', 'auth/login', () => { auth = { authenticated: true, mode: 'local', user: 'reader' }; return {}; });
|
||||
await emit(form(), 'submit');
|
||||
await settle();
|
||||
assert.ok(find(ui.app, 'button', 'Log out'));
|
||||
assert.match(ui.app.textContent, /reader/);
|
||||
const request = backend.sent('POST', 'auth/login')[1];
|
||||
assert.deepEqual(request.body, { username: 'reader', password: 'correct', remember: false });
|
||||
assert.equal(request.headers['X-Requested-With'], 'bindery');
|
||||
auth = { ...auth, authenticated: false };
|
||||
await assert.rejects(api('expired'), /Session ended/);
|
||||
await settle();
|
||||
assert.ok(find(ui.app, 'button', 'Log in'));
|
||||
const polls = backend.sent('GET', 'jobs').length;
|
||||
t.mock.timers.tick(60000);
|
||||
await settle();
|
||||
assert.equal(backend.sent('GET', 'jobs').length, polls);
|
||||
await emit(form(), 'submit');
|
||||
await settle();
|
||||
await emit(find(ui.app, 'button', 'Log out'), 'click');
|
||||
await settle();
|
||||
assert.equal(backend.sent('POST', 'auth/logout').length, 1);
|
||||
assert.ok(find(ui.app, 'button', 'Log in'));
|
||||
});
|
||||
Reference in New Issue
Block a user