@fonderie/workspaces 6.0.0 → 6.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,6 +15,7 @@ new WorkspacesModule(store: IStoreAdapter, config?: IWorkspacesConfig, bus?: Eve
15
15
  interface IWorkspacesConfig {
16
16
  invitationTtl?: string;
17
17
  management?: 'owner-or-admin' | 'any-member';
18
+ managerRoles?: string[];
18
19
  personalWorkspace?: boolean;
19
20
  routes?: Partial<Record<WorkspaceRouteId, WorkspaceRouteOverride>>;
20
21
  }
package/dist/index.cjs CHANGED
@@ -468,6 +468,7 @@ function withWorkspace(store, ctx, next) {
468
468
  // src/middlewares/require-manager.ts
469
469
  var import_core2 = require("@fonderie/core");
470
470
  function requireManager(store, config) {
471
+ const managerRoles = config.managerRoles ?? ["ADMIN"];
471
472
  return async (ctx, next) => {
472
473
  if (config.management === "any-member") return next();
473
474
  if (!ctx.user) {
@@ -486,8 +487,9 @@ function requireManager(store, config) {
486
487
  AND ruw.suspended = false
487
488
  AND r.is_system = true
488
489
  AND r.active = true
490
+ AND r.name = ANY($3)
489
491
  LIMIT 1`,
490
- [ctx.user.id, ctx.workspace.id]
492
+ [ctx.user.id, ctx.workspace.id, managerRoles]
491
493
  );
492
494
  if (!row) {
493
495
  return (0, import_core2.setApiResponse)(
@@ -1394,6 +1396,25 @@ function invitationController(store, ttl, bus) {
1394
1396
  return (0, import_core6.setApiResponse)(import_core6.HTTP.SERVER_ERROR, "SERVER_ERROR", "Default role not found");
1395
1397
  }
1396
1398
  }
1399
+ const explicitRoleIds = [...new Set(
1400
+ entries.map((e) => e["roleId"]).filter((r) => typeof r === "string")
1401
+ )];
1402
+ if (explicitRoleIds.length > 0) {
1403
+ const rows = await store.query(
1404
+ `SELECT id FROM fonderie_roles
1405
+ WHERE id = ANY($1) AND workspace_id = $2 AND is_system = false`,
1406
+ [explicitRoleIds, ctx.workspace.id]
1407
+ );
1408
+ const assignable = new Set(rows.map((r) => r.id));
1409
+ const bad = explicitRoleIds.find((id) => !assignable.has(id));
1410
+ if (bad) {
1411
+ return (0, import_core6.setApiResponse)(
1412
+ import_core6.HTTP.UNPROCESSABLE,
1413
+ "INVALID_ROLE",
1414
+ "Role is not assignable in this workspace."
1415
+ );
1416
+ }
1417
+ }
1397
1418
  const results = await Promise.all(
1398
1419
  entries.map(async (entry) => {
1399
1420
  const email2 = entry["email"];