@selvajs/platform 0.17.0 → 0.19.0

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.
Files changed (53) hide show
  1. package/dist/access/index.d.ts +2 -2
  2. package/dist/access/index.d.ts.map +1 -1
  3. package/dist/access/index.js +1 -1
  4. package/dist/access/index.js.map +1 -1
  5. package/dist/access/rules.d.ts +31 -2
  6. package/dist/access/rules.d.ts.map +1 -1
  7. package/dist/access/rules.js +28 -3
  8. package/dist/access/rules.js.map +1 -1
  9. package/dist/computeServer/index.d.ts +1 -1
  10. package/dist/computeServer/index.d.ts.map +1 -1
  11. package/dist/computeServer/index.js +1 -1
  12. package/dist/computeServer/index.js.map +1 -1
  13. package/dist/computeServer/interface.d.ts +17 -4
  14. package/dist/computeServer/interface.d.ts.map +1 -1
  15. package/dist/computeServer/utils.d.ts +10 -0
  16. package/dist/computeServer/utils.d.ts.map +1 -1
  17. package/dist/computeServer/utils.js +21 -0
  18. package/dist/computeServer/utils.js.map +1 -1
  19. package/dist/context.d.ts +20 -0
  20. package/dist/context.d.ts.map +1 -1
  21. package/dist/context.js +18 -0
  22. package/dist/context.js.map +1 -1
  23. package/dist/events/interface.d.ts +30 -0
  24. package/dist/events/interface.d.ts.map +1 -1
  25. package/dist/events/interface.js.map +1 -1
  26. package/dist/index.d.ts +5 -5
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +3 -3
  29. package/dist/index.js.map +1 -1
  30. package/dist/invites/interface.d.ts +15 -0
  31. package/dist/invites/interface.d.ts.map +1 -1
  32. package/dist/invites/types.d.ts +10 -0
  33. package/dist/invites/types.d.ts.map +1 -1
  34. package/dist/permissions/interface.d.ts +17 -0
  35. package/dist/permissions/interface.d.ts.map +1 -1
  36. package/dist/shareLinks/index.d.ts +1 -1
  37. package/dist/shareLinks/index.d.ts.map +1 -1
  38. package/dist/shareLinks/interface.d.ts +14 -1
  39. package/dist/shareLinks/interface.d.ts.map +1 -1
  40. package/dist/shareLinks/types.d.ts +17 -0
  41. package/dist/shareLinks/types.d.ts.map +1 -1
  42. package/dist/shareLinks/types.js.map +1 -1
  43. package/dist/testing/suites/inviteStoreSuite.d.ts.map +1 -1
  44. package/dist/testing/suites/inviteStoreSuite.js +47 -0
  45. package/dist/testing/suites/inviteStoreSuite.js.map +1 -1
  46. package/dist/testing/suites/platformPermissionStoreSuite.d.ts.map +1 -1
  47. package/dist/testing/suites/platformPermissionStoreSuite.js +120 -0
  48. package/dist/testing/suites/platformPermissionStoreSuite.js.map +1 -1
  49. package/dist/testing/suites/shareLinkStoreSuite.d.ts +8 -0
  50. package/dist/testing/suites/shareLinkStoreSuite.d.ts.map +1 -1
  51. package/dist/testing/suites/shareLinkStoreSuite.js +78 -3
  52. package/dist/testing/suites/shareLinkStoreSuite.js.map +1 -1
  53. package/package.json +1 -1
@@ -1,4 +1,5 @@
1
1
  import type { OrgRole, OrgPermission } from '../organizations/schemas.js';
2
+ import type { PlatformPermission } from '../permissions/types.js';
2
3
  /**
3
4
  * "The holder of the raw token whose hash is `tokenHash` may join `orgId` at
4
5
  * `orgRole` with these org permissions." Accepting creates the user (if
@@ -22,6 +23,15 @@ export interface Invite {
22
23
  orgRole: OrgRole;
23
24
  /** May be empty — adapters may seed from `DEFAULT_ORG_PERMISSIONS` in that case. */
24
25
  orgPermissions: OrgPermission[];
