40464-vm/backend/test/liveIsolationMatrix.js
2026-07-22 15:25:42 +00:00

102 lines
4.8 KiB
JavaScript

const assert = require("node:assert/strict");
const crypto = require("node:crypto");
const jwt = require("jsonwebtoken");
const db = require("../src/db/models");
const config = require("../src/config");
db.sequelize.options.logging = false;
const ids = {
coachA: crypto.randomUUID(),
coachB: crypto.randomUUID(),
clientUserA: crypto.randomUUID(),
clientUserB: crypto.randomUUID(),
disabledClient: crypto.randomUUID(),
clientA: crypto.randomUUID(),
clientB: crypto.randomUUID(),
sessionA: crypto.randomUUID(),
sessionB: crypto.randomUUID(),
};
function tokenFor(user) {
return jwt.sign({ user: { id: user.id, email: user.email } }, config.secret_key, { expiresIn: "5m" });
}
async function api(path, user) {
return fetch(`http://127.0.0.1:3000/api/coaching${path}`, {
headers: { Authorization: `Bearer ${tokenFor(user)}` },
});
}
async function cleanup() {
await db.sessions.destroy({ where: { id: [ids.sessionA, ids.sessionB] }, force: true });
await db.clients.destroy({ where: { id: [ids.clientA, ids.clientB] }, force: true });
await db.users.destroy({
where: { id: [ids.coachA, ids.coachB, ids.clientUserA, ids.clientUserB, ids.disabledClient] },
force: true,
});
}
async function run() {
const coachRole = await db.roles.findOne({ where: { name: "Coach" } });
const clientRole = await db.roles.findOne({ where: { name: "Client" } });
const adminRole = await db.roles.findOne({ where: { name: "Administrator" } });
assert.ok(coachRole && clientRole && adminRole, "Required roles must exist");
const admin = await db.users.findOne({ where: { app_roleId: adminRole.id, disabled: false } });
assert.ok(admin, "An enabled Administrator fixture must exist");
const [coachA, coachB, clientUserA, clientUserB, disabledClient] = await Promise.all([
db.users.create({ id: ids.coachA, email: `fixture-coach-a-${ids.coachA}@example.invalid`, app_roleId: coachRole.id, emailVerified: true }),
db.users.create({ id: ids.coachB, email: `fixture-coach-b-${ids.coachB}@example.invalid`, app_roleId: coachRole.id, emailVerified: true }),
db.users.create({ id: ids.clientUserA, email: `fixture-client-a-${ids.clientUserA}@example.invalid`, app_roleId: clientRole.id, emailVerified: true }),
db.users.create({ id: ids.clientUserB, email: `fixture-client-b-${ids.clientUserB}@example.invalid`, app_roleId: clientRole.id, emailVerified: true }),
db.users.create({ id: ids.disabledClient, email: `fixture-disabled-${ids.disabledClient}@example.invalid`, app_roleId: clientRole.id, emailVerified: true, disabled: true }),
]);
await db.clients.bulkCreate([
{ id: ids.clientA, name: "Synthetic Client A", email: clientUserA.email, ownerId: coachA.id, portalUserId: clientUserA.id, notes: "private-a" },
{ id: ids.clientB, name: "Synthetic Client B", email: clientUserB.email, ownerId: coachB.id, portalUserId: clientUserB.id, notes: "private-b" },
]);
await db.sessions.bulkCreate([
{ id: ids.sessionA, clientId: ids.clientA, title: "Synthetic Session A", status: "shared", shared_client_notes: "safe-a", private_coach_notes: "private-a" },
{ id: ids.sessionB, clientId: ids.clientB, title: "Synthetic Session B", status: "shared", shared_client_notes: "safe-b", private_coach_notes: "private-b" },
]);
const coachAListResponse = await api("/clients", coachA);
assert.equal(coachAListResponse.status, 200);
const coachAList = await coachAListResponse.json();
assert.equal(coachAList.some((client) => client.id === ids.clientA), true);
assert.equal(coachAList.some((client) => client.id === ids.clientB), false);
assert.equal((await api(`/clients/${ids.clientB}`, coachA)).status, 404);
assert.equal((await api(`/sessions/${ids.sessionB}`, coachA)).status, 404);
assert.equal((await api(`/sessions/${ids.sessionB}/audio`, coachA)).status, 404);
const portalAResponse = await api("/client-portal/me", clientUserA);
assert.equal(portalAResponse.status, 200);
const portalA = await portalAResponse.json();
assert.equal(portalA.id, ids.clientA);
assert.equal(portalA.sessions.some((session) => session.id === ids.sessionB), false);
assert.equal(Object.prototype.hasOwnProperty.call(portalA, "notes"), false);
assert.equal((await api(`/client-portal/${ids.clientB}`, clientUserA)).status, 404);
assert.equal((await api(`/clients/${ids.clientA}`, clientUserA)).status, 403);
assert.equal((await api(`/clients/${ids.clientB}`, admin)).status, 200);
assert.equal((await api("/client-portal/me", disabledClient)).status, 401);
const loggedOut = await fetch("http://127.0.0.1:3000/api/coaching/clients");
assert.equal(loggedOut.status, 401);
console.log("live_isolation_matrix=passed");
}
run()
.finally(cleanup)
.then(() => db.sequelize.close())
.catch(async (error) => {
console.error(error);
await db.sequelize.close();
process.exitCode = 1;
});