diff --git a/server/src/__tests__/invite-join-grants.test.ts b/server/src/__tests__/invite-join-grants.test.ts index 0b3becaffc9..fae007e059d 100644 --- a/server/src/__tests__/invite-join-grants.test.ts +++ b/server/src/__tests__/invite-join-grants.test.ts @@ -1,5 +1,8 @@ import { describe, expect, it } from "vitest"; -import { agentJoinGrantsFromDefaults } from "../services/invite-grants.js"; +import { + agentJoinGrantsFromDefaults, + humanJoinGrantsFromDefaults, +} from "../services/invite-grants.js"; import { grantsForHumanRole, normalizeHumanRole, @@ -86,4 +89,33 @@ describe("human invite roles", () => { }), ).toBe("viewer"); }); + + it("falls back to role grants when human invite defaults omit explicit grants", () => { + expect(humanJoinGrantsFromDefaults(null, "operator")).toEqual([ + { permissionKey: "tasks:assign", scope: null }, + ]); + }); + + it("preserves explicit human invite grants", () => { + expect( + humanJoinGrantsFromDefaults( + { + human: { + grants: [ + { + permissionKey: "users:invite", + scope: { companyId: "company-1" }, + }, + ], + }, + }, + "operator", + ), + ).toEqual([ + { + permissionKey: "users:invite", + scope: { companyId: "company-1" }, + }, + ]); + }); }); diff --git a/server/src/routes/access.ts b/server/src/routes/access.ts index ee4f6b5ac2e..c86637caf04 100644 --- a/server/src/routes/access.ts +++ b/server/src/routes/access.ts @@ -61,6 +61,7 @@ import { normalizeHumanRole, resolveHumanInviteRole, } from "../services/company-member-roles.js"; +import { humanJoinGrantsFromDefaults } from "../services/invite-grants.js"; import { collapseDuplicatePendingHumanJoinRequests, findReusableHumanJoinRequest, @@ -3359,9 +3360,9 @@ export function accessRoutes( membershipRole, "active" ); - const grants = grantsFromDefaults( + const grants = humanJoinGrantsFromDefaults( invite.defaultsPayload as Record | null, - "human" + membershipRole ); await access.setPrincipalGrants( companyId, diff --git a/server/src/services/invite-grants.ts b/server/src/services/invite-grants.ts index e31d910fb8c..32c9aa42fe1 100644 --- a/server/src/services/invite-grants.ts +++ b/server/src/services/invite-grants.ts @@ -1,4 +1,6 @@ import { PERMISSION_KEYS } from "@paperclipai/shared"; +import type { HumanCompanyMembershipRole } from "@paperclipai/shared"; +import { grantsForHumanRole } from "./company-member-roles.js"; export function grantsFromDefaults( defaultsPayload: Record | null | undefined, @@ -53,3 +55,14 @@ export function agentJoinGrantsFromDefaults( }, ]; } + +export function humanJoinGrantsFromDefaults( + defaultsPayload: Record | null | undefined, + membershipRole: HumanCompanyMembershipRole +): Array<{ + permissionKey: (typeof PERMISSION_KEYS)[number]; + scope: Record | null; +}> { + const grants = grantsFromDefaults(defaultsPayload, "human"); + return grants.length > 0 ? grants : grantsForHumanRole(membershipRole); +}