26
+ /**
27
+ * Instance-wide permissions granted on accept — usually empty.
28
+ *
29
+ * Only a caller who already holds `instance_admin` may mint an invite
30
+ * carrying these; the mint route enforces that, because anyone able to set
31
+ * this field can hand out `instance_admin` and escalate past org scope.
32
+ * Optional so invites stored before this field existed still parse.
33
+ */
34
+ platformPermissions?: PlatformPermission[];
25
35
  invitedBy: string;
26
36
  createdAt: string;
27
37
  expiresAt: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/invites/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE1E;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,MAAM;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,0GAA0G;IAC1G,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/invites/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAElE;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,MAAM;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,0GAA0G;IAC1G,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,oFAAoF;IACpF,cAAc,EAAE,aAAa,EAAE,CAAC;IAChC;;;;;;;OAOG;IACH,mBAAmB,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAC3C,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC1B"}
@@ -36,5 +36,22 @@ export interface IPlatformPermissionStore {
36
36
  * admin and the op must be refused. Must exclude disabled users.
37
37
  */
38
38
  countInstanceAdminsExcluding(ctx: RequestContext, excludeUserId: string): Promise<number>;
39
+ /**
40
+ * First-run bootstrap: grant `userId` every platform permission **only if
41
+ * the instance has no enabled `instance_admin` yet**. Returns whether this
42
+ * call was the one that claimed it.
43
+ *
44
+ * Exists because `hasInstanceAdmin()` followed by `set()` is a read-then-
45
+ * write: on a fresh single-tenant install with no
46
+ * `BOOTSTRAP_INSTANCE_ADMIN_EMAIL` configured, any signer is eligible, so
47
+ * two people signing in at the same moment both observe "no admin" and both
48
+ * become permanent platform admins. §2 promises "first signer wins" — this
49
+ * is what makes that true rather than aspirational.
50
+ *
51
+ * Same shape as the sole-admin invariant (`set`), pointing the other way:
52
+ * that one refuses to drop the last admin, this one refuses to create a
53
+ * second first admin. Adapters MUST make the check and the write atomic.
54
+ */
55
+ claimFirstInstanceAdmin(ctx: RequestContext, userId: string, permissions: readonly PlatformPermission[]): Promise<boolean>;
39
56
  }
40
57
  //# sourceMappingURL=interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/permissions/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,wBAAwB;IACxC,wFAAwF;IACxF,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE3E,kBAAkB;IAClB,WAAW,CACV,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,GAAG,CACF,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;OAGG;IACH,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAExD;;;;OAIG;IACH,4BAA4B,CAAC,GAAG,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAC1F"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/permissions/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAErD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,wBAAwB;IACxC,wFAAwF;IACxF,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC,CAAC;IAE3E,kBAAkB;IAClB,WAAW,CACV,GAAG,EAAE,cAAc,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACxB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;IAE9C;;;;;OAKG;IACH,GAAG,CACF,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAEjC;;;OAGG;IACH,gBAAgB,CAAC,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAExD;;;;OAIG;IACH,4BAA4B,CAAC,GAAG,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1F;;;;;;;;;;;;;;;OAeG;IACH,uBAAuB,CACtB,GAAG,EAAE,cAAc,EACnB,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,SAAS,kBAAkB,EAAE,GACxC,OAAO,CAAC,OAAO,CAAC,CAAC;CACpB"}
@@ -1,4 +1,4 @@
1
- export type { ShareLink } from './types.js';
1
+ export type { OrgShareLink, ShareLink } from './types.js';
2
2
  export type { IShareLinkStore } from './interface.js';
3
3
  export { DEFAULT_SHARE_LINK_MAX_SOLVES } from './types.js';
4
4
  export type { CreateShareLinkInput } from './schemas.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shareLinks/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shareLinks/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,YAAY,CAAC;AAC3D,YAAY,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { RequestContext } from '../context.js';
2
2
  import type { ListOptions, Page } from '../pagination.js';
