@memberjunction/core-entities-server 6.1.4 → 6.1.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.
- package/dist/custom/MJDataContextItemEntityServer.server.d.ts +33 -0
- package/dist/custom/MJDataContextItemEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJDataContextItemEntityServer.server.js +84 -0
- package/dist/custom/MJDataContextItemEntityServer.server.js.map +1 -0
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.d.ts +26 -14
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.js +57 -32
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserViewEntityServer.server.d.ts +26 -0
- package/dist/custom/MJUserViewEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserViewEntityServer.server.js +68 -4
- package/dist/custom/MJUserViewEntityServer.server.js.map +1 -1
- package/dist/custom/query-extraction/pipeline.js +1 -1
- package/dist/custom/query-extraction/pipeline.js.map +1 -1
- package/dist/custom/query-extraction/resolve.d.ts +5 -2
- package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
- package/dist/custom/query-extraction/resolve.js +6 -3
- package/dist/custom/query-extraction/resolve.js.map +1 -1
- package/dist/custom/query-extraction/sync.d.ts.map +1 -1
- package/dist/custom/query-extraction/sync.js +4 -2
- package/dist/custom/query-extraction/sync.js.map +1 -1
- package/dist/custom/rowFilterValidation.d.ts +47 -2
- package/dist/custom/rowFilterValidation.d.ts.map +1 -1
- package/dist/custom/rowFilterValidation.js +122 -11
- package/dist/custom/rowFilterValidation.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 +28 -28
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { EntitySaveOptions, ValidationResult } from '@memberjunction/core';
|
|
2
|
+
import { MJDataContextItemEntity } from '@memberjunction/core-entities';
|
|
3
|
+
/**
|
|
4
|
+
* Server-side `MJ: Data Context Items` entity. The SQL of a `sql` item runs when its data context is
|
|
5
|
+
* loaded, so only an administrator (Owner-type user) may save an item that is a SQL item or holds SQL
|
|
6
|
+
* text: creating it, changing any of its fields, or moving it to another data context. Other items
|
|
7
|
+
* stay writable as before.
|
|
8
|
+
*
|
|
9
|
+
* The rule reads the item's values, not which fields changed, because this entity does not track
|
|
10
|
+
* record changes and a client's `OldValues___` can decide what looks changed. A non-Owner's save of an
|
|
11
|
+
* existing item whose `Type` or `SQL` was not loaded is refused as well: those columns keep their
|
|
12
|
+
* stored values on save, and the stored item may be a SQL item.
|
|
13
|
+
*/
|
|
14
|
+
export declare class MJDataContextItemEntityServer extends MJDataContextItemEntity {
|
|
15
|
+
private static readonly SQL_WRITE_REFUSED;
|
|
16
|
+
private static readonly SQL_NOT_LOADED_REFUSED;
|
|
17
|
+
/** The columns that decide whether an item holds SQL. */
|
|
18
|
+
private static readonly SQL_COLUMNS;
|
|
19
|
+
Validate(): ValidationResult;
|
|
20
|
+
/** Applies the same rule to a `ReplayOnly` save, which skips `Validate()`. */
|
|
21
|
+
Save(options?: EntitySaveOptions): Promise<boolean>;
|
|
22
|
+
/** Returns why the acting user may not save this item, or null when they may. */
|
|
23
|
+
private saveRefusal;
|
|
24
|
+
/** True when this is an existing item whose `Type` or `SQL` was not loaded. */
|
|
25
|
+
private sqlColumnsNotLoaded;
|
|
26
|
+
/** True when the item, as loaded and changed, is a SQL item or holds SQL text. */
|
|
27
|
+
private holdsSQL;
|
|
28
|
+
/** True when the acting user is an Owner-type user. */
|
|
29
|
+
private callerIsOwner;
|
|
30
|
+
/** Records the refusal so `LatestResult.CompleteMessage` carries it, and returns false. */
|
|
31
|
+
private refuseSave;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=MJDataContextItemEntityServer.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJDataContextItemEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJDataContextItemEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,iBAAiB,EAAsD,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7J,OAAO,EAAE,uBAAuB,EAA+B,MAAM,+BAA+B,CAAC;AAErG;;;;;;;;;;GAUG;AACH,qBACa,6BAA8B,SAAQ,uBAAuB;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAC8F;IAEvI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CACuG;IAErJ,yDAAyD;IACzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAqE;IAExF,QAAQ,IAAI,gBAAgB;IAU5C,8EAA8E;IACxD,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAQzE,iFAAiF;IACjF,OAAO,CAAC,WAAW;IAUnB,+EAA+E;IAC/E,OAAO,CAAC,mBAAmB;IAI3B,kFAAkF;IAClF,OAAO,CAAC,QAAQ;IAIhB,uDAAuD;IACvD,OAAO,CAAC,aAAa;IAKrB,2FAA2F;IAC3F,OAAO,CAAC,UAAU;CAUrB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
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 MJDataContextItemEntityServer_1;
|
|
8
|
+
import { BaseEntity, BaseEntityResult, ValidationErrorInfo, ValidationErrorType } from '@memberjunction/core';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { MJDataContextItemEntity } from '@memberjunction/core-entities';
|
|
11
|
+
/**
|
|
12
|
+
* Server-side `MJ: Data Context Items` entity. The SQL of a `sql` item runs when its data context is
|
|
13
|
+
* loaded, so only an administrator (Owner-type user) may save an item that is a SQL item or holds SQL
|
|
14
|
+
* text: creating it, changing any of its fields, or moving it to another data context. Other items
|
|
15
|
+
* stay writable as before.
|
|
16
|
+
*
|
|
17
|
+
* The rule reads the item's values, not which fields changed, because this entity does not track
|
|
18
|
+
* record changes and a client's `OldValues___` can decide what looks changed. A non-Owner's save of an
|
|
19
|
+
* existing item whose `Type` or `SQL` was not loaded is refused as well: those columns keep their
|
|
20
|
+
* stored values on save, and the stored item may be a SQL item.
|
|
21
|
+
*/
|
|
22
|
+
let MJDataContextItemEntityServer = class MJDataContextItemEntityServer extends MJDataContextItemEntity {
|
|
23
|
+
static { MJDataContextItemEntityServer_1 = this; }
|
|
24
|
+
static { this.SQL_WRITE_REFUSED = 'Only an administrator (Owner-type user) may save a data context item that holds SQL, because that SQL runs against the database.'; }
|
|
25
|
+
static { this.SQL_NOT_LOADED_REFUSED = 'Only an administrator (Owner-type user) may save a data context item whose Type and SQL were not loaded, because the stored item may hold SQL.'; }
|
|
26
|
+
/** The columns that decide whether an item holds SQL. */
|
|
27
|
+
static { this.SQL_COLUMNS = ['Type', 'SQL']; }
|
|
28
|
+
Validate() {
|
|
29
|
+
const result = super.Validate();
|
|
30
|
+
const refusal = this.saveRefusal();
|
|
31
|
+
if (refusal) {
|
|
32
|
+
result.Errors.push(new ValidationErrorInfo('SQL', refusal, this.SQL, ValidationErrorType.Failure));
|
|
33
|
+
}
|
|
34
|
+
result.Success = result.Success && result.Errors.length === 0;
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
/** Applies the same rule to a `ReplayOnly` save, which skips `Validate()`. */
|
|
38
|
+
async Save(options) {
|
|
39
|
+
const refusal = options?.ReplayOnly ? this.saveRefusal() : null;
|
|
40
|
+
if (refusal) {
|
|
41
|
+
return this.refuseSave(refusal);
|
|
42
|
+
}
|
|
43
|
+
return super.Save(options);
|
|
44
|
+
}
|
|
45
|
+
/** Returns why the acting user may not save this item, or null when they may. */
|
|
46
|
+
saveRefusal() {
|
|
47
|
+
if (this.callerIsOwner()) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (this.sqlColumnsNotLoaded()) {
|
|
51
|
+
return MJDataContextItemEntityServer_1.SQL_NOT_LOADED_REFUSED;
|
|
52
|
+
}
|
|
53
|
+
return this.holdsSQL() ? MJDataContextItemEntityServer_1.SQL_WRITE_REFUSED : null;
|
|
54
|
+
}
|
|
55
|
+
/** True when this is an existing item whose `Type` or `SQL` was not loaded. */
|
|
56
|
+
sqlColumnsNotLoaded() {
|
|
57
|
+
return this.IsSaved && MJDataContextItemEntityServer_1.SQL_COLUMNS.some((name) => this.GetFieldByName(name)?.NotLoaded === true);
|
|
58
|
+
}
|
|
59
|
+
/** True when the item, as loaded and changed, is a SQL item or holds SQL text. */
|
|
60
|
+
holdsSQL() {
|
|
61
|
+
return this.Type === 'sql' || !!this.SQL?.trim();
|
|
62
|
+
}
|
|
63
|
+
/** True when the acting user is an Owner-type user. */
|
|
64
|
+
callerIsOwner() {
|
|
65
|
+
const caller = this.ActiveUser;
|
|
66
|
+
return caller?.Type?.trim().toLowerCase() === 'owner';
|
|
67
|
+
}
|
|
68
|
+
/** Records the refusal so `LatestResult.CompleteMessage` carries it, and returns false. */
|
|
69
|
+
refuseSave(message) {
|
|
70
|
+
const result = new BaseEntityResult();
|
|
71
|
+
result.Success = false;
|
|
72
|
+
result.Type = this.IsSaved ? 'update' : 'create';
|
|
73
|
+
result.Message = message;
|
|
74
|
+
result.StartedAt = new Date();
|
|
75
|
+
result.EndedAt = new Date();
|
|
76
|
+
this.RegisterResultHistoryEntry(result);
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
MJDataContextItemEntityServer = MJDataContextItemEntityServer_1 = __decorate([
|
|
81
|
+
RegisterClass(BaseEntity, 'MJ: Data Context Items')
|
|
82
|
+
], MJDataContextItemEntityServer);
|
|
83
|
+
export { MJDataContextItemEntityServer };
|
|
84
|
+
//# sourceMappingURL=MJDataContextItemEntityServer.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJDataContextItemEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJDataContextItemEntityServer.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,25 +7,37 @@ import { MJRowLevelSecurityFilterEntity } from '@memberjunction/core-entities';
|
|
|
7
7
|
* against the rule's entity when the RULE is saved; without an equivalent
|
|
8
8
|
* check when the FILTER is saved, both are trivially bypassable: attach a
|
|
9
9
|
* valid filter, then edit its text (or acquire a new, different-entity
|
|
10
|
-
* referrer) to reference anything. On a `FilterText` change
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* (fail closed). Check 6 has no single rule to anchor on here (a filter
|
|
16
|
-
* record itself carries no entity binding — see plan §5.1), so it anchors on
|
|
17
|
-
* the first referrer that DOES resolve to an entity and requires every other
|
|
18
|
-
* referrer to agree with it; zero or one resolvable referrer trivially
|
|
19
|
-
* satisfies the invariant.
|
|
10
|
+
* referrer) to reference anything. On a `FilterText` change this subclass
|
|
11
|
+
* re-validates the new text against EVERY current referrer (EntityPermission
|
|
12
|
+
* rows via their four `*RLSFilterID` columns, plus both API scope tables via
|
|
13
|
+
* `RowFilterID`) and rejects if any check fails — including referrers whose
|
|
14
|
+
* entity cannot be resolved (fail closed).
|
|
20
15
|
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
16
|
+
* Which checks apply depends on who references the filter:
|
|
17
|
+
* - **Any API-key or API-application scope rule** → the strict API-key rules
|
|
18
|
+
* (checks 4 and 6): plain columns of the referrer's entity only, and every
|
|
19
|
+
* referrer must agree on ONE entity. Check 6 has no single rule to anchor on
|
|
20
|
+
* here (a filter record carries no entity binding — see plan §5.1), so it
|
|
21
|
+
* anchors on the first referrer that resolves to an entity.
|
|
22
|
+
* - **Only role permission rows** → a role filter. Role filters legitimately use
|
|
23
|
+
* subqueries (a user's tenant memberships) and are shared across every
|
|
24
|
+
* tenant-scoped entity, so the new text is instead screened for dangerous SQL
|
|
25
|
+
* and compiled against each referencing entity's base view.
|
|
26
|
+
*
|
|
27
|
+
* Either way an invalid filter is rejected at save, where it is diagnosable,
|
|
28
|
+
* rather than failing every read of the entities it scopes with an unexplained
|
|
29
|
+
* SQL error.
|
|
25
30
|
*/
|
|
26
31
|
export declare class MJRowLevelSecurityFilterEntityServer extends MJRowLevelSecurityFilterEntity {
|
|
27
32
|
/** Enable async validation so the referrer re-validation (which queries three tables) runs on Save. */
|
|
28
33
|
get DefaultSkipAsyncValidation(): boolean;
|
|
29
34
|
ValidateAsync(): Promise<ValidationResult>;
|
|
35
|
+
/**
|
|
36
|
+
* The strict API-key rules: check 4 (FilterText's columns must resolve against every
|
|
37
|
+
* referrer's entity) and check 6 (every referrer must agree on the same entity).
|
|
38
|
+
*/
|
|
39
|
+
private validateAsApiKeyFilter;
|
|
40
|
+
/** A role filter: screened, then compiled against every referencing entity's base view. */
|
|
41
|
+
private validateAsRoleFilter;
|
|
30
42
|
}
|
|
31
43
|
//# sourceMappingURL=MJRowLevelSecurityFilterEntityServer.server.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJRowLevelSecurityFilterEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJRowLevelSecurityFilterEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"MJRowLevelSecurityFilterEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJRowLevelSecurityFilterEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7G,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAW/E;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,oCAAqC,SAAQ,8BAA8B;IACpF,uGAAuG;IACvG,IAAoB,0BAA0B,IAAI,OAAO,CAExD;IAEqB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAgChE;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAuB9B,2FAA2F;YAC7E,oBAAoB;CAOrC"}
|
|
@@ -4,10 +4,10 @@ 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 } from '@memberjunction/core';
|
|
7
|
+
import { BaseEntity, DatabaseProviderBase } from '@memberjunction/core';
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { MJRowLevelSecurityFilterEntity } from '@memberjunction/core-entities';
|
|
10
|
-
import { BuildSameEntityErrors, CollectRowFilterReferrers, ToValidationErrors, ValidateRowFilterTextAgainstEntity } from './rowFilterValidation.js';
|
|
10
|
+
import { BuildSameEntityErrors, CollectRowFilterReferrers, IsRoleOnlyReferrerSet, ToValidationErrors, ValidateRoleRowFilterText, ValidateRowFilterTextAgainstEntity } from './rowFilterValidation.js';
|
|
11
11
|
/**
|
|
12
12
|
* Server-side `MJ: Row Level Security Filters` entity — the SECOND enforcement
|
|
13
13
|
* point of the row-filter validation (plan §5.3). The scope-rule subclasses
|
|
@@ -15,21 +15,26 @@ import { BuildSameEntityErrors, CollectRowFilterReferrers, ToValidationErrors, V
|
|
|
15
15
|
* against the rule's entity when the RULE is saved; without an equivalent
|
|
16
16
|
* check when the FILTER is saved, both are trivially bypassable: attach a
|
|
17
17
|
* valid filter, then edit its text (or acquire a new, different-entity
|
|
18
|
-
* referrer) to reference anything. On a `FilterText` change
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* (fail closed). Check 6 has no single rule to anchor on here (a filter
|
|
24
|
-
* record itself carries no entity binding — see plan §5.1), so it anchors on
|
|
25
|
-
* the first referrer that DOES resolve to an entity and requires every other
|
|
26
|
-
* referrer to agree with it; zero or one resolvable referrer trivially
|
|
27
|
-
* satisfies the invariant.
|
|
18
|
+
* referrer) to reference anything. On a `FilterText` change this subclass
|
|
19
|
+
* re-validates the new text against EVERY current referrer (EntityPermission
|
|
20
|
+
* rows via their four `*RLSFilterID` columns, plus both API scope tables via
|
|
21
|
+
* `RowFilterID`) and rejects if any check fails — including referrers whose
|
|
22
|
+
* entity cannot be resolved (fail closed).
|
|
28
23
|
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
24
|
+
* Which checks apply depends on who references the filter:
|
|
25
|
+
* - **Any API-key or API-application scope rule** → the strict API-key rules
|
|
26
|
+
* (checks 4 and 6): plain columns of the referrer's entity only, and every
|
|
27
|
+
* referrer must agree on ONE entity. Check 6 has no single rule to anchor on
|
|
28
|
+
* here (a filter record carries no entity binding — see plan §5.1), so it
|
|
29
|
+
* anchors on the first referrer that resolves to an entity.
|
|
30
|
+
* - **Only role permission rows** → a role filter. Role filters legitimately use
|
|
31
|
+
* subqueries (a user's tenant memberships) and are shared across every
|
|
32
|
+
* tenant-scoped entity, so the new text is instead screened for dangerous SQL
|
|
33
|
+
* and compiled against each referencing entity's base view.
|
|
34
|
+
*
|
|
35
|
+
* Either way an invalid filter is rejected at save, where it is diagnosable,
|
|
36
|
+
* rather than failing every read of the entities it scopes with an unexplained
|
|
37
|
+
* SQL error.
|
|
33
38
|
*/
|
|
34
39
|
let MJRowLevelSecurityFilterEntityServer = class MJRowLevelSecurityFilterEntityServer extends MJRowLevelSecurityFilterEntity {
|
|
35
40
|
/** Enable async validation so the referrer re-validation (which queries three tables) runs on Save. */
|
|
@@ -39,7 +44,7 @@ let MJRowLevelSecurityFilterEntityServer = class MJRowLevelSecurityFilterEntityS
|
|
|
39
44
|
async ValidateAsync() {
|
|
40
45
|
const result = await super.ValidateAsync();
|
|
41
46
|
// Only re-validate when the text changes (or on create — a new filter has
|
|
42
|
-
// no referrers yet, so
|
|
47
|
+
// no referrers yet, so there is nothing to validate against).
|
|
43
48
|
const filterTextDirty = this.GetFieldByName('FilterText')?.Dirty ?? false;
|
|
44
49
|
if (this.IsSaved && !filterTextDirty) {
|
|
45
50
|
return result;
|
|
@@ -49,22 +54,11 @@ let MJRowLevelSecurityFilterEntityServer = class MJRowLevelSecurityFilterEntityS
|
|
|
49
54
|
const filterText = this.FilterText ?? '';
|
|
50
55
|
try {
|
|
51
56
|
const referrers = await CollectRowFilterReferrers(this.ID, md, this.ContextCurrentUser);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (!referrer.Entity) {
|
|
55
|
-
errors.push(`${referrer.Description} references this filter but does not resolve to an entity — the new ` +
|
|
56
|
-
`FilterText cannot be validated against it; rejecting (fail closed).`);
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
const validation = ValidateRowFilterTextAgainstEntity(filterText, referrer.Entity);
|
|
60
|
-
errors.push(...validation.errors.map(e => `${referrer.Description}: ${e}`));
|
|
57
|
+
if (IsRoleOnlyReferrerSet(referrers)) {
|
|
58
|
+
errors.push(...await this.validateAsRoleFilter(filterText, referrers));
|
|
61
59
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
// referrer that resolves to an entity and require every other referrer to match it.
|
|
65
|
-
const anchor = referrers.find(r => r.Entity)?.Entity;
|
|
66
|
-
if (anchor) {
|
|
67
|
-
errors.push(...BuildSameEntityErrors(referrers, anchor));
|
|
60
|
+
else {
|
|
61
|
+
errors.push(...this.validateAsApiKeyFilter(filterText, referrers));
|
|
68
62
|
}
|
|
69
63
|
}
|
|
70
64
|
catch (e) {
|
|
@@ -76,6 +70,37 @@ let MJRowLevelSecurityFilterEntityServer = class MJRowLevelSecurityFilterEntityS
|
|
|
76
70
|
}
|
|
77
71
|
return result;
|
|
78
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* The strict API-key rules: check 4 (FilterText's columns must resolve against every
|
|
75
|
+
* referrer's entity) and check 6 (every referrer must agree on the same entity).
|
|
76
|
+
*/
|
|
77
|
+
validateAsApiKeyFilter(filterText, referrers) {
|
|
78
|
+
const errors = [];
|
|
79
|
+
for (const referrer of referrers) {
|
|
80
|
+
if (!referrer.Entity) {
|
|
81
|
+
errors.push(`${referrer.Description} references this filter but does not resolve to an entity — the new ` +
|
|
82
|
+
`FilterText cannot be validated against it; rejecting (fail closed).`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const validation = ValidateRowFilterTextAgainstEntity(filterText, referrer.Entity);
|
|
86
|
+
errors.push(...validation.errors.map(e => `${referrer.Description}: ${e}`));
|
|
87
|
+
}
|
|
88
|
+
// No single referrer is "the rule" here (unlike the scope-rule save path), so anchor on
|
|
89
|
+
// the first referrer that resolves to an entity and require every other referrer to match it.
|
|
90
|
+
const anchor = referrers.find(r => r.Entity)?.Entity;
|
|
91
|
+
if (anchor) {
|
|
92
|
+
errors.push(...BuildSameEntityErrors(referrers, anchor));
|
|
93
|
+
}
|
|
94
|
+
return errors;
|
|
95
|
+
}
|
|
96
|
+
/** A role filter: screened, then compiled against every referencing entity's base view. */
|
|
97
|
+
async validateAsRoleFilter(filterText, referrers) {
|
|
98
|
+
const provider = this.ProviderToUse;
|
|
99
|
+
if (!(provider instanceof DatabaseProviderBase)) {
|
|
100
|
+
return ['A role row-level-security filter can only be validated against a database provider; rejecting (fail closed).'];
|
|
101
|
+
}
|
|
102
|
+
return ValidateRoleRowFilterText(filterText, referrers, provider, this.ContextCurrentUser);
|
|
103
|
+
}
|
|
79
104
|
};
|
|
80
105
|
MJRowLevelSecurityFilterEntityServer = __decorate([
|
|
81
106
|
RegisterClass(BaseEntity, 'MJ: Row Level Security Filters')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJRowLevelSecurityFilterEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJRowLevelSecurityFilterEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAuC,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"MJRowLevelSecurityFilterEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJRowLevelSecurityFilterEntityServer.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -19,6 +19,32 @@ export declare class MJUserViewEntityServer extends MJUserViewEntityExtended {
|
|
|
19
19
|
*/
|
|
20
20
|
protected get SmartFilterImplemented(): boolean;
|
|
21
21
|
Validate(): ValidationResult;
|
|
22
|
+
/**
|
|
23
|
+
* SECURITY: screens the SQL this view stores with the clause screen the RunView API applies to
|
|
24
|
+
* client filters — its WhereClause (set directly, compiled from FilterState, or made by a Smart
|
|
25
|
+
* Filter) and the ORDER BY built from SortState / GridState. Any user who can save a view can
|
|
26
|
+
* write these, and the provider splices them into view SQL. A CustomWhereClause is left to the
|
|
27
|
+
* Owner gate above. Only a new view or a changed clause is screened here; the provider screens
|
|
28
|
+
* every stored clause again when the view runs. Both use the provider's own screen, so a clause
|
|
29
|
+
* is judged the same way at save and at run.
|
|
30
|
+
*/
|
|
31
|
+
private validateStoredClauses;
|
|
32
|
+
/**
|
|
33
|
+
* The ORDER BY built from SortState / GridState, or null when SortState is not valid JSON. Such
|
|
34
|
+
* a view cannot build an ORDER BY when it runs either, so there is nothing to screen.
|
|
35
|
+
*/
|
|
36
|
+
private storedOrderBy;
|
|
37
|
+
/**
|
|
38
|
+
* Adds a validation failure on `field` when the provider's client-clause screen refuses `clause`,
|
|
39
|
+
* or when the provider cannot screen (fails closed).
|
|
40
|
+
*/
|
|
41
|
+
private screenStoredClause;
|
|
42
|
+
/**
|
|
43
|
+
* A `{%UserView "id"%}` template becomes a subquery only when the view runs, and the provider
|
|
44
|
+
* screens that rendered clause. Here each template stands in as `SELECT NULL` so the rest of
|
|
45
|
+
* the clause can be parsed.
|
|
46
|
+
*/
|
|
47
|
+
private static neutralizeViewTemplates;
|
|
22
48
|
/**
|
|
23
49
|
* SECURITY gate: `CustomWhereClause = 1` tells the platform to fold the stored
|
|
24
50
|
* `WhereClause` into view SQL verbatim — it bypasses both the auto-generation in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJUserViewEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJUserViewEntityServer.server.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,UAAU,EAAY,iBAAiB,EAAsD,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACjK,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;
|
|
1
|
+
{"version":3,"file":"MJUserViewEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJUserViewEntityServer.server.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,UAAU,EAAY,iBAAiB,EAAsD,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACjK,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAA;AAexE;;GAEG;AACH,UAAU,uBAAwB,SAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC7D,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uBAAuB,EAAE,MAAM,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;CAC7B;AAED,qBACa,sBAAuB,SAAQ,wBAAwB;IAChE;;OAEG;IACH,cAAuB,sBAAsB,IAAI,OAAO,CAEvD;IAEe,QAAQ,IAAI,gBAAgB;IAQ5C;;;;;;;;OAQG;IACH,OAAO,CAAC,qBAAqB;IAc7B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAc1B;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,uBAAuB;IAItC;;;;;;;;OAQG;IACH,OAAO,CAAC,sCAAsC;IAyB9C;;;;OAIG;IACU,8BAA8B,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAA;KAAC,CAAC;IAkF5I;;;OAGG;IACH,SAAS,CAAC,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,uBAAuB;IAwC5E;;OAEG;IACH,SAAS,CAAC,4BAA4B,CAAC,UAAU,EAAE,UAAU,EAAE,EAAE,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,MAAM;CAoC1H"}
|
|
@@ -4,13 +4,15 @@ 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
|
+
var MJUserViewEntityServer_1;
|
|
7
8
|
import { RegisterClass, CleanAndParseJSON } from "@memberjunction/global";
|
|
8
9
|
import { BaseEntity, LogError, ValidationErrorInfo, ValidationErrorType } from "@memberjunction/core";
|
|
9
10
|
import { MJUserViewEntityExtended } from '@memberjunction/core-entities';
|
|
10
11
|
import { AIPromptParams } from "@memberjunction/ai-core-plus";
|
|
11
12
|
import { AIEngine } from "@memberjunction/aiengine";
|
|
12
13
|
import { AIPromptRunner } from "@memberjunction/ai-prompts";
|
|
13
|
-
|
|
14
|
+
import { IsClientClauseScreeningProvider } from "@memberjunction/generic-database-provider";
|
|
15
|
+
let MJUserViewEntityServer = MJUserViewEntityServer_1 = class MJUserViewEntityServer extends MJUserViewEntityExtended {
|
|
14
16
|
/**
|
|
15
17
|
* This property is hard-coded to true in this class because we DO support smart filters in this class. If you want to disable smart filters for a specific view you can override this property in your subclass and set it to false.
|
|
16
18
|
*/
|
|
@@ -20,9 +22,70 @@ let MJUserViewEntityServer = class MJUserViewEntityServer extends MJUserViewEnti
|
|
|
20
22
|
Validate() {
|
|
21
23
|
const result = super.Validate();
|
|
22
24
|
this.validateCustomWhereClauseAuthorization(result);
|
|
25
|
+
this.validateStoredClauses(result);
|
|
23
26
|
result.Success = result.Success && result.Errors.length === 0;
|
|
24
27
|
return result;
|
|
25
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* SECURITY: screens the SQL this view stores with the clause screen the RunView API applies to
|
|
31
|
+
* client filters — its WhereClause (set directly, compiled from FilterState, or made by a Smart
|
|
32
|
+
* Filter) and the ORDER BY built from SortState / GridState. Any user who can save a view can
|
|
33
|
+
* write these, and the provider splices them into view SQL. A CustomWhereClause is left to the
|
|
34
|
+
* Owner gate above. Only a new view or a changed clause is screened here; the provider screens
|
|
35
|
+
* every stored clause again when the view runs. Both use the provider's own screen, so a clause
|
|
36
|
+
* is judged the same way at save and at run.
|
|
37
|
+
*/
|
|
38
|
+
validateStoredClauses(result) {
|
|
39
|
+
const changed = (...fields) => !this.IsSaved || fields.some(f => this.GetFieldByName(f)?.Dirty === true);
|
|
40
|
+
if (!this.CustomWhereClause && changed('WhereClause', 'CustomWhereClause')) {
|
|
41
|
+
const where = MJUserViewEntityServer_1.neutralizeViewTemplates(this.WhereClause ?? '');
|
|
42
|
+
this.screenStoredClause(result, 'WhereClause', where, 'view WhereClause');
|
|
43
|
+
}
|
|
44
|
+
const orderBy = changed('SortState', 'GridState') ? this.storedOrderBy() : null;
|
|
45
|
+
if (orderBy) {
|
|
46
|
+
// The provider transforms a stored sort for its platform before running it; screen that form.
|
|
47
|
+
this.screenStoredClause(result, 'SortState', orderBy, 'OrderBy', this.ViewEntityInfo);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The ORDER BY built from SortState / GridState, or null when SortState is not valid JSON. Such
|
|
52
|
+
* a view cannot build an ORDER BY when it runs either, so there is nothing to screen.
|
|
53
|
+
*/
|
|
54
|
+
storedOrderBy() {
|
|
55
|
+
try {
|
|
56
|
+
return this.OrderByClause;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Adds a validation failure on `field` when the provider's client-clause screen refuses `clause`,
|
|
64
|
+
* or when the provider cannot screen (fails closed).
|
|
65
|
+
*/
|
|
66
|
+
screenStoredClause(result, field, clause, label, entityInfo) {
|
|
67
|
+
if (!clause.trim())
|
|
68
|
+
return;
|
|
69
|
+
const provider = this.ProviderToUse;
|
|
70
|
+
try {
|
|
71
|
+
if (!IsClientClauseScreeningProvider(provider)) {
|
|
72
|
+
throw new Error(`Invalid ${label}: the data provider cannot screen client SQL`);
|
|
73
|
+
}
|
|
74
|
+
provider.ScreenClientClause(clause, label, this.ActiveUser, entityInfo);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
78
|
+
result.Errors.push(new ValidationErrorInfo(field, message, clause, ValidationErrorType.Failure));
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* A `{%UserView "id"%}` template becomes a subquery only when the view runs, and the provider
|
|
83
|
+
* screens that rendered clause. Here each template stands in as `SELECT NULL` so the rest of
|
|
84
|
+
* the clause can be parsed.
|
|
85
|
+
*/
|
|
86
|
+
static neutralizeViewTemplates(whereClause) {
|
|
87
|
+
return whereClause.replace(/{%[^%]+%}/g, 'SELECT NULL');
|
|
88
|
+
}
|
|
26
89
|
/**
|
|
27
90
|
* SECURITY gate: `CustomWhereClause = 1` tells the platform to fold the stored
|
|
28
91
|
* `WhereClause` into view SQL verbatim — it bypasses both the auto-generation in
|
|
@@ -39,8 +102,9 @@ let MJUserViewEntityServer = class MJUserViewEntityServer extends MJUserViewEnti
|
|
|
39
102
|
}
|
|
40
103
|
const customDirty = this.GetFieldByName('CustomWhereClause')?.Dirty === true;
|
|
41
104
|
const whereDirty = this.GetFieldByName('WhereClause')?.Dirty === true;
|
|
42
|
-
|
|
43
|
-
|
|
105
|
+
// A new record is always authorized: a field first written without NewRecord() seeding it
|
|
106
|
+
// does not read as dirty. On an existing record, only a change needs authorizing.
|
|
107
|
+
if (this.IsSaved && !customDirty && !whereDirty) {
|
|
44
108
|
return;
|
|
45
109
|
}
|
|
46
110
|
const user = this.ContextCurrentUser
|
|
@@ -199,7 +263,7 @@ let MJUserViewEntityServer = class MJUserViewEntityServer extends MJUserViewEnti
|
|
|
199
263
|
return [fkeyViewsDesc, relatedEntitiesDesc].filter(s => s.length > 0).join('\n');
|
|
200
264
|
}
|
|
201
265
|
};
|
|
202
|
-
MJUserViewEntityServer = __decorate([
|
|
266
|
+
MJUserViewEntityServer = MJUserViewEntityServer_1 = __decorate([
|
|
203
267
|
RegisterClass(BaseEntity, 'MJ: User Views')
|
|
204
268
|
], MJUserViewEntityServer);
|
|
205
269
|
export { MJUserViewEntityServer };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJUserViewEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJUserViewEntityServer.server.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"MJUserViewEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJUserViewEntityServer.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -50,7 +50,7 @@ function resolve(ctx, parseResult) {
|
|
|
50
50
|
const { params: passthroughParams, contextMap: passthroughContext } = BuildPassthroughParams(resolvedCompositionRefs);
|
|
51
51
|
const allDeterministicParams = MergePassthroughParams(parseResult.deterministicParams, passthroughParams);
|
|
52
52
|
// Entity metadata (for LLM context and entity sync)
|
|
53
|
-
const entityMetadata = ExtractEntityMetadataFromSQL(ctx.sql, parseResult.tableRefs, md);
|
|
53
|
+
const entityMetadata = ExtractEntityMetadataFromSQL(ctx.sql, parseResult.tableRefs, md, ctx.platform);
|
|
54
54
|
// Field resolution: try SELECT * expansion first (uses entity metadata), fall back to explicit SELECT columns
|
|
55
55
|
const resolvedFields = BuildFieldsForSelectStar(ctx.sql, parseResult.tableRefs, parseResult.selectColumns, md)
|
|
56
56
|
?? BuildFieldsFromSelectColumns(parseResult.selectColumns);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/pipeline.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/pipeline.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Contains all deterministic resolution logic — no LLM calls, no database writes.
|
|
5
5
|
* Every function is stateless: context is passed in as parameters rather than via `this`.
|
|
6
6
|
*/
|
|
7
|
-
import { EntityInfo, IMetadataProvider } from "@memberjunction/core";
|
|
7
|
+
import { DatabasePlatform, EntityInfo, IMetadataProvider } from "@memberjunction/core";
|
|
8
8
|
import { MJQueryEntityExtended, MJQueryDependencyEntity } from "@memberjunction/core-entities";
|
|
9
9
|
import type { MJParameterInfo, SQLSelectColumn, SQLTableReference } from "@memberjunction/sql-parser";
|
|
10
10
|
import type { EntityMetadataEntry, ExtractedField, PassthroughParamContext, ResolvedCompositionReference } from "./types.js";
|
|
@@ -109,8 +109,11 @@ export declare function ExpandWildcardFields(fields: ExtractedField[], md: IMeta
|
|
|
109
109
|
/**
|
|
110
110
|
* Extracts entity metadata from the SQL to provide context for parameter type inference.
|
|
111
111
|
* Uses SQLParser for robust SQL parsing with MJ template support.
|
|
112
|
+
*
|
|
113
|
+
* @param platform The platform the SQL is written for; selects the grammar used to read its
|
|
114
|
+
* column references. Defaults to SQL Server.
|
|
112
115
|
*/
|
|
113
|
-
export declare function ExtractEntityMetadataFromSQL(sql: string, tableRefs: SQLTableReference[], md: IMetadataProvider): EntityMetadataEntry[];
|
|
116
|
+
export declare function ExtractEntityMetadataFromSQL(sql: string, tableRefs: SQLTableReference[], md: Pick<IMetadataProvider, 'Entities'>, platform?: DatabasePlatform): EntityMetadataEntry[];
|
|
114
117
|
/**
|
|
115
118
|
* Detects circular dependencies by walking the dependency graph.
|
|
116
119
|
* Returns a descriptive error string if a cycle is found, or null if clean.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/custom/query-extraction/resolve.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAA6B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/custom/query-extraction/resolve.ts"],"names":[],"mappings":"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"}
|