@memberjunction/core-entities-server 6.2.0-edge.4 → 6.2.0-edge.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts +9 -3
  2. package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts.map +1 -1
  3. package/dist/custom/MJAIAgentSessionEntityServer.server.js +21 -6
  4. package/dist/custom/MJAIAgentSessionEntityServer.server.js.map +1 -1
  5. package/dist/custom/MJComponentEntityServer.server.d.ts +9 -0
  6. package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
  7. package/dist/custom/MJComponentEntityServer.server.js +25 -1
  8. package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
  9. package/dist/custom/MJConversationEntityServer.server.d.ts +13 -0
  10. package/dist/custom/MJConversationEntityServer.server.d.ts.map +1 -0
  11. package/dist/custom/MJConversationEntityServer.server.js +33 -0
  12. package/dist/custom/MJConversationEntityServer.server.js.map +1 -0
  13. package/dist/custom/MJDashboardEntityServer.server.d.ts +14 -0
  14. package/dist/custom/MJDashboardEntityServer.server.d.ts.map +1 -0
  15. package/dist/custom/MJDashboardEntityServer.server.js +38 -0
  16. package/dist/custom/MJDashboardEntityServer.server.js.map +1 -0
  17. package/dist/custom/MJDataContextItemEntityServer.server.d.ts +33 -0
  18. package/dist/custom/MJDataContextItemEntityServer.server.d.ts.map +1 -0
  19. package/dist/custom/MJDataContextItemEntityServer.server.js +84 -0
  20. package/dist/custom/MJDataContextItemEntityServer.server.js.map +1 -0
  21. package/dist/custom/MJDuplicateRunEntityServer.server.d.ts +34 -2
  22. package/dist/custom/MJDuplicateRunEntityServer.server.d.ts.map +1 -1
  23. package/dist/custom/MJDuplicateRunEntityServer.server.js +103 -23
  24. package/dist/custom/MJDuplicateRunEntityServer.server.js.map +1 -1
  25. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts +73 -0
  26. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts.map +1 -0
  27. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js +391 -0
  28. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js.map +1 -0
  29. package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts +96 -22
  30. package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts.map +1 -1
  31. package/dist/custom/MJEntityFieldPermissionEntityServer.server.js +239 -55
  32. package/dist/custom/MJEntityFieldPermissionEntityServer.server.js.map +1 -1
  33. package/dist/custom/MJFileEntityServer.server.d.ts +45 -0
  34. package/dist/custom/MJFileEntityServer.server.d.ts.map +1 -0
  35. package/dist/custom/MJFileEntityServer.server.js +101 -0
  36. package/dist/custom/MJFileEntityServer.server.js.map +1 -0
  37. package/dist/custom/MJQueryEntityServer.server.d.ts +13 -1
  38. package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
  39. package/dist/custom/MJQueryEntityServer.server.js +56 -8
  40. package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
  41. package/dist/custom/MJQuerySQLEntityServer.server.js +3 -3
  42. package/dist/custom/MJQuerySQLEntityServer.server.js.map +1 -1
  43. package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.d.ts +26 -14
  44. package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.d.ts.map +1 -1
  45. package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.js +57 -32
  46. package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.js.map +1 -1
  47. package/dist/custom/MJUserRoleEntityServer.server.d.ts +74 -7
  48. package/dist/custom/MJUserRoleEntityServer.server.d.ts.map +1 -1
  49. package/dist/custom/MJUserRoleEntityServer.server.js +206 -20
  50. package/dist/custom/MJUserRoleEntityServer.server.js.map +1 -1
  51. package/dist/custom/MJUserRoutineEntityServer.server.d.ts.map +1 -1
  52. package/dist/custom/MJUserRoutineEntityServer.server.js +12 -3
  53. package/dist/custom/MJUserRoutineEntityServer.server.js.map +1 -1
  54. package/dist/custom/MJUserViewEntityServer.server.d.ts +43 -1
  55. package/dist/custom/MJUserViewEntityServer.server.d.ts.map +1 -1
  56. package/dist/custom/MJUserViewEntityServer.server.js +169 -11
  57. package/dist/custom/MJUserViewEntityServer.server.js.map +1 -1
  58. package/dist/custom/MJVectorIndexEntityServer.server.d.ts +83 -11
  59. package/dist/custom/MJVectorIndexEntityServer.server.d.ts.map +1 -1
  60. package/dist/custom/MJVectorIndexEntityServer.server.js +285 -42
  61. package/dist/custom/MJVectorIndexEntityServer.server.js.map +1 -1
  62. package/dist/custom/anonymousOwnershipKeyGuard.d.ts +42 -0
  63. package/dist/custom/anonymousOwnershipKeyGuard.d.ts.map +1 -0
  64. package/dist/custom/anonymousOwnershipKeyGuard.js +36 -0
  65. package/dist/custom/anonymousOwnershipKeyGuard.js.map +1 -0
  66. package/dist/custom/approvalStamp.d.ts +37 -0
  67. package/dist/custom/approvalStamp.d.ts.map +1 -0
  68. package/dist/custom/approvalStamp.js +67 -0
  69. package/dist/custom/approvalStamp.js.map +1 -0
  70. package/dist/custom/fieldPermissionAccess.d.ts +31 -0
  71. package/dist/custom/fieldPermissionAccess.d.ts.map +1 -0
  72. package/dist/custom/fieldPermissionAccess.js +38 -0
  73. package/dist/custom/fieldPermissionAccess.js.map +1 -0
  74. package/dist/custom/fieldPermissionReconciler.d.ts.map +1 -1
  75. package/dist/custom/fieldPermissionReconciler.js +12 -2
  76. package/dist/custom/fieldPermissionReconciler.js.map +1 -1
  77. package/dist/custom/query-extraction/pipeline.d.ts.map +1 -1
  78. package/dist/custom/query-extraction/pipeline.js +56 -5
  79. package/dist/custom/query-extraction/pipeline.js.map +1 -1
  80. package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
  81. package/dist/custom/query-extraction/resolve.js +25 -7
  82. package/dist/custom/query-extraction/resolve.js.map +1 -1
  83. package/dist/custom/query-extraction/sync.d.ts +1 -1
  84. package/dist/custom/query-extraction/sync.d.ts.map +1 -1
  85. package/dist/custom/query-extraction/sync.js +84 -21
  86. package/dist/custom/query-extraction/sync.js.map +1 -1
  87. package/dist/custom/query-extraction/types.d.ts +7 -0
  88. package/dist/custom/query-extraction/types.d.ts.map +1 -1
  89. package/dist/custom/rowFilterValidation.d.ts +47 -2
  90. package/dist/custom/rowFilterValidation.d.ts.map +1 -1
  91. package/dist/custom/rowFilterValidation.js +122 -11
  92. package/dist/custom/rowFilterValidation.js.map +1 -1
  93. package/dist/custom/systemUserGuardState.d.ts +73 -0
  94. package/dist/custom/systemUserGuardState.d.ts.map +1 -0
  95. package/dist/custom/systemUserGuardState.js +161 -0
  96. package/dist/custom/systemUserGuardState.js.map +1 -0
  97. package/dist/custom/template-extraction/parser.js +5 -2
  98. package/dist/custom/template-extraction/parser.js.map +1 -1
  99. package/dist/custom/template-extraction/pipeline.d.ts +6 -1
  100. package/dist/custom/template-extraction/pipeline.d.ts.map +1 -1
  101. package/dist/custom/template-extraction/pipeline.js +15 -6
  102. package/dist/custom/template-extraction/pipeline.js.map +1 -1
  103. package/dist/custom/template-extraction/types.d.ts +2 -2
  104. package/dist/custom/template-extraction/types.d.ts.map +1 -1
  105. package/dist/index.d.ts +7 -0
  106. package/dist/index.d.ts.map +1 -1
  107. package/dist/index.js +7 -0
  108. package/dist/index.js.map +1 -1
  109. package/package.json +30 -30
