@fonderie/workspaces 5.2.3 → 5.3.1
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.
- package/brain/signatures.md +2 -0
- package/dist/index.cjs +61 -18
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.js +60 -18
- package/dist/index.js.map +1 -1
- package/dist/middlewares/index.cjs.map +1 -1
- package/dist/middlewares/index.js.map +1 -1
- package/package.json +4 -4
package/brain/signatures.md
CHANGED
|
@@ -26,6 +26,8 @@ const MESSAGE_KEYS: { readonly workspaceInvitation: "workspace-invitation"; }
|
|
|
26
26
|
|
|
27
27
|
const EVENT_KEYS: { readonly personalWorkspaceCreated: "fonderie.workspace.personal.created"; }
|
|
28
28
|
|
|
29
|
+
const DEFAULT_TEMPLATES: { "workspace-invitation": { subject: string; html: string; text: string; }; }
|
|
30
|
+
|
|
29
31
|
type WorkspaceType = 'ORGANIZATION' | 'PERSONAL' | 'TEAM' | 'COMMUNITY' | 'VENDOR';
|
|
30
32
|
|
|
31
33
|
type InvitationStatus = 'PENDING' | 'ACCEPTED' | 'REJECTED' | 'CANCELLED';
|
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
DEFAULT_TEMPLATES: () => DEFAULT_TEMPLATES,
|
|
23
24
|
EVENT_KEYS: () => EVENT_KEYS,
|
|
24
25
|
MESSAGE_KEYS: () => MESSAGE_KEYS,
|
|
25
26
|
WorkspacesModule: () => WorkspacesModule,
|
|
@@ -209,13 +210,21 @@ async function getUserRoles(userId, workspaceId, store) {
|
|
|
209
210
|
);
|
|
210
211
|
}
|
|
211
212
|
async function addRoleToMember(userId, workspaceId, roleId, store) {
|
|
212
|
-
await store.query(
|
|
213
|
+
const rows = await store.query(
|
|
213
214
|
`INSERT INTO fonderie_role_user_workspaces (user_id, workspace_id, role_id, confirmed)
|
|
214
|
-
|
|
215
|
+
SELECT $1, $2, $3, true
|
|
216
|
+
WHERE EXISTS (
|
|
217
|
+
SELECT 1 FROM fonderie_roles r
|
|
218
|
+
WHERE r.id = $3
|
|
219
|
+
AND r.workspace_id = $2
|
|
220
|
+
AND r.is_system = false
|
|
221
|
+
)
|
|
215
222
|
ON CONFLICT (user_id, workspace_id, role_id) DO UPDATE
|
|
216
|
-
SET confirmed = true, removed = false, suspended = false
|
|
223
|
+
SET confirmed = true, removed = false, suspended = false
|
|
224
|
+
RETURNING user_id`,
|
|
217
225
|
[userId, workspaceId, roleId]
|
|
218
226
|
);
|
|
227
|
+
return rows.length > 0;
|
|
219
228
|
}
|
|
220
229
|
async function removeRoleFromMember(userId, workspaceId, roleId, store) {
|
|
221
230
|
const remaining = await store.query(
|
|
@@ -547,10 +556,11 @@ async function findSystemRole(name2, store) {
|
|
|
547
556
|
);
|
|
548
557
|
return row ?? null;
|
|
549
558
|
}
|
|
550
|
-
async function getRoleById(id, store) {
|
|
559
|
+
async function getRoleById(id, workspaceId, store) {
|
|
551
560
|
const [row] = await store.query(
|
|
552
|
-
`SELECT ${SELECT_ROLE} FROM fonderie_roles
|
|
553
|
-
|
|
561
|
+
`SELECT ${SELECT_ROLE} FROM fonderie_roles
|
|
562
|
+
WHERE id = $1 AND (workspace_id = $2 OR is_system = true)`,
|
|
563
|
+
[id, workspaceId]
|
|
554
564
|
);
|
|
555
565
|
return row ?? null;
|
|
556
566
|
}
|
|
@@ -563,9 +573,9 @@ async function listWorkspaceRoles(workspaceId, store) {
|
|
|
563
573
|
[workspaceId]
|
|
564
574
|
);
|
|
565
575
|
}
|
|
566
|
-
async function updateRole(id, opts, store) {
|
|
576
|
+
async function updateRole(id, workspaceId, opts, store) {
|
|
567
577
|
const sets = [];
|
|
568
|
-
const params = [id];
|
|
578
|
+
const params = [id, workspaceId];
|
|
569
579
|
if (opts.name !== void 0) {
|
|
570
580
|
params.push(opts.name);
|
|
571
581
|
sets.push(`name = $${params.length}`);
|
|
@@ -578,11 +588,11 @@ async function updateRole(id, opts, store) {
|
|
|
578
588
|
params.push(opts.active);
|
|
579
589
|
sets.push(`active = $${params.length}`);
|
|
580
590
|
}
|
|
581
|
-
if (sets.length === 0) return getRoleById(id, store);
|
|
591
|
+
if (sets.length === 0) return getRoleById(id, workspaceId, store);
|
|
582
592
|
const [row] = await store.query(
|
|
583
593
|
`UPDATE fonderie_roles
|
|
584
594
|
SET ${sets.join(", ")}
|
|
585
|
-
WHERE id = $1 AND is_system = false
|
|
595
|
+
WHERE id = $1 AND workspace_id = $2 AND is_system = false
|
|
586
596
|
RETURNING ${SELECT_ROLE}`,
|
|
587
597
|
params
|
|
588
598
|
);
|
|
@@ -648,14 +658,14 @@ var RoleModel = class {
|
|
|
648
658
|
findSystem(name2) {
|
|
649
659
|
return findSystemRole(name2, this.store);
|
|
650
660
|
}
|
|
651
|
-
findById(id) {
|
|
652
|
-
return getRoleById(id, this.store);
|
|
661
|
+
findById(id, workspaceId) {
|
|
662
|
+
return getRoleById(id, workspaceId, this.store);
|
|
653
663
|
}
|
|
654
664
|
list(workspaceId) {
|
|
655
665
|
return listWorkspaceRoles(workspaceId, this.store);
|
|
656
666
|
}
|
|
657
|
-
update(id, opts) {
|
|
658
|
-
return updateRole(id, opts, this.store);
|
|
667
|
+
update(id, workspaceId, opts) {
|
|
668
|
+
return updateRole(id, workspaceId, opts, this.store);
|
|
659
669
|
}
|
|
660
670
|
delete(id, workspaceId) {
|
|
661
671
|
return deleteRole(id, workspaceId, this.store);
|
|
@@ -927,7 +937,14 @@ function memberController(store) {
|
|
|
927
937
|
return (0, import_core3.setApiResponse)(import_core3.HTTP.UNPROCESSABLE, "INVALID_PARAMETER", "userId is required");
|
|
928
938
|
if (!roleId)
|
|
929
939
|
return (0, import_core3.setApiResponse)(import_core3.HTTP.UNPROCESSABLE, "INVALID_PARAMETER", "roleId is required");
|
|
930
|
-
await members.addRole(userId, ctx.workspace.id, roleId);
|
|
940
|
+
const assigned = await members.addRole(userId, ctx.workspace.id, roleId);
|
|
941
|
+
if (!assigned) {
|
|
942
|
+
return (0, import_core3.setApiResponse)(
|
|
943
|
+
import_core3.HTTP.UNPROCESSABLE,
|
|
944
|
+
"INVALID_ROLE",
|
|
945
|
+
"Role is not assignable in this workspace."
|
|
946
|
+
);
|
|
947
|
+
}
|
|
931
948
|
return (0, import_core3.setApiResponse)(import_core3.HTTP.OK, "ROLE_ASSIGNED", "Role assigned successfully.");
|
|
932
949
|
},
|
|
933
950
|
async removeRole(ctx) {
|
|
@@ -1000,7 +1017,7 @@ function roleController(store) {
|
|
|
1000
1017
|
if (!roleId) {
|
|
1001
1018
|
return (0, import_core4.setApiResponse)(import_core4.HTTP.UNPROCESSABLE, "INVALID_PARAMETER", "roleId is required");
|
|
1002
1019
|
}
|
|
1003
|
-
const role = await roles.findById(roleId);
|
|
1020
|
+
const role = await roles.findById(roleId, ctx.workspace.id);
|
|
1004
1021
|
if (!role) {
|
|
1005
1022
|
return (0, import_core4.setApiResponse)(import_core4.HTTP.NOT_FOUND, "NOT_FOUND", "Role not found");
|
|
1006
1023
|
}
|
|
@@ -1031,7 +1048,7 @@ function roleController(store) {
|
|
|
1031
1048
|
if (typeof body?.["active"] === "boolean") {
|
|
1032
1049
|
opts.active = body["active"];
|
|
1033
1050
|
}
|
|
1034
|
-
const role = await roles.update(roleId, opts);
|
|
1051
|
+
const role = await roles.update(roleId, ctx.workspace.id, opts);
|
|
1035
1052
|
if (!role) {
|
|
1036
1053
|
return (0, import_core4.setApiResponse)(import_core4.HTTP.NOT_FOUND, "NOT_FOUND", "Role not found or is a system role");
|
|
1037
1054
|
}
|
|
@@ -1060,7 +1077,7 @@ function roleController(store) {
|
|
|
1060
1077
|
if (!roleId) {
|
|
1061
1078
|
return (0, import_core4.setApiResponse)(import_core4.HTTP.UNPROCESSABLE, "INVALID_PARAMETER", "roleId is required");
|
|
1062
1079
|
}
|
|
1063
|
-
const role = await roles.findById(roleId);
|
|
1080
|
+
const role = await roles.findById(roleId, ctx.workspace.id);
|
|
1064
1081
|
if (!role) {
|
|
1065
1082
|
return (0, import_core4.setApiResponse)(import_core4.HTTP.NOT_FOUND, "NOT_FOUND", "Role not found");
|
|
1066
1083
|
}
|
|
@@ -1079,6 +1096,10 @@ function roleController(store) {
|
|
|
1079
1096
|
if (!roleId) {
|
|
1080
1097
|
return (0, import_core4.setApiResponse)(import_core4.HTTP.UNPROCESSABLE, "INVALID_PARAMETER", "roleId is required");
|
|
1081
1098
|
}
|
|
1099
|
+
const target = await roles.findById(roleId, ctx.workspace.id);
|
|
1100
|
+
if (!target || target.isSystem) {
|
|
1101
|
+
return (0, import_core4.setApiResponse)(import_core4.HTTP.NOT_FOUND, "NOT_FOUND", "Role not found");
|
|
1102
|
+
}
|
|
1082
1103
|
const perms = body?.["permissions"];
|
|
1083
1104
|
if (!Array.isArray(perms)) {
|
|
1084
1105
|
return (0, import_core4.setApiResponse)(
|
|
@@ -1453,6 +1474,27 @@ var WorkspacesModule = class {
|
|
|
1453
1474
|
}
|
|
1454
1475
|
};
|
|
1455
1476
|
|
|
1477
|
+
// src/templates.ts
|
|
1478
|
+
var DEFAULT_TEMPLATES = {
|
|
1479
|
+
// Payload carries { token, pin }; the code path is PIN-based, so the copy
|
|
1480
|
+
// uses {{pin}} only — token is intentionally not surfaced.
|
|
1481
|
+
[MESSAGE_KEYS.workspaceInvitation]: {
|
|
1482
|
+
subject: "You've been invited to a workspace",
|
|
1483
|
+
html: `<h1>You’ve been invited</h1>
|
|
1484
|
+
<p>You’ve been invited to join a workspace. Use this code to accept the invitation:</p>
|
|
1485
|
+
<p><span class="pin-code">{{pin}}</span></p>
|
|
1486
|
+
<p class="muted">Enter this code on the invitation screen to join the team.</p>`,
|
|
1487
|
+
text: `You've been invited
|
|
1488
|
+
|
|
1489
|
+
You've been invited to join a workspace. Use this code to accept the invitation: {{pin}}
|
|
1490
|
+
|
|
1491
|
+
Enter this code on the invitation screen to join the team.`
|
|
1492
|
+
}
|
|
1493
|
+
};
|
|
1494
|
+
var SAMPLE_PAYLOADS = {
|
|
1495
|
+
[MESSAGE_KEYS.workspaceInvitation]: { token: "inv_abc123", pin: "123456" }
|
|
1496
|
+
};
|
|
1497
|
+
|
|
1456
1498
|
// src/middlewares/require-workspace.ts
|
|
1457
1499
|
var import_core6 = require("@fonderie/core");
|
|
1458
1500
|
var requireWorkspace = async (ctx, next) => {
|
|
@@ -1561,6 +1603,7 @@ function workspaceExportContributor(store) {
|
|
|
1561
1603
|
}
|
|
1562
1604
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1563
1605
|
0 && (module.exports = {
|
|
1606
|
+
DEFAULT_TEMPLATES,
|
|
1564
1607
|
EVENT_KEYS,
|
|
1565
1608
|
MESSAGE_KEYS,
|
|
1566
1609
|
WorkspacesModule,
|