const assert = require("node:assert/strict"); const test = require("node:test"); const { authorizeCoachingRoute, clientAccessWhere, isAdministratorUser, isClientUser, isStaffUser, requireStaff, } = require("../src/security/coachingAuthorization"); function user(role) { return { id: `${role}-id`, app_role: { name: role } }; } function response() { return { body: null, statusCode: null, status(code) { this.statusCode = code; return this; }, send(body) { this.body = body; return this; }, }; } test("role helpers classify workspace roles", () => { assert.equal(isAdministratorUser(user("Administrator")), true); assert.equal(isAdministratorUser(user("Workspace Owner")), true); assert.equal(isAdministratorUser(user("Coach")), false); assert.equal(isStaffUser(user("Coach")), true); assert.equal(isStaffUser(user("Assistant")), true); assert.equal(isClientUser(user("Client")), true); }); test("client scope follows the deployment role policy", () => { assert.deepEqual(clientAccessWhere(user("Administrator")), {}); assert.deepEqual(clientAccessWhere(user("Workspace Owner")), {}); assert.deepEqual(clientAccessWhere(user("Coach")), { ownerId: "Coach-id" }); assert.deepEqual(clientAccessWhere(user("Assistant")), { ownerId: "Assistant-id" }); assert.deepEqual(clientAccessWhere(user("Client")), { id: null }); }); test("client is rejected from coach-only endpoints", () => { const res = response(); let nextCalled = false; requireStaff({ currentUser: user("Client") }, res, () => { nextCalled = true; }); assert.equal(nextCalled, false); assert.equal(res.statusCode, 403); assert.deepEqual(res.body, { error: "coach_only" }); }); test("staff is allowed through coach-only endpoints", () => { for (const role of ["Administrator", "Workspace Owner", "Coach", "Assistant"]) { const res = response(); let nextCalled = false; requireStaff({ currentUser: user(role) }, res, () => { nextCalled = true; }); assert.equal(nextCalled, true, role); assert.equal(res.statusCode, null, role); } }); test("client can use only the client-portal coaching namespace", () => { for (const path of ["/client-portal/me", "/client-portal/client-id", "/client-portal/action-items/item-id"]) { const res = response(); let nextCalled = false; authorizeCoachingRoute({ path, currentUser: user("Client") }, res, () => { nextCalled = true; }); assert.equal(nextCalled, true, path); } for (const path of ["/clients", "/intake-leads", "/session-memory", "/sessions/session-id/audio"]) { const res = response(); let nextCalled = false; authorizeCoachingRoute({ path, currentUser: user("Client") }, res, () => { nextCalled = true; }); assert.equal(nextCalled, false, path); assert.equal(res.statusCode, 403, path); } });