@memberjunction/react-runtime 5.51.0 → 5.51.1
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/.turbo/turbo-build.log +8 -8
- package/CHANGELOG.md +12 -0
- package/dist/324.runtime.umd.js +1 -1
- package/dist/runtime.umd.js +94 -15
- package/package.json +6 -6
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
|
|
2
|
-
> @memberjunction/react-runtime@5.51.
|
|
2
|
+
> @memberjunction/react-runtime@5.51.1 build
|
|
3
3
|
> npm run build:node && npm run build:umd
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
> @memberjunction/react-runtime@5.51.
|
|
6
|
+
> @memberjunction/react-runtime@5.51.1 build:node
|
|
7
7
|
> tsc && tsc-alias -f
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
> @memberjunction/react-runtime@5.51.
|
|
10
|
+
> @memberjunction/react-runtime@5.51.1 build:umd
|
|
11
11
|
> webpack --config webpack.umd.config.cjs
|
|
12
12
|
|
|
13
|
-
Browserslist: browsers data (caniuse-lite) is
|
|
13
|
+
Browserslist: browsers data (caniuse-lite) is 7 months old. Please run:
|
|
14
14
|
npx update-browserslist-db@latest
|
|
15
15
|
Why you should do it regularly: https://github.com/browserslist/update-db#readme
|
|
16
16
|
[BABEL] Note: The code generator has deoptimised the styling of /home/runner/work/MJ/MJ/packages/MJCoreEntities/dist/generated/entity_subclasses.js as it exceeds the max of 500KB.
|
|
17
|
-
asset [1m[33mruntime.umd.js[39m[22m [1m[33m8.
|
|
17
|
+
asset [1m[33mruntime.umd.js[39m[22m [1m[33m8.79 MiB[39m[22m [1m[33m[compared for emit][39m[22m [1m[33m[big][39m[22m (name: main)
|
|
18
18
|
asset [1m[32m324.runtime.umd.js[39m[22m 218 KiB [1m[33m[compared for emit][39m[22m
|
|
19
19
|
asset [1m[32m490.runtime.umd.js[39m[22m 182 KiB [1m[33m[compared for emit][39m[22m (id hint: vendors)
|
|
20
20
|
orphan modules 8.77 MiB [1m[33m[orphan][39m[22m 571 modules
|
|
21
21
|
runtime modules 6.94 KiB 10 modules
|
|
22
|
-
cacheable modules 8.
|
|
22
|
+
cacheable modules 8.92 MiB
|
|
23
23
|
modules by path [1m../../../node_modules/[39m[22m 781 KiB
|
|
24
24
|
modules by path [1m../../../node_modules/rxjs/dist/esm5/internal/[39m[22m 30.4 KiB 16 modules
|
|
25
25
|
modules by path [1m../../../node_modules/debug/src/*.js[39m[22m 12.7 KiB 2 modules
|
|
@@ -29,6 +29,6 @@ cacheable modules 8.91 MiB
|
|
|
29
29
|
[1m../../MJCoreEntities/dist/engines/UserViewEngine.js[39m[22m 19.6 KiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
|
|
30
30
|
[1m./dist/index.js + 29 modules[39m[22m 440 KiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
|
|
31
31
|
[1m../../MJCore/dist/index.js + 88 modules[39m[22m 1.8 MiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
|
|
32
|
-
[1m../../MJGlobal/dist/index.js + 24 modules[39m[22m
|
|
32
|
+
[1m../../MJGlobal/dist/index.js + 24 modules[39m[22m 316 KiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
|
|
33
33
|
[1m../../GraphQLDataProvider/dist/index.mjs[39m[22m 194 KiB [1m[33m[built][39m[22m [1m[33m[code generated][39m[22m
|
|
34
|
-
webpack 5.105.0 compiled [1m[32msuccessfully[39m[22m in
|
|
34
|
+
webpack 5.105.0 compiled [1m[32msuccessfully[39m[22m in 70131 ms
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# @memberjunction/react-runtime
|
|
2
2
|
|
|
3
|
+
## 5.51.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [cc6f321]
|
|
8
|
+
- Updated dependencies [e10a71f]
|
|
9
|
+
- @memberjunction/global@5.51.1
|
|
10
|
+
- @memberjunction/core@5.51.1
|
|
11
|
+
- @memberjunction/graphql-dataprovider@5.51.1
|
|
12
|
+
- @memberjunction/core-entities@5.51.1
|
|
13
|
+
- @memberjunction/interactive-component-types@5.51.1
|
|
14
|
+
|
|
3
15
|
## 5.51.0
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/dist/324.runtime.umd.js
CHANGED
|
@@ -361,7 +361,7 @@ var se=Object.defineProperty;var d=(g,e)=>se(g,"name",{value:e,configurable:!0})
|
|
|
361
361
|
}
|
|
362
362
|
}
|
|
363
363
|
}
|
|
364
|
-
`,r={entityDocumentID:e.entityDocumentID};e.maxRecords!==void 0&&(r.maxRecords=e.maxRecords),e.filter!==void 0&&(r.filter=e.filter);const s=await this._dataProvider.ExecuteGQL(t,r);if(!s?.FetchEntityVectors)throw new Error("Invalid response from server");return s.FetchEntityVectors}catch(t){const r=t;return (0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogError */ .ZI8)("GraphQLAIClient.FetchEntityVectors failed",void 0,r),{Success:!1,Results:[],TotalCount:0,ElapsedMs:0,ErrorMessage:r.message||"Unknown error"}}}}const F="5.51.
|
|
364
|
+
`,r={entityDocumentID:e.entityDocumentID};e.maxRecords!==void 0&&(r.maxRecords=e.maxRecords),e.filter!==void 0&&(r.filter=e.filter);const s=await this._dataProvider.ExecuteGQL(t,r);if(!s?.FetchEntityVectors)throw new Error("Invalid response from server");return s.FetchEntityVectors}catch(t){const r=t;return (0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogError */ .ZI8)("GraphQLAIClient.FetchEntityVectors failed",void 0,r),{Success:!1,Results:[],TotalCount:0,ElapsedMs:0,ErrorMessage:r.message||"Unknown error"}}}}const F="5.51.1",$="default";class X{static{d(this,"BrowserStorageProviderBase")}constructor(){this._storage=new Map}getCategoryMap(e){const t=e||$;let r=this._storage.get(t);return r||(r=new Map,this._storage.set(t,r)),r}async GetItem(e,t){const s=this.getCategoryMap(t||$).get(e);return s===void 0?null:s}async GetItems(e,t){const r=new Map;if(e.length===0)return r;const s=this.getCategoryMap(t||$);for(const n of new Set(e)){const a=s.get(n);r.set(n,a===void 0?null:a)}return r}async SetItem(e,t,r){this.getCategoryMap(r||$).set(e,t)}async Remove(e,t){this.getCategoryMap(t||$).delete(e)}async ClearCategory(e){const t=e||$;this._storage.delete(t)}async GetCategoryKeys(e){const t=this._storage.get(e||$);return t?Array.from(t.keys()):[]}}const $e="MJ_Metadata",Pe=0;function Me(){try{const g=F.split("."),e=parseInt(g[0],10),t=parseInt(g[1],10);if(!Number.isFinite(e)||!Number.isFinite(t))throw new Error(`Could not parse major.minor from version "${F}"`);return e*1e3+t+Pe}catch(g){return (0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:g,message:"Failed to derive IDB version from PACKAGE_VERSION; using fallback 99999"}),99999}}d(Me,"computeIdbVersion");const Ae=Me(),Y=["mj:default","mj:Metadata","mj:RunViewCache","mj:RunQueryCache","mj:DatasetCache"];class Z extends X{static{d(this,"BrowserIndexedDBStorageProvider")}constructor(){super(),this._dbReady=!1,this.dbPromise=(0,_tempfix_idb__WEBPACK_IMPORTED_MODULE_10__/* .openDB */ .P2)($e,Ae,{upgrade:d((e,t,r)=>{try{(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogStatus */ .b09)(`[IDBCache] Upgrading IndexedDB schema v${t} \u2192 v${r} (package ${F}). Dropping all stores; caches will repopulate on first use.`);for(const s of Array.from(e.objectStoreNames))e.deleteObjectStore(s);for(const s of Y)e.objectStoreNames.contains(s)||e.createObjectStore(s)}catch(s){(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:s,message:s?.message})}},"upgrade"),blocked:d((e,t)=>{(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogStatus */ .b09)(`[IDBCache] Upgrade from v${e} to v${t} blocked by another tab. Close other tabs to allow the upgrade to proceed.`)},"blocked")}),this.dbPromise.then(e=>{this._dbReady=!0,e.onversionchange=()=>{(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogStatus */ .b09)("[IDBCache] DB schema upgraded in another tab \u2014 closing local connection."),e.close(),this._dbReady=!1}}).catch(e=>{(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:e,message:"IndexedDB initialization failed: "+e?.message})})}get IsReady(){return this._dbReady}isKnownCategory(e){const t=`mj:${e}`;return Y.includes(t)}getStoreName(e){const t=e||$;return this.isKnownCategory(t)?`mj:${t}`:"mj:default"}getStoreKey(e,t){const r=t||$;return this.isKnownCategory(r)?e:`[${r}]:${e}`}async SetItem(e,t,r){try{const s=await this.dbPromise,n=this.getStoreName(r),a=this.getStoreKey(e,r),i=s.transaction(n,"readwrite");await i.objectStore(n).put(t,a),await i.done}catch(s){(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:s,message:s?.message})}}async GetItem(e,t){try{const r=await this.dbPromise,s=this.getStoreName(t),n=this.getStoreKey(e,t),a=await r.transaction(s).objectStore(s).get(n);return a===void 0?null:a}catch(r){return (0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:r,message:r?.message}),null}}async GetItems(e,t){const r=new Map;if(e.length===0)return r;try{const s=await this.dbPromise,n=this.getStoreName(t),a=Array.from(new Set(e)),i=a.map(f=>this.getStoreKey(f,t)),o=s.transaction(n,"readonly"),m=o.objectStore(n),u=i.map(f=>m.get(f)),h=await Promise.all(u);await o.done;for(let f=0;f<a.length;f++){const y=h[f];r.set(a[f],y===void 0?null:y)}return r}catch(s){(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:s,message:s?.message});for(const n of new Set(e))r.set(n,null);return r}}async Remove(e,t){try{const r=await this.dbPromise,s=this.getStoreName(t),n=this.getStoreKey(e,t),a=r.transaction(s,"readwrite");await a.objectStore(s).delete(n),await a.done}catch(r){(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:r,message:r?.message})}}async ClearCategory(e){try{const t=await this.dbPromise,r=e||$,s=this.getStoreName(e);if(this.isKnownCategory(r)){const n=t.transaction(s,"readwrite");await n.objectStore(s).clear(),await n.done}else{const n=`[${r}]:`,a=t.transaction("mj:default","readwrite"),i=a.objectStore("mj:default"),o=await i.getAllKeys();for(const m of o)typeof m=="string"&&m.startsWith(n)&&await i.delete(m);await a.done}}catch(t){(0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:t,message:t?.message})}}async GetCategoryKeys(e){try{const t=await this.dbPromise,r=e||$,s=this.getStoreName(e),i=await t.transaction(s,"readonly").objectStore(s).getAllKeys();if(this.isKnownCategory(r))return i.map(m=>String(m));const o=`[${r}]:`;return i.map(m=>String(m)).filter(m=>m.startsWith(o)).map(m=>m.slice(o.length))}catch(t){return (0,_memberjunction_core__WEBPACK_IMPORTED_MODULE_1__/* .LogErrorEx */ .Q1A)({error:t,message:t?.message}),[]}}}const b=new A,Ne=(0,graphql_request__WEBPACK_IMPORTED_MODULE_0__/* .gql */ .J1)`subscription RemoteOperationProgress($channelId: ID!) {
|
|
365
365
|
RemoteOperationProgress(channelId: $channelId) {
|
|
366
366
|
ChannelId
|
|
367
367
|
ProgressJSON
|
package/dist/runtime.umd.js
CHANGED
|
@@ -23018,8 +23018,9 @@ var RowLevelSecurityFilterInfo = /*#__PURE__*/function (_BaseInfo4) {
|
|
|
23018
23018
|
for (var i = 0; i < keys.length; i++) {
|
|
23019
23019
|
var key = keys[i];
|
|
23020
23020
|
var val = user[key];
|
|
23021
|
-
if (val !== null && securityInfo_typeof(val) !== 'object') {
|
|
23022
|
-
|
|
23021
|
+
if (val !== null && val !== undefined && securityInfo_typeof(val) !== 'object') {
|
|
23022
|
+
var safeVal = String(val).replace(/'/g, "''");
|
|
23023
|
+
ret = ret.replace(new RegExp("{{User".concat(key, "}}"), 'g'), safeVal);
|
|
23023
23024
|
}
|
|
23024
23025
|
}
|
|
23025
23026
|
// Per-session magic-link resource scope. Fail-closed: an absent scope resolves
|
|
@@ -55796,11 +55797,17 @@ var DatabaseProviderBase = /*#__PURE__*/function (_ProviderBase) {
|
|
|
55796
55797
|
}, {
|
|
55797
55798
|
key: "ValidateUserProvidedSQLClause",
|
|
55798
55799
|
value: function ValidateUserProvidedSQLClause(clause) {
|
|
55799
|
-
// Remove string literals to avoid false positives
|
|
55800
|
-
|
|
55801
|
-
|
|
55800
|
+
// Remove string literals to avoid false positives.
|
|
55801
|
+
//
|
|
55802
|
+
// 🚨 SECURITY: this uses the SHARED stripper in @memberjunction/global. It must match how
|
|
55803
|
+
// SQL Server / PostgreSQL actually parse literals — see StripSQLStringLiterals for the full
|
|
55804
|
+
// rationale and the backslash-escape bypass it exists to prevent. Do NOT inline a regex here;
|
|
55805
|
+
// an inline copy is exactly how this screen and SQLExpressionValidator drifted apart before.
|
|
55806
|
+
var clauseWithoutStrings = (0,dist/* StripSQLStringLiterals */.SN)(clause);
|
|
55802
55807
|
var lowerClause = clauseWithoutStrings.toLowerCase();
|
|
55803
|
-
var forbiddenPatterns = [/\binsert\b/, /\bupdate\b/, /\bdelete\b/, /\bexec\b/, /\bexecute\b/, /\bdrop\b/, /--/, /\/\*/, /\*\//, /\bunion\b/, /\bxp_/,
|
|
55808
|
+
var forbiddenPatterns = [/\binsert\b/, /\bupdate\b/, /\bdelete\b/, /\bexec\b/, /\bexecute\b/, /\bdrop\b/, /--/, /\/\*/, /\*\//, /\bunion\b/, /\bxp_/, /;/,
|
|
55809
|
+
// Time-based blind injection vector — no legitimate filter/order-by clause uses WAITFOR.
|
|
55810
|
+
/\bwaitfor\b/];
|
|
55804
55811
|
for (var _i = 0, _forbiddenPatterns = forbiddenPatterns; _i < _forbiddenPatterns.length; _i++) {
|
|
55805
55812
|
var pattern = _forbiddenPatterns[_i];
|
|
55806
55813
|
if (pattern.test(lowerClause)) return false;
|
|
@@ -124267,6 +124274,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
124267
124274
|
fK: () => (/* reexport */ RequiresSubclass),
|
|
124268
124275
|
rH: () => (/* reexport */ SQLExpressionValidator),
|
|
124269
124276
|
NG: () => (/* reexport */ SafeJSONParse),
|
|
124277
|
+
SN: () => (/* reexport */ StripSQLStringLiterals),
|
|
124270
124278
|
jd: () => (/* reexport */ UUIDsEqual),
|
|
124271
124279
|
Om: () => (/* reexport */ ValidationErrorInfo),
|
|
124272
124280
|
wX: () => (/* reexport */ ValidationErrorType),
|
|
@@ -124275,7 +124283,7 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
124275
124283
|
gZ: () => (/* reexport */ uuidv4)
|
|
124276
124284
|
});
|
|
124277
124285
|
|
|
124278
|
-
// UNUSED EXPORTS: ALLOWED_SQL_FUNCTIONS, BuildCronExpression, CRON_DAY_NAMES, ClassFactory, ClassIsOptionalKeyedSpecialization, ClassRegistration, ClassRequiresSubclass, CleanJSON, CleanJavaScript, ConvertMarkdownStringToHtmlList, CopyScalarsAndArrays, DANGEROUS_SQL_KEYWORDS, DEFAULT_RICH_TEXT_SCAN_LENGTH, DeepDiffer, DefaultCronSchedule, DeprecationWarningManager, DescribeCronExpression, DiffChangeType, ENCRYPTED_SENTINEL, EscapeHTML, FULL_QUERY_ALLOWED_KEYWORDS, FieldRulesEvaluator, FieldTransformEngine, FormatTimeOfDay, GetClassInheritance, GetClassName, GetFieldTransform, GetFullClassHierarchy, GetRootClass, GetSuperclass, HighlightSearchMatches, InvokeManualResize, IsClassConstructor, IsDescendantClassOf, IsEncryptedSentinel, IsOnlyTimezoneShift, IsPlausibleCronExpression, IsRootClass, IsSubclassOf, IsValidUUID, IsValueEncrypted, JSONValidator, KeyedSerialTaskQueue, MJEvent, MJGlobalProperty, OPTIONAL_KEYED_SPECIALIZATION_KEY, ObjectCache, ObjectCacheEntry, Ordinal, ParseCronExpression, ParseJSONRecursive, REQUIRES_SUBCLASS_KEY, RegisterClassEx, RegisterFieldTransform, SafeExpressionEvaluator, ShutdownRegistry, ToJSONSafe, adjustCasing, compareStringsByLine, convertCamelCaseToHaveSpaces, createDisplayName, defaultExpressionEvaluator, detectRichTextFormat, ensureRegExp, ensureRegExps, generatePluralName, getIrregularPlural, getValueAtPath, matchesAllPatterns, matchesAnyPattern, parsePattern, parsePatterns, replaceAllSpaces, resolveMappingRef, resolveValueMapping, stripTrailingChars, stripWhitespace
|
|
124286
|
+
// UNUSED EXPORTS: ALLOWED_SQL_FUNCTIONS, BLOCKED_SYSTEM_OBJECT_PATTERNS, BuildCronExpression, CRON_DAY_NAMES, ClassFactory, ClassIsOptionalKeyedSpecialization, ClassRegistration, ClassRequiresSubclass, CleanJSON, CleanJavaScript, ConvertMarkdownStringToHtmlList, CopyScalarsAndArrays, DANGEROUS_SQL_KEYWORDS, DEFAULT_RICH_TEXT_SCAN_LENGTH, DeepDiffer, DefaultCronSchedule, DeprecationWarningManager, DescribeCronExpression, DiffChangeType, ENCRYPTED_SENTINEL, EscapeHTML, FULL_QUERY_ALLOWED_KEYWORDS, FieldRulesEvaluator, FieldTransformEngine, FormatTimeOfDay, GetClassInheritance, GetClassName, GetFieldTransform, GetFullClassHierarchy, GetRootClass, GetSuperclass, HighlightSearchMatches, InvokeManualResize, IsClassConstructor, IsDescendantClassOf, IsEncryptedSentinel, IsOnlyTimezoneShift, IsPlausibleCronExpression, IsRootClass, IsSubclassOf, IsValidUUID, IsValueEncrypted, JSONValidator, KeyedSerialTaskQueue, MJEvent, MJGlobalProperty, OPTIONAL_KEYED_SPECIALIZATION_KEY, ObjectCache, ObjectCacheEntry, Ordinal, ParseCronExpression, ParseJSONRecursive, REQUIRES_SUBCLASS_KEY, RegisterClassEx, RegisterFieldTransform, SafeExpressionEvaluator, ShutdownRegistry, ToJSONSafe, adjustCasing, compareStringsByLine, convertCamelCaseToHaveSpaces, createDisplayName, defaultExpressionEvaluator, detectRichTextFormat, ensureRegExp, ensureRegExps, generatePluralName, getIrregularPlural, getValueAtPath, matchesAllPatterns, matchesAnyPattern, parsePattern, parsePatterns, replaceAllSpaces, resolveMappingRef, resolveValueMapping, stripTrailingChars, stripWhitespace
|
|
124279
124287
|
|
|
124280
124288
|
;// ../../MJGlobal/dist/ClassUtils.js
|
|
124281
124289
|
/**
|
|
@@ -129136,6 +129144,63 @@ var FULL_QUERY_ALLOWED_KEYWORDS = [
|
|
|
129136
129144
|
// standalone SELECT statement, so allowing FOR in full-query context is safe.
|
|
129137
129145
|
// (FOR UPDATE remains blocked via the independent UPDATE keyword.)
|
|
129138
129146
|
'FOR'];
|
|
129147
|
+
/**
|
|
129148
|
+
* System catalog / metadata objects that must never be referenced from a user-supplied
|
|
129149
|
+
* expression or ad-hoc query, in ANY context (including `full_query`). These sit outside
|
|
129150
|
+
* MemberJunction's entity-permission model, so allowing them turns a validated SELECT into
|
|
129151
|
+
* a schema-enumeration and credential-exfiltration primitive
|
|
129152
|
+
* (e.g. `SELECT name, password_hash FROM sys.sql_logins`,
|
|
129153
|
+
* `SELECT * FROM INFORMATION_SCHEMA.COLUMNS`, `SELECT * FROM pg_catalog.pg_authid`).
|
|
129154
|
+
* String literals are stripped before this check runs, so a literal value like `'sys.x'` is safe.
|
|
129155
|
+
*/
|
|
129156
|
+
var BLOCKED_SYSTEM_OBJECT_PATTERNS = [/\bSYS\s*\.\s*\w/i,
|
|
129157
|
+
// SQL Server system catalog schema: sys.sql_logins, sys.objects, sys.fn_*, ...
|
|
129158
|
+
/\bINFORMATION_SCHEMA\b/i,
|
|
129159
|
+
// ANSI catalog views — schema/table/column enumeration
|
|
129160
|
+
/\bSYSLOGINS\b/i,
|
|
129161
|
+
// legacy SQL Server logins view
|
|
129162
|
+
/\bPG_CATALOG\s*\./i,
|
|
129163
|
+
// PostgreSQL system catalog schema
|
|
129164
|
+
/\bPG_(AUTHID|SHADOW|USER|ROLES)\b/i // PostgreSQL credential / role catalogs
|
|
129165
|
+
];
|
|
129166
|
+
/**
|
|
129167
|
+
* Matches SQL string literals the way SQL Server and PostgreSQL (with the default
|
|
129168
|
+
* `standard_conforming_strings=on`) actually parse them: a literal is closed by the next
|
|
129169
|
+
* single quote, `''` is an embedded quote, and a backslash is an ORDINARY character that
|
|
129170
|
+
* does NOT escape the closing quote. Double-quoted runs are matched with the same doubling
|
|
129171
|
+
* rule so a delimited identifier can't hide a payload either.
|
|
129172
|
+
*
|
|
129173
|
+
* @see StripSQLStringLiterals — use that, not this constant, so every caller gets the
|
|
129174
|
+
* documented semantics and the two validators in MJ can never drift apart again.
|
|
129175
|
+
*/
|
|
129176
|
+
var SQL_STRING_LITERAL_PATTERN = /'(?:[^']|'')*'|"(?:[^"]|"")*"/g;
|
|
129177
|
+
/**
|
|
129178
|
+
* Removes SQL string literals from a clause or expression so that a keyword denylist can be
|
|
129179
|
+
* applied to the *code* portion without tripping over keywords that appear inside quoted data
|
|
129180
|
+
* (e.g. `Comments LIKE '%--%'`).
|
|
129181
|
+
*
|
|
129182
|
+
* 🚨 SECURITY — this is the single implementation of literal-stripping for MJ's SQL screens, and
|
|
129183
|
+
* it MUST stay byte-for-byte consistent with how the database parses literals. If the stripper
|
|
129184
|
+
* removes a span the database does NOT treat as a literal, everything hidden inside that span
|
|
129185
|
+
* bypasses the denylist while the database still executes it.
|
|
129186
|
+
*
|
|
129187
|
+
* An earlier version of this logic (duplicated in two places, which is how it survived) honored
|
|
129188
|
+
* **backslash escaping** — `/(['"])(?:(?=(\\?))\2[\s\S])*?\1/g`. SQL Server and PostgreSQL do not
|
|
129189
|
+
* treat `\` as an escape character, so `x = 'a\') ; DROP TABLE Users; --'` was swallowed whole as
|
|
129190
|
+
* one "literal" and stripped to `x = `, which passed every denylist — while the database closed
|
|
129191
|
+
* the literal at the real quote and executed the stacked statement.
|
|
129192
|
+
*
|
|
129193
|
+
* **Do NOT reintroduce backslash-escape handling here, and do NOT inline a second copy of this
|
|
129194
|
+
* regex anywhere else — call this function.**
|
|
129195
|
+
*
|
|
129196
|
+
* @param sql The clause, expression, or query to strip literals from
|
|
129197
|
+
* @returns The input with every complete string literal removed. An UNTERMINATED literal is left
|
|
129198
|
+
* in place on purpose: the stray quote and everything after it stay visible to the
|
|
129199
|
+
* denylist rather than being silently swallowed.
|
|
129200
|
+
*/
|
|
129201
|
+
function StripSQLStringLiterals(sql) {
|
|
129202
|
+
return sql.replace(SQL_STRING_LITERAL_PATTERN, '');
|
|
129203
|
+
}
|
|
129139
129204
|
/**
|
|
129140
129205
|
* Safe SQL functions allowed in expressions, organized by category
|
|
129141
129206
|
*/
|
|
@@ -129241,14 +129306,14 @@ var SQLExpressionValidator = /*#__PURE__*/function (_BaseSingleton) {
|
|
|
129241
129306
|
}
|
|
129242
129307
|
/**
|
|
129243
129308
|
* Remove string literals to avoid false positives in keyword detection.
|
|
129244
|
-
*
|
|
129309
|
+
*
|
|
129310
|
+
* 🚨 SECURITY: delegates to {@link StripSQLStringLiterals} — read the warning there before
|
|
129311
|
+
* changing anything about how literals are matched. This must never grow its own regex again.
|
|
129245
129312
|
*/
|
|
129246
129313
|
}, {
|
|
129247
129314
|
key: "removeStringLiterals",
|
|
129248
129315
|
value: function removeStringLiterals(expression) {
|
|
129249
|
-
|
|
129250
|
-
var stringPattern = /(['"])(?:(?=(\\?))\2[\s\S])*?\1/g;
|
|
129251
|
-
return expression.replace(stringPattern, '');
|
|
129316
|
+
return StripSQLStringLiterals(expression);
|
|
129252
129317
|
}
|
|
129253
129318
|
/**
|
|
129254
129319
|
* Check for dangerous SQL patterns that indicate injection attempts
|
|
@@ -129308,15 +129373,29 @@ var SQLExpressionValidator = /*#__PURE__*/function (_BaseSingleton) {
|
|
|
129308
129373
|
};
|
|
129309
129374
|
}
|
|
129310
129375
|
}
|
|
129311
|
-
//
|
|
129312
|
-
//
|
|
129313
|
-
//
|
|
129314
|
-
//
|
|
129376
|
+
// Block references to database system catalogs / metadata objects in ALL contexts
|
|
129377
|
+
// (including full_query). These live outside MemberJunction's entity-permission model, so
|
|
129378
|
+
// permitting them turns a validated SELECT into a schema-enumeration / credential-exfiltration
|
|
129379
|
+
// primitive. String literals were already stripped upstream, so legitimate literal values are safe.
|
|
129315
129380
|
} catch (err) {
|
|
129316
129381
|
_iterator.e(err);
|
|
129317
129382
|
} finally {
|
|
129318
129383
|
_iterator.f();
|
|
129319
129384
|
}
|
|
129385
|
+
for (var _i = 0, _BLOCKED_SYSTEM_OBJEC = BLOCKED_SYSTEM_OBJECT_PATTERNS; _i < _BLOCKED_SYSTEM_OBJEC.length; _i++) {
|
|
129386
|
+
var sysPattern = _BLOCKED_SYSTEM_OBJEC[_i];
|
|
129387
|
+
if (sysPattern.test(textToCheck)) {
|
|
129388
|
+
return {
|
|
129389
|
+
valid: false,
|
|
129390
|
+
error: 'Access to database system catalogs / metadata objects is not allowed',
|
|
129391
|
+
trigger: 'system-object'
|
|
129392
|
+
};
|
|
129393
|
+
}
|
|
129394
|
+
}
|
|
129395
|
+
// Check statement terminator (prevents multi-statement injection).
|
|
129396
|
+
// For full_query context, strip comments first (a trailing semicolon may be followed by
|
|
129397
|
+
// an inline comment like `ORDER BY x DESC; -- highest first`), then strip the trailing
|
|
129398
|
+
// semicolon. Only reject if semicolons remain mid-statement, indicating injection.
|
|
129320
129399
|
var textForSemicolonCheck = isFullQuery ? this.stripSQLComments(expression).replace(/;\s*$/, '') // strip comments then trailing semicolon
|
|
129321
129400
|
: expression;
|
|
129322
129401
|
if (textForSemicolonCheck.includes(';')) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/react-runtime",
|
|
3
|
-
"version": "5.51.
|
|
3
|
+
"version": "5.51.1",
|
|
4
4
|
"description": "Platform-agnostic React component runtime for MemberJunction. Provides core compilation, registry, and execution capabilities for React components in any JavaScript environment.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
},
|
|
30
30
|
"homepage": "https://github.com/MemberJunction/MJ#readme",
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@memberjunction/core": "5.51.
|
|
33
|
-
"@memberjunction/global": "5.51.
|
|
34
|
-
"@memberjunction/interactive-component-types": "5.51.
|
|
35
|
-
"@memberjunction/core-entities": "5.51.
|
|
36
|
-
"@memberjunction/graphql-dataprovider": "5.51.
|
|
32
|
+
"@memberjunction/core": "5.51.1",
|
|
33
|
+
"@memberjunction/global": "5.51.1",
|
|
34
|
+
"@memberjunction/interactive-component-types": "5.51.1",
|
|
35
|
+
"@memberjunction/core-entities": "5.51.1",
|
|
36
|
+
"@memberjunction/graphql-dataprovider": "5.51.1",
|
|
37
37
|
"@babel/standalone": "^7.29.1",
|
|
38
38
|
"rxjs": "^7.8.2"
|
|
39
39
|
},
|