prostgles-server 4.2.448 → 4.2.450
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/DboBuilder/DboBuilderTypes.d.ts +11 -7
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.js +31 -31
- package/dist/DboBuilder/QueryBuilder/Functions/Functions.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts +5 -5
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js +1 -1
- package/dist/DboBuilder/QueryBuilder/QueryBuilder.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts +2 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js +12 -10
- package/dist/DboBuilder/QueryBuilder/getJoinQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.d.ts.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js +6 -12
- package/dist/DboBuilder/QueryBuilder/getSelectQuery.js.map +1 -1
- package/dist/DboBuilder/TableRules/getValidatedRules.d.ts.map +1 -1
- package/dist/DboBuilder/TableRules/getValidatedRules.js +33 -35
- package/dist/DboBuilder/TableRules/getValidatedRules.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.js +3 -3
- package/dist/DboBuilder/ViewHandler/parseComplexFilter.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/prepareSortItems.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareSortItems.js +6 -4
- package/dist/DboBuilder/ViewHandler/prepareSortItems.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/prepareWhere.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.d.ts +2 -2
- package/dist/DboBuilder/getCondition.d.ts.map +1 -1
- package/dist/DboBuilder/getCondition.js +6 -6
- package/dist/DboBuilder/getCondition.js.map +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.js +1 -1
- package/dist/DboBuilder/getSubscribeRelatedTables.js.map +1 -1
- package/dist/Filtering.d.ts +1 -1
- package/dist/Filtering.d.ts.map +1 -1
- package/dist/Filtering.js +3 -3
- package/dist/Filtering.js.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts +1 -0
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +52 -2
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.js +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +14 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/eslint.config.mjs +2 -2
- package/lib/DboBuilder/DboBuilderTypes.ts +12 -7
- package/lib/DboBuilder/QueryBuilder/Functions/COMPUTED_FIELDS.ts +1 -1
- package/lib/DboBuilder/QueryBuilder/Functions/Functions.ts +66 -62
- package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +6 -6
- package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +16 -12
- package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +5 -5
- package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +11 -17
- package/lib/DboBuilder/TableRules/getValidatedRules.ts +39 -40
- package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +4 -4
- package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +14 -12
- package/lib/DboBuilder/ViewHandler/prepareWhere.ts +6 -6
- package/lib/DboBuilder/getCondition.ts +8 -12
- package/lib/DboBuilder/getSubscribeRelatedTables.ts +1 -1
- package/lib/Filtering.ts +11 -13
- package/lib/PublishParser/PublishParser.ts +62 -5
- package/lib/PublishParser/getSchemaFromPublish.ts +1 -1
- package/lib/PublishParser/getTableRulesWithoutFileTable.ts +2 -2
- package/lib/PublishParser/publishTypesAndUtils.ts +23 -1
- package/package.json +18 -18
package/lib/Filtering.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
FilterDataType,
|
|
3
|
-
FullFilter} from "prostgles-types";
|
|
1
|
+
import type { FilterDataType, FullFilter } from "prostgles-types";
|
|
4
2
|
import {
|
|
5
3
|
BetweenFilterKeys,
|
|
6
4
|
CompareFilterKeys,
|
|
@@ -47,7 +45,7 @@ export const FILTER_OPERAND_TO_SQL_OPERAND = Object.fromEntries(
|
|
|
47
45
|
else if (filterOperand === "$isDistinctFrom") sqlOperand = "IS DISTINCT FROM";
|
|
48
46
|
else if (filterOperand === "$isNotDistinctFrom") sqlOperand = "IS NOT DISTINCT FROM";
|
|
49
47
|
return [filterOperand, sqlOperand];
|
|
50
|
-
})
|
|
48
|
+
}),
|
|
51
49
|
) as Record<(typeof FILTER_OPERANDS)[number], string>;
|
|
52
50
|
|
|
53
51
|
/**
|
|
@@ -57,12 +55,12 @@ export const FILTER_OPERAND_TO_SQL_OPERAND = Object.fromEntries(
|
|
|
57
55
|
type ParseFilterItemArgs = {
|
|
58
56
|
filter: FullFilter<void, void> | undefined;
|
|
59
57
|
select: SelectItemValidated[] | undefined;
|
|
60
|
-
|
|
58
|
+
tableAliasRaw: string | undefined;
|
|
61
59
|
allowedColumnNames: string[];
|
|
62
60
|
};
|
|
63
61
|
|
|
64
62
|
export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
65
|
-
const { filter: _f, select,
|
|
63
|
+
const { filter: _f, select, tableAliasRaw, allowedColumnNames } = args;
|
|
66
64
|
|
|
67
65
|
if (!_f || isEmpty(_f)) return "";
|
|
68
66
|
|
|
@@ -84,9 +82,9 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
84
82
|
parseFilterItem({
|
|
85
83
|
filter: { [fk]: _f[fk] },
|
|
86
84
|
select,
|
|
87
|
-
|
|
85
|
+
tableAliasRaw,
|
|
88
86
|
allowedColumnNames,
|
|
89
|
-
})
|
|
87
|
+
}),
|
|
90
88
|
)
|
|
91
89
|
.sort() /* sorted to ensure duplicate subscription channels are not created due to different condition order */
|
|
92
90
|
.join(" AND ");
|
|
@@ -106,7 +104,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
106
104
|
const dissallowedFields = fields.filter((fname) => !allowedColumnNames.includes(fname));
|
|
107
105
|
if (dissallowedFields.length) {
|
|
108
106
|
throw new Error(
|
|
109
|
-
`Invalid/disallowed columns found in filter: ${dissallowedFields.join(", ")}
|
|
107
|
+
`Invalid/disallowed columns found in filter: ${dissallowedFields.join(", ")}`,
|
|
110
108
|
);
|
|
111
109
|
}
|
|
112
110
|
}
|
|
@@ -114,7 +112,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
114
112
|
const getLeftQ = (selItm: SelectItemValidated) => {
|
|
115
113
|
validateSelectedItemFilter(selItem);
|
|
116
114
|
if (selItm.type === "function" || selItm.type === "aggregation") return selItm.getQuery();
|
|
117
|
-
return selItm.getQuery(
|
|
115
|
+
return selItm.getQuery(tableAliasRaw);
|
|
118
116
|
};
|
|
119
117
|
|
|
120
118
|
/**
|
|
@@ -131,14 +129,14 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
131
129
|
/* See if dot notation. Pick the best matching starting string */
|
|
132
130
|
if (select) {
|
|
133
131
|
selItem = select.find((s) =>
|
|
134
|
-
dot_notation_delims.find((delimiter) => fKey.startsWith(s.alias + delimiter))
|
|
132
|
+
dot_notation_delims.find((delimiter) => fKey.startsWith(s.alias + delimiter)),
|
|
135
133
|
);
|
|
136
134
|
validateSelectedItemFilter(selItem);
|
|
137
135
|
}
|
|
138
136
|
if (!selItem) {
|
|
139
137
|
return mErr(
|
|
140
138
|
"Bad filter. Could not match to a column or alias or dot notation" +
|
|
141
|
-
select?.map((s) => s.alias).join(", ")
|
|
139
|
+
select?.map((s) => s.alias).join(", "),
|
|
142
140
|
);
|
|
143
141
|
}
|
|
144
142
|
|
|
@@ -148,7 +146,7 @@ export const parseFilterItem = (args: ParseFilterItemArgs): string => {
|
|
|
148
146
|
if (remainingStr.startsWith("->")) {
|
|
149
147
|
/** Has shorthand operand 'col->>key.<>' */
|
|
150
148
|
const matchingOperand = CompareFilterKeys.find((operand) =>
|
|
151
|
-
remainingStr.endsWith(`.${operand}`)
|
|
149
|
+
remainingStr.endsWith(`.${operand}`),
|
|
152
150
|
);
|
|
153
151
|
if (matchingOperand) {
|
|
154
152
|
remainingStr = remainingStr.slice(0, -matchingOperand.length - 1);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getObjectEntries, includes, isDefined, pickKeys } from "prostgles-types";
|
|
2
2
|
import { getClientRequestIPsInfo } from "../Auth/AuthHandler";
|
|
3
3
|
import type { AuthClientRequest, AuthResultWithSID } from "../Auth/AuthTypes";
|
|
4
4
|
import type { DBOFullyTyped } from "../DBSchemaBuilder/DBSchemaBuilder";
|
|
@@ -212,10 +212,61 @@ export class PublishParser {
|
|
|
212
212
|
}
|
|
213
213
|
const tableScope = scope.tables?.[args.tableName];
|
|
214
214
|
if (!tableScope) return;
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
|
|
216
|
+
const tableHandler = this.dbo[args.tableName];
|
|
217
|
+
if (!tableHandler) {
|
|
218
|
+
throw "INTERNAL ERROR: table handler not found for " + args.tableName;
|
|
219
|
+
}
|
|
220
|
+
const validatedTableRules = tableHandler.getValidatedRules?.(tableRules);
|
|
221
|
+
if (!validatedTableRules) {
|
|
222
|
+
throw "INTERNAL ERROR: getValidatedRules is missing for " + args.tableName;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/** Make sure the scope does not allow things outside the validatedTableRules */
|
|
226
|
+
const result = fromEntries(
|
|
227
|
+
getObjectEntries(tableScope)
|
|
228
|
+
.map(([ruleName, ruleScope]) => {
|
|
229
|
+
if (!ruleScope) return undefined;
|
|
230
|
+
const rule = tableRules[ruleName];
|
|
231
|
+
const validatedRule = validatedTableRules[ruleName];
|
|
232
|
+
if (!validatedRule || !rule) {
|
|
233
|
+
throw `Invalid scope: ${args.tableName}.${ruleName}. The publish does not allow this command.`;
|
|
234
|
+
}
|
|
235
|
+
if (ruleScope === true) {
|
|
236
|
+
return [ruleName, validatedRule] as const;
|
|
237
|
+
}
|
|
238
|
+
const scopeFields = tableHandler.parseFieldFilter!(ruleScope.fields);
|
|
239
|
+
const scopeForcedFilter =
|
|
240
|
+
"forcedFilter" in ruleScope ? ruleScope.forcedFilter : undefined;
|
|
241
|
+
|
|
242
|
+
const ruleFields = "fields" in validatedRule ? validatedRule.fields : undefined;
|
|
243
|
+
for (const field of scopeFields) {
|
|
244
|
+
if (!ruleFields?.includes(field)) {
|
|
245
|
+
throw `Invalid scope: ${args.tableName}.${ruleName}. The field "${field}" is not allowed to be selected according to the publish rules.`;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (!scopeFields.length) {
|
|
249
|
+
throw `Invalid scope: ${args.tableName}.${ruleName}. At least one field must be selected.`;
|
|
250
|
+
}
|
|
251
|
+
const ruleForcedFilter =
|
|
252
|
+
"forcedFilter" in validatedRule ? validatedRule.forcedFilter : undefined;
|
|
253
|
+
const combinedForcedFilter =
|
|
254
|
+
scopeForcedFilter && ruleForcedFilter ?
|
|
255
|
+
{ $and: [scopeForcedFilter, ruleForcedFilter] }
|
|
256
|
+
: scopeForcedFilter || ruleForcedFilter;
|
|
257
|
+
|
|
258
|
+
return [
|
|
259
|
+
ruleName,
|
|
260
|
+
{
|
|
261
|
+
...rule,
|
|
262
|
+
fields: fromEntries(scopeFields.map((field) => [field, 1] as const)),
|
|
263
|
+
...(scopeForcedFilter ? { forcedFilter: combinedForcedFilter } : {}),
|
|
264
|
+
} as any,
|
|
265
|
+
] as const;
|
|
266
|
+
})
|
|
267
|
+
.filter(isDefined),
|
|
268
|
+
) as ParsedTableRule;
|
|
269
|
+
return result;
|
|
219
270
|
};
|
|
220
271
|
if (this.dbo[args.tableName]?.is_media) {
|
|
221
272
|
const { rules: fileTableRules } = await getFileTableRules.bind(this)(
|
|
@@ -256,3 +307,9 @@ function applyParamsIfFunc<T>(
|
|
|
256
307
|
//@ts-ignore
|
|
257
308
|
return maybeFunc;
|
|
258
309
|
}
|
|
310
|
+
|
|
311
|
+
export const fromEntries = <K extends string | number | symbol, V>(
|
|
312
|
+
entries: readonly (readonly [K, V])[],
|
|
313
|
+
): Record<K, V> => {
|
|
314
|
+
return Object.fromEntries(entries) as Record<K, V>;
|
|
315
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { getKeys, isObject } from "prostgles-types";
|
|
1
|
+
import { getKeys, includes, isObject } from "prostgles-types";
|
|
2
2
|
import type { AuthResultWithSID } from "../Auth/AuthTypes";
|
|
3
3
|
import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
|
|
4
4
|
import type { ViewHandler } from "../DboBuilder/ViewHandler/ViewHandler";
|
|
@@ -73,7 +73,7 @@ export async function getTableRulesWithoutFileTable(
|
|
|
73
73
|
});
|
|
74
74
|
|
|
75
75
|
/* All methods allowed. Add no limits for table rules */
|
|
76
|
-
if ([true, "*"]
|
|
76
|
+
if (includes([true, "*"], rawTableRule)) {
|
|
77
77
|
parsedTableRule = {};
|
|
78
78
|
MY_RULES.filter((r) => r.no_limits).forEach((r) => {
|
|
79
79
|
parsedTableRule[r.rule] = { ...(r.no_limits as object) } as any;
|
|
@@ -506,7 +506,29 @@ export type DbTableInfo = {
|
|
|
506
506
|
export type PermissionScope = {
|
|
507
507
|
sql?: "commited" | "rolledback";
|
|
508
508
|
/** TODO: this should match publish types */
|
|
509
|
-
tables?: Record<
|
|
509
|
+
tables?: Record<
|
|
510
|
+
string,
|
|
511
|
+
Partial<{
|
|
512
|
+
select:
|
|
513
|
+
| true
|
|
514
|
+
| {
|
|
515
|
+
fields: FieldFilter;
|
|
516
|
+
forcedFilter: AnyObject;
|
|
517
|
+
};
|
|
518
|
+
insert:
|
|
519
|
+
| true
|
|
520
|
+
| {
|
|
521
|
+
fields: FieldFilter;
|
|
522
|
+
};
|
|
523
|
+
update:
|
|
524
|
+
| true
|
|
525
|
+
| {
|
|
526
|
+
fields: FieldFilter;
|
|
527
|
+
forcedFilter: AnyObject;
|
|
528
|
+
};
|
|
529
|
+
delete: true;
|
|
530
|
+
}>
|
|
531
|
+
>;
|
|
510
532
|
methods?: Record<string, boolean>;
|
|
511
533
|
};
|
|
512
534
|
export type PublishParams<S = void, SUser extends SessionUser = SessionUser> = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prostgles-server",
|
|
3
|
-
"version": "4.2.
|
|
3
|
+
"version": "4.2.450",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -38,16 +38,16 @@
|
|
|
38
38
|
],
|
|
39
39
|
"homepage": "https://prostgles.com",
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@aws-sdk/client-ses": "^3.
|
|
42
|
-
"@aws-sdk/credential-provider-node": "^3.972.
|
|
41
|
+
"@aws-sdk/client-ses": "^3.993.0",
|
|
42
|
+
"@aws-sdk/credential-provider-node": "^3.972.10",
|
|
43
43
|
"@types/passport": "^1.0.17",
|
|
44
|
-
"@types/passport-facebook": "^3.0.
|
|
44
|
+
"@types/passport-facebook": "^3.0.4",
|
|
45
45
|
"@types/passport-github2": "^1.2.9",
|
|
46
|
-
"@types/passport-google-oauth20": "^2.0.
|
|
46
|
+
"@types/passport-google-oauth20": "^2.0.17",
|
|
47
47
|
"@types/passport-microsoft": "^1.0.3",
|
|
48
48
|
"check-disk-space": "^3.4.0",
|
|
49
|
-
"file-type": "^18.
|
|
50
|
-
"nodemailer": "^7.0.
|
|
49
|
+
"file-type": "^18.7.0",
|
|
50
|
+
"nodemailer": "^7.0.13",
|
|
51
51
|
"passport": "^0.7.0",
|
|
52
52
|
"passport-facebook": "^3.0.0",
|
|
53
53
|
"passport-github2": "^0.1.12",
|
|
@@ -56,23 +56,23 @@
|
|
|
56
56
|
"passport-oauth2": "^1.8.0",
|
|
57
57
|
"pg": "^8.15.6",
|
|
58
58
|
"pg-cursor": "^2.17.0",
|
|
59
|
-
"pg-promise": "^12.6.
|
|
60
|
-
"prostgles-types": "^4.0.
|
|
59
|
+
"pg-promise": "^12.6.1",
|
|
60
|
+
"prostgles-types": "^4.0.211"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@eslint/js": "^9.22.0",
|
|
64
|
-
"@types/express": "^4.17.
|
|
64
|
+
"@types/express": "^4.17.25",
|
|
65
65
|
"@types/json-schema": "^7.0.15",
|
|
66
|
-
"@types/node": "^22.
|
|
67
|
-
"@types/nodemailer": "^6.4.
|
|
68
|
-
"@types/pg": "^8.
|
|
66
|
+
"@types/node": "^22.19.11",
|
|
67
|
+
"@types/nodemailer": "^6.4.22",
|
|
68
|
+
"@types/pg": "^8.16.0",
|
|
69
69
|
"@types/pg-cursor": "^2.7.2",
|
|
70
|
-
"@types/sharp": "^0.30.
|
|
70
|
+
"@types/sharp": "^0.30.5",
|
|
71
71
|
"eslint": "^9.39.2",
|
|
72
72
|
"eslint-plugin-security": "^3.0.1",
|
|
73
|
-
"prettier": "^3.
|
|
74
|
-
"socket.io": "^4.8.
|
|
75
|
-
"typescript": "^5.
|
|
76
|
-
"typescript-eslint": "^8.
|
|
73
|
+
"prettier": "^3.8.1",
|
|
74
|
+
"socket.io": "^4.8.3",
|
|
75
|
+
"typescript": "^5.9.3",
|
|
76
|
+
"typescript-eslint": "^8.56.0"
|
|
77
77
|
}
|
|
78
78
|
}
|