@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.
- package/dist/access/index.d.ts +2 -2
- package/dist/access/index.d.ts.map +1 -1
- package/dist/access/index.js +1 -1
- package/dist/access/index.js.map +1 -1
- package/dist/access/rules.d.ts +31 -2
- package/dist/access/rules.d.ts.map +1 -1
- package/dist/access/rules.js +28 -3
- package/dist/access/rules.js.map +1 -1
- package/dist/computeServer/index.d.ts +1 -1
- package/dist/computeServer/index.d.ts.map +1 -1
- package/dist/computeServer/index.js +1 -1
- package/dist/computeServer/index.js.map +1 -1
- package/dist/computeServer/interface.d.ts +17 -4
- package/dist/computeServer/interface.d.ts.map +1 -1
- package/dist/computeServer/utils.d.ts +10 -0
- package/dist/computeServer/utils.d.ts.map +1 -1
- package/dist/computeServer/utils.js +21 -0
- package/dist/computeServer/utils.js.map +1 -1
- package/dist/context.d.ts +20 -0
- package/dist/context.d.ts.map +1 -1
- package/dist/context.js +18 -0
- package/dist/context.js.map +1 -1
- package/dist/events/interface.d.ts +30 -0
- package/dist/events/interface.d.ts.map +1 -1
- package/dist/events/interface.js.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/invites/interface.d.ts +15 -0
- package/dist/invites/interface.d.ts.map +1 -1
- package/dist/invites/types.d.ts +10 -0
- package/dist/invites/types.d.ts.map +1 -1
- package/dist/permissions/interface.d.ts +17 -0
- package/dist/permissions/interface.d.ts.map +1 -1
- package/dist/shareLinks/index.d.ts +1 -1
- package/dist/shareLinks/index.d.ts.map +1 -1
- package/dist/shareLinks/interface.d.ts +14 -1
- package/dist/shareLinks/interface.d.ts.map +1 -1
- package/dist/shareLinks/types.d.ts +17 -0
- package/dist/shareLinks/types.d.ts.map +1 -1
- package/dist/shareLinks/types.js.map +1 -1
- package/dist/testing/suites/inviteStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/inviteStoreSuite.js +47 -0
- package/dist/testing/suites/inviteStoreSuite.js.map +1 -1
- package/dist/testing/suites/platformPermissionStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/platformPermissionStoreSuite.js +120 -0
- package/dist/testing/suites/platformPermissionStoreSuite.js.map +1 -1
- package/dist/testing/suites/shareLinkStoreSuite.d.ts +8 -0
- package/dist/testing/suites/shareLinkStoreSuite.d.ts.map +1 -1
- package/dist/testing/suites/shareLinkStoreSuite.js +78 -3
- package/dist/testing/suites/shareLinkStoreSuite.js.map +1 -1
- package/package.json +1 -1
package/dist/invites/types.d.ts
CHANGED
|
@@ -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;
|
|
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;
|
|
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;
|
|
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;
|
|
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":"
|
|
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,
|
|
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":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAG9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,QAAQ,EAAE,YAAY,EAAmB,MAAM,cAAc,CAAC;AAqBxF,SAAS,MAAM,CAAC,KAAsB,EAAE,YAA6B,EAAE;IACtE,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,OAAO;QACN,EAAE,EAAE,SAAS,CAAC,EAAE,IAAI,QAAQ,EAAE;QAC9B,uEAAuE;QACvE,oEAAoE;QACpE,mEAAmE;QACnE,yCAAyC;QACzC,SAAS,EACR,SAAS,CAAC,SAAS,IAAI,QAAQ,QAAQ,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;QACtF,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,WAAW,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,aAAa;QACxF,KAAK,EAAE,SAAS,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK;QACrC,OAAO,EAAE,SAAS,CAAC,OAAO,IAAI,QAAQ;QACtC,cAAc,EAAE,SAAS,CAAC,cAAc,IAAI,EAAE;QAC9C,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,KAAK,CAAC,OAAO;QAC/C,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,GAAG,CAAC,WAAW,EAAE;QACnD,SAAS,EAAE,SAAS,CAAC,SAAS,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,WAAW,EAAE;QAC7F,UAAU,EAAE,SAAS,CAAC,UAAU;QAChC,gBAAgB,EAAE,SAAS,CAAC,gBAAgB;KAC5C,CAAC;AACH,CAAC;AAED,MAAM,aAAa,GAAoB;IACtC,OAAO,EAAE,SAAS;IAClB,KAAK,EAAE,OAAO;CACd,CAAC;AAEF,MAAM,UAAU,yBAAyB,CAAC,IAAmC;IAC5E,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,GAAG,YAAY,EAAE,GAAG,IAAI,CAAC;IACzE,MAAM,EAAE,GAAG,EAAE,aAAa,EAAE,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACzD,MAAM,QAAQ,GAAG,KAAK,IAA8B,EAAE;QACrD,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,WAAW,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC;QAC5D,IAAI,CAAC,CAAC,iBAAiB;YAAE,aAAa,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,iBAAiB,CAAC,CAAC;QACvE,OAAO,CAAC,CAAC;IACV,CAAC,CAAC;IAEF,QAAQ,CAAC,6BAA6B,IAAI,EAAE,EAAE,GAAG,EAAE;QAClD,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;YACpD,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;YAC5C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YACtE,MAAM,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7B,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;YAC7D,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAClC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,cAAc,EAAE,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC;YAC7E,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC/D,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,EAAE;gBACzB,SAAS,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,CAAC,WAAW,EAAE;aACtD,CAAC,CAAC;YACH,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;YAC5C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YACtE,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;YAClG,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;YAC5C,MAAM,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC3D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YACtE,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;YACpE,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAC;YACxD,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;YAC5C,MAAM,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;YAC3D,MAAM,KAAK,CAAC,YAAY,CAAC,cAAc,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;YACtD,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAClF,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,KAAK,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC;YACpF,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QACrD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;YAChD,MAAM,KAAK,GAAG,MAAM,WAAW,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;YAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;YAC1B,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;YAC5C,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,cAAc,EAAE,GAAG,CAAC,SAAS,CAAC,CAAC;YACtE,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC;QACxB,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
|
|
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,
|
|
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;
|
|
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
|
|
103
|
-
//
|
|
104
|
-
//
|
|
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();
|