@marinoscar/platform-api 0.1.0-next.23 → 0.1.0-next.24
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/CHANGELOG.md +11 -0
- package/dist/core/data-access/access-reason.registry.d.ts +4 -1
- package/dist/core/data-access/access-reason.registry.d.ts.map +1 -1
- package/dist/core/data-access/access-reason.registry.js +5 -0
- package/dist/core/data-access/access-reason.registry.js.map +1 -1
- package/dist/core/testing/vocabulary-conformance.js +2 -2
- package/dist/core/testing/vocabulary-conformance.js.map +1 -1
- package/dist/sharing/events.d.ts +23 -0
- package/dist/sharing/events.d.ts.map +1 -1
- package/dist/sharing/events.js +1 -0
- package/dist/sharing/events.js.map +1 -1
- package/dist/sharing/groups/group-common.d.ts +1 -1
- package/dist/sharing/groups/group-common.d.ts.map +1 -1
- package/dist/sharing/groups/group-common.js.map +1 -1
- package/dist/sharing/groups/group-invites.service.d.ts +77 -2
- package/dist/sharing/groups/group-invites.service.d.ts.map +1 -1
- package/dist/sharing/groups/group-invites.service.js +181 -0
- package/dist/sharing/groups/group-invites.service.js.map +1 -1
- package/dist/sharing/groups/invite-auto-accept.listener.d.ts +37 -0
- package/dist/sharing/groups/invite-auto-accept.listener.d.ts.map +1 -0
- package/dist/sharing/groups/invite-auto-accept.listener.js +115 -0
- package/dist/sharing/groups/invite-auto-accept.listener.js.map +1 -0
- package/dist/sharing/index.d.ts +5 -3
- package/dist/sharing/index.d.ts.map +1 -1
- package/dist/sharing/index.js +6 -3
- package/dist/sharing/index.js.map +1 -1
- package/dist/sharing/metrics.d.ts +1 -1
- package/dist/sharing/metrics.d.ts.map +1 -1
- package/dist/sharing/metrics.js +1 -0
- package/dist/sharing/metrics.js.map +1 -1
- package/dist/sharing/ports.d.ts +3 -2
- package/dist/sharing/ports.d.ts.map +1 -1
- package/dist/sharing/ports.js.map +1 -1
- package/dist/sharing/sharing.module.d.ts.map +1 -1
- package/dist/sharing/sharing.module.js +3 -0
- package/dist/sharing/sharing.module.js.map +1 -1
- package/dist/sharing/sharing.options.d.ts +39 -5
- package/dist/sharing/sharing.options.d.ts.map +1 -1
- package/dist/sharing/sharing.options.js +17 -8
- package/dist/sharing/sharing.options.js.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @marinoscar/platform-api
|
|
2
2
|
|
|
3
|
+
## 0.1.0-next.24
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- e86f35f: Sharing: `groups.autoAcceptInvitesOnSignup` is real (#1078). The new `InviteAutoAcceptListener` (registered only when an option is on) claims a person's open, unexpired group invites from identity's `identity.user.created` event, and with the new `groups.autoAcceptInvitesOnSignIn` from every `identity.login.succeeded`. `GroupInvitesService.claimPendingForEmail(userId, email, { orgId? })` and `claimPendingForUser(userId)` do the work: the user must exist, be active and own the address; each invite is claimed in its own organization and transaction (a failing one never blocks the others or the sign-in); a new member gets the invite's role and an existing member is merged by the new `groups.inviteRoleMerge` (`upgrade-only` default, `replace`, `keep`). New event `sharing.group.invite_auto_accepted` (`GroupInviteAutoAcceptedPayload`), audit action `group:invite_auto_accepted`, metric op `invite_auto_accept`, span `sharing.invites.auto_accept`. New `SystemAccessReason` `invite-claim` (the cross-organization lookup of the open invites addressed to one user's own address; also a `SharingSystemReason`): an app whose `SharingDataPort.runAsSystem` passes reasons through needs no change. The startup "no effect" warning is gone.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- @marinoscar/platform-contract@0.1.0-next.24
|
|
12
|
+
- @marinoscar/platform-ai-providers@0.1.0-next.24
|
|
13
|
+
|
|
3
14
|
## 0.1.0-next.23
|
|
4
15
|
|
|
5
16
|
### Minor Changes
|
|
@@ -13,10 +13,13 @@ import { type Registry } from '../registry/registry';
|
|
|
13
13
|
* - `link-resolution`: resolving a link-share token: ONE row of `grants`, by
|
|
14
14
|
* its unique token hash, before any organization is known.
|
|
15
15
|
* - `export`: the data-export sources and the export file lookups.
|
|
16
|
+
* - `invite-claim`: finding the open group invites addressed to ONE user's own
|
|
17
|
+
* verified e-mail address across organizations, before any organization is
|
|
18
|
+
* known (each claim then runs in its invite's organization).
|
|
16
19
|
*
|
|
17
20
|
* @stability experimental
|
|
18
21
|
*/
|
|
19
|
-
export declare const BUILTIN_SYSTEM_ACCESS_REASONS: readonly ["backup", "restore", "purge", "doctor", "retention", "admin-aggregate", "migration-tooling", "link-resolution", "export"];
|
|
22
|
+
export declare const BUILTIN_SYSTEM_ACCESS_REASONS: readonly ["backup", "restore", "purge", "doctor", "retention", "admin-aggregate", "migration-tooling", "link-resolution", "export", "invite-claim"];
|
|
20
23
|
/**
|
|
21
24
|
* One of the platform's own access reasons. See {@link BUILTIN_SYSTEM_ACCESS_REASONS}.
|
|
22
25
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-reason.registry.d.ts","sourceRoot":"","sources":["../../../src/core/data-access/access-reason.registry.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErE
|
|
1
|
+
{"version":3,"file":"access-reason.registry.d.ts","sourceRoot":"","sources":["../../../src/core/data-access/access-reason.registry.ts"],"names":[],"mappings":"AAwBA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAErE;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,6BAA6B,qJAW/B,CAAC;AAEZ;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG,CAAC,OAAO,6BAA6B,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvF;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,QAA2B,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,qBAAqB;IACpC,kEAAkE;IAClE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,+GAA+G;IAC/G,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAE,QAAQ,CAAC,qBAAqB,CASrE,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,qBAAqB,GAAG,IAAI,CAE9E;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAEpE"}
|
|
@@ -41,6 +41,9 @@ const registry_1 = require("../registry/registry");
|
|
|
41
41
|
* - `link-resolution`: resolving a link-share token: ONE row of `grants`, by
|
|
42
42
|
* its unique token hash, before any organization is known.
|
|
43
43
|
* - `export`: the data-export sources and the export file lookups.
|
|
44
|
+
* - `invite-claim`: finding the open group invites addressed to ONE user's own
|
|
45
|
+
* verified e-mail address across organizations, before any organization is
|
|
46
|
+
* known (each claim then runs in its invite's organization).
|
|
44
47
|
*
|
|
45
48
|
* @stability experimental
|
|
46
49
|
*/
|
|
@@ -54,6 +57,7 @@ exports.BUILTIN_SYSTEM_ACCESS_REASONS = Object.freeze([
|
|
|
54
57
|
'migration-tooling',
|
|
55
58
|
'link-resolution',
|
|
56
59
|
'export',
|
|
60
|
+
'invite-claim',
|
|
57
61
|
]);
|
|
58
62
|
/**
|
|
59
63
|
* The pattern every access reason id matches: lower-case, 3 to 48 characters,
|
|
@@ -129,6 +133,7 @@ const BUILTIN_DESCRIPTIONS = {
|
|
|
129
133
|
'migration-tooling': 'Seeds and migration helpers.',
|
|
130
134
|
'link-resolution': 'Resolving a link-share token: one grants row, by its unique token hash, before any organization is known.',
|
|
131
135
|
export: 'The data-export sources and the export file lookups.',
|
|
136
|
+
'invite-claim': 'Finding the open group invites addressed to one user\'s own verified e-mail address across organizations; each claim then runs in its invite\'s organization.',
|
|
132
137
|
};
|
|
133
138
|
for (const id of exports.BUILTIN_SYSTEM_ACCESS_REASONS) {
|
|
134
139
|
registerSystemAccessReason({ id, description: BUILTIN_DESCRIPTIONS[id] });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"access-reason.registry.js","sourceRoot":"","sources":["../../../src/core/data-access/access-reason.registry.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+CAA+C;AAC/C,gFAAgF;AAChF,EAAE;AACF,kEAAkE;AAClE,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,gBAAgB;AAChB,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,4EAA4E;AAC5E,8EAA8E;AAC9E,iFAAiF;AACjF,iFAAiF;AACjF,qCAAqC;AACrC,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;
|
|
1
|
+
{"version":3,"file":"access-reason.registry.js","sourceRoot":"","sources":["../../../src/core/data-access/access-reason.registry.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,+CAA+C;AAC/C,gFAAgF;AAChF,EAAE;AACF,kEAAkE;AAClE,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,gBAAgB;AAChB,EAAE;AACF,6EAA6E;AAC7E,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,4EAA4E;AAC5E,8EAA8E;AAC9E,iFAAiF;AACjF,iFAAiF;AACjF,qCAAqC;AACrC,EAAE;AACF,gFAAgF;AAChF,gFAAgF;;;AAmHhF,gEAEC;AAUD,oDAEC;AA/HD,mDAAqE;AAErE;;;;;;;;;;;;;;;;;;;GAmBG;AACU,QAAA,6BAA6B,GAAG,MAAM,CAAC,MAAM,CAAC;IACzD,QAAQ;IACR,SAAS;IACT,OAAO;IACP,QAAQ;IACR,WAAW;IACX,iBAAiB;IACjB,mBAAmB;IACnB,iBAAiB;IACjB,QAAQ;IACR,cAAc;CACN,CAAC,CAAC;AASZ;;;;;GAKG;AACU,QAAA,+BAA+B,GAAG,wBAAwB,CAAC;AAqBxE;;;;;;;GAOG;AACU,QAAA,0BAA0B,GAAoC,IAAA,yBAAc,EAAwB;IAC/G,IAAI,EAAE,4BAA4B;IAClC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE;IAC3B,SAAS,EAAE,uCAA+B;IAC1C,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;QACnB,IAAI,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;YAC/E,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,CAAC,EAAE,2CAA2C,CAAC,CAAC;QACjG,CAAC;IACH,CAAC;CACF,CAAC,CAAC;AAEH;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,SAAgB,0BAA0B,CAAC,MAA6B;IACtE,kCAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9C,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,oBAAoB,CAAC,KAAc;IACjD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,kCAA0B,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAC5E,CAAC;AAED,MAAM,oBAAoB,GAAwD;IAChF,MAAM,EAAE,oBAAoB;IAC5B,OAAO,EAAE,gCAAgC;IACzC,KAAK,EAAE,6EAA6E;IACpF,MAAM,EAAE,+DAA+D;IACvE,SAAS,EAAE,+BAA+B;IAC1C,iBAAiB,EAAE,4GAA4G;IAC/H,mBAAmB,EAAE,8BAA8B;IACnD,iBAAiB,EAAE,2GAA2G;IAC9H,MAAM,EAAE,sDAAsD;IAC9D,cAAc,EAAE,+JAA+J;CAChL,CAAC;AAEF,KAAK,MAAM,EAAE,IAAI,qCAA6B,EAAE,CAAC;IAC/C,0BAA0B,CAAC,EAAE,EAAE,EAAE,WAAW,EAAE,oBAAoB,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// what the enforcement relies on:
|
|
10
10
|
//
|
|
11
11
|
// access reasons every id matches the pattern and has a description; the
|
|
12
|
-
//
|
|
12
|
+
// built-ins are registered and unchanged; an
|
|
13
13
|
// unregistered, empty, non-string or prototype-named reason
|
|
14
14
|
// is REFUSED by the bypass entry points (`systemScopeExtension`,
|
|
15
15
|
// `runAsSystem`); a registered one is accepted
|
|
@@ -65,7 +65,7 @@ const NO_DATABASE_CLIENT = {
|
|
|
65
65
|
function describeVocabularyConformance(harness, options = {}) {
|
|
66
66
|
const { describe, it, expect } = harness;
|
|
67
67
|
describe('system access reasons', () => {
|
|
68
|
-
it('registers the
|
|
68
|
+
it('registers the built-in reasons first, in order', () => {
|
|
69
69
|
expect(access_reason_registry_1.systemAccessReasonRegistry.ids().slice(0, access_reason_registry_1.BUILTIN_SYSTEM_ACCESS_REASONS.length)).toEqual([...access_reason_registry_1.BUILTIN_SYSTEM_ACCESS_REASONS]);
|
|
70
70
|
});
|
|
71
71
|
it('gives every reason a well-formed id and a description', () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vocabulary-conformance.js","sourceRoot":"","sources":["../../../src/core/testing/vocabulary-conformance.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,6CAA6C;AAC7C,gFAAgF;AAChF,EAAE;AACF,+EAA+E;AAC/E,gFAAgF;AAChF,8EAA8E;AAC9E,kCAAkC;AAClC,EAAE;AACF,8EAA8E;AAC9E,
|
|
1
|
+
{"version":3,"file":"vocabulary-conformance.js","sourceRoot":"","sources":["../../../src/core/testing/vocabulary-conformance.ts"],"names":[],"mappings":"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"}
|
package/dist/sharing/events.d.ts
CHANGED
|
@@ -20,6 +20,13 @@ export declare const SHARING_EVENTS: {
|
|
|
20
20
|
readonly INVITE_CREATED: 'sharing.group.invite_created';
|
|
21
21
|
/** An invite was accepted (a `MEMBER_ADDED` follows). */
|
|
22
22
|
readonly INVITE_ACCEPTED: 'sharing.group.invite_accepted';
|
|
23
|
+
/**
|
|
24
|
+
* An invite was claimed automatically at sign-up or sign-in
|
|
25
|
+
* (`groups.autoAcceptInvitesOnSignup` / `autoAcceptInvitesOnSignIn`). Emitted
|
|
26
|
+
* once per claimed invite, after `INVITE_ACCEPTED` and the member event of the
|
|
27
|
+
* same claim; the app sends its own confirmation from it.
|
|
28
|
+
*/
|
|
29
|
+
readonly INVITE_AUTO_ACCEPTED: 'sharing.group.invite_auto_accepted';
|
|
23
30
|
/** A record was shared: a new grant (#729). */
|
|
24
31
|
readonly GRANT_CREATED: 'sharing.grant.created';
|
|
25
32
|
/** A grant's role or expiry changed, or a re-grant replaced its role (#729). */
|
|
@@ -71,6 +78,22 @@ export interface GroupInviteEventPayload extends GroupEventPayload {
|
|
|
71
78
|
/** The role it grants. */
|
|
72
79
|
readonly role: GroupRole;
|
|
73
80
|
}
|
|
81
|
+
/**
|
|
82
|
+
* The payload of `sharing.group.invite_auto_accepted`: ids and roles only.
|
|
83
|
+
* `actorUserId` is the invitee, who is also `userId`.
|
|
84
|
+
*
|
|
85
|
+
* @stability experimental
|
|
86
|
+
*/
|
|
87
|
+
export interface GroupInviteAutoAcceptedPayload extends GroupInviteEventPayload {
|
|
88
|
+
/** The user who joined or was upgraded. */
|
|
89
|
+
readonly userId: string;
|
|
90
|
+
/** What the claim did: added the user, raised their role, or left it as it was. */
|
|
91
|
+
readonly outcome: 'joined' | 'upgraded' | 'unchanged';
|
|
92
|
+
/** The role the user held before the claim (`null` when newly added). */
|
|
93
|
+
readonly previousRole: GroupRole | null;
|
|
94
|
+
/** The role the user holds now. */
|
|
95
|
+
readonly memberRole: GroupRole;
|
|
96
|
+
}
|
|
74
97
|
/**
|
|
75
98
|
* The payload of the three grant events (#729): ids and roles only.
|
|
76
99
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sharing/events.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAEvE;;;;;GAKG;AACH,eAAO,MAAM,cAAc,EAAE;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;IAChD,wDAAwD;IACxD,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;IAChD,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,4BAA4B,CAAC;IACpD,oCAAoC;IACpC,QAAQ,CAAC,cAAc,EAAE,8BAA8B,CAAC;IACxD,+BAA+B;IAC/B,QAAQ,CAAC,mBAAmB,EAAE,mCAAmC,CAAC;IAClE,6BAA6B;IAC7B,QAAQ,CAAC,cAAc,EAAE,8BAA8B,CAAC;IACxD,yDAAyD;IACzD,QAAQ,CAAC,eAAe,EAAE,+BAA+B,CAAC;IAC1D,+CAA+C;IAC/C,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;IAChD,gFAAgF;IAChF,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;IAChD,kCAAkC;IAClC,QAAQ,CAAC,aAAa,EAAE,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/sharing/events.ts"],"names":[],"mappings":"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"}
|
package/dist/sharing/events.js
CHANGED
|
@@ -29,6 +29,7 @@ exports.SHARING_EVENTS = {
|
|
|
29
29
|
MEMBER_ROLE_CHANGED: 'sharing.group.member_role_changed',
|
|
30
30
|
INVITE_CREATED: 'sharing.group.invite_created',
|
|
31
31
|
INVITE_ACCEPTED: 'sharing.group.invite_accepted',
|
|
32
|
+
INVITE_AUTO_ACCEPTED: 'sharing.group.invite_auto_accepted',
|
|
32
33
|
GRANT_CREATED: 'sharing.grant.created',
|
|
33
34
|
GRANT_UPDATED: 'sharing.grant.updated',
|
|
34
35
|
GRANT_REVOKED: 'sharing.grant.revoked',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sharing/events.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0EAA0E;AAC1E,gFAAgF;AAChF,EAAE;AACF,kFAAkF;AAClF,iEAAiE;AACjE,gCAAgC;AAChC,EAAE;AACF,8EAA8E;AAC9E,gCAAgC;AAChC,8EAA8E;AAC9E,8EAA8E;AAC9E,4DAA4D;AAC5D,gFAAgF;;;AAIhF;;;;;GAKG;AACU,QAAA,cAAc,
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/sharing/events.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,0EAA0E;AAC1E,gFAAgF;AAChF,EAAE;AACF,kFAAkF;AAClF,iEAAiE;AACjE,gCAAgC;AAChC,EAAE;AACF,8EAA8E;AAC9E,gCAAgC;AAChC,8EAA8E;AAC9E,8EAA8E;AAC9E,4DAA4D;AAC5D,gFAAgF;;;AAIhF;;;;;GAKG;AACU,QAAA,cAAc,GA4BvB;IACF,aAAa,EAAE,uBAAuB;IACtC,aAAa,EAAE,uBAAuB;IACtC,YAAY,EAAE,4BAA4B;IAC1C,cAAc,EAAE,8BAA8B;IAC9C,mBAAmB,EAAE,mCAAmC;IACxD,cAAc,EAAE,8BAA8B;IAC9C,eAAe,EAAE,+BAA+B;IAChD,oBAAoB,EAAE,oCAAoC;IAC1D,aAAa,EAAE,uBAAuB;IACtC,aAAa,EAAE,uBAAuB;IACtC,aAAa,EAAE,uBAAuB;CACvC,CAAC"}
|
|
@@ -23,7 +23,7 @@ export declare function isGroupsAdmin(principal: Principal): boolean;
|
|
|
23
23
|
*/
|
|
24
24
|
export declare function lockGroup(tx: SharingTx, groupId: string): Promise<void>;
|
|
25
25
|
/** The audit actions of the slice, `group:<verb>`. */
|
|
26
|
-
export type GroupAuditAction = 'group:created' | 'group:updated' | 'group:deleted' | 'group:member_added' | 'group:member_removed' | 'group:member_role_changed' | 'group:invite_created' | 'group:invite_revoked' | 'group:invite_accepted' | 'group:invite_declined';
|
|
26
|
+
export type GroupAuditAction = 'group:created' | 'group:updated' | 'group:deleted' | 'group:member_added' | 'group:member_removed' | 'group:member_role_changed' | 'group:invite_created' | 'group:invite_revoked' | 'group:invite_accepted' | 'group:invite_declined' | 'group:invite_auto_accepted';
|
|
27
27
|
/**
|
|
28
28
|
* Writes one audit row INSIDE the caller's transaction, with the
|
|
29
29
|
* organization (#725). `meta` carries ids and roles only, never an address.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-common.d.ts","sourceRoot":"","sources":["../../../src/sharing/groups/group-common.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKpD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAK7D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED,wFAAwF;AACxF,wBAAgB,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAE3D;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7E;AAED,sDAAsD;AACtD,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,eAAe,GACf,eAAe,GACf,oBAAoB,GACpB,sBAAsB,GACtB,2BAA2B,GAC3B,sBAAsB,GACtB,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"group-common.d.ts","sourceRoot":"","sources":["../../../src/sharing/groups/group-common.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uCAAuC,CAAC;AAEvE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAKpD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAK7D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEnD;AAED,wFAAwF;AACxF,wBAAgB,KAAK,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAEvE;AAED,qFAAqF;AACrF,wBAAgB,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAE3D;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE7E;AAED,sDAAsD;AACtD,MAAM,MAAM,gBAAgB,GACxB,eAAe,GACf,eAAe,GACf,eAAe,GACf,oBAAoB,GACpB,sBAAsB,GACtB,2BAA2B,GAC3B,sBAAsB,GACtB,sBAAsB,GACtB,uBAAuB,GACvB,uBAAuB,GACvB,4BAA4B,CAAC;AAEjC;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,EAAE,EAAE,SAAS,EACb,KAAK,EAAE;IACL,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,gBAAgB,CAAC;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,CAAC;CACzD,GACA,OAAO,CAAC,IAAI,CAAC,CAWf;AAED,uEAAuE;AACvE,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAEzD;AAED,iDAAiD;AACjD,wBAAgB,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAEjE;AAED,6EAA6E;AAC7E,wBAAgB,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM;;;;;;EAEjF;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAKtF;AAED,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-common.js","sourceRoot":"","sources":["../../../src/sharing/groups/group-common.ts"],"names":[],"mappings":";AAAA,gFAAgF;AAChF,qEAAqE;AACrE,gFAAgF;;AAehF,4CAKC;AAOD,4CAEC;AAGD,sBAEC;AAGD,sCAEC;AAOD,8BAEC;
|
|
1
|
+
{"version":3,"file":"group-common.js","sourceRoot":"","sources":["../../../src/sharing/groups/group-common.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type { CreateGroupInviteInput, GroupInviteDto, GroupInviteList, GroupInviteListQuery, GroupInviteStatus, GroupMembershipDto, MyGroupInviteList } from '@marinoscar/platform-contract/sharing';
|
|
1
|
+
import type { GroupRole, CreateGroupInviteInput, GroupInviteDto, GroupInviteList, GroupInviteListQuery, GroupInviteStatus, GroupMembershipDto, MyGroupInviteList } from '@marinoscar/platform-contract/sharing';
|
|
2
2
|
import type { Principal } from '../../core/index';
|
|
3
3
|
import { type GroupInviteRow } from '../data/sharing-tx';
|
|
4
4
|
import { type SharingDataPort, type SharingTenancy } from '../ports';
|
|
5
|
-
import { type ResolvedSharingModuleOptions } from '../sharing.options';
|
|
5
|
+
import { type InviteRoleMerge, type ResolvedSharingModuleOptions } from '../sharing.options';
|
|
6
6
|
import { GroupMembershipService } from './group-membership.service';
|
|
7
7
|
import { SharingEffects } from './sharing-effects';
|
|
8
8
|
/**
|
|
@@ -36,6 +36,35 @@ export declare function inviteStatus(row: {
|
|
|
36
36
|
* @stability experimental
|
|
37
37
|
*/
|
|
38
38
|
export declare function toGroupInviteDto(row: GroupInviteRow, now: Date): GroupInviteDto;
|
|
39
|
+
/**
|
|
40
|
+
* What {@link GroupInvitesService.claimPendingForEmail} did.
|
|
41
|
+
*
|
|
42
|
+
* @stability experimental
|
|
43
|
+
*/
|
|
44
|
+
export interface InviteClaimResult {
|
|
45
|
+
/** Group ids the user newly joined. */
|
|
46
|
+
joined: string[];
|
|
47
|
+
/** Group ids where an existing membership was raised (or, under `replace`, changed) to the invite's role. */
|
|
48
|
+
upgraded: string[];
|
|
49
|
+
/**
|
|
50
|
+
* Invite ids that changed nothing: the user already held an equal or higher
|
|
51
|
+
* role (the invite is still consumed), or the claim could not be applied
|
|
52
|
+
* (the group is full, the organization is not joined yet, or a transaction
|
|
53
|
+
* failed; those invites stay pending).
|
|
54
|
+
*/
|
|
55
|
+
skipped: string[];
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* The role a claimed invite leaves an EXISTING member with.
|
|
59
|
+
*
|
|
60
|
+
* @param mode - the `groups.inviteRoleMerge` option.
|
|
61
|
+
* @param current - the member's role now.
|
|
62
|
+
* @param invited - the invite's role.
|
|
63
|
+
* @returns the role to store (rank comes from the group role catalog).
|
|
64
|
+
*
|
|
65
|
+
* @stability experimental
|
|
66
|
+
*/
|
|
67
|
+
export declare function mergeInviteRole(mode: InviteRoleMerge, current: GroupRole, invited: GroupRole): GroupRole;
|
|
39
68
|
/**
|
|
40
69
|
* Invitations to groups: the admin routes and the invitee's answers.
|
|
41
70
|
*
|
|
@@ -48,6 +77,7 @@ export declare class GroupInvitesService {
|
|
|
48
77
|
private readonly effects;
|
|
49
78
|
private readonly tenancy?;
|
|
50
79
|
private readonly clock;
|
|
80
|
+
private readonly logger;
|
|
51
81
|
constructor(data: SharingDataPort, options: ResolvedSharingModuleOptions, membership: GroupMembershipService, effects: SharingEffects, tenancy?: SharingTenancy | undefined, clock?: () => number);
|
|
52
82
|
private now;
|
|
53
83
|
/**
|
|
@@ -114,5 +144,50 @@ export declare class GroupInvitesService {
|
|
|
114
144
|
* @throws GoneException 410 `INVITE_EXPIRED`.
|
|
115
145
|
*/
|
|
116
146
|
decline(principal: Principal, inviteId: string): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* Claims every open, unexpired invite addressed to `email` for `userId`, in
|
|
149
|
+
* every organization: joins the group with the invite's role, or applies
|
|
150
|
+
* `groups.inviteRoleMerge` (default upgrade-only, never a downgrade) to an
|
|
151
|
+
* existing member. This is the platform form of a sign-in invite claim; the
|
|
152
|
+
* automatic listener (`groups.autoAcceptInvitesOnSignup` / `...OnSignIn`)
|
|
153
|
+
* calls it, and an app may call it directly.
|
|
154
|
+
*
|
|
155
|
+
* Safe by construction: the user must exist, be active and have exactly this
|
|
156
|
+
* address (identity creates and signs in users only on a provider-verified
|
|
157
|
+
* address), so one user's call can never claim another's invites. The
|
|
158
|
+
* discovery is the only cross-organization read (system reason
|
|
159
|
+
* `invite-claim`); each invite is then claimed in ITS organization, in its
|
|
160
|
+
* own transaction, so a failing invite never blocks the others. In
|
|
161
|
+
* multi-organization mode the user must already be an active member of the
|
|
162
|
+
* invite's organization, else the invite stays pending. Events, cache
|
|
163
|
+
* invalidation and the counter run after each commit.
|
|
164
|
+
*
|
|
165
|
+
* @param userId - the user the invites are for.
|
|
166
|
+
* @param email - the user's address (matched case-insensitively).
|
|
167
|
+
* @param opts - `orgId` limits the claim to one organization.
|
|
168
|
+
* @returns the groups joined, the groups upgraded, and the invites that changed nothing.
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```ts
|
|
172
|
+
* const { joined } = await invites.claimPendingForEmail(user.id, user.email);
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
claimPendingForEmail(userId: string, email: string, opts?: {
|
|
176
|
+
orgId?: string;
|
|
177
|
+
}): Promise<InviteClaimResult>;
|
|
178
|
+
/**
|
|
179
|
+
* Like {@link claimPendingForEmail}, with the address read from the user's
|
|
180
|
+
* own record (for a sign-in event that carries no address).
|
|
181
|
+
*
|
|
182
|
+
* @param userId - the user.
|
|
183
|
+
* @param opts - `orgId` limits the claim to one organization.
|
|
184
|
+
* @returns the same result.
|
|
185
|
+
*/
|
|
186
|
+
claimPendingForUser(userId: string, opts?: {
|
|
187
|
+
orgId?: string;
|
|
188
|
+
}): Promise<InviteClaimResult>;
|
|
189
|
+
private claim;
|
|
190
|
+
/** One invite, in its own organization and transaction. */
|
|
191
|
+
private claimOne;
|
|
117
192
|
}
|
|
118
193
|
//# sourceMappingURL=group-invites.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"group-invites.service.d.ts","sourceRoot":"","sources":["../../../src/sharing/groups/group-invites.service.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,kBAAkB,EAElB,iBAAiB,EAClB,MAAM,uCAAuC,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAElD,OAAO,EAAe,KAAK,cAAc,EAAkB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"group-invites.service.d.ts","sourceRoot":"","sources":["../../../src/sharing/groups/group-invites.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -40,11 +40,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
exports.GroupInvitesService = exports.GROUP_INVITES_CLOCK = void 0;
|
|
41
41
|
exports.inviteStatus = inviteStatus;
|
|
42
42
|
exports.toGroupInviteDto = toGroupInviteDto;
|
|
43
|
+
exports.mergeInviteRole = mergeInviteRole;
|
|
43
44
|
const common_1 = require("@nestjs/common");
|
|
44
45
|
const index_1 = require("../../otel-core/index");
|
|
45
46
|
const sharing_tx_1 = require("../data/sharing-tx");
|
|
46
47
|
const errors_1 = require("../errors");
|
|
47
48
|
const events_1 = require("../events");
|
|
49
|
+
const group_roles_1 = require("../group-roles");
|
|
48
50
|
const ports_1 = require("../ports");
|
|
49
51
|
const sharing_options_1 = require("../sharing.options");
|
|
50
52
|
const group_common_1 = require("./group-common");
|
|
@@ -104,6 +106,23 @@ function toGroupInviteDto(row, now) {
|
|
|
104
106
|
createdAt: (0, group_common_1.iso)(row.createdAt),
|
|
105
107
|
};
|
|
106
108
|
}
|
|
109
|
+
/**
|
|
110
|
+
* The role a claimed invite leaves an EXISTING member with.
|
|
111
|
+
*
|
|
112
|
+
* @param mode - the `groups.inviteRoleMerge` option.
|
|
113
|
+
* @param current - the member's role now.
|
|
114
|
+
* @param invited - the invite's role.
|
|
115
|
+
* @returns the role to store (rank comes from the group role catalog).
|
|
116
|
+
*
|
|
117
|
+
* @stability experimental
|
|
118
|
+
*/
|
|
119
|
+
function mergeInviteRole(mode, current, invited) {
|
|
120
|
+
if (mode === 'keep')
|
|
121
|
+
return current;
|
|
122
|
+
if (mode === 'replace')
|
|
123
|
+
return invited;
|
|
124
|
+
return (0, group_roles_1.groupRoleRank)(invited) > (0, group_roles_1.groupRoleRank)(current) ? invited : current;
|
|
125
|
+
}
|
|
107
126
|
/** The organizations a principal belongs to and may act in, active one first. */
|
|
108
127
|
function orgsOf(principal) {
|
|
109
128
|
const listed = (principal.memberships ?? []).filter((m) => m.status !== 'suspended').map((m) => m.orgId);
|
|
@@ -122,6 +141,7 @@ let GroupInvitesService = class GroupInvitesService {
|
|
|
122
141
|
effects;
|
|
123
142
|
tenancy;
|
|
124
143
|
clock;
|
|
144
|
+
logger = new common_1.Logger('GroupInvitesService');
|
|
125
145
|
constructor(data, options, membership, effects, tenancy, clock = Date.now) {
|
|
126
146
|
this.data = data;
|
|
127
147
|
this.options = options;
|
|
@@ -411,6 +431,155 @@ let GroupInvitesService = class GroupInvitesService {
|
|
|
411
431
|
});
|
|
412
432
|
this.effects.committed({ op: 'invite_decline' });
|
|
413
433
|
}
|
|
434
|
+
/**
|
|
435
|
+
* Claims every open, unexpired invite addressed to `email` for `userId`, in
|
|
436
|
+
* every organization: joins the group with the invite's role, or applies
|
|
437
|
+
* `groups.inviteRoleMerge` (default upgrade-only, never a downgrade) to an
|
|
438
|
+
* existing member. This is the platform form of a sign-in invite claim; the
|
|
439
|
+
* automatic listener (`groups.autoAcceptInvitesOnSignup` / `...OnSignIn`)
|
|
440
|
+
* calls it, and an app may call it directly.
|
|
441
|
+
*
|
|
442
|
+
* Safe by construction: the user must exist, be active and have exactly this
|
|
443
|
+
* address (identity creates and signs in users only on a provider-verified
|
|
444
|
+
* address), so one user's call can never claim another's invites. The
|
|
445
|
+
* discovery is the only cross-organization read (system reason
|
|
446
|
+
* `invite-claim`); each invite is then claimed in ITS organization, in its
|
|
447
|
+
* own transaction, so a failing invite never blocks the others. In
|
|
448
|
+
* multi-organization mode the user must already be an active member of the
|
|
449
|
+
* invite's organization, else the invite stays pending. Events, cache
|
|
450
|
+
* invalidation and the counter run after each commit.
|
|
451
|
+
*
|
|
452
|
+
* @param userId - the user the invites are for.
|
|
453
|
+
* @param email - the user's address (matched case-insensitively).
|
|
454
|
+
* @param opts - `orgId` limits the claim to one organization.
|
|
455
|
+
* @returns the groups joined, the groups upgraded, and the invites that changed nothing.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```ts
|
|
459
|
+
* const { joined } = await invites.claimPendingForEmail(user.id, user.email);
|
|
460
|
+
* ```
|
|
461
|
+
*/
|
|
462
|
+
async claimPendingForEmail(userId, email, opts = {}) {
|
|
463
|
+
return this.claim(userId, email, opts);
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* Like {@link claimPendingForEmail}, with the address read from the user's
|
|
467
|
+
* own record (for a sign-in event that carries no address).
|
|
468
|
+
*
|
|
469
|
+
* @param userId - the user.
|
|
470
|
+
* @param opts - `orgId` limits the claim to one organization.
|
|
471
|
+
* @returns the same result.
|
|
472
|
+
*/
|
|
473
|
+
async claimPendingForUser(userId, opts = {}) {
|
|
474
|
+
return this.claim(userId, null, opts);
|
|
475
|
+
}
|
|
476
|
+
async claim(userId, email, opts) {
|
|
477
|
+
const result = { joined: [], upgraded: [], skipped: [] };
|
|
478
|
+
const now = this.now();
|
|
479
|
+
const invites = await this.data.runAsSystem('invite-claim', async (raw) => {
|
|
480
|
+
const tx = (0, sharing_tx_1.asSharingTx)(raw);
|
|
481
|
+
const user = await tx.user.findFirst({ where: { id: userId }, select: { id: true, email: true, isActive: true } });
|
|
482
|
+
if (!user || !user.isActive)
|
|
483
|
+
return [];
|
|
484
|
+
const address = user.email.toLowerCase();
|
|
485
|
+
if (email !== null && email.trim().toLowerCase() !== address)
|
|
486
|
+
return [];
|
|
487
|
+
return tx.groupInvite.findMany({
|
|
488
|
+
where: {
|
|
489
|
+
email: address,
|
|
490
|
+
...OPEN,
|
|
491
|
+
OR: [{ expiresAt: null }, { expiresAt: { gt: now } }],
|
|
492
|
+
...(opts.orgId ? { orgId: opts.orgId } : {}),
|
|
493
|
+
},
|
|
494
|
+
select: { id: true, orgId: true },
|
|
495
|
+
orderBy: [{ createdAt: 'asc' }, { id: 'asc' }],
|
|
496
|
+
take: 200,
|
|
497
|
+
});
|
|
498
|
+
});
|
|
499
|
+
for (const { id: inviteId, orgId } of invites) {
|
|
500
|
+
try {
|
|
501
|
+
const step = await this.claimOne(userId, orgId, inviteId, now);
|
|
502
|
+
if (step.kind === 'gone')
|
|
503
|
+
continue;
|
|
504
|
+
if (step.kind === 'blocked') {
|
|
505
|
+
result.skipped.push(inviteId);
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
const outcome = step.previousRole === null ? 'joined' : step.role !== step.previousRole ? 'upgraded' : 'unchanged';
|
|
509
|
+
if (outcome === 'joined')
|
|
510
|
+
result.joined.push(step.groupId);
|
|
511
|
+
else if (outcome === 'upgraded')
|
|
512
|
+
result.upgraded.push(step.groupId);
|
|
513
|
+
else
|
|
514
|
+
result.skipped.push(inviteId);
|
|
515
|
+
const base = { orgId, groupId: step.groupId, actorUserId: userId };
|
|
516
|
+
this.effects.committed({
|
|
517
|
+
op: 'invite_auto_accept',
|
|
518
|
+
invalidate: [userId],
|
|
519
|
+
events: [
|
|
520
|
+
{ name: events_1.SHARING_EVENTS.INVITE_ACCEPTED, payload: { ...base, inviteId, role: step.inviteRole } },
|
|
521
|
+
...(outcome === 'joined'
|
|
522
|
+
? [{ name: events_1.SHARING_EVENTS.MEMBER_ADDED, payload: { ...base, userId, role: step.role, previousRole: null } }]
|
|
523
|
+
: outcome === 'upgraded'
|
|
524
|
+
? [{ name: events_1.SHARING_EVENTS.MEMBER_ROLE_CHANGED, payload: { ...base, userId, role: step.role, previousRole: step.previousRole } }]
|
|
525
|
+
: []),
|
|
526
|
+
{
|
|
527
|
+
name: events_1.SHARING_EVENTS.INVITE_AUTO_ACCEPTED,
|
|
528
|
+
payload: { ...base, inviteId, role: step.inviteRole, userId, outcome, previousRole: step.previousRole, memberRole: step.role },
|
|
529
|
+
},
|
|
530
|
+
],
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
catch (error) {
|
|
534
|
+
// One bad invite never blocks the others or the sign-in. Ids only.
|
|
535
|
+
result.skipped.push(inviteId);
|
|
536
|
+
this.logger.warn(`Invite ${inviteId} could not be auto-accepted: ${error instanceof Error ? error.message : String(error)}`);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
return result;
|
|
540
|
+
}
|
|
541
|
+
/** One invite, in its own organization and transaction. */
|
|
542
|
+
async claimOne(userId, orgId, inviteId, now) {
|
|
543
|
+
const open = { id: inviteId, orgId, ...OPEN, OR: [{ expiresAt: null }, { expiresAt: { gt: now } }] };
|
|
544
|
+
return this.data.runInOrg({ orgId, userId }, async (raw) => {
|
|
545
|
+
const tx = (0, sharing_tx_1.asSharingTx)(raw);
|
|
546
|
+
const first = await tx.groupInvite.findFirst({ where: open });
|
|
547
|
+
if (!first)
|
|
548
|
+
return { kind: 'gone' };
|
|
549
|
+
await (0, group_common_1.lockGroup)(tx, first.groupId);
|
|
550
|
+
// Re-check under the lock: a concurrent revoke, accept or claim loses.
|
|
551
|
+
const invite = await tx.groupInvite.findFirst({ where: open });
|
|
552
|
+
if (!invite)
|
|
553
|
+
return { kind: 'gone' };
|
|
554
|
+
if ((this.tenancy?.mode() ?? 'single') === 'multi') {
|
|
555
|
+
const member = await tx.membership.findFirst({ where: { orgId, userId, status: 'active' }, select: { userId: true } });
|
|
556
|
+
if (!member)
|
|
557
|
+
return { kind: 'blocked' };
|
|
558
|
+
}
|
|
559
|
+
const groupId = invite.groupId;
|
|
560
|
+
const existing = await tx.groupMember.findUnique({ where: { groupId_userId: { groupId, userId } } });
|
|
561
|
+
let role;
|
|
562
|
+
if (!existing) {
|
|
563
|
+
if ((await tx.groupMember.count({ where: { groupId } })) >= this.options.groups.maxMembersPerGroup)
|
|
564
|
+
return { kind: 'blocked' };
|
|
565
|
+
role = (await tx.groupMember.create({ data: { groupId, orgId, userId, role: invite.role, addedById: invite.invitedById } })).role;
|
|
566
|
+
}
|
|
567
|
+
else {
|
|
568
|
+
role = mergeInviteRole(this.options.groups.inviteRoleMerge, existing.role, invite.role);
|
|
569
|
+
if (role !== existing.role)
|
|
570
|
+
await tx.groupMember.update({ where: { groupId_userId: { groupId, userId } }, data: { role } });
|
|
571
|
+
}
|
|
572
|
+
await tx.groupInvite.update({ where: { id: inviteId }, data: { acceptedAt: now, acceptedById: userId } });
|
|
573
|
+
await (0, group_common_1.writeAudit)(tx, {
|
|
574
|
+
orgId,
|
|
575
|
+
actorUserId: userId,
|
|
576
|
+
action: 'group:invite_auto_accepted',
|
|
577
|
+
groupId,
|
|
578
|
+
meta: { inviteId, role, previousRole: existing?.role ?? null, alreadyMember: existing !== null },
|
|
579
|
+
});
|
|
580
|
+
return { kind: 'claimed', groupId, inviteRole: invite.role, role, previousRole: existing?.role ?? null };
|
|
581
|
+
});
|
|
582
|
+
}
|
|
414
583
|
};
|
|
415
584
|
exports.GroupInvitesService = GroupInvitesService;
|
|
416
585
|
__decorate([
|
|
@@ -449,6 +618,18 @@ __decorate([
|
|
|
449
618
|
__metadata("design:paramtypes", [Object, String]),
|
|
450
619
|
__metadata("design:returntype", Promise)
|
|
451
620
|
], GroupInvitesService.prototype, "decline", null);
|
|
621
|
+
__decorate([
|
|
622
|
+
(0, index_1.Trace)('sharing.invites.auto_accept'),
|
|
623
|
+
__metadata("design:type", Function),
|
|
624
|
+
__metadata("design:paramtypes", [String, String, Object]),
|
|
625
|
+
__metadata("design:returntype", Promise)
|
|
626
|
+
], GroupInvitesService.prototype, "claimPendingForEmail", null);
|
|
627
|
+
__decorate([
|
|
628
|
+
(0, index_1.Trace)('sharing.invites.auto_accept'),
|
|
629
|
+
__metadata("design:type", Function),
|
|
630
|
+
__metadata("design:paramtypes", [String, Object]),
|
|
631
|
+
__metadata("design:returntype", Promise)
|
|
632
|
+
], GroupInvitesService.prototype, "claimPendingForUser", null);
|
|
452
633
|
exports.GroupInvitesService = GroupInvitesService = __decorate([
|
|
453
634
|
(0, common_1.Injectable)(),
|
|
454
635
|
__param(0, (0, common_1.Inject)(ports_1.SHARING_DATA)),
|