@memberjunction/core-entities 6.2.0-edge.4 → 6.2.0-edge.5
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/.tsbuildinfo +1 -1
- package/dist/custom/ConversationWriteAccess.d.ts +5 -0
- package/dist/custom/ConversationWriteAccess.d.ts.map +1 -1
- package/dist/custom/ConversationWriteAccess.js +6 -6
- package/dist/custom/ConversationWriteAccess.js.map +1 -1
- package/dist/custom/MJConversationDetailEntityExtended.d.ts +46 -4
- package/dist/custom/MJConversationDetailEntityExtended.d.ts.map +1 -1
- package/dist/custom/MJConversationDetailEntityExtended.js +185 -28
- package/dist/custom/MJConversationDetailEntityExtended.js.map +1 -1
- package/dist/custom/MJThemeEntityExtended.d.ts +13 -0
- package/dist/custom/MJThemeEntityExtended.d.ts.map +1 -0
- package/dist/custom/MJThemeEntityExtended.js +37 -0
- package/dist/custom/MJThemeEntityExtended.js.map +1 -0
- package/dist/engines/InstanceConfigEngine.d.ts.map +1 -1
- package/dist/engines/InstanceConfigEngine.js +13 -3
- package/dist/engines/InstanceConfigEngine.js.map +1 -1
- package/dist/engines/PermissionEngine.d.ts +5 -4
- package/dist/engines/PermissionEngine.d.ts.map +1 -1
- package/dist/engines/PermissionEngine.js +7 -5
- package/dist/engines/PermissionEngine.js.map +1 -1
- package/dist/engines/QueryEngine.d.ts +81 -6
- package/dist/engines/QueryEngine.d.ts.map +1 -1
- package/dist/engines/QueryEngine.js +283 -4
- package/dist/engines/QueryEngine.js.map +1 -1
- package/dist/engines/UserInfoEngine.d.ts +48 -2
- package/dist/engines/UserInfoEngine.d.ts.map +1 -1
- package/dist/engines/UserInfoEngine.js +65 -8
- package/dist/engines/UserInfoEngine.js.map +1 -1
- package/dist/engines/conversations.d.ts +19 -1
- package/dist/engines/conversations.d.ts.map +1 -1
- package/dist/engines/conversations.js +125 -22
- package/dist/engines/conversations.js.map +1 -1
- package/dist/generated/entities/__mj.d.ts +1762 -44
- package/dist/generated/entities/__mj.d.ts.map +1 -1
- package/dist/generated/entities/__mj.js +2231 -18
- package/dist/generated/entities/__mj.js.map +1 -1
- package/dist/generated/remote_operations.d.ts +17 -5
- package/dist/generated/remote_operations.d.ts.map +1 -1
- package/dist/generated/remote_operations.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
|
@@ -6,6 +6,11 @@ export interface ConversationWriteDecision {
|
|
|
6
6
|
Reason: string | null;
|
|
7
7
|
/** True only when the conversation loaded and the user is its owner. */
|
|
8
8
|
IsOwner: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* True when the conversation loaded for the user. A conversation that did not load is `Allowed` whether it is
|
|
11
|
+
* missing or hidden from the user by a row filter, so a caller that must tell those apart checks this.
|
|
12
|
+
*/
|
|
13
|
+
Loaded: boolean;
|
|
9
14
|
}
|
|
10
15
|
/**
|
|
11
16
|
* Whether a user may write rows that belong to a conversation: the owner, or a user with
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationWriteAccess.d.ts","sourceRoot":"","sources":["../../src/custom/ConversationWriteAccess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKnE,4EAA4E;AAC5E,eAAO,MAAM,8BAA8B,yCAAyC,CAAC;AAErF,MAAM,WAAW,yBAAyB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"ConversationWriteAccess.d.ts","sourceRoot":"","sources":["../../src/custom/ConversationWriteAccess.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKnE,4EAA4E;AAC5E,eAAO,MAAM,8BAA8B,yCAAyC,CAAC;AAErF,MAAM,WAAW,yBAAyB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wEAAwE;IACxE,OAAO,EAAE,OAAO,CAAC;IACjB;;;OAGG;IACH,MAAM,EAAE,OAAO,CAAC;CACnB;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAC1C,QAAQ,EAAE,iBAAiB,EAC3B,IAAI,EAAE,QAAQ,GAAG,IAAI,GAAG,SAAS,EACjC,cAAc,EAAE,MAAM,GACvB,OAAO,CAAC,yBAAyB,CAAC,CAuBpC"}
|
|
@@ -9,14 +9,14 @@ export const CONVERSATIONS_RESOURCE_TYPE_ID = '81D4BC3D-9FEB-EF11-B01A-286B35C04
|
|
|
9
9
|
*/
|
|
10
10
|
export async function UserMayWriteConversation(provider, user, conversationId) {
|
|
11
11
|
if (provider?.ProviderType !== 'Database' || !user) {
|
|
12
|
-
return { Allowed: true, Reason: null, IsOwner: false };
|
|
12
|
+
return { Allowed: true, Reason: null, IsOwner: false, Loaded: false };
|
|
13
13
|
}
|
|
14
14
|
const conversation = await provider.GetEntityObject('MJ: Conversations', user);
|
|
15
15
|
if (!(await conversation.Load(conversationId))) {
|
|
16
|
-
return { Allowed: true, Reason: null, IsOwner: false };
|
|
16
|
+
return { Allowed: true, Reason: null, IsOwner: false, Loaded: false };
|
|
17
17
|
}
|
|
18
18
|
if (conversation.UserID && UUIDsEqual(conversation.UserID, user.ID)) {
|
|
19
|
-
return { Allowed: true, Reason: null, IsOwner: true };
|
|
19
|
+
return { Allowed: true, Reason: null, IsOwner: true, Loaded: true };
|
|
20
20
|
}
|
|
21
21
|
const engine = ResourcePermissionEngine.GetProviderInstance(provider, ResourcePermissionEngine);
|
|
22
22
|
await engine.Config(false, user);
|
|
@@ -24,11 +24,11 @@ export async function UserMayWriteConversation(provider, user, conversationId) {
|
|
|
24
24
|
.GetUserAvailableResources(user, CONVERSATIONS_RESOURCE_TYPE_ID)
|
|
25
25
|
.find((p) => UUIDsEqual(p.ResourceRecordID, conversationId));
|
|
26
26
|
if (!grant) {
|
|
27
|
-
return { Allowed: false, Reason: 'You do not have access to this conversation.', IsOwner: false };
|
|
27
|
+
return { Allowed: false, Reason: 'You do not have access to this conversation.', IsOwner: false, Loaded: true };
|
|
28
28
|
}
|
|
29
29
|
if (grant.PermissionLevel === 'Edit' || grant.PermissionLevel === 'Owner') {
|
|
30
|
-
return { Allowed: true, Reason: null, IsOwner: false };
|
|
30
|
+
return { Allowed: true, Reason: null, IsOwner: false, Loaded: true };
|
|
31
31
|
}
|
|
32
|
-
return { Allowed: false, Reason: 'You have view-only access to this conversation.', IsOwner: false };
|
|
32
|
+
return { Allowed: false, Reason: 'You have view-only access to this conversation.', IsOwner: false, Loaded: true };
|
|
33
33
|
}
|
|
34
34
|
//# sourceMappingURL=ConversationWriteAccess.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConversationWriteAccess.js","sourceRoot":"","sources":["../../src/custom/ConversationWriteAccess.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AAE1F,4EAA4E;AAC5E,MAAM,CAAC,MAAM,8BAA8B,GAAG,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"ConversationWriteAccess.js","sourceRoot":"","sources":["../../src/custom/ConversationWriteAccess.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,wBAAwB,EAAE,MAAM,gDAAgD,CAAC;AAE1F,4EAA4E;AAC5E,MAAM,CAAC,MAAM,8BAA8B,GAAG,sCAAsC,CAAC;AAcrF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC1C,QAA2B,EAC3B,IAAiC,EACjC,cAAsB;IAEtB,IAAI,QAAQ,EAAE,YAAY,KAAK,UAAU,IAAI,CAAC,IAAI,EAAE,CAAC;QACjD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC1E,CAAC;IACD,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAuB,mBAAmB,EAAE,IAAI,CAAC,CAAC;IACrG,IAAI,CAAC,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC;QAC7C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC1E,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,IAAI,UAAU,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;QAClE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACxE,CAAC;IACD,MAAM,MAAM,GAAG,wBAAwB,CAAC,mBAAmB,CAA2B,QAAQ,EAAE,wBAAwB,CAA6B,CAAC;IACtJ,MAAM,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,MAAM;SACf,yBAAyB,CAAC,IAAI,EAAE,8BAA8B,CAAC;SAC/D,IAAI,CAAC,CAAC,CAA6B,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,gBAAgB,EAAE,cAAc,CAAC,CAAC,CAAC;IAC7F,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,8CAA8C,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACpH,CAAC;IACD,IAAI,KAAK,CAAC,eAAe,KAAK,MAAM,IAAI,KAAK,CAAC,eAAe,KAAK,OAAO,EAAE,CAAC;QACxE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IACzE,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,iDAAiD,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;AACvH,CAAC"}
|
|
@@ -15,6 +15,22 @@ import { MJConversationDetailEntity } from '../generated/entity_subclasses.js';
|
|
|
15
15
|
* owner-only — even users with `Edit`-level grants on the conversation are
|
|
16
16
|
* blocked from changing them, because the storage is a single value per
|
|
17
17
|
* message (it represents the owner's evaluation, not per-grantee opinions).
|
|
18
|
+
*
|
|
19
|
+
* **Who a message is from** (A19, the rules for people's messages). For a `Role='User'` message, the owner and
|
|
20
|
+
* grantees alike:
|
|
21
|
+
* - post only as themselves: a new message naming another person's `UserID` is refused, and a grantee's message
|
|
22
|
+
* with no `UserID` gets the grantee's (an empty one reads as the conversation's owner). The owner's stays empty,
|
|
23
|
+
* since it already means them;
|
|
24
|
+
* - change who wrote it and what it says ({@link AUTHORED_FIELDS}) only when they wrote it, and never its role;
|
|
25
|
+
* - never move it to another conversation or fork ({@link PLACEMENT_FIELDS});
|
|
26
|
+
* - delete it only when they wrote it, or own the conversation.
|
|
27
|
+
*
|
|
28
|
+
* The system user is exempt from these authorship rules, since server code writes on people's behalf, but it still
|
|
29
|
+
* needs to own the conversation or hold a grant on it, as before: some server paths elevate an anonymous visitor to
|
|
30
|
+
* the system user (MJ#4791), and this gate keeps those paths out of other people's conversations, so no transaction
|
|
31
|
+
* variable may set the row or conversation it writes ({@link ACCESS_GATED_FIELDS}) for it either. The plan's "the
|
|
32
|
+
* system user may write any message" lands with A19's second half, which must design that boundary. Agent replies
|
|
33
|
+
* (`Role='AI'`/`'Error'`) keep today's rules until MJ's chat stops writing them from the browser.
|
|
18
34
|
* MJ's permissions engine has no native primitive for per-field row-conditional
|
|
19
35
|
* write rules, so this gate lives here rather than in `MJ: Entity Permissions`.
|
|
20
36
|
*
|
|
@@ -28,11 +44,37 @@ export declare class MJConversationDetailEntityExtended extends MJConversationDe
|
|
|
28
44
|
Delete(options?: EntityDeleteOptions): Promise<boolean>;
|
|
29
45
|
private currentUserMayWrite;
|
|
30
46
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
47
|
+
* Why the user may not write to this message's conversation at all, or `null` when they may. The owner may. Anyone
|
|
48
|
+
* else may not change the rating fields, which are the owner's alone, and needs an `Edit` or `Owner` grant. A
|
|
49
|
+
* conversation that does not load for the user is hidden from them when it exists (a row filter), and they may not
|
|
50
|
+
* write to it; when no one can find it, it is missing or being created in this same transaction, and the foreign
|
|
51
|
+
* key and the base save decide, as before.
|
|
52
|
+
*/
|
|
53
|
+
private accessRefusal;
|
|
54
|
+
/**
|
|
55
|
+
* Why this write breaks the rules for people's messages (see the class doc), or `null` when it does not. On a new
|
|
56
|
+
* message from a grantee with no `UserID`, fills in the grantee's.
|
|
57
|
+
*/
|
|
58
|
+
private authorshipRefusal;
|
|
59
|
+
/** A new person's message names its author as the poster, or names no one (filled in for a grantee). */
|
|
60
|
+
private postRefusal;
|
|
61
|
+
/**
|
|
62
|
+
* An existing person's message: only its author changes who wrote it and what it says, no one its role (to or
|
|
63
|
+
* from `User`), and no one moves it to another conversation or fork. A message with no `UserID` is the owner's.
|
|
64
|
+
*/
|
|
65
|
+
private changeRefusal;
|
|
66
|
+
/** A person's message is deleted by its author or by the conversation's owner (whose it is with no `UserID`). */
|
|
67
|
+
private deleteRefusal;
|
|
68
|
+
/** Whether the conversation exists, read as the system user; false when there is no system user to ask. */
|
|
69
|
+
private conversationExists;
|
|
70
|
+
/**
|
|
71
|
+
* Whether a transaction variable of this message's group sets one of `fields` on it. The field is resolved the way
|
|
72
|
+
* `Set` resolves it at submit (trimmed, any case).
|
|
34
73
|
*/
|
|
35
|
-
private
|
|
74
|
+
private fieldSetByTransactionVariable;
|
|
75
|
+
private isFieldDirty;
|
|
76
|
+
/** A field's value as loaded, before this save's changes; `null` when it was empty or is not text. */
|
|
77
|
+
private originalFieldText;
|
|
36
78
|
/**
|
|
37
79
|
* Records WHY the write was refused as a NEW `ResultHistory` entry, so callers that read
|
|
38
80
|
* `LatestResult.CompleteMessage` see the reason (issue #4791).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJConversationDetailEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJConversationDetailEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,mBAAmB,
|
|
1
|
+
{"version":3,"file":"MJConversationDetailEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJConversationDetailEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,mBAAmB,EAEnB,iBAAiB,EAKpB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,0BAA0B,EAAwB,MAAM,gCAAgC,CAAC;AA4ClG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,qBACa,kCAAmC,SAAQ,0BAA0B;IAC/D,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAYnD,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;YAOxD,mBAAmB;IAwDjC;;;;;;OAMG;YACW,aAAa;IAoB3B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAOzB,wGAAwG;IACxG,OAAO,CAAC,WAAW;IAgBnB;;;OAGG;IACH,OAAO,CAAC,aAAa;IA2BrB,iHAAiH;IACjH,OAAO,CAAC,aAAa;IASrB,2GAA2G;YAC7F,kBAAkB;IAahC;;;OAGG;IACH,OAAO,CAAC,6BAA6B;IAOrC,OAAO,CAAC,YAAY;IAIpB,sGAAsG;IACtG,OAAO,CAAC,iBAAiB;IAKzB;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;CASvB;AAED,6FAA6F;AAC7F,wBAAgB,sCAAsC,IAAI,IAAI,CAE7D"}
|
|
@@ -4,8 +4,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { BaseEntity, BaseEntityResult, LogError } from '@memberjunction/core';
|
|
8
|
-
import { RegisterClass } from '@memberjunction/global';
|
|
7
|
+
import { BaseEntity, BaseEntityResult, EntityFieldInfo, LogError, WellKnownUserSource } from '@memberjunction/core';
|
|
8
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
9
9
|
import { MJConversationDetailEntity } from '../generated/entity_subclasses.js';
|
|
10
10
|
import { UserMayWriteConversation } from './ConversationWriteAccess.js';
|
|
11
11
|
/**
|
|
@@ -15,6 +15,34 @@ import { UserMayWriteConversation } from './ConversationWriteAccess.js';
|
|
|
15
15
|
* the parent conversation cannot retroactively rewrite the owner's rating.
|
|
16
16
|
*/
|
|
17
17
|
const OWNER_ONLY_RATING_FIELDS = ['UserRating', 'UserFeedback'];
|
|
18
|
+
/**
|
|
19
|
+
* The fields of a person's (`Role='User'`) message that say who wrote it and what it says: its author, its role, its
|
|
20
|
+
* text, its attachment, its media type and where it sits in a thread. Only its author may change them, except
|
|
21
|
+
* `Role`, which no one may change. Other fields (pinning, hiding, bookkeeping the server writes) keep the
|
|
22
|
+
* conversation-level rules.
|
|
23
|
+
*/
|
|
24
|
+
const AUTHORED_FIELDS = ['UserID', 'Role', 'Message', 'ArtifactID', 'ArtifactVersionID', 'MediaType', 'ParentID'];
|
|
25
|
+
/**
|
|
26
|
+
* Where a message sits: its conversation and its fork (`BranchID`, null is Main). No one moves a person's message,
|
|
27
|
+
* its author included: moving it takes it out of the thread it was written in.
|
|
28
|
+
*/
|
|
29
|
+
const PLACEMENT_FIELDS = ['ConversationID', 'BranchID'];
|
|
30
|
+
/**
|
|
31
|
+
* The fields the access rule, which holds for everyone, decides on: which row is written (`ID`; an update's SQL is
|
|
32
|
+
* rebuilt with the variable's value at submit, so it would write another row), its conversation, and the owner's
|
|
33
|
+
* rating. A transaction variable sets its field at submit, after the gate has run, so none of these may take its
|
|
34
|
+
* value from one.
|
|
35
|
+
*/
|
|
36
|
+
const ACCESS_GATED_FIELDS = ['ID', 'ConversationID', ...OWNER_ONLY_RATING_FIELDS];
|
|
37
|
+
/** {@link ACCESS_GATED_FIELDS} plus the fields the authorship rules decide on, which the system user skips. */
|
|
38
|
+
const GATED_FIELDS = [...ACCESS_GATED_FIELDS, 'BranchID', ...AUTHORED_FIELDS];
|
|
39
|
+
/**
|
|
40
|
+
* Whether a `Role` value is a person's message. Compared the way validation and the database's CHECK constraint
|
|
41
|
+
* compare it (trimmed, any case), so `'user'` or `'User '`, which both store, cannot slip past these rules.
|
|
42
|
+
*/
|
|
43
|
+
function isPersonRole(role) {
|
|
44
|
+
return role != null && EntityFieldInfo.NormalizeValueListValue(role) === 'user';
|
|
45
|
+
}
|
|
18
46
|
/**
|
|
19
47
|
* Server-side defense-in-depth for conversation sharing. The Angular chat UI
|
|
20
48
|
* disables the message input when the current user only holds `View` access,
|
|
@@ -30,6 +58,22 @@ const OWNER_ONLY_RATING_FIELDS = ['UserRating', 'UserFeedback'];
|
|
|
30
58
|
* owner-only — even users with `Edit`-level grants on the conversation are
|
|
31
59
|
* blocked from changing them, because the storage is a single value per
|
|
32
60
|
* message (it represents the owner's evaluation, not per-grantee opinions).
|
|
61
|
+
*
|
|
62
|
+
* **Who a message is from** (A19, the rules for people's messages). For a `Role='User'` message, the owner and
|
|
63
|
+
* grantees alike:
|
|
64
|
+
* - post only as themselves: a new message naming another person's `UserID` is refused, and a grantee's message
|
|
65
|
+
* with no `UserID` gets the grantee's (an empty one reads as the conversation's owner). The owner's stays empty,
|
|
66
|
+
* since it already means them;
|
|
67
|
+
* - change who wrote it and what it says ({@link AUTHORED_FIELDS}) only when they wrote it, and never its role;
|
|
68
|
+
* - never move it to another conversation or fork ({@link PLACEMENT_FIELDS});
|
|
69
|
+
* - delete it only when they wrote it, or own the conversation.
|
|
70
|
+
*
|
|
71
|
+
* The system user is exempt from these authorship rules, since server code writes on people's behalf, but it still
|
|
72
|
+
* needs to own the conversation or hold a grant on it, as before: some server paths elevate an anonymous visitor to
|
|
73
|
+
* the system user (MJ#4791), and this gate keeps those paths out of other people's conversations, so no transaction
|
|
74
|
+
* variable may set the row or conversation it writes ({@link ACCESS_GATED_FIELDS}) for it either. The plan's "the
|
|
75
|
+
* system user may write any message" lands with A19's second half, which must design that boundary. Agent replies
|
|
76
|
+
* (`Role='AI'`/`'Error'`) keep today's rules until MJ's chat stops writing them from the browser.
|
|
33
77
|
* MJ's permissions engine has no native primitive for per-field row-conditional
|
|
34
78
|
* write rules, so this gate lives here rather than in `MJ: Entity Permissions`.
|
|
35
79
|
*
|
|
@@ -40,10 +84,15 @@ const OWNER_ONLY_RATING_FIELDS = ['UserRating', 'UserFeedback'];
|
|
|
40
84
|
*/
|
|
41
85
|
let MJConversationDetailEntityExtended = class MJConversationDetailEntityExtended extends MJConversationDetailEntity {
|
|
42
86
|
async Save(options) {
|
|
87
|
+
const callerUserID = this.UserID; // the gate may fill in a grantee's; a save that fails keeps the caller's
|
|
43
88
|
if (!(await this.currentUserMayWrite('save'))) {
|
|
44
89
|
return false;
|
|
45
90
|
}
|
|
46
|
-
|
|
91
|
+
const saved = await super.Save(options);
|
|
92
|
+
if (!saved) {
|
|
93
|
+
this.UserID = callerUserID;
|
|
94
|
+
}
|
|
95
|
+
return saved;
|
|
47
96
|
}
|
|
48
97
|
async Delete(options) {
|
|
49
98
|
if (!(await this.currentUserMayWrite('delete'))) {
|
|
@@ -63,6 +112,17 @@ let MJConversationDetailEntityExtended = class MJConversationDetailEntityExtende
|
|
|
63
112
|
// No user context on a server save = system operation; allow.
|
|
64
113
|
return true;
|
|
65
114
|
}
|
|
115
|
+
// The system user skips the authorship rules (server code writes on people's behalf) but, like anyone, must own
|
|
116
|
+
// the conversation or hold a grant on it: some server paths elevate an anonymous visitor to the system user
|
|
117
|
+
// (MJ#4791), and this gate is what keeps those paths out of other people's conversations.
|
|
118
|
+
const isSystemUser = WellKnownUserSource.Instance.IsSystemUser(user);
|
|
119
|
+
if (operation === 'save' && this.fieldSetByTransactionVariable(isSystemUser ? ACCESS_GATED_FIELDS : GATED_FIELDS)) {
|
|
120
|
+
// A transaction variable sets its field after this check has passed, at submit, to any value an earlier
|
|
121
|
+
// item in the group produced: a message would be checked as one row, author or conversation and saved as
|
|
122
|
+
// another.
|
|
123
|
+
this.recordDenied('A conversation message cannot take its values from a transaction variable.', resultType);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
66
126
|
// A message created by the record-cloning engine, as part of copying a conversation into a
|
|
67
127
|
// new user's account. The engine has already authorized that copy (Owner-only, the clone
|
|
68
128
|
// authorization, and conversations are copyable only from a template user), and the
|
|
@@ -72,20 +132,11 @@ let MJConversationDetailEntityExtended = class MJConversationDetailEntityExtende
|
|
|
72
132
|
return true;
|
|
73
133
|
}
|
|
74
134
|
try {
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
// when they hold Edit/Owner grants on the conversation. UserRating
|
|
81
|
-
// and UserFeedback represent the owner's evaluation of an AI
|
|
82
|
-
// message and there is no per-user storage to overwrite.
|
|
83
|
-
if (this.dirtyRatingFieldNames().length > 0) {
|
|
84
|
-
this.recordDenied('Only the conversation owner can set or change the rating and feedback on this message.', resultType);
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
if (!decision.Allowed) {
|
|
88
|
-
this.recordDenied(decision.Reason ?? 'Permission denied.', resultType);
|
|
135
|
+
const access = await UserMayWriteConversation(provider, user, this.ConversationID);
|
|
136
|
+
const refusal = (await this.accessRefusal(provider, access))
|
|
137
|
+
?? (isSystemUser ? null : this.authorshipRefusal(operation, user, access.IsOwner));
|
|
138
|
+
if (refusal) {
|
|
139
|
+
this.recordDenied(refusal, resultType);
|
|
89
140
|
return false;
|
|
90
141
|
}
|
|
91
142
|
return true;
|
|
@@ -100,18 +151,124 @@ let MJConversationDetailEntityExtended = class MJConversationDetailEntityExtende
|
|
|
100
151
|
}
|
|
101
152
|
}
|
|
102
153
|
/**
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
154
|
+
* Why the user may not write to this message's conversation at all, or `null` when they may. The owner may. Anyone
|
|
155
|
+
* else may not change the rating fields, which are the owner's alone, and needs an `Edit` or `Owner` grant. A
|
|
156
|
+
* conversation that does not load for the user is hidden from them when it exists (a row filter), and they may not
|
|
157
|
+
* write to it; when no one can find it, it is missing or being created in this same transaction, and the foreign
|
|
158
|
+
* key and the base save decide, as before.
|
|
159
|
+
*/
|
|
160
|
+
async accessRefusal(provider, access) {
|
|
161
|
+
if (access.IsOwner) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
// Non-owners are *never* allowed to touch the rating fields, even
|
|
165
|
+
// when they hold Edit/Owner grants on the conversation. UserRating
|
|
166
|
+
// and UserFeedback represent the owner's evaluation of an AI
|
|
167
|
+
// message and there is no per-user storage to overwrite.
|
|
168
|
+
if (OWNER_ONLY_RATING_FIELDS.some((name) => this.isFieldDirty(name))) {
|
|
169
|
+
return 'Only the conversation owner can set or change the rating and feedback on this message.';
|
|
170
|
+
}
|
|
171
|
+
if (!access.Allowed) {
|
|
172
|
+
return access.Reason ?? 'Permission denied.';
|
|
173
|
+
}
|
|
174
|
+
if (!access.Loaded && (await this.conversationExists(provider))) {
|
|
175
|
+
return 'You do not have access to this conversation.';
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Why this write breaks the rules for people's messages (see the class doc), or `null` when it does not. On a new
|
|
181
|
+
* message from a grantee with no `UserID`, fills in the grantee's.
|
|
182
|
+
*/
|
|
183
|
+
authorshipRefusal(operation, user, isOwner) {
|
|
184
|
+
if (operation === 'delete') {
|
|
185
|
+
return this.deleteRefusal(user, isOwner);
|
|
186
|
+
}
|
|
187
|
+
return this.IsSaved ? this.changeRefusal(user, isOwner) : this.postRefusal(user, isOwner);
|
|
188
|
+
}
|
|
189
|
+
/** A new person's message names its author as the poster, or names no one (filled in for a grantee). */
|
|
190
|
+
postRefusal(user, isOwner) {
|
|
191
|
+
if (!isPersonRole(this.Role)) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
if (!this.UserID) {
|
|
195
|
+
// An empty UserID reads as the conversation's owner. A grantee's message gets the grantee's ID; the
|
|
196
|
+
// owner's stays empty, so server code writing as the owner (a room transcript of what other people said)
|
|
197
|
+
// is not stamped with the owner's ID.
|
|
198
|
+
if (!isOwner) {
|
|
199
|
+
this.UserID = user.ID;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
return UUIDsEqual(this.UserID, user.ID) ? null : 'You can post a message only as yourself.';
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* An existing person's message: only its author changes who wrote it and what it says, no one its role (to or
|
|
207
|
+
* from `User`), and no one moves it to another conversation or fork. A message with no `UserID` is the owner's.
|
|
208
|
+
*/
|
|
209
|
+
changeRefusal(user, isOwner) {
|
|
210
|
+
const wasPerson = isPersonRole(this.originalFieldText('Role'));
|
|
211
|
+
if (this.isFieldDirty('Role') && (wasPerson || isPersonRole(this.Role))) {
|
|
212
|
+
return "A message's role cannot be changed.";
|
|
213
|
+
}
|
|
214
|
+
if (!wasPerson) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
if (PLACEMENT_FIELDS.some((name) => this.isFieldDirty(name))) {
|
|
218
|
+
// Moving it would take it out of the thread it was written in (a delete) and put it in one its author never
|
|
219
|
+
// wrote in, and, with no UserID, make it read as another conversation's owner's.
|
|
220
|
+
return 'A message cannot be moved to another conversation or fork.';
|
|
221
|
+
}
|
|
222
|
+
const changed = AUTHORED_FIELDS.filter((name) => this.isFieldDirty(name));
|
|
223
|
+
if (changed.length === 0) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const author = this.originalFieldText('UserID') ?? (isOwner ? user.ID : null);
|
|
227
|
+
if (!author || !UUIDsEqual(author, user.ID)) {
|
|
228
|
+
return 'Only the person who wrote this message can change it.';
|
|
229
|
+
}
|
|
230
|
+
if (changed.includes('UserID') && !(this.UserID && UUIDsEqual(this.UserID, user.ID))) {
|
|
231
|
+
return 'You can post a message only as yourself.';
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
/** A person's message is deleted by its author or by the conversation's owner (whose it is with no `UserID`). */
|
|
236
|
+
deleteRefusal(user, isOwner) {
|
|
237
|
+
if (!isPersonRole(this.Role) || isOwner) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
return this.UserID && UUIDsEqual(this.UserID, user.ID)
|
|
241
|
+
? null
|
|
242
|
+
: "Only the message's author or the conversation's owner can delete it.";
|
|
243
|
+
}
|
|
244
|
+
/** Whether the conversation exists, read as the system user; false when there is no system user to ask. */
|
|
245
|
+
async conversationExists(provider) {
|
|
246
|
+
const systemUser = await WellKnownUserSource.Instance.GetSystemUser(provider);
|
|
247
|
+
if (!systemUser) {
|
|
248
|
+
LogError(`MJConversationDetailEntityExtended: no system user to check whether conversation ${this.ConversationID} ` +
|
|
249
|
+
'exists; treating it as missing.');
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
const conversation = await provider.GetEntityObject('MJ: Conversations', systemUser);
|
|
253
|
+
return conversation.Load(this.ConversationID);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Whether a transaction variable of this message's group sets one of `fields` on it. The field is resolved the way
|
|
257
|
+
* `Set` resolves it at submit (trimmed, any case).
|
|
106
258
|
*/
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
return
|
|
259
|
+
fieldSetByTransactionVariable(fields) {
|
|
260
|
+
return !!this.TransactionGroup?.Variables.some((v) => {
|
|
261
|
+
const name = v.EntityObject === this && v.Type === 'Use' ? this.GetFieldByName(v.FieldName)?.Name : null;
|
|
262
|
+
return !!name && fields.includes(name);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
isFieldDirty(name) {
|
|
266
|
+
return !!this.GetFieldByName(name)?.Dirty;
|
|
267
|
+
}
|
|
268
|
+
/** A field's value as loaded, before this save's changes; `null` when it was empty or is not text. */
|
|
269
|
+
originalFieldText(name) {
|
|
270
|
+
const original = this.GetFieldByName(name)?.OldValue;
|
|
271
|
+
return typeof original === 'string' && original.length > 0 ? original : null;
|
|
115
272
|
}
|
|
116
273
|
/**
|
|
117
274
|
* Records WHY the write was refused as a NEW `ResultHistory` entry, so callers that read
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJConversationDetailEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJConversationDetailEntityExtended.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACH,UAAU,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"MJConversationDetailEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJConversationDetailEntityExtended.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ValidationResult } from '@memberjunction/core';
|
|
2
|
+
import { MJThemeEntity } from '../generated/entity_subclasses.js';
|
|
3
|
+
/**
|
|
4
|
+
* `MJ: Themes`: refuses a sign-in page design (`LoginScreen`, `LoginScreenDraft`) the login screen cannot
|
|
5
|
+
* draw safely. Runs on both tiers, so Login Studio hears the reason before the request leaves the browser.
|
|
6
|
+
* Only a column this save changes is checked, so a theme whose stored design predates a stricter contract
|
|
7
|
+
* can still be renamed or recolored.
|
|
8
|
+
*/
|
|
9
|
+
export declare class MJThemeEntityExtended extends MJThemeEntity {
|
|
10
|
+
Validate(): ValidationResult;
|
|
11
|
+
private checkLoginDesign;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=MJThemeEntityExtended.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJThemeEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJThemeEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwD,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGnH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D;;;;;GAKG;AACH,qBACa,qBAAsB,SAAQ,aAAa;IACpC,QAAQ,IAAI,gBAAgB;IAQ5C,OAAO,CAAC,gBAAgB;CAM3B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { BaseEntity, ValidationErrorInfo, ValidationErrorType } from '@memberjunction/core';
|
|
8
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
+
import { StoredLoginDesignProblems } from '@memberjunction/theme-engine';
|
|
10
|
+
import { MJThemeEntity } from '../generated/entity_subclasses.js';
|
|
11
|
+
/**
|
|
12
|
+
* `MJ: Themes`: refuses a sign-in page design (`LoginScreen`, `LoginScreenDraft`) the login screen cannot
|
|
13
|
+
* draw safely. Runs on both tiers, so Login Studio hears the reason before the request leaves the browser.
|
|
14
|
+
* Only a column this save changes is checked, so a theme whose stored design predates a stricter contract
|
|
15
|
+
* can still be renamed or recolored.
|
|
16
|
+
*/
|
|
17
|
+
let MJThemeEntityExtended = class MJThemeEntityExtended extends MJThemeEntity {
|
|
18
|
+
Validate() {
|
|
19
|
+
const result = super.Validate();
|
|
20
|
+
this.checkLoginDesign(result, 'LoginScreen', this.LoginScreen);
|
|
21
|
+
this.checkLoginDesign(result, 'LoginScreenDraft', this.LoginScreenDraft);
|
|
22
|
+
result.Success = result.Errors.every((e) => e.Type !== ValidationErrorType.Failure);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
checkLoginDesign(result, field, value) {
|
|
26
|
+
if (!this.GetFieldByName(field)?.Dirty)
|
|
27
|
+
return;
|
|
28
|
+
for (const problem of StoredLoginDesignProblems(value)) {
|
|
29
|
+
result.Errors.push(new ValidationErrorInfo(field, problem, null, ValidationErrorType.Failure));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
MJThemeEntityExtended = __decorate([
|
|
34
|
+
RegisterClass(BaseEntity, 'MJ: Themes')
|
|
35
|
+
], MJThemeEntityExtended);
|
|
36
|
+
export { MJThemeEntityExtended };
|
|
37
|
+
//# sourceMappingURL=MJThemeEntityExtended.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJThemeEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJThemeEntityExtended.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,EAAyB,MAAM,sBAAsB,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D;;;;;GAKG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,aAAa;IACpC,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/D,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACzE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACpF,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,gBAAgB,CAAC,MAAwB,EAAE,KAAyC,EAAE,KAAoB;QAC9G,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK;YAAE,OAAO;QAC/C,KAAK,MAAM,OAAO,IAAI,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QACnG,CAAC;IACL,CAAC;CACJ,CAAA;AAfY,qBAAqB;IADjC,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC;GAC3B,qBAAqB,CAejC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstanceConfigEngine.d.ts","sourceRoot":"","sources":["../../src/engines/InstanceConfigEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,
|
|
1
|
+
{"version":3,"file":"InstanceConfigEngine.d.ts","sourceRoot":"","sources":["../../src/engines/InstanceConfigEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,EAAsB,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC7H,OAAO,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBACa,oBAAqB,SAAQ,UAAU,CAAC,oBAAoB,CAAC;IACtE;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,oBAAoB,CAEjD;IAED,OAAO,CAAC,QAAQ,CAAuC;IAEvD;;;;;OAKG;IACU,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBhH,yCAAyC;IACzC,IAAW,eAAe,IAAI,6BAA6B,EAAE,CAE5D;IAMD;;;;OAIG;IACI,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,6BAA6B,GAAG,SAAS;IAKpF;;;;OAIG;IACI,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,6BAA6B,EAAE;IAU9E;;;;;OAKG;IACI,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAMlD;;;;;OAKG;IACI,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,GAAE,OAAc,GAAG,OAAO;IAM5E;;;;;OAKG;IACI,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,GAAE,MAAU,GAAG,MAAM;IAOtE;;;;;OAKG;IACI,OAAO,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,SAAS;IActE;;;;;;;;;;;OAWG;IACU,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IA0B7F;;;OAGG;IACH,OAAO,CAAC,YAAY;CAOvB"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { BaseEngine, RegisterForStartup } from "@memberjunction/core";
|
|
2
8
|
/**
|
|
3
9
|
* InstanceConfigEngine provides centralized, cached access to instance-level feature configuration.
|
|
4
10
|
* It loads all MJ: Instance Configurations records into memory and provides typed getters
|
|
@@ -25,7 +31,7 @@ import { BaseEngine } from "@memberjunction/core";
|
|
|
25
31
|
* await engine.Set('Shell.SearchBar.Enabled', 'true', contextUser);
|
|
26
32
|
* ```
|
|
27
33
|
*/
|
|
28
|
-
|
|
34
|
+
let InstanceConfigEngine = class InstanceConfigEngine extends BaseEngine {
|
|
29
35
|
constructor() {
|
|
30
36
|
super(...arguments);
|
|
31
37
|
this._configs = [];
|
|
@@ -194,5 +200,9 @@ export class InstanceConfigEngine extends BaseEngine {
|
|
|
194
200
|
}
|
|
195
201
|
return config.DefaultValue;
|
|
196
202
|
}
|
|
197
|
-
}
|
|
203
|
+
};
|
|
204
|
+
InstanceConfigEngine = __decorate([
|
|
205
|
+
RegisterForStartup()
|
|
206
|
+
], InstanceConfigEngine);
|
|
207
|
+
export { InstanceConfigEngine };
|
|
198
208
|
//# sourceMappingURL=InstanceConfigEngine.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"InstanceConfigEngine.js","sourceRoot":"","sources":["../../src/engines/InstanceConfigEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"InstanceConfigEngine.js","sourceRoot":"","sources":["../../src/engines/InstanceConfigEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,16 +31,17 @@ export declare const PERMISSION_DOMAIN_ICON_FALLBACK = "fa-solid fa-lock";
|
|
|
31
31
|
* );
|
|
32
32
|
* ```
|
|
33
33
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
34
|
+
* Runs at the default startup priority (100) alongside `UserInfoEngine`, `ApplicationManager`,
|
|
35
|
+
* and `DashboardEngine` so its `MJ: Permission Domains` `RunView` coalesces into the main
|
|
36
|
+
* synchronous startup batch rather than forcing a solo round-trip. Providers lazy-resolve
|
|
37
|
+
* their backing engines on first use, so configure order within the priority group does not matter.
|
|
38
38
|
*/
|
|
39
39
|
export declare class PermissionEngine extends BaseEngine<PermissionEngine> {
|
|
40
40
|
static get Instance(): PermissionEngine;
|
|
41
41
|
private _domains;
|
|
42
42
|
private _providers;
|
|
43
43
|
Config(forceRefresh?: boolean, contextUser?: UserInfo, provider?: IMetadataProvider): Promise<void>;
|
|
44
|
+
protected AdditionalLoading(): Promise<void>;
|
|
44
45
|
/**
|
|
45
46
|
* Walks the loaded domain catalog and instantiates each active provider via ClassFactory.
|
|
46
47
|
* Called on every `Config()` so a `forceRefresh` re-wires the provider map.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PermissionEngine.d.ts","sourceRoot":"","sources":["../../src/engines/PermissionEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,UAAU,EAEV,iBAAiB,EAGjB,oBAAoB,EACpB,gBAAgB,EAChB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EAErB,sBAAsB,EAGtB,QAAQ,EACX,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAoB1E;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAW1D,CAAC;AAEF,wFAAwF;AACxF,eAAO,MAAM,+BAA+B,qBAAqB,CAAC;AAElE;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,qBACa,gBAAiB,SAAQ,UAAU,CAAC,gBAAgB,CAAC;IAC9D,WAAkB,QAAQ,IAAI,gBAAgB,CAE7C;IAED,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,UAAU,CAAkD;IAEvD,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"PermissionEngine.d.ts","sourceRoot":"","sources":["../../src/engines/PermissionEngine.ts"],"names":[],"mappings":"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"}
|