3
- import type { ShareLink } from './types.js';
3
+ import type { OrgShareLink, ShareLink } from './types.js';
4
4
  /**
5
5
  * Per-definition tokens granting unauthenticated access to one
6
6
  * (definitionId, channel). The store sees only the HMAC hash; the raw token
@@ -13,6 +13,19 @@ export interface IShareLinkStore {
13
13
  create(ctx: RequestContext, link: ShareLink): Promise<void>;
14
14
  /** Newest first by `createdAt`. Excludes revoked links. */
15
15
  listByDefinition(ctx: RequestContext, definitionId: string, opts?: ListOptions): Promise<Page<ShareLink>>;
16
+ /**
17
+ * Every live link across every definition in the org, newest first.
18
+ *
19
+ * A share link is a bearer credential: the URL is the whole authentication.
20
+ * Listing by definition — the only other read — means "what reaches my org's
21
+ * data right now?" can only be answered by walking every definition by hand,
22
+ * so in practice it goes unanswered. Offboarding depends on this being one
23
+ * query.
24
+ *
25
+ * Rows carry the definition and project they hang off, because a roster of
26
+ * bare GUIDs is not something anyone can act on.
27
+ */
28
+ listByOrg(ctx: RequestContext, orgId: string, opts?: ListOptions): Promise<Page<OrgShareLink>>;
16
29
  getById(ctx: RequestContext, id: string): Promise<ShareLink | null>;
17
30
  /** Returns null when the link doesn't exist, is revoked, or its parent definition is soft-deleted. */
18
31
  getByTokenHash(ctx: RequestContext, tokenHash: string): Promise<ShareLink | null>;
