Backend/frontend hardening & consistency cleanups (#1113)

* refactor(auth): session token validation and password-change consistency

* refactor(journey): entry field allow-list and public share-link consistency

* refactor(mcp): align tool authorization with the REST permission checks

* chore: input validation and sanitisation touch-ups (uploads, pdf, maps, backup, csp)
This commit is contained in:
Maurice
2026-06-06 16:37:03 +02:00
committed by GitHub
parent 070ef01328
commit 093e069ccc
41 changed files with 653 additions and 74 deletions
+17
View File
@@ -134,6 +134,23 @@ describe('authenticate', () => {
expect(next).not.toHaveBeenCalled();
expect(status).toHaveBeenCalledWith(401);
});
it('AUTH-MW-007: rejects a purpose-scoped mfa_login token even when the user is valid', () => {
// The token issued after the password check but before TOTP is signed with
// the same secret. It must never authenticate a normal request, otherwise
// password alone grants full access and MFA is bypassed.
const mockUser = { id: 1, username: 'alice', email: 'alice@example.com', role: 'user', password_version: 0 };
vi.mocked(db.prepare).mockReturnValue({ get: vi.fn(() => mockUser), all: vi.fn() } as any);
const mfaToken = jwt.sign({ id: 1, purpose: 'mfa_login', pv: 0 }, 'test-secret', { algorithm: 'HS256' });
const next = vi.fn() as unknown as NextFunction;
const { res, status } = makeRes();
authenticate(makeReq({ headers: { authorization: `Bearer ${mfaToken}` } }), res, next);
expect(next).not.toHaveBeenCalled();
expect(status).toHaveBeenCalledWith(401);
});
});
// ── adminOnly ─────────────────────────────────────────────────────────────────