@@ -5,10 +5,15 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
7
  var MJEntityFieldPermissionEntityServer_1;
8
- import { BaseEntity, BaseEntityResult, FieldPermissionAccess, IsRestrictingFieldRule, LogError, RunView, ValidationErrorInfo, ValidationErrorType, } from '@memberjunction/core';
8
+ import { BaseEntity, BaseEntityResult, FieldPermissionAccess, LogError, RunView, ValidationErrorInfo, ValidationErrorType, } from '@memberjunction/core';
9
9
  import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
10
10
  import { MJEntityFieldPermissionEntity } from '@memberjunction/core-entities';
11
- import { SystemUserFieldAccessLossReason, SystemUserHoldsRole, UserCache } from '@memberjunction/generic-database-provider';
11
+ import { SystemUserFieldAccessLossReason, UserCache } from '@memberjunction/generic-database-provider';
12
+ import { FieldPermissionAccessIs, FieldPermissionAccessVerbs, IsRestrictingFieldRuleAnyCase, NormalizeFieldPermissionAccess, } from './fieldPermissionAccess.js';
13
+ import { GuardedTransactionGroupRefusal, LoadStoredSystemUser, ReleaseGuardedTransactionGroupWrite, ReserveGuardedTransactionGroupWrite, UserHoldsRole, } from './systemUserGuardState.js';
14
+ const UNDETERMINED_PRIOR_BINDING_MESSAGE = 'Could not determine which role and field this permission rule was bound to before the edit, so the ' +
15
+ "change cannot be checked against the MJ system user's access on the target it is leaving. Refusing to " +
16
+ 'save rather than risk removing access the server depends on. Reload the record and try again.';
12
17
  /**
13
18
  * Server-side `MJ: Entity Field Permissions` entity — the save-time half of the
14
19
  * unrestrictable-target guard for field-level security.
@@ -40,6 +45,11 @@ import { SystemUserFieldAccessLossReason, SystemUserHoldsRole, UserCache } from
40
45
  * confidentiality cannot ship with a role that quietly reads everything.
41
46
  */