@@ -1 +1 @@
1
- {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/shareLinks/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC/B,+CAA+C;IAC/C,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,2DAA2D;IAC3D,gBAAgB,CACf,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5B,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACpE,sGAAsG;IACtG,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAClF,iDAAiD;IACjD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,sBAAsB,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChF"}
1
+ {"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/shareLinks/interface.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC/B,+CAA+C;IAC/C,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5D,2DAA2D;IAC3D,gBAAgB,CACf,GAAG,EAAE,cAAc,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,WAAW,GAChB,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAC5B;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,GAAG,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/F,OAAO,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IACpE,sGAAsG;IACtG,cAAc,CAAC,GAAG,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CAAC;IAClF,iDAAiD;IACjD,MAAM,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD;;;;OAIG;IACH,sBAAsB,CAAC,GAAG,EAAE,cAAc,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CAChF"}
@@ -23,6 +23,23 @@ export interface ShareLink {
23
23
  maxSolves?: number | null;
24
24
  solveCount: number;
25
25
  }
26
+ /**
27
+ * A share link plus the definition and project it hangs off.
28
+ *
29
+ * The org-wide roster is the one read where the parent matters: `definitionId`
30
+ * alone identifies nothing a person can recognize, and revoking the wrong link
31
+ * is unrecoverable — the raw token is gone.
32
+ *
33
+ * `tokenHash` is omitted, not merely unused. This is the only share-link shape
34
+ * built for a page, and the roster spans every definition in the org — so a
35
+ * careless `JSON.stringify` here would ship every credential digest in the
36
+ * tenant to the browser at once.
37
+ */
38
+ export interface OrgShareLink extends Omit<ShareLink, 'tokenHash'> {
39
+ definitionName: string;
40
+ projectId: string;
41
+ projectName: string;
42
+ }
26
43
  /**
27
44
  * Default cap applied when the minter doesn't specify one. Tokens are
28
45
  * leak-prone by design (visible in iframes), so a default bounds the
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sDAAsD;IACtD,UAAU,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAEjE;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,iBAAiB,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0BAA0B;IAC1B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,sDAAsD;IACtD,UAAU,EAAE,OAAO,CAAC;IACpB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAa,SAAQ,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC;IACjE,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AA2BA;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/shareLinks/types.ts"],"names":[],"mappings":"AA6CA;;;;GAIG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,IAAI,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"inviteStoreSuite.d.ts","sourceRoot":"","sources":["../../../src/testing/suites/inviteStoreSuite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,EAA2C,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAExF,MAAM,WAAW,eAAe;IAC/B,wFAAwF;IACxF,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,6BAA6B;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;IAC/D,QAAQ,CAAC,EAAE,UAAU,CAAC;CACtB;AA6BD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,6BAA6B,GAAG,IAAI,CA4EnF"}
1
+ {"version":3,"file":"inviteStoreSuite.d.ts","sourceRoot":"","sources":["../../../src/testing/suites/inviteStoreSuite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAG/D,OAAO,EAA2C,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAExF,MAAM,WAAW,eAAe;IAC/B,wFAAwF;IACxF,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,6EAA6E;IAC7E,KAAK,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,6BAA6B;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY,CAAC;IACxD,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;IAC/D,QAAQ,CAAC,EAAE,UAAU,CAAC;CACtB;AA6BD,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,6BAA6B,GAAG,IAAI,CAuInF"}
@@ -108,6 +108,53 @@ export function runInviteStoreConformance(opts) {
108
108
  const got = await store.getByTokenHash(SYSTEM_CONTEXT, inv.tokenHash);
109
109
  expect(got).toBeNull();
110
110
  });
111
+ it('revokePendingByEmail kills every pending invite to that address', async () => {
112
+ const store = await createStore();
113
+ const scope = await scopeFor();
114
+ const email = `offboard-${makeUuid()}@test.local`;
115
+ const first = invite(scope, { email });
116
+ const second = invite(scope, { email });
117
+ await store.create(ctx(scope.adminId), first);
118
+ await store.create(ctx(scope.adminId), second);
119
+ const revoked = await store.revokePendingByEmail(ctx(scope.adminId), scope.orgId, email);
120
+ expect(revoked.sort()).toEqual([first.id, second.id].sort());
121
+ expect(await store.getByTokenHash(SYSTEM_CONTEXT, first.tokenHash)).toBeNull();
122
+ expect(await store.getByTokenHash(SYSTEM_CONTEXT, second.tokenHash)).toBeNull();
123
+ });
124
+ it('revokePendingByEmail leaves other addresses and other orgs alone', async () => {
125
+ const store = await createStore();
126
+ const scope = await scopeFor();
127
+ const target = `target-${makeUuid()}@test.local`;
128
+ const bystander = invite(scope, { email: `bystander-${makeUuid()}@test.local` });
129
+ await store.create(ctx(scope.adminId), invite(scope, { email: target }));
130
+ await store.create(ctx(scope.adminId), bystander);
131
+ await store.revokePendingByEmail(ctx(scope.adminId), scope.orgId, target);
132
+ expect(await store.getByTokenHash(SYSTEM_CONTEXT, bystander.tokenHash)).not.toBeNull();
133
+ });
134
+ it('revokePendingByEmail does not un-consume an accepted invite', async () => {
135
+ const store = await createStore();
136
+ const scope = await scopeFor();
137
+ const { userId: acceptor } = await seedUser(makeUuid());
138
+ const email = `accepted-${makeUuid()}@test.local`;
139
+ const inv = invite(scope, { email });
140
+ await store.create(ctx(scope.adminId), inv);
141
+ await store.markAccepted(SYSTEM_CONTEXT, inv.id, acceptor);
142
+ // Accepting is history, not a live grant — offboarding must not erase
143
+ // the record that this person once joined.
144
+ const revoked = await store.revokePendingByEmail(ctx(scope.adminId), scope.orgId, email);
145
+ expect(revoked).toEqual([]);
146
+ const listed = await store.listByOrg(ctx(scope.adminId), scope.orgId, { limit: 100 });
147
+ expect(listed.items.find((i) => i.id === inv.id)?.acceptedAt).toBeTruthy();
148
+ });
149
+ it('revokePendingByEmail matches case-insensitively', async () => {
150
+ const store = await createStore();
151
+ const scope = await scopeFor();
152
+ const email = `mixed-${makeUuid()}@test.local`;
153
+ const inv = invite(scope, { email });
154
+ await store.create(ctx(scope.adminId), inv);
155
+ const revoked = await store.revokePendingByEmail(ctx(scope.adminId), scope.orgId, email.toUpperCase());
156
+ expect(revoked).toEqual([inv.id]);
157
+ });
111
158
  });
112
159
  }
113
160
  //# sourceMappingURL=inviteStoreSuite.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"inviteStoreSuite.js","sourceRoot":"","sources":["../../../src/testing/suites/inviteStoreSuite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inviteStoreSuite.js","sourceRoot":"","sources":["../../../src/testing/suites/inviteStoreSuite.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"platformPermissionStoreSuite.d.ts","sourceRoot":"","sources":["../../../src/testing/suites/platformPermissionStoreSuite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAkB,MAAM,gBAAgB,CAAC;AAG/E,MAAM,WAAW,yCAAyC;IACzD,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC;QAC1B,KAAK,EAAE,wBAAwB,CAAC;QAChC,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;KAChC,CAAC,CAAC;IACH;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACrC;AAED,wBAAgB,qCAAqC,CACpD,IAAI,EAAE,yCAAyC,GAC7C,IAAI,CAqMN"}
1
+ {"version":3,"file":"platformPermissionStoreSuite.d.ts","sourceRoot":"","sources":["../../../src/testing/suites/platformPermissionStoreSuite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAkB,MAAM,gBAAgB,CAAC;AAG/E,MAAM,WAAW,yCAAyC;IACzD,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,WAAW,EAAE,MAAM,OAAO,CAAC;QAC1B,KAAK,EAAE,wBAAwB,CAAC;QAChC,QAAQ,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;KAChC,CAAC,CAAC;IACH;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACrC;AAED,wBAAgB,qCAAqC,CACpD,IAAI,EAAE,yCAAyC,GAC7C,IAAI,CAkVN"}
@@ -29,6 +29,14 @@ export function runPlatformPermissionStoreConformance(opts) {
29
29
  orgPermissions: []
30
30
  };
31
31
  }
32
+ /** §8's user-admin role: runs `/admin/users`, holds no `instance_admin`. */
33
+ function userAdminCtx(userId) {
34
+ return {
35
+ userId,
36
+ platformPermissions: ['manage_instance_users'],
37
+ orgPermissions: []
38
+ };
39
+ }
32
40
  describe(`IPlatformPermissionStore conformance: ${name}`, () => {
33
41
  beforeEach(() => {
34
42
  // Every test creates its own store via createStore — no shared state.
@@ -113,6 +121,89 @@ export function runPlatformPermissionStoreConformance(opts) {
113
121
  const after = await store.getFor(adminCtx(adminA), adminB);
114
122
  expect(after).toContain('instance_admin');
115
123
  });
124
+ // The invariant has to survive concurrency, not just sequence. Two admins
125
+ // demoting each other at the same moment used to each read the other as
126
+ // "another admin exists" and both commit, bricking the instance. Exactly
127
+ // one must win.
128
+ it('concurrent demotions of two admins leave one standing', async () => {
129
+ const { store, seedUser } = await createStore();
130
+ const adminA = await seedUser();
131
+ const adminB = await seedUser();
132
+ await store.set(adminCtx(adminA), adminA, ['instance_admin']);
133
+ await store.set(adminCtx(adminA), adminB, ['instance_admin']);
134
+ const [resA, resB] = await Promise.all([
135
+ store.set(adminCtx(adminA), adminA, []),
136
+ store.set(adminCtx(adminB), adminB, [])
137
+ ]);
138
+ // One demotion succeeds, the other is refused — never both.
139
+ expect([resA, resB].filter((r) => r === 'ok')).toHaveLength(1);
140
+ expect([resA, resB].filter((r) => r === 'last_admin')).toHaveLength(1);
141
+ const sysCtx = {
142
+ userId: '',
143
+ platformPermissions: [],
144
+ orgPermissions: [],
145
+ system: true
146
+ };
147
+ expect(await store.hasInstanceAdmin(sysCtx)).toBe(true);
148
+ });
149
+ it('a burst of concurrent demotions never drops the last admin', async () => {
150
+ const { store, seedUser } = await createStore();
151
+ // Seeded sequentially on purpose: concurrent seeding races the
152
+ // adapter's own row-creation writes, which is not what this asserts.
153
+ const ids = [];
154
+ for (let i = 0; i < 4; i++)
155
+ ids.push(await seedUser());
156
+ for (const id of ids)
157
+ await store.set(adminCtx(ids[0]), id, ['instance_admin']);
158
+ const results = await Promise.all(ids.map((id) => store.set(adminCtx(id), id, [])));
159
+ // Whatever the interleaving, exactly one admin survives.
160
+ expect(results.filter((r) => r === 'ok')).toHaveLength(ids.length - 1);
161
+ expect(results.filter((r) => r === 'last_admin')).toHaveLength(1);
162
+ const sysCtx = {
163
+ userId: '',
164
+ platformPermissions: [],
165
+ orgPermissions: [],
166
+ system: true
167
+ };
168
+ expect(await store.hasInstanceAdmin(sysCtx)).toBe(true);
169
+ });
170
+ it('claimFirstInstanceAdmin grants on a fresh instance and refuses once claimed', async () => {
171
+ const { store, seedUser } = await createStore();
172
+ const first = await seedUser();
173
+ const second = await seedUser();
174
+ const sysCtx = {
175
+ userId: '',
176
+ platformPermissions: [],
177
+ orgPermissions: [],
178
+ system: true
179
+ };
180
+ expect(await store.claimFirstInstanceAdmin(sysCtx, first, ['instance_admin'])).toBe(true);
181
+ expect(await store.getFor(adminCtx(first), first)).toContain('instance_admin');
182
+ // The instance is claimed. A later signer must not become a second
183
+ // "first" admin, however they arrive.
184
+ expect(await store.claimFirstInstanceAdmin(sysCtx, second, ['instance_admin'])).toBe(false);
185
+ expect(await store.getFor(adminCtx(first), second)).not.toContain('instance_admin');
186
+ });
187
+ it('a burst of concurrent first-admin claims produces exactly one admin', async () => {
188
+ const { store, seedUser } = await createStore();
189
+ // The §2 "first signer wins" promise. With no
190
+ // BOOTSTRAP_INSTANCE_ADMIN_EMAIL configured every signer is eligible,
191
+ // so this is four different people hitting a fresh install at once —
192
+ // the read-then-write version granted all four.
193
+ const ids = [];
194
+ for (let i = 0; i < 4; i++)
195
+ ids.push(await seedUser());
196
+ const sysCtx = {
197
+ userId: '',
198
+ platformPermissions: [],
199
+ orgPermissions: [],
200
+ system: true
201
+ };
202
+ const results = await Promise.all(ids.map((id) => store.claimFirstInstanceAdmin(sysCtx, id, ['instance_admin'])));
203
+ expect(results.filter(Boolean)).toHaveLength(1);
204
+ const admins = await store.getForBatch(adminCtx(ids[0]), ids);
205
+ expect([...admins.values()].filter((p) => p.includes('instance_admin'))).toHaveLength(1);
206
+ });
116
207
  it('countInstanceAdminsExcluding excludes the named user', async () => {
117
208
  const { store, seedUser } = await createStore();
118
209
  const adminA = await seedUser();
@@ -190,6 +281,35 @@ export function runPlatformPermissionStoreConformance(opts) {
190
281
  const target = await seedUser();
191
282
  await expect(store.getForBatch(selfCtx(attacker), [target])).rejects.toThrow();
192
283
  });
284
+ // §8 — `manage_instance_users` runs the user-admin surface, so it must be
285
+ // able to see who holds `instance_admin`: without that read the page cannot
286
+ // render its locks, and `/admin/users` fails for the exact role it serves.
287
+ // The two adapters disagreed here (local admitted the role, Supabase did
288
+ // not), which surfaced as "User store unavailable" on Supabase only. Read
289
+ // access is not authority — the `set` case below is what keeps them apart.
290
+ it('manage_instance_users can batch-read platform permissions', async () => {
291
+ const { store, seedUser } = await createStore();
292
+ const admin = await seedUser();
293
+ const userAdmin = await seedUser();
294
+ await store.set(adminCtx(admin), admin, ['instance_admin']);
295
+ const map = await store.getForBatch(userAdminCtx(userAdmin), [admin, userAdmin]);
296
+ expect(map.get(admin)).toContain('instance_admin');
297
+ });
298
+ it('manage_instance_users can read another user’s permissions singly', async () => {
299
+ const { store, seedUser } = await createStore();
300
+ const admin = await seedUser();
301
+ const userAdmin = await seedUser();
302
+ await store.set(adminCtx(admin), admin, ['instance_admin']);
303
+ // Single and batch reads must agree; when they didn't, the delete/disable
304
+ // routes threw 500 where they meant to return 403.
305
+ expect(await store.getFor(userAdminCtx(userAdmin), admin)).toContain('instance_admin');
306
+ });
307
+ it('manage_instance_users cannot grant permissions', async () => {
308
+ const { store, seedUser } = await createStore();
309
+ const target = await seedUser();
310
+ const userAdmin = await seedUser();
311
+ await expect(store.set(userAdminCtx(userAdmin), target, ['instance_admin'])).rejects.toThrow();
312
+ });
193
313
  });
194
314
  }
195
315
  //# sourceMappingURL=platformPermissionStoreSuite.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"platformPermissionStoreSuite.js","sourceRoot":"","sources":["../../../src/testing/suites/platformPermissionStoreSuite.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"platformPermissionStoreSuite.js","sourceRoot":"","sources":["../../../src/testing/suites/platformPermissionStoreSuite.ts"],"names":[],"mappings":"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"}
@@ -19,6 +19,14 @@ export interface ShareLinkTestScope {
19
19
  definitionId: string;
20
20
  /** A second definition id for cross-definition isolation tests. */
21
21
  otherDefinitionId: string;
22
+ /**
23
+ * Org owning both definitions' project. Set it to run the `listByOrg`
24
+ * cases; adapters that can't seed the definition→project→org chain leave it
25
+ * undefined and those cases skip.
26
+ */
27
+ orgId?: string;
28
+ /** An org with no share links, to prove the roster is tenant-scoped. */
29
+ otherOrgId?: string;
22
30
  }
23
31
  export interface ShareLinkStoreConformanceOptions {
24
32
  name: string;
@@ -1 +1 @@
1
- {"version":3,"file":"shareLinkStoreSuite.d.ts","sourceRoot":"","sources":["../../../src/testing/suites/shareLinkStoreSuite.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAoBrE,MAAM,WAAW,kBAAkB;IAClC,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,iBAAiB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gCAAgC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;IAC9D;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;CACrE;AA0BD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,gCAAgC,GAAG,IAAI,CAmKzF"}
1
+ {"version":3,"file":"shareLinkStoreSuite.d.ts","sourceRoot":"","sources":["../../../src/testing/suites/shareLinkStoreSuite.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAoBrE,MAAM,WAAW,kBAAkB;IAClC,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,gCAAgC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,OAAO,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;IAC9D;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC,kBAAkB,CAAC,GAAG,kBAAkB,CAAC;CACrE;AA0BD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,gCAAgC,GAAG,IAAI,CAmPzF"}
@@ -99,9 +99,9 @@ export function runShareLinkStoreConformance(opts) {
99
99
  const got = await store.getByTokenHash(ctx(scope.ownerId), 'will-revoke');
100
100
  expect(got).toBeNull();
101
101
  });
102
- // Expiry is a store-level filter, not just a route-level check: the local
103
- // store once tested only `revokedAt`, so an expired link stayed listed and
104
- // resolvable while Supabase (which filters both in SQL) reported it dead.
102
+ // Expiry is a store-level filter, not just a route-level check. Each
103
+ // provider has at some point filtered only `revokedAt`, leaving an expired
104
+ // link listed and resolvable there while the other reported it dead.
105
105
  it('an expired link is excluded from listByDefinition', async () => {
106
106
  const store = await createStore();
107
107
  const scope = await scopeFor();
@@ -132,6 +132,81 @@ export function runShareLinkStoreConformance(opts) {
132
132
  const got = await store.getByTokenHash(ctx(scope.ownerId), 'not-yet-expired');
133
133
  expect(got?.id).toBe(l.id);
134
134
  });
135
+ // The org roster is the only read that answers "what reaches this
136
+ // tenant's data right now?". `it.skipIf` rather than an omitted block, so
137
+ // an adapter that stops seeding an org shows as skipped instead of silently
138
+ // covering nothing.
139
+ describe('listByOrg', () => {
140
+ it('returns links across every definition in the org, newest first', async () => {
141
+ const scope = await scopeFor();
142
+ if (!scope.orgId)
143
+ return;
144
+ const store = await createStore();
145
+ const a = link(scope, { createdAt: '2026-04-01T00:00:00.000Z' });
146
+ const b = link(scope, {
147
+ definitionId: scope.otherDefinitionId,
148
+ createdAt: '2026-04-02T00:00:00.000Z'
149
+ });
150
+ await store.create(ctx(scope.ownerId), a);
151
+ await store.create(ctx(scope.ownerId), b);
152
+ const page = await store.listByOrg(ctx(scope.ownerId), scope.orgId, { limit: 100 });
153
+ expect(page.items.map((l) => l.id)).toEqual([b.id, a.id]);
154
+ });
155
+ it('names the parent definition and project on every row', async () => {
156
+ const scope = await scopeFor();
157
+ if (!scope.orgId)
158
+ return;
159
+ const store = await createStore();
160
+ const l = link(scope);
161
+ await store.create(ctx(scope.ownerId), l);
162
+ const page = await store.listByOrg(ctx(scope.ownerId), scope.orgId, { limit: 100 });
163
+ const row = page.items.find((x) => x.id === l.id);
164
+ // A roster of bare GUIDs can't be acted on — revoking the wrong link
165
+ // is unrecoverable.
166
+ expect(row?.definitionName).toBeTruthy();
167
+ expect(row?.projectName).toBeTruthy();
168
+ expect(row?.projectId).toBeTruthy();
169
+ });
170
+ it('never carries tokenHash — the roster spans the whole tenant', async () => {
171
+ const scope = await scopeFor();
172
+ if (!scope.orgId)
173
+ return;
174
+ const store = await createStore();
175
+ await store.create(ctx(scope.ownerId), link(scope));
176
+ const page = await store.listByOrg(ctx(scope.ownerId), scope.orgId, { limit: 100 });
177
+ expect(page.items.length).toBeGreaterThan(0);
178
+ for (const row of page.items) {
179
+ expect(row).not.toHaveProperty('tokenHash');
180
+ }
181
+ });
182
+ it('excludes revoked and expired links', async () => {
183
+ const scope = await scopeFor();
184
+ if (!scope.orgId)
185
+ return;
186
+ const store = await createStore();
187
+ const revoked = link(scope);
188
+ const expired = link(scope, { expiresAt: new Date(Date.now() - 60_000).toISOString() });
189
+ const live = link(scope);
190
+ await store.create(ctx(scope.ownerId), revoked);
191
+ await store.create(ctx(scope.ownerId), expired);
192
+ await store.create(ctx(scope.ownerId), live);
193
+ await store.revoke(ctx(scope.ownerId), revoked.id);
194
+ const page = await store.listByOrg(ctx(scope.ownerId), scope.orgId, { limit: 100 });
195
+ const ids = page.items.map((x) => x.id);
196
+ expect(ids).toContain(live.id);
197
+ expect(ids).not.toContain(revoked.id);
198
+ expect(ids).not.toContain(expired.id);
199
+ });
200
+ it('does not leak links into another org', async () => {
201
+ const scope = await scopeFor();
202
+ if (!scope.orgId || !scope.otherOrgId)
203
+ return;
204
+ const store = await createStore();
205
+ await store.create(ctx(scope.ownerId), link(scope));
206
+ const page = await store.listByOrg(ctx(scope.ownerId), scope.otherOrgId, { limit: 100 });
207
+ expect(page.items).toHaveLength(0);
208
+ });
209
+ });
135
210
  it('revoke is idempotent (no error on double-revoke)', async () => {
136
211
  const store = await createStore();
137
212
  const scope = await scopeFor();