99 lines
2.8 KiB
JavaScript
99 lines
2.8 KiB
JavaScript
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);
|
|
}
|
|
});
|