42
47
  let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1 = class MJEntityFieldPermissionEntityServer extends MJEntityFieldPermissionEntity {
48
+ constructor() {
49
+ super(...arguments);
50
+ /** This write's place in its transaction group, held from the group check until the write enrols. */
51
+ this.pendingGroupWrite = null;
52
+ }
43
53
  Validate() {
44
54
  const result = super.Validate();
45
55
  const target = this.resolveTarget();
@@ -68,12 +78,18 @@ let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1
68
78
  return result;
69
79
  }
70
80
  /**
71
- * Refuses an EDIT that would strip the MJ system user's last `Allow` on a field.
81
+ * Normalizes Access spellings, then refuses an EDIT that would strip the MJ system user's last
82
+ * `Allow` on a field.
83
+ *
84
+ * **Normalization.** The Access columns' CHECK constraint is case-insensitive, so `'deny'` or
85
+ * `'ALLOW'` would otherwise persist and read one way while enforcing another. Rewriting them to
86
+ * the canonical value-list spelling keeps the stored data honest; the guards compare
87
+ * case-insensitively regardless, so normalization is not the only line of defence.
72
88
  *
73
- * Not in `Validate()` for two reasons. It needs the field's rules as they stand in the
74
- * DATABASE — loaded metadata lags recent writes, and reading a stale sibling row as `Allow` is
75
- * exactly how three individually-innocent `No Access` edits get through one at a time. And
76
- * loading them is asynchronous, which `Validate()` is not.
89
+ * **The access-loss guard** is not in `Validate()` for two reasons. It needs the field's rules
90
+ * as they stand in the DATABASE — loaded metadata lags recent writes, and reading a stale
91
+ * sibling row as `Allow` is exactly how three individually-innocent `No Access` edits get
92
+ * through one at a time. And loading them is asynchronous, which `Validate()` is not.
77
93
  *
78
94
  * Inserts are deliberately not checked: adding a rule can only add access, never remove an
79
95
  * existing `Allow`, so the `Deny` check in `Validate()` covers them completely. It has to —
@@ -81,28 +97,125 @@ let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1
81
97
  * the half-built state.
82
98
  */
83
99
  async Save(options) {
84
- if (this.IsSaved) {
85
- const rejection = await this.systemUserAccessLossReason(false);
100
+ this.normalizeAccessSpellings();
101
+ let saved = false;
102
+ try {
103
+ const rejection = await this.systemUserSaveRejection();
86
104
  if (rejection) {
87
105
  return this.refuse(rejection, 'save');
88
106
  }
107
+ saved = await super.Save(options);
108
+ return saved;
109
+ }
110
+ finally {
111
+ this.settleGroupWrite(saved);
112
+ }
113
+ }
114
+ /**
115
+ * Ends this write's hold on its reserved group place: kept when the write enrolled, given back
116
+ * when it was refused, returned false or threw, so a retry is not counted as a second write.
117
+ */
118
+ settleGroupWrite(enrolled) {
119
+ const pending = this.pendingGroupWrite;
120
+ this.pendingGroupWrite = null;
121
+ if (!enrolled) {
122
+ ReleaseGuardedTransactionGroupWrite(pending);
123
+ }
124
+ }
125
+ /**
126
+ * The transaction-group rule for this write. When it passes, the write's place in the group is
127
+ * reserved in the same step, so a second guarded write in flight at once sees it.
128
+ */
129
+ groupRefusal(concernsSystemUser) {
130
+ const refusal = GuardedTransactionGroupRefusal(this.TransactionGroup, concernsSystemUser);
131
+ if (!refusal) {
132
+ this.pendingGroupWrite = ReserveGuardedTransactionGroupWrite(this.TransactionGroup, concernsSystemUser);
133
+ }
134
+ return refusal;
135
+ }
136
+ /**
137
+ * The system-user checks for a save, on the role set as stored in the database (the cached one
138
+ * lags a role assigned a moment ago): a `Deny` on a role the system user holds; an edit that
139
+ * strips its last `Allow`; and a transaction group holding this and another guarded write that
140
+ * concerns it. An insert that restricts nothing needs none of these and reads nothing, which
141
+ * keeps reconciliation's bulk inserts free. A read that fails refuses the save.
142
+ */
143
+ async systemUserSaveRejection() {
144
+ this.pendingGroupWrite = null;
145
+ const restricting = IsRestrictingFieldRuleAnyCase(this);
146
+ if (!this.IsSaved && !restricting) {
147
+ return null;
148
+ }
149
+ try {
150
+ const systemUser = await LoadStoredSystemUser(this.RunViewProviderToUse);
151
+ const prior = this.IsSaved ? this.priorBinding() : null;
152
+ const concerns = UserHoldsRole(systemUser, this.RoleID) || (prior === null && this.IsSaved) || UserHoldsRole(systemUser, prior?.RoleID);
153
+ const groupRefusal = this.groupRefusal(concerns);
154
+ if (groupRefusal) {
155
+ return groupRefusal;
156
+ }
157
+ if (restricting && UserHoldsRole(systemUser, this.RoleID)) {
158
+ return MJEntityFieldPermissionEntityServer_1.SystemUserRoleRejectionReason(this.RoleID, this, systemUser);
159
+ }
160
+ return this.IsSaved ? await this.systemUserEditLossReason(systemUser) : null;
161
+ }
162
+ catch (e) {
163
+ return MJEntityFieldPermissionEntityServer_1.unverifiableMessage(e);
89
164
  }
90
- return super.Save(options);
165
+ }
166
+ /** The refusal when the system user's field access cannot be checked because a read failed. */
167
+ static unverifiableMessage(error) {
168
+ const detail = error instanceof Error ? error.message : String(error);
169
+ return `Could not check this field rule against the MJ system user's field access, so it was not saved. ${detail}`;
91
170
  }
92
171
  /**
93
172
  * Refuses a DELETE that would strip the MJ system user's last `Allow` on a field — the other
94
173
  * way, besides editing one to `No Access`, to remove access without writing a `Deny`.
95
174
  *
96
- * Reconciliation's own orphan deletes are unaffected: it only removes rows whose role has lost
97
- * entity-level read (so the system user is already denied one level up and the guard stands
98
- * down) or whose field became unrestrictable (forced open regardless).
175
+ * Judged against the row's STORED binding: a delete removes the row by ID, so an unsaved
176
+ * re-point on this object does not change which target loses it.
177
+ *
178
+ * Reconciliation's orphan deletes usually clear this guard — a row whose field became
179
+ * unrestrictable is forced open regardless — but not always: an orphaned row can be the system
180
+ * user's last `Allow` on a field while another of its roles still reads the entity. The
181
+ * reconciler logs and skips such a refusal rather than aborting.
99
182
  */
100
183
  async Delete(options) {
101
- const rejection = await this.systemUserAccessLossReason(true);
102
- if (rejection) {
103
- return this.refuse(rejection, 'delete');
184
+ let deleted = false;
185
+ try {
186
+ const rejection = await this.systemUserDeleteRejection();
187
+ if (rejection) {
188
+ return this.refuse(rejection, 'delete');
189
+ }
190
+ deleted = await super.Delete(options);
191
+ return deleted;
192
+ }
193
+ finally {
194
+ this.settleGroupWrite(deleted);
195
+ }
196
+ }
197
+ /** The system-user checks for a delete, on the role set as stored in the database. */
198
+ async systemUserDeleteRejection() {
199
+ this.pendingGroupWrite = null;
200
+ try {
201
+ const systemUser = await LoadStoredSystemUser(this.RunViewProviderToUse);
202
+ const prior = this.priorBinding();
203
+ const concerns = prior === null || UserHoldsRole(systemUser, prior.RoleID);
204
+ const groupRefusal = this.groupRefusal(concerns);
205
+ return groupRefusal ?? (await this.systemUserDeleteLossReason(systemUser));
206
+ }
207
+ catch (e) {
208
+ return MJEntityFieldPermissionEntityServer_1.unverifiableMessage(e);
209
+ }
210
+ }
211
+ /** Rewrites each Access value to its canonical spelling; unrecognized values are left for validation to report. */
212
+ normalizeAccessSpellings() {
213
+ for (const verb of FieldPermissionAccessVerbs) {
214
+ const canonical = NormalizeFieldPermissionAccess(this[verb]);
215
+ if (canonical && canonical !== this[verb]) {
216
+ this[verb] = canonical;
217
+ }
104
218
  }
105
- return super.Delete(options);
106
219
  }
107
220
  /**
108
221
  * Records a refusal on the result history so `LatestResult.CompleteMessage` explains it, and
@@ -119,36 +232,99 @@ let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1
119
232
  return false;
120
233
  }
121
234
  /**
122
- * Why the pending change would leave the system user short of its entity-level access, or null.
235
+ * Why the pending EDIT would leave the system user short of its entity-level access, or null.
236
+ *
237
+ * An edit that changes `RoleID` or `EntityFieldID` MOVES the rule: it is a delete from the
238
+ * target it leaves as well as an insert into the one it joins. Judging only the destination
239
+ * let a sequence of saves strip the system user's last `Allow` without writing a `Deny` —
240
+ * re-point that row at a role the system user does not hold, and the cheap exit on the NEW
241
+ * role waved it through. So both targets are evaluated:
123
242
  *
124
- * @param removing true when this row is being deleted rather than edited
243
+ * - **the destination field**, with this row's new values projected in, whenever the system
244
+ * user holds the new role — or, when the field is unchanged, the old one (the row's old
245
+ * binding drops out of that same field's aggregate);
246
+ * - **the vacated field**, with this row removed, whenever the field itself changed and the
247
+ * system user holds the old role.
248
+ *
249
+ * The cheap exits are what keep the queries off ordinary permission administration: the
250
+ * aggregation only consults rules bound to roles the user holds, so a change touching no such
251
+ * role cannot move the system user's access at all.
125
252
  */
126
- async systemUserAccessLossReason(removing) {
127
- // Cheap exit first: the aggregation only ever consults rules bound to a role the user
128
- // holds, so a change to any other role's rule cannot move the system user's access at all.
129
- // This is what keeps the query below off the path of ordinary permission administration —
130
- // it runs only for edits to the handful of roles the server's own account holds.
131
- if (!SystemUserHoldsRole(this.RoleID)) {
253
+ async systemUserEditLossReason(systemUser) {
254
+ const prior = this.priorBinding();
255
+ if (!prior) {
256
+ return UNDETERMINED_PRIOR_BINDING_MESSAGE;
257
+ }
258
+ const holds = (roleID) => UserHoldsRole(systemUser, roleID);
259
+ const fieldMoved = !UUIDsEqual(prior.EntityFieldID, this.EntityFieldID);
260
+ const touchesDestination = holds(this.RoleID) || (!fieldMoved && holds(prior.RoleID));
261
+ if (touchesDestination) {
262
+ const rejection = await this.projectedLossReason(this.EntityFieldID, true, systemUser);
263
+ if (rejection) {
264
+ return rejection;
265
+ }
266
+ }
267
+ if (fieldMoved && holds(prior.RoleID)) {
268
+ return this.projectedLossReason(prior.EntityFieldID, false, systemUser);
269
+ }
270
+ return null;
271
+ }
272
+ /** Why deleting this row would leave the system user short of its entity-level access, or null. */
273
+ async systemUserDeleteLossReason(systemUser) {
274
+ const prior = this.priorBinding();
275
+ if (!prior) {
276
+ return UNDETERMINED_PRIOR_BINDING_MESSAGE;
277
+ }
278
+ if (!UserHoldsRole(systemUser, prior.RoleID)) {
132
279
  return null;
133
280
  }
134
- const target = this.resolveTarget();
281
+ return this.projectedLossReason(prior.EntityFieldID, false, systemUser);
282
+ }
283
+ /**
284
+ * Projects one field's stored rules with this row's change applied and asks whether the
285
+ * system user keeps its access there.
286
+ *
287
+ * @param entityFieldID the field whose aggregate to evaluate
288
+ * @param includeThisRow true to project this row in with its CURRENT values (it is on this
289
+ * field after the change); false to project it out (it is leaving)
290
+ * @param systemUser the system user with its role set as stored
291
+ */
292
+ async projectedLossReason(entityFieldID, includeThisRow, systemUser) {
293
+ const target = this.resolveTargetByFieldID(entityFieldID);
135
294
  if (!target) {
136
295
  return null;
137
296
  }
138
297
  const current = await this.loadCurrentRules(target.Field.ID);
139
- const others = current.filter(r => !UUIDsEqual(r.ID, this.ID));
140
- const projected = removing
141
- ? others
142
- : [
298
+ const others = current.filter((r) => !UUIDsEqual(r.ID, this.ID));
299
+ const projected = includeThisRow
300
+ ? [
143
301
  ...others,
144
- {
145
- RoleID: this.RoleID,
146
- ReadAccess: this.ReadAccess,
147
- UpdateAccess: this.UpdateAccess,
148
- CreateAccess: this.CreateAccess,
149
- },
150
- ];
151
- return SystemUserFieldAccessLossReason(target.Entity, target.Field, projected);
302
+ { RoleID: this.RoleID, ReadAccess: this.ReadAccess, UpdateAccess: this.UpdateAccess, CreateAccess: this.CreateAccess },
303
+ ]
304
+ : others;
305
+ return SystemUserFieldAccessLossReason(target.Entity, target.Field, projected, systemUser);
306
+ }
307
+ /**
308
+ * The (role, field) pair this row occupies in the database — the dirty fields' old values,
309
+ * otherwise their current ones. Null when a re-pointed field's prior value cannot be
310
+ * established, which callers treat as a refusal: an unknown vacated target cannot be shown safe.
311
+ */
312
+ priorBinding() {
313
+ const roleID = this.priorValue('RoleID', this.RoleID);
314
+ const entityFieldID = this.priorValue('EntityFieldID', this.EntityFieldID);
315
+ if (roleID === undefined || entityFieldID === undefined) {
316
+ return null;
317
+ }
318
+ return { RoleID: roleID, EntityFieldID: entityFieldID };
319
+ }
320
+ /** A column's stored value; undefined when it is dirty and its old value is not a usable ID. */
321
+ priorValue(fieldName, current) {
322
+ const field = this.GetFieldByName(fieldName);
323
+ if (!field?.Dirty) {
324
+ return current;
325
+ }
326
+ const old = field.OldValue;
327
+ return typeof old === 'string' && old.length > 0 ? old : undefined;
152
328
  }
153
329
  /**
154
330
  * Every rule currently stored against this field, straight from the database.
@@ -208,17 +384,20 @@ let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1
208
384
  * @param roleID the role the rule targets
209
385
  * @param rule the rule's three verbs; omitted only by callers that are pre-checking a role
210
386
  * rather than a specific rule, which are answered as though the rule denied
387
+ * @param storedSystemUser the system user with its role set as stored in the database;
388
+ * defaults to the user cache's system user
211
389
  */
212
- static SystemUserRoleRejectionReason(roleID, rule) {
390
+ static SystemUserRoleRejectionReason(roleID, rule, storedSystemUser) {
213
391
  if (!roleID) {
214
392
  return null;
215
393
  }
216
- if (rule && !IsRestrictingFieldRule(rule)) {
394
+ if (rule && !IsRestrictingFieldRuleAnyCase(rule)) {
217
395
  return null; // grants and neutrals are exactly what keep the system user working
218
396
  }
219
397
  // UserCache is populated on the server; a client-side save (or a cold cache) simply
220
- // skips the check rather than blocking an administrator on missing state.
221
- const systemUser = UserCache.Instance?.GetSystemUser?.();
398
+ // skips the check rather than blocking an administrator on missing state. `Save()` passes
399
+ // the system user with its role set as stored, which the cache may not show yet.
400
+ const systemUser = storedSystemUser ?? UserCache.Instance?.GetSystemUser?.();
222
401
  if (!systemUser?.UserRoles?.length) {
223
402
  return null;
224
403
  }
@@ -254,10 +433,11 @@ let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1
254
433
  if (!field.ReadOnly) {
255
434
  return null;
256
435
  }
436
+ // Compared case-insensitively: the column's collation stores 'no access' as the same value.
257
437
  const offending = [];
258
- if (rule.UpdateAccess !== FieldPermissionAccess.NoAccess)
438
+ if (!FieldPermissionAccessIs(rule.UpdateAccess, FieldPermissionAccess.NoAccess))
259
439
  offending.push('Update');
260
- if (rule.CreateAccess !== FieldPermissionAccess.NoAccess)
440
+ if (!FieldPermissionAccessIs(rule.CreateAccess, FieldPermissionAccess.NoAccess))
261
441
  offending.push('Create');
262
442
  if (offending.length === 0) {
263
443
  return null;
@@ -285,15 +465,6 @@ let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1
285
465
  }
286
466
  return null;
287
467
  }
288
- /**
289
- * Resolves `EntityFieldID` to its {@link EntityFieldInfo} from loaded metadata.
290
- *
291
- * Returns null when metadata cannot resolve it — for instance immediately after a schema
292
- * change, before the metadata cache has refreshed. That case passes validation rather than
293
- * blocking the administrator: the foreign key already guarantees the row points at a real
294
- * field, and the runtime aggregation guards hold regardless of what is stored here. Failing
295
- * closed would trade a real, recurring workflow block for no additional protection.
296
- */
297
468
  /**
298
469
  * Why this role may not carry a field rule on this entity, or null when it may.
299
470
  *
@@ -326,13 +497,26 @@ let MJEntityFieldPermissionEntityServer = MJEntityFieldPermissionEntityServer_1
326
497
  `permission on '${entity.Name}' first (one that grants nothing is fine, and is how a deny-only ` +
327
498
  `carve-out is expressed), then set the field rule.`);
328
499
  }
500
+ /**
501
+ * Resolves `EntityFieldID` to its {@link EntityFieldInfo} from loaded metadata.
502
+ *
503
+ * Returns null when metadata cannot resolve it — for instance immediately after a schema
504
+ * change, before the metadata cache has refreshed. That case passes validation rather than
505
+ * blocking the administrator: the foreign key already guarantees the row points at a real
506
+ * field, and the runtime aggregation guards hold regardless of what is stored here. Failing
507
+ * closed would trade a real, recurring workflow block for no additional protection.
508
+ */
329
509
  resolveTarget() {
330
- if (!this.EntityFieldID) {
510
+ return this.resolveTargetByFieldID(this.EntityFieldID);
511
+ }
512
+ /** The field a given `EntityFieldID` names, so the re-point guard can resolve a row's OLD field too. */
513
+ resolveTargetByFieldID(entityFieldID) {
514
+ if (!entityFieldID) {
331
515
  return null; // the NOT NULL column is the base class's problem to report, not ours
332
516
  }
333
517
  const md = this.ProviderToUse;
334
518
  for (const entity of md?.Entities ?? []) {
335
- const match = entity.Fields.find((f) => UUIDsEqual(f.ID, this.EntityFieldID));
519
+ const match = entity.Fields.find((f) => UUIDsEqual(f.ID, entityFieldID));
336
520
  if (match) {
337
521
  return { Entity: entity, Field: match };
338
522
  }
@@ -1 +1 @@
1
- {"version":3,"file":"MJEntityFieldPermissionEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJEntityFieldPermissionEntityServer.server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MJEntityFieldPermissionEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJEntityFieldPermissionEntityServer.server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { EntitySaveOptions, ValidationResult } from '@memberjunction/core';
2
+ import { MJFileEntity } from '@memberjunction/core-entities';
3
+ /**
4
+ * Server-side `MJ: Files` entity: once a row exists, WHERE its bytes live is server-owned.
5
+ *
6
+ * `ProviderID` and `ProviderKey` decide which storage provider (and so which account) and which object every
7
+ * file-ID route — `DownloadUrl`, `GetFileContents`, `CreateMediaAccessToken`, `DeleteFile`, the artifact download URL,
8
+ * the agent file handler — reads, signs or deletes. A client that could re-point an existing row could make a row other
9
+ * users trust (an attachment, an artifact's file) serve, or delete, a different object. So a save that changes either
10
+ * field on an existing row is refused, unless trusted server code that chose the new location itself sets
11
+ * {@link AllowStorageLocationChange} first — the same opt-in pattern `MJRubricEvaluationScoreEntityServer` uses for
12
+ * server-computed rows. A GraphQL save never sets it.
13
+ *
14
+ * **What this does not cover — a new row.** A client may still create a row with a `ProviderKey` of its choosing, and
15
+ * `Name` (the object key when `ProviderKey` is empty) is client-writable on every row. Refusing a client-supplied
16
+ * `ProviderKey` on create would break Explorer's direct-upload path, which registers the object it just uploaded through
17
+ * a client save, and would not stop aliasing anyway (`Name` is the fallback key). MJStorage's `UploadFile` sets the field
18
+ * from a package that cannot reach this class. The guarantee for a new row comes from the routes instead: each one
19
+ * resolves the row through the storage gate (`FileStorageEngine.ResolveFileObject`), which requires the caller's access
20
+ * to the account and refuses an object any other `MJ: Files` row tracks when the caller cannot read that row. Closing the
21
+ * create path needs a server-side registration mutation for the direct-upload flow — a follow-up.
22
+ */
23
+ export declare class MJFileEntityServer extends MJFileEntity {
24
+ /**
25
+ * Set by trusted server code, before `Save()`, when it re-points an existing row to a storage location it chose
26
+ * itself. A client save leaves this false, so a change to `ProviderID` or `ProviderKey` on an existing row is refused.
27
+ */
28
+ AllowStorageLocationChange: boolean;
29
+ /** Adds the storage-location rule to the generated validation. */
30
+ Validate(): ValidationResult;
31
+ /**
32
+ * Applies the rule to a `ReplayOnly` save too: `ReplayOnly` skips `Validate()` but still writes, so without this the
33
+ * rule would be one save option away from off.
34
+ */
35
+ Save(options?: EntitySaveOptions): Promise<boolean>;
36
+ /** The location fields this save would change on an existing row without the trusted opt-in. */
37
+ private refusedLocationChanges;
38
+ /** Whether `field` holds a different value from the one loaded (`ProviderID` compared as a UUID). */
39
+ private locationFieldChanged;
40
+ /** Records a refused save on the result history (so `LatestResult.CompleteMessage` carries why) and returns false. */
41
+ private refuse;
42
+ /** The refusal for a client change to a storage-location field. */
43
+ private static locationChangeMessage;
44
+ }
45
+ //# sourceMappingURL=MJFileEntityServer.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJFileEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJFileEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,iBAAiB,EAGjB,gBAAgB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAK7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,kBAAmB,SAAQ,YAAY;IAChD;;;OAGG;IACI,0BAA0B,UAAS;IAE1C,kEAAkE;IAClD,QAAQ,IAAI,gBAAgB;IAc5C;;;OAGG;IACmB,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAQzE,gGAAgG;IAChG,OAAO,CAAC,sBAAsB;IAQ9B,qGAAqG;IACrG,OAAO,CAAC,oBAAoB;IAa5B,sHAAsH;IACtH,OAAO,CAAC,MAAM;IAWd,mEAAmE;IACnE,OAAO,CAAC,MAAM,CAAC,qBAAqB;CAGvC"}
@@ -0,0 +1,101 @@
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
+ var MJFileEntityServer_1;
8
+ import { BaseEntity, BaseEntityResult, ValidationErrorInfo, ValidationErrorType, } from '@memberjunction/core';
9
+ import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
10
+ import { MJFileEntity } from '@memberjunction/core-entities';
11
+ /**
12
+ * Server-side `MJ: Files` entity: once a row exists, WHERE its bytes live is server-owned.
13
+ *
14
+ * `ProviderID` and `ProviderKey` decide which storage provider (and so which account) and which object every
15
+ * file-ID route — `DownloadUrl`, `GetFileContents`, `CreateMediaAccessToken`, `DeleteFile`, the artifact download URL,
16
+ * the agent file handler — reads, signs or deletes. A client that could re-point an existing row could make a row other
17
+ * users trust (an attachment, an artifact's file) serve, or delete, a different object. So a save that changes either
18
+ * field on an existing row is refused, unless trusted server code that chose the new location itself sets
19
+ * {@link AllowStorageLocationChange} first — the same opt-in pattern `MJRubricEvaluationScoreEntityServer` uses for
20
+ * server-computed rows. A GraphQL save never sets it.
21
+ *
22
+ * **What this does not cover — a new row.** A client may still create a row with a `ProviderKey` of its choosing, and
23
+ * `Name` (the object key when `ProviderKey` is empty) is client-writable on every row. Refusing a client-supplied
24
+ * `ProviderKey` on create would break Explorer's direct-upload path, which registers the object it just uploaded through
25
+ * a client save, and would not stop aliasing anyway (`Name` is the fallback key). MJStorage's `UploadFile` sets the field
26
+ * from a package that cannot reach this class. The guarantee for a new row comes from the routes instead: each one
27
+ * resolves the row through the storage gate (`FileStorageEngine.ResolveFileObject`), which requires the caller's access
28
+ * to the account and refuses an object any other `MJ: Files` row tracks when the caller cannot read that row. Closing the
29
+ * create path needs a server-side registration mutation for the direct-upload flow — a follow-up.
30
+ */
31
+ let MJFileEntityServer = MJFileEntityServer_1 = class MJFileEntityServer extends MJFileEntity {
32
+ constructor() {
33
+ super(...arguments);
34
+ /**
35
+ * Set by trusted server code, before `Save()`, when it re-points an existing row to a storage location it chose
36
+ * itself. A client save leaves this false, so a change to `ProviderID` or `ProviderKey` on an existing row is refused.
37
+ */
38
+ this.AllowStorageLocationChange = false;
39
+ }
40
+ /** Adds the storage-location rule to the generated validation. */
41
+ Validate() {
42
+ const result = super.Validate();
43
+ for (const field of this.refusedLocationChanges()) {
44
+ result.Errors.push(new ValidationErrorInfo(field, MJFileEntityServer_1.locationChangeMessage(field), this.GetFieldByName(field)?.Value, ValidationErrorType.Failure));
45
+ }
46
+ result.Success = result.Success && result.Errors.length === 0;
47
+ return result;
48
+ }
49
+ /**
50
+ * Applies the rule to a `ReplayOnly` save too: `ReplayOnly` skips `Validate()` but still writes, so without this the
51
+ * rule would be one save option away from off.
52
+ */
53
+ async Save(options) {
54
+ const refused = options?.ReplayOnly ? this.refusedLocationChanges() : [];
55
+ if (refused.length > 0) {
56
+ return this.refuse(MJFileEntityServer_1.locationChangeMessage(refused[0]));
57
+ }
58
+ return super.Save(options);
59
+ }
60
+ /** The location fields this save would change on an existing row without the trusted opt-in. */
61
+ refusedLocationChanges() {
62
+ if (!this.IsSaved || this.AllowStorageLocationChange) {
63
+ return [];
64
+ }
65
+ const fields = ['ProviderID', 'ProviderKey'];
66
+ return fields.filter(field => this.locationFieldChanged(field));
67
+ }
68
+ /** Whether `field` holds a different value from the one loaded (`ProviderID` compared as a UUID). */
69
+ locationFieldChanged(field) {
70
+ const info = this.GetFieldByName(field);
71
+ if (!info?.Dirty) {
72
+ return false;
73
+ }
74
+ const before = info.OldValue;
75
+ const after = info.Value;
76
+ if (field === 'ProviderID') {
77
+ return !(before && after ? UUIDsEqual(before, after) : before === after);
78
+ }
79
+ return (before ?? null) !== (after ?? null);
80
+ }
81
+ /** Records a refused save on the result history (so `LatestResult.CompleteMessage` carries why) and returns false. */
82
+ refuse(message) {
83
+ const result = new BaseEntityResult();
84
+ result.Success = false;
85
+ result.Type = 'update';
86
+ result.Message = message;
87
+ result.StartedAt = new Date();
88
+ result.EndedAt = new Date();
89
+ this.RegisterResultHistoryEntry(result);
90
+ return false;
91
+ }
92
+ /** The refusal for a client change to a storage-location field. */
93
+ static locationChangeMessage(field) {
94
+ return `${field} cannot be changed on an existing file: where a file's bytes live is set by the server when the file is stored.`;
95
+ }
96
+ };
97
+ MJFileEntityServer = MJFileEntityServer_1 = __decorate([
98
+ RegisterClass(BaseEntity, 'MJ: Files')
99
+ ], MJFileEntityServer);
100
+ export { MJFileEntityServer };
101
+ //# sourceMappingURL=MJFileEntityServer.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJFileEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJFileEntityServer.server.ts"],"names":[],"mappings":"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"}
@@ -29,6 +29,14 @@ export declare class MJQueryEntityServer extends MJQueryEntityExtended {
29
29
  /** Clears the stored vector (both forms) and the model it was computed with. */
30
30
  private clearEmbedding;
31
31
  Save(options?: EntitySaveOptions): Promise<boolean>;
32
+ /**
33
+ * Stores the fingerprint of the definition just approved: this row's SQL, template flag and
34
+ * external source, with its dialect and parameter rows read back from the database. Until this
35
+ * write lands the approval is not current, so a failure here fails closed.
36
+ */
37
+ private stampApprovalFingerprintAsync;
38
+ /** This query's dialect and parameter rows as stored, bypassing every cache. */
39
+ private loadDefinitionRowsAsync;
32
40
  Delete(options?: EntitySaveOptions): Promise<boolean>;
33
41
  /**
34
42
  * Returns the database platform of the connected database.
@@ -67,11 +75,15 @@ export declare class MJQueryEntityServer extends MJQueryEntityExtended {
67
75
  * when a dialect variant matching the current platform is saved — this handles
68
76
  * the timing issue where the parent Query is saved before its QuerySQL children
69
77
  * exist in the cache.
78
+ *
79
+ * @param skipAIEnrichment Skip the LLM enrichment stage, as `SkipEntityAIActions` does for Save.
70
80
  */
71
- RerunExtraction(): Promise<void>;
81
+ RerunExtraction(skipAIEnrichment?: boolean): Promise<void>;
72
82
  /**
73
83
  * Runs the extraction pipeline and saves the UsesTemplate flag.
74
84
  * On error, sets UsesTemplate=false and attempts to save so the query remains usable.
85
+ *
86
+ * @param skipAIEnrichment Skip the LLM enrichment stage (the save asked to skip AI actions).
75
87
  */
76
88
  private extractAndSyncDataAsync;
77
89
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"MJQueryEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJQueryEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,iBAAiB,EAGjB,qBAAqB,EAExB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAoB,qBAAqB,EAAmC,MAAM,+BAA+B,CAAC;AAazH;;;;GAIG;AACH,qBACa,mBAAoB,SAAQ,qBAAqB;IAC1D;;;yEAGqE;IAC9D,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI5C;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5F;;;;;;;;;OASG;cACa,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3D,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAQP,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAyCnD,MAAM,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpE;;;OAGG;IACH,OAAO,KAAK,eAAe,GAE1B;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;;;;;;;OAQG;IACH,OAAO,CAAC,4BAA4B;IAgBpC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;;;;OAKG;IACU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7C;;;OAGG;YACW,uBAAuB;IAsBrC;;OAEG;YACW,sBAAsB;IAmBpC;;;OAGG;YACW,wBAAwB;IAiCtC;;OAEG;YACW,sBAAsB;IA4BpC;;OAEG;YACW,oBAAoB;IA4BlC;;OAEG;YACW,6BAA6B;CAgB9C"}
1
+ {"version":3,"file":"MJQueryEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJQueryEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,iBAAiB,EAGjB,qBAAqB,EAExB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAIH,qBAAqB,EAIxB,MAAM,+BAA+B,CAAC;AAcvC;;;;GAIG;AACH,qBACa,mBAAoB,SAAQ,qBAAqB;IAC1D;;;yEAGqE;IAC9D,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI5C;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5F;;;;;;;;;OASG;cACa,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3D,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAQP,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAuDlE;;;;OAIG;YACW,6BAA6B;IAW3C,gFAAgF;YAClE,uBAAuB;IActB,MAAM,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpE;;;OAGG;IACH,OAAO,KAAK,eAAe,GAE1B;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;;;;;;;OAQG;IACH,OAAO,CAAC,4BAA4B;IAgBpC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;;;;OAOG;IACU,eAAe,CAAC,gBAAgB,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE;;;;;OAKG;YACW,uBAAuB;IAsBrC;;OAEG;YACW,sBAAsB;IAmBpC;;;OAGG;YACW,wBAAwB;IAiCtC;;OAEG;YACW,sBAAsB;IA4BpC;;OAEG;YACW,oBAAoB;IA4BlC;;OAEG;YACW,6BAA6B;CAgB9C"}