prostgles-server 4.2.192 → 4.2.193
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/Auth/AuthHandler.d.ts +8 -13
- package/dist/Auth/AuthHandler.d.ts.map +1 -1
- package/dist/Auth/AuthHandler.js +34 -89
- package/dist/Auth/AuthHandler.js.map +1 -1
- package/dist/Auth/AuthTypes.d.ts +16 -6
- package/dist/Auth/AuthTypes.d.ts.map +1 -1
- package/dist/Auth/authProviders/setOAuthProviders.js +1 -1
- package/dist/Auth/authProviders/setOAuthProviders.js.map +1 -1
- package/dist/Auth/endpoints/getConfirmEmailRequestHandler.js +1 -1
- package/dist/Auth/endpoints/getConfirmEmailRequestHandler.js.map +1 -1
- package/dist/Auth/endpoints/getRegisterRequestHandler.js +1 -1
- package/dist/Auth/endpoints/getRegisterRequestHandler.js.map +1 -1
- package/dist/Auth/setupAuthRoutes.d.ts.map +1 -1
- package/dist/Auth/setupAuthRoutes.js +16 -10
- package/dist/Auth/setupAuthRoutes.js.map +1 -1
- package/dist/Auth/utils/getUserFromRequest.d.ts +7 -0
- package/dist/Auth/utils/getUserFromRequest.d.ts.map +1 -0
- package/dist/Auth/utils/getUserFromRequest.js +66 -0
- package/dist/Auth/utils/getUserFromRequest.js.map +1 -0
- package/dist/DboBuilder/DboBuilder.d.ts +1 -1
- package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilder.js +6 -1
- package/dist/DboBuilder/DboBuilder.js.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.d.ts +15 -7
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js +2 -2
- package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
- package/dist/DboBuilder/QueryStreamer.js +1 -1
- package/dist/DboBuilder/QueryStreamer.js.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +2 -3
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert.js +2 -2
- package/dist/DboBuilder/TableHandler/update.js +1 -1
- package/dist/DboBuilder/TableHandler/update.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +0 -4
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.js +37 -24
- package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/find.js +1 -1
- package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/getExistsCondition.js +4 -4
- package/dist/DboBuilder/ViewHandler/getExistsCondition.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/subscribe.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/subscribe.js +9 -15
- package/dist/DboBuilder/ViewHandler/subscribe.js.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
- package/dist/DboBuilder/dboBuilderUtils.js +3 -1
- package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
- package/dist/DboBuilder/insertNestedRecords.d.ts +4 -3
- package/dist/DboBuilder/insertNestedRecords.d.ts.map +1 -1
- package/dist/DboBuilder/insertNestedRecords.js +12 -12
- package/dist/DboBuilder/insertNestedRecords.js.map +1 -1
- package/dist/DboBuilder/runSQL.d.ts +3 -2
- package/dist/DboBuilder/runSQL.d.ts.map +1 -1
- package/dist/DboBuilder/runSQL.js +12 -15
- package/dist/DboBuilder/runSQL.js.map +1 -1
- package/dist/FileManager/initFileManager.d.ts.map +1 -1
- package/dist/FileManager/initFileManager.js +5 -4
- package/dist/FileManager/initFileManager.js.map +1 -1
- package/dist/Prostgles.d.ts +3 -2
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +8 -16
- package/dist/Prostgles.js.map +1 -1
- package/dist/ProstglesTypes.d.ts +2 -2
- package/dist/ProstglesTypes.d.ts.map +1 -1
- package/dist/ProstglesTypes.js +1 -6
- package/dist/ProstglesTypes.js.map +1 -1
- package/dist/PubSubManager/PubSubManager.js +2 -2
- package/dist/PubSubManager/PubSubManager.js.map +1 -1
- package/dist/PubSubManager/addSync.d.ts.map +1 -1
- package/dist/PubSubManager/addSync.js +1 -3
- package/dist/PubSubManager/addSync.js.map +1 -1
- package/dist/PublishParser/PublishParser.d.ts +11 -18
- package/dist/PublishParser/PublishParser.d.ts.map +1 -1
- package/dist/PublishParser/PublishParser.js +28 -27
- package/dist/PublishParser/PublishParser.js.map +1 -1
- package/dist/PublishParser/getFileTableRules.d.ts +2 -3
- package/dist/PublishParser/getFileTableRules.d.ts.map +1 -1
- package/dist/PublishParser/getFileTableRules.js +18 -20
- package/dist/PublishParser/getFileTableRules.js.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.d.ts +2 -9
- package/dist/PublishParser/getSchemaFromPublish.d.ts.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js +5 -5
- package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.d.ts +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.d.ts.map +1 -1
- package/dist/PublishParser/getTableRulesWithoutFileTable.js +30 -33
- package/dist/PublishParser/getTableRulesWithoutFileTable.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +6 -11
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
- package/dist/RestApi.d.ts +1 -1
- package/dist/RestApi.d.ts.map +1 -1
- package/dist/RestApi.js +19 -16
- package/dist/RestApi.js.map +1 -1
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js +11 -15
- package/dist/initProstgles.js.map +1 -1
- package/dist/onSocketConnected.d.ts.map +1 -1
- package/dist/onSocketConnected.js +5 -5
- package/dist/onSocketConnected.js.map +1 -1
- package/dist/runClientRequest.d.ts +14 -29
- package/dist/runClientRequest.d.ts.map +1 -1
- package/dist/runClientRequest.js +20 -34
- package/dist/runClientRequest.js.map +1 -1
- package/lib/Auth/AuthHandler.ts +45 -103
- package/lib/Auth/AuthTypes.ts +19 -8
- package/lib/Auth/authProviders/setOAuthProviders.ts +1 -1
- package/lib/Auth/endpoints/getConfirmEmailRequestHandler.ts +1 -1
- package/lib/Auth/endpoints/getRegisterRequestHandler.ts +1 -1
- package/lib/Auth/setupAuthRoutes.ts +17 -13
- package/lib/Auth/utils/getUserFromRequest.ts +71 -0
- package/lib/DboBuilder/DboBuilder.ts +7 -3
- package/lib/DboBuilder/DboBuilderTypes.ts +19 -17
- package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +2 -2
- package/lib/DboBuilder/QueryStreamer.ts +1 -1
- package/lib/DboBuilder/TableHandler/TableHandler.ts +2 -3
- package/lib/DboBuilder/TableHandler/insert.ts +2 -2
- package/lib/DboBuilder/TableHandler/update.ts +1 -1
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +38 -37
- package/lib/DboBuilder/ViewHandler/find.ts +1 -1
- package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +4 -4
- package/lib/DboBuilder/ViewHandler/subscribe.ts +22 -41
- package/lib/DboBuilder/dboBuilderUtils.ts +3 -1
- package/lib/DboBuilder/insertNestedRecords.ts +18 -16
- package/lib/DboBuilder/runSQL.ts +14 -16
- package/lib/FileManager/initFileManager.ts +16 -12
- package/lib/Prostgles.ts +10 -24
- package/lib/ProstglesTypes.ts +9 -31
- package/lib/PubSubManager/PubSubManager.ts +3 -3
- package/lib/PubSubManager/addSync.ts +1 -3
- package/lib/PublishParser/PublishParser.ts +35 -45
- package/lib/PublishParser/getFileTableRules.ts +24 -48
- package/lib/PublishParser/getSchemaFromPublish.ts +12 -23
- package/lib/PublishParser/getTableRulesWithoutFileTable.ts +30 -41
- package/lib/PublishParser/publishTypesAndUtils.ts +8 -21
- package/lib/RestApi.ts +43 -31
- package/lib/initProstgles.ts +51 -64
- package/lib/onSocketConnected.ts +12 -9
- package/lib/runClientRequest.ts +50 -66
- package/package.json +3 -3
|
@@ -109,12 +109,12 @@ export class ViewHandler {
|
|
|
109
109
|
error?: any;
|
|
110
110
|
}) => {
|
|
111
111
|
if (localParams?.noLog) {
|
|
112
|
-
if (localParams.
|
|
112
|
+
if (localParams.clientReq) {
|
|
113
113
|
throw new Error("noLog option is not allowed from a remote client");
|
|
114
114
|
}
|
|
115
115
|
return;
|
|
116
116
|
}
|
|
117
|
-
const sid = this.dboBuilder.prostgles.authHandler?.getSIDNoError(localParams);
|
|
117
|
+
const sid = this.dboBuilder.prostgles.authHandler?.getSIDNoError(localParams?.clientReq);
|
|
118
118
|
return this.dboBuilder.prostgles.opts.onLog?.({
|
|
119
119
|
type: "table",
|
|
120
120
|
command,
|
|
@@ -122,7 +122,7 @@ export class ViewHandler {
|
|
|
122
122
|
error,
|
|
123
123
|
txInfo: this.tx?.t.ctx,
|
|
124
124
|
sid,
|
|
125
|
-
socketId: localParams?.socket?.id,
|
|
125
|
+
socketId: localParams?.clientReq?.socket?.id,
|
|
126
126
|
tableName: this.name,
|
|
127
127
|
data,
|
|
128
128
|
localParams,
|
|
@@ -148,39 +148,40 @@ export class ViewHandler {
|
|
|
148
148
|
|
|
149
149
|
validateViewRules = validateViewRules.bind(this);
|
|
150
150
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
}
|
|
151
|
+
// DEAD CODE?!
|
|
152
|
+
// getShortestJoin(
|
|
153
|
+
// table1: string,
|
|
154
|
+
// table2: string,
|
|
155
|
+
// startAlias: number,
|
|
156
|
+
// isInner = false
|
|
157
|
+
// ): { query: string; toOne: boolean } {
|
|
158
|
+
// const getJoinCondition = (
|
|
159
|
+
// on: Record<string, string>[],
|
|
160
|
+
// leftTable: string,
|
|
161
|
+
// rightTable: string
|
|
162
|
+
// ) => {
|
|
163
|
+
// return on
|
|
164
|
+
// .map((cond) =>
|
|
165
|
+
// Object.keys(cond)
|
|
166
|
+
// .map((lKey) => `${leftTable}.${lKey} = ${rightTable}.${cond[lKey]}`)
|
|
167
|
+
// .join("\nAND ")
|
|
168
|
+
// )
|
|
169
|
+
// .join(" OR ");
|
|
170
|
+
// };
|
|
171
|
+
|
|
172
|
+
// // let toOne = true;
|
|
173
|
+
// const query = this.joins
|
|
174
|
+
// .map(({ tables, on, type }, i) => {
|
|
175
|
+
// if (type.split("-")[1] === "many") {
|
|
176
|
+
// // toOne = false;
|
|
177
|
+
// }
|
|
178
|
+
// const tl = `tl${startAlias + i}`,
|
|
179
|
+
// tr = `tr${startAlias + i}`;
|
|
180
|
+
// return `FROM ${tables[0]} ${tl} ${isInner ? "INNER" : "LEFT"} JOIN ${tables[1]} ${tr} ON ${getJoinCondition(on, tl, tr)}`;
|
|
181
|
+
// })
|
|
182
|
+
// .join("\n");
|
|
183
|
+
// return { query, toOne: false };
|
|
184
|
+
// }
|
|
184
185
|
|
|
185
186
|
checkFilter(filter: any) {
|
|
186
187
|
if (filter === null || (filter && !isObject(filter)))
|
|
@@ -192,7 +193,7 @@ export class ViewHandler {
|
|
|
192
193
|
getColumns = getColumns.bind(this);
|
|
193
194
|
|
|
194
195
|
getValidatedRules(tableRules?: TableRule, localParams?: LocalParams): ValidatedTableRules {
|
|
195
|
-
if (localParams?.socket && !tableRules) {
|
|
196
|
+
if (localParams?.clientReq?.socket && !tableRules) {
|
|
196
197
|
throw "INTERNAL ERROR: Unexpected case -> localParams && !tableRules";
|
|
197
198
|
}
|
|
198
199
|
|
|
@@ -203,7 +203,7 @@ export const runQueryReturnType = async ({
|
|
|
203
203
|
})
|
|
204
204
|
);
|
|
205
205
|
} else if (sqlTypes.some((v) => v === returnType)) {
|
|
206
|
-
if (!(await canRunSQL(handler.dboBuilder.prostgles, localParams))) {
|
|
206
|
+
if (!(await canRunSQL(handler.dboBuilder.prostgles, localParams?.clientReq))) {
|
|
207
207
|
throw `Not allowed: { returnType: ${JSON.stringify(returnType)} } requires execute sql privileges `;
|
|
208
208
|
}
|
|
209
209
|
if (returnType === "statement-no-rls") {
|
|
@@ -29,15 +29,15 @@ export async function getExistsCondition(
|
|
|
29
29
|
tableAlias;
|
|
30
30
|
|
|
31
31
|
/* Check if allowed to view data - forcedFilters will bypass this check through isForcedFilterBypass */
|
|
32
|
-
if (localParams?.isRemoteRequest && !localParams.
|
|
33
|
-
throw "Unexpected: localParams isRemoteRequest and missing
|
|
32
|
+
if (localParams?.isRemoteRequest && !localParams.clientReq) {
|
|
33
|
+
throw "Unexpected: localParams isRemoteRequest and missing clientReq";
|
|
34
34
|
}
|
|
35
35
|
const targetTable = eConfig.isJoined ? eConfig.parsedPath.at(-1)!.table : eConfig.targetTable;
|
|
36
|
-
if (
|
|
36
|
+
if (localParams?.clientReq && this.dboBuilder.publishParser) {
|
|
37
37
|
t2Rules = (await this.dboBuilder.publishParser.getValidatedRequestRuleWusr({
|
|
38
38
|
tableName: targetTable,
|
|
39
39
|
command: "find",
|
|
40
|
-
localParams,
|
|
40
|
+
clientReq: localParams.clientReq,
|
|
41
41
|
})) as TableRule | undefined;
|
|
42
42
|
|
|
43
43
|
if (!t2Rules || !t2Rules.select) throw "Dissallowed";
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
AnyObject,
|
|
3
|
-
SubscribeParams,
|
|
4
|
-
SubscriptionChannels,
|
|
5
|
-
} from "prostgles-types";
|
|
1
|
+
import { AnyObject, SubscribeParams, SubscriptionChannels } from "prostgles-types";
|
|
6
2
|
import { TableRule } from "../../PublishParser/PublishParser";
|
|
7
3
|
import {
|
|
8
4
|
Filter,
|
|
@@ -23,38 +19,33 @@ export type LocalFuncs =
|
|
|
23
19
|
}
|
|
24
20
|
| OnData;
|
|
25
21
|
|
|
26
|
-
export const getOnDataFunc = (
|
|
27
|
-
localFuncs: LocalFuncs | undefined,
|
|
28
|
-
): OnData | undefined => {
|
|
22
|
+
export const getOnDataFunc = (localFuncs: LocalFuncs | undefined): OnData | undefined => {
|
|
29
23
|
return typeof localFuncs === "function" ? localFuncs : localFuncs?.onData;
|
|
30
24
|
};
|
|
31
25
|
export const matchesLocalFuncs = (
|
|
32
26
|
localFuncs1: LocalFuncs | undefined,
|
|
33
|
-
localFuncs2: LocalFuncs | undefined
|
|
27
|
+
localFuncs2: LocalFuncs | undefined
|
|
34
28
|
) => {
|
|
35
|
-
return (
|
|
36
|
-
localFuncs1 &&
|
|
37
|
-
localFuncs2 &&
|
|
38
|
-
getOnDataFunc(localFuncs1) === getOnDataFunc(localFuncs2)
|
|
39
|
-
);
|
|
29
|
+
return localFuncs1 && localFuncs2 && getOnDataFunc(localFuncs1) === getOnDataFunc(localFuncs2);
|
|
40
30
|
};
|
|
41
31
|
export const parseLocalFuncs = (
|
|
42
|
-
localFuncs1: LocalFuncs | undefined
|
|
32
|
+
localFuncs1: LocalFuncs | undefined
|
|
43
33
|
): Extract<LocalFuncs, { onData: OnData }> | undefined => {
|
|
44
|
-
return
|
|
45
|
-
? undefined
|
|
46
|
-
: typeof localFuncs1 === "function"
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
34
|
+
return (
|
|
35
|
+
!localFuncs1 ? undefined
|
|
36
|
+
: typeof localFuncs1 === "function" ?
|
|
37
|
+
{
|
|
38
|
+
onData: localFuncs1,
|
|
39
|
+
}
|
|
40
|
+
: localFuncs1
|
|
41
|
+
);
|
|
51
42
|
};
|
|
52
43
|
|
|
53
44
|
async function subscribe(
|
|
54
45
|
this: ViewHandler,
|
|
55
46
|
filter: Filter,
|
|
56
47
|
params: SubscribeParams,
|
|
57
|
-
localFuncs: LocalFuncs
|
|
48
|
+
localFuncs: LocalFuncs
|
|
58
49
|
): Promise<{ unsubscribe: () => any }>;
|
|
59
50
|
async function subscribe(
|
|
60
51
|
this: ViewHandler,
|
|
@@ -62,7 +53,7 @@ async function subscribe(
|
|
|
62
53
|
params: SubscribeParams,
|
|
63
54
|
localFuncs: undefined,
|
|
64
55
|
table_rules: TableRule | undefined,
|
|
65
|
-
localParams: LocalParams
|
|
56
|
+
localParams: LocalParams
|
|
66
57
|
): Promise<SubscriptionChannels>;
|
|
67
58
|
async function subscribe(
|
|
68
59
|
this: ViewHandler,
|
|
@@ -70,7 +61,7 @@ async function subscribe(
|
|
|
70
61
|
params: SubscribeParams,
|
|
71
62
|
localFuncs?: LocalFuncs,
|
|
72
63
|
table_rules?: TableRule,
|
|
73
|
-
localParams?: LocalParams
|
|
64
|
+
localParams?: LocalParams
|
|
74
65
|
): Promise<{ unsubscribe: () => any } | SubscriptionChannels> {
|
|
75
66
|
const start = Date.now();
|
|
76
67
|
try {
|
|
@@ -81,10 +72,11 @@ async function subscribe(
|
|
|
81
72
|
if (this.tx) {
|
|
82
73
|
throw "subscribe not allowed within transactions";
|
|
83
74
|
}
|
|
84
|
-
|
|
75
|
+
const clientReq = localParams?.clientReq;
|
|
76
|
+
if (!clientReq && !localFuncs) {
|
|
85
77
|
throw " missing data. provide -> localFunc | localParams { socket } ";
|
|
86
78
|
}
|
|
87
|
-
if (
|
|
79
|
+
if (clientReq?.socket && localFuncs) {
|
|
88
80
|
console.error({ localParams, localFuncs });
|
|
89
81
|
throw " Cannot have localFunc AND socket ";
|
|
90
82
|
}
|
|
@@ -92,25 +84,14 @@ async function subscribe(
|
|
|
92
84
|
const { throttle = 0, throttleOpts, ...selectParams } = params;
|
|
93
85
|
|
|
94
86
|
/** Ensure request is valid */
|
|
95
|
-
await this.find(
|
|
96
|
-
filter,
|
|
97
|
-
{ ...selectParams, limit: 0 },
|
|
98
|
-
undefined,
|
|
99
|
-
table_rules,
|
|
100
|
-
localParams,
|
|
101
|
-
);
|
|
102
|
-
|
|
103
|
-
// TODO: Implement comprehensive canSubscribe check
|
|
104
|
-
// if (!this.dboBuilder.prostgles.isSuperUser) {
|
|
105
|
-
// throw "Subscribe not possible. Must be superuser";
|
|
106
|
-
// }
|
|
87
|
+
await this.find(filter, { ...selectParams, limit: 0 }, undefined, table_rules, localParams);
|
|
107
88
|
|
|
108
89
|
const newQuery: NewQuery = (await this.find(
|
|
109
90
|
filter,
|
|
110
91
|
{ ...selectParams, limit: 0 },
|
|
111
92
|
undefined,
|
|
112
93
|
table_rules,
|
|
113
|
-
{ ...localParams, returnNewQuery: true }
|
|
94
|
+
{ ...localParams, returnNewQuery: true }
|
|
114
95
|
)) as any;
|
|
115
96
|
const viewOptions = await getSubscribeRelatedTables.bind(this)({
|
|
116
97
|
filter,
|
|
@@ -135,7 +116,7 @@ async function subscribe(
|
|
|
135
116
|
|
|
136
117
|
const pubSubManager = await this.dboBuilder.getPubSubManager();
|
|
137
118
|
if (!localFuncs) {
|
|
138
|
-
const { socket } =
|
|
119
|
+
const { socket } = clientReq ?? {};
|
|
139
120
|
const result = await pubSubManager.addSub({
|
|
140
121
|
...commonSubOpts,
|
|
141
122
|
socket,
|
|
@@ -89,7 +89,9 @@ export function getSerializedClientErrorFromPGError(
|
|
|
89
89
|
const isServerSideRequest = !args.localParams;
|
|
90
90
|
//TODO: add a rawSQL check for HTTP requests
|
|
91
91
|
const showFullError =
|
|
92
|
-
isServerSideRequest ||
|
|
92
|
+
isServerSideRequest ||
|
|
93
|
+
args.type === "sql" ||
|
|
94
|
+
args.localParams?.clientReq?.socket?.prostgles?.rawSQL;
|
|
93
95
|
if (showFullError) {
|
|
94
96
|
return err;
|
|
95
97
|
}
|
|
@@ -3,12 +3,13 @@ import { LocalParams, TableHandlers } from "./DboBuilder";
|
|
|
3
3
|
import { TableRule } from "../PublishParser/PublishParser";
|
|
4
4
|
import { omitKeys } from "../PubSubManager/PubSubManager";
|
|
5
5
|
import { TableHandler } from "./TableHandler/TableHandler";
|
|
6
|
+
import { AuthClientRequest } from "../Auth/AuthTypes";
|
|
6
7
|
|
|
7
8
|
type InsertNestedRecordsArgs = {
|
|
8
9
|
data: AnyObject | AnyObject[];
|
|
9
10
|
param2?: InsertParams;
|
|
10
|
-
tableRules
|
|
11
|
-
localParams
|
|
11
|
+
tableRules: TableRule | undefined;
|
|
12
|
+
localParams: LocalParams | undefined;
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -16,7 +17,7 @@ type InsertNestedRecordsArgs = {
|
|
|
16
17
|
*/
|
|
17
18
|
export async function insertNestedRecords(
|
|
18
19
|
this: TableHandler,
|
|
19
|
-
{ data, param2, tableRules, localParams
|
|
20
|
+
{ data, param2, tableRules, localParams }: InsertNestedRecordsArgs
|
|
20
21
|
): Promise<{
|
|
21
22
|
data?: AnyObject | AnyObject[];
|
|
22
23
|
insertResult?: AnyObject | AnyObject[];
|
|
@@ -60,7 +61,7 @@ export async function insertNestedRecords(
|
|
|
60
61
|
* Make sure nested insert uses a transaction
|
|
61
62
|
*/
|
|
62
63
|
const dbTX = this.getFinalDBtx(localParams);
|
|
63
|
-
const t = localParams
|
|
64
|
+
const t = localParams?.tx?.t || this.tx?.t;
|
|
64
65
|
if (hasNestedInserts && (!dbTX || !t)) {
|
|
65
66
|
return {
|
|
66
67
|
insertResult: await this.dboBuilder.getTX((dbTX, _t) =>
|
|
@@ -107,7 +108,7 @@ export async function insertNestedRecords(
|
|
|
107
108
|
const newLocalParams: LocalParams = {
|
|
108
109
|
...localParams,
|
|
109
110
|
nestedInsert: {
|
|
110
|
-
depth: (localParams
|
|
111
|
+
depth: (localParams?.nestedInsert?.depth ?? 0) + 1,
|
|
111
112
|
previousData: rootData,
|
|
112
113
|
previousTable: this.name,
|
|
113
114
|
referencingColumn: colInsert.col,
|
|
@@ -165,9 +166,14 @@ export async function insertNestedRecords(
|
|
|
165
166
|
|
|
166
167
|
await Promise.all(
|
|
167
168
|
extraKeys.map(async (targetTable) => {
|
|
168
|
-
const childDataItems =
|
|
169
|
+
const childDataItems: AnyObject[] =
|
|
169
170
|
Array.isArray(row[targetTable]) ? row[targetTable] : [row[targetTable]];
|
|
170
171
|
|
|
172
|
+
/** check */
|
|
173
|
+
if (childDataItems.some((d) => !isObject(d))) {
|
|
174
|
+
throw "Expected array of objects";
|
|
175
|
+
}
|
|
176
|
+
|
|
171
177
|
const childInsert = async (cdata: AnyObject | AnyObject[], tableName: string) => {
|
|
172
178
|
return referencedInsert(this, dbTX, localParams, tableName, cdata);
|
|
173
179
|
};
|
|
@@ -176,7 +182,7 @@ export async function insertNestedRecords(
|
|
|
176
182
|
|
|
177
183
|
const { path } = joinPath;
|
|
178
184
|
const [tbl1, tbl2, tbl3] = path;
|
|
179
|
-
targetTableRules = await getInsertTableRules(this, targetTable, localParams);
|
|
185
|
+
targetTableRules = await getInsertTableRules(this, targetTable, localParams?.clientReq);
|
|
180
186
|
|
|
181
187
|
const cols2 = this.dboBuilder.dbo[tbl2!]!.columns || [];
|
|
182
188
|
if (!this.dboBuilder.dbo[tbl2!]) throw "Invalid/disallowed table: " + tbl2;
|
|
@@ -299,12 +305,12 @@ export async function insertNestedRecords(
|
|
|
299
305
|
export const getInsertTableRules = async (
|
|
300
306
|
tableHandler: TableHandler,
|
|
301
307
|
targetTable: string,
|
|
302
|
-
|
|
308
|
+
clientReq: AuthClientRequest | undefined
|
|
303
309
|
) => {
|
|
304
310
|
const childRules = await tableHandler.dboBuilder.publishParser?.getValidatedRequestRuleWusr({
|
|
305
311
|
tableName: targetTable,
|
|
306
312
|
command: "insert",
|
|
307
|
-
|
|
313
|
+
clientReq,
|
|
308
314
|
});
|
|
309
315
|
if (!childRules || !childRules.insert) throw "Dissallowed nested insert into table " + childRules;
|
|
310
316
|
return childRules;
|
|
@@ -332,22 +338,18 @@ const getJoinPath = async (
|
|
|
332
338
|
const referencedInsert = async (
|
|
333
339
|
tableHandler: TableHandler,
|
|
334
340
|
dbTX: TableHandlers | undefined,
|
|
335
|
-
localParams: LocalParams,
|
|
341
|
+
localParams: LocalParams | undefined,
|
|
336
342
|
targetTable: string,
|
|
337
343
|
targetData: AnyObject | AnyObject[]
|
|
338
344
|
): Promise<AnyObject[]> => {
|
|
339
345
|
await getJoinPath(tableHandler, targetTable);
|
|
340
346
|
|
|
341
|
-
|
|
342
|
-
if (!targetData || !dbTX?.[targetTable] || !("insert" in dbTX[targetTable]!)) {
|
|
347
|
+
if (!dbTX?.[targetTable] || !("insert" in dbTX[targetTable]!)) {
|
|
343
348
|
throw new Error("childInsertErr: Table handler missing for referenced table: " + targetTable);
|
|
344
349
|
}
|
|
345
350
|
|
|
346
|
-
const childRules = await getInsertTableRules(tableHandler, targetTable, localParams);
|
|
351
|
+
const childRules = await getInsertTableRules(tableHandler, targetTable, localParams?.clientReq);
|
|
347
352
|
|
|
348
|
-
// if (thisInfo.has_media === "one" && thisInfo.media_table_name === targetTable && Array.isArray(targetData) && targetData.length > 1) {
|
|
349
|
-
// throw "Constraint check fail: Cannot insert more than one record into " + JSON.stringify(targetTable);
|
|
350
|
-
// }
|
|
351
353
|
return Promise.all(
|
|
352
354
|
(Array.isArray(targetData) ? targetData : [targetData]).map((m) =>
|
|
353
355
|
(dbTX![targetTable] as TableHandler)
|
package/lib/DboBuilder/runSQL.ts
CHANGED
|
@@ -3,13 +3,14 @@ import pg from "pg-promise/typescript/pg-subset";
|
|
|
3
3
|
import { AnyObject, SQLOptions, SQLResult, SQLResultInfo } from "prostgles-types";
|
|
4
4
|
import { DB, Prostgles } from "../Prostgles";
|
|
5
5
|
import { DboBuilder, LocalParams, pgp, postgresToTsType } from "./DboBuilder";
|
|
6
|
+
import { AuthClientRequest } from "../Auth/AuthTypes";
|
|
6
7
|
|
|
7
8
|
export async function runSQL(
|
|
8
9
|
this: DboBuilder,
|
|
9
10
|
queryWithoutRLS: string,
|
|
10
11
|
args: undefined | AnyObject | any[],
|
|
11
12
|
options: SQLOptions | undefined,
|
|
12
|
-
localParams
|
|
13
|
+
localParams: LocalParams | undefined
|
|
13
14
|
) {
|
|
14
15
|
const queryWithRLS = queryWithoutRLS;
|
|
15
16
|
if (
|
|
@@ -29,17 +30,17 @@ export async function runSQL(
|
|
|
29
30
|
|
|
30
31
|
await this.cacheDBTypes();
|
|
31
32
|
|
|
32
|
-
if (!(await canRunSQL(this.prostgles, localParams))) {
|
|
33
|
+
if (!(await canRunSQL(this.prostgles, localParams?.clientReq))) {
|
|
33
34
|
throw "Not allowed to run SQL";
|
|
34
35
|
}
|
|
35
36
|
|
|
36
37
|
const { returnType, allowListen, hasParams = true }: SQLOptions = options || ({} as SQLOptions);
|
|
37
|
-
const { socket } = localParams
|
|
38
|
+
const { socket } = localParams?.clientReq ?? {};
|
|
38
39
|
|
|
39
40
|
const db = localParams?.tx?.t || this.db;
|
|
40
41
|
if (returnType === "stream") {
|
|
41
42
|
if (localParams?.tx) throw "Cannot use stream with localParams transaction";
|
|
42
|
-
if (!socket) throw "
|
|
43
|
+
if (!socket) throw "stream allowed only with client socket";
|
|
43
44
|
const streamInfo = await this.queryStreamer.create({
|
|
44
45
|
socket,
|
|
45
46
|
query: pgp.as.format(queryWithRLS, args),
|
|
@@ -47,7 +48,7 @@ export async function runSQL(
|
|
|
47
48
|
});
|
|
48
49
|
return streamInfo;
|
|
49
50
|
} else if (returnType === "noticeSubscription") {
|
|
50
|
-
if (!socket) throw "
|
|
51
|
+
if (!socket) throw "noticeSubscription allowed only with client socket";
|
|
51
52
|
return await this.prostgles.dbEventsManager?.addNotice(socket);
|
|
52
53
|
} else if (returnType === "statement") {
|
|
53
54
|
try {
|
|
@@ -86,7 +87,7 @@ export async function runSQL(
|
|
|
86
87
|
queryWithoutRLS,
|
|
87
88
|
queryResult,
|
|
88
89
|
allowListen,
|
|
89
|
-
localParams
|
|
90
|
+
localParams?.clientReq
|
|
90
91
|
);
|
|
91
92
|
if (listenHandlers) {
|
|
92
93
|
return listenHandlers;
|
|
@@ -115,7 +116,7 @@ const onSQLResult = async function (
|
|
|
115
116
|
queryWithoutRLS: string,
|
|
116
117
|
{ command }: Omit<SQLResultInfo, "duration">,
|
|
117
118
|
allowListen: boolean | undefined,
|
|
118
|
-
|
|
119
|
+
clientReq: AuthClientRequest | undefined
|
|
119
120
|
) {
|
|
120
121
|
this.prostgles.schemaWatch?.onSchemaChangeFallback?.({
|
|
121
122
|
command,
|
|
@@ -123,12 +124,12 @@ const onSQLResult = async function (
|
|
|
123
124
|
});
|
|
124
125
|
|
|
125
126
|
if (command === "LISTEN") {
|
|
126
|
-
const { socket } =
|
|
127
|
+
const { socket } = clientReq || {};
|
|
127
128
|
if (!allowListen)
|
|
128
129
|
throw new Error(
|
|
129
130
|
`Your query contains a LISTEN command. Set { allowListen: true } to get subscription hooks. Or ignore this message`
|
|
130
131
|
);
|
|
131
|
-
if (!socket) throw "
|
|
132
|
+
if (!socket) throw "LISTEN allowed only with client socket";
|
|
132
133
|
return await this.prostgles.dbEventsManager?.addNotify(queryWithoutRLS, socket);
|
|
133
134
|
}
|
|
134
135
|
};
|
|
@@ -188,14 +189,11 @@ export function getDetailedFieldInfo(this: DboBuilder, fields: pg.IColumn[]) {
|
|
|
188
189
|
|
|
189
190
|
export const canRunSQL = async (
|
|
190
191
|
prostgles: Prostgles,
|
|
191
|
-
|
|
192
|
+
clientReq: AuthClientRequest | undefined
|
|
192
193
|
): Promise<boolean> => {
|
|
193
|
-
if (!
|
|
194
|
+
if (!clientReq) return true;
|
|
194
195
|
|
|
195
|
-
const
|
|
196
|
-
const publishParams = await prostgles.publishParser!.getPublishParams({
|
|
197
|
-
socket,
|
|
198
|
-
});
|
|
196
|
+
const publishParams = await prostgles.publishParser!.getPublishParams(clientReq);
|
|
199
197
|
//@ts-ignore
|
|
200
198
|
const res = await prostgles.opts.publishRawSQL?.(publishParams);
|
|
201
199
|
return Boolean((res && typeof res === "boolean") || res === "*");
|
|
@@ -204,5 +202,5 @@ export const canRunSQL = async (
|
|
|
204
202
|
export const canCreateTables = async (db: DB): Promise<boolean> => {
|
|
205
203
|
return db
|
|
206
204
|
.any(`SELECT has_database_privilege(current_database(), 'create') as yes`)
|
|
207
|
-
.then((rows) => rows[0]
|
|
205
|
+
.then((rows: { yes: boolean }[]) => rows[0]?.yes === true);
|
|
208
206
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as fs from "fs";
|
|
2
|
-
import { asName, tryCatch } from "prostgles-types";
|
|
2
|
+
import { asName, tryCatch, tryCatchV2 } from "prostgles-types";
|
|
3
3
|
import { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
|
|
4
4
|
import { canCreateTables } from "../DboBuilder/runSQL";
|
|
5
5
|
import { Prostgles } from "../Prostgles";
|
|
@@ -24,7 +24,7 @@ export async function initFileManager(this: FileManager, prg: Prostgles) {
|
|
|
24
24
|
|
|
25
25
|
const canCreate = await canCreateTables(this.db);
|
|
26
26
|
const runQuery = async (q: string, debugInfo: string): Promise<void> => {
|
|
27
|
-
const res = await
|
|
27
|
+
const res = await tryCatchV2(async () => {
|
|
28
28
|
if (!canCreate)
|
|
29
29
|
throw "File table creation failed. Your postgres user does not have CREATE table privileges";
|
|
30
30
|
await this.db.any(q);
|
|
@@ -35,7 +35,7 @@ export async function initFileManager(this: FileManager, prg: Prostgles) {
|
|
|
35
35
|
...res,
|
|
36
36
|
data: { debugInfo },
|
|
37
37
|
});
|
|
38
|
-
if (res.
|
|
38
|
+
if (res.hasError) {
|
|
39
39
|
throw res.error;
|
|
40
40
|
}
|
|
41
41
|
};
|
|
@@ -161,15 +161,19 @@ export async function initFileManager(this: FileManager, prg: Prostgles) {
|
|
|
161
161
|
content_type: 1,
|
|
162
162
|
},
|
|
163
163
|
};
|
|
164
|
-
const media = await runClientRequest.bind(this.prostgles)(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
164
|
+
const media = await runClientRequest.bind(this.prostgles)(
|
|
165
|
+
{
|
|
166
|
+
command: "findOne",
|
|
167
|
+
tableName,
|
|
168
|
+
param1: { id },
|
|
169
|
+
param2: selectParams,
|
|
170
|
+
param3: undefined,
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
res,
|
|
174
|
+
httpReq: req,
|
|
175
|
+
}
|
|
176
|
+
);
|
|
173
177
|
|
|
174
178
|
if (!media) {
|
|
175
179
|
res.status(HTTP_FAIL_CODES.NOT_FOUND).send("File not found or not allowed");
|
package/lib/Prostgles.ts
CHANGED
|
@@ -20,7 +20,6 @@ import TableConfigurator from "./TableConfig/TableConfig";
|
|
|
20
20
|
import {
|
|
21
21
|
DBHandlerServer,
|
|
22
22
|
DboBuilder,
|
|
23
|
-
LocalParams,
|
|
24
23
|
PRGLIOSocket,
|
|
25
24
|
getErrorAsObject,
|
|
26
25
|
} from "./DboBuilder/DboBuilder";
|
|
@@ -67,6 +66,7 @@ const DEFAULT_KEYWORDS = {
|
|
|
67
66
|
|
|
68
67
|
import { randomUUID } from "crypto";
|
|
69
68
|
import * as fs from "fs";
|
|
69
|
+
import { AuthClientRequest } from "./Auth/AuthTypes";
|
|
70
70
|
|
|
71
71
|
export class Prostgles {
|
|
72
72
|
/**
|
|
@@ -383,14 +383,7 @@ export class Prostgles {
|
|
|
383
383
|
|
|
384
384
|
if (!this.dbo) throw "dbo missing";
|
|
385
385
|
|
|
386
|
-
const publishParser = new PublishParser(
|
|
387
|
-
this.opts.publish,
|
|
388
|
-
this.opts.publishMethods,
|
|
389
|
-
this.opts.publishRawSQL,
|
|
390
|
-
this.dbo,
|
|
391
|
-
this.db!,
|
|
392
|
-
this
|
|
393
|
-
);
|
|
386
|
+
const publishParser = new PublishParser(this);
|
|
394
387
|
this.publishParser = publishParser;
|
|
395
388
|
|
|
396
389
|
if (!this.opts.io) return;
|
|
@@ -413,15 +406,14 @@ export class Prostgles {
|
|
|
413
406
|
|
|
414
407
|
onSocketConnected = onSocketConnected.bind(this);
|
|
415
408
|
|
|
416
|
-
getClientSchema = async (clientReq:
|
|
409
|
+
getClientSchema = async (clientReq: AuthClientRequest) => {
|
|
417
410
|
const result = await tryCatchV2(async () => {
|
|
418
411
|
const clientInfo =
|
|
419
|
-
clientReq.socket ?
|
|
420
|
-
|
|
421
|
-
:
|
|
422
|
-
if (!clientInfo) throw "Invalid client";
|
|
412
|
+
clientReq.socket ?
|
|
413
|
+
{ type: "socket" as const, ...clientReq }
|
|
414
|
+
: { type: "http" as const, ...clientReq };
|
|
423
415
|
|
|
424
|
-
const userData = await this.authHandler?.
|
|
416
|
+
const userData = await this.authHandler?.getUserFromRequest(clientInfo);
|
|
425
417
|
const { publishParser } = this;
|
|
426
418
|
let fullSchema: Awaited<ReturnType<PublishParser["getSchemaFromPublish"]>> | undefined;
|
|
427
419
|
let publishValidationError;
|
|
@@ -501,7 +493,7 @@ export class Prostgles {
|
|
|
501
493
|
userData,
|
|
502
494
|
};
|
|
503
495
|
});
|
|
504
|
-
const sid =
|
|
496
|
+
const sid = this.authHandler?.getSIDNoError(clientReq);
|
|
505
497
|
await this.opts.onLog?.({
|
|
506
498
|
type: "connect.getClientSchema",
|
|
507
499
|
duration: result.duration,
|
|
@@ -522,19 +514,13 @@ export class Prostgles {
|
|
|
522
514
|
socket.on(
|
|
523
515
|
CHANNELS.SQL,
|
|
524
516
|
async (
|
|
525
|
-
|
|
517
|
+
sqlRequestData: SQLRequest,
|
|
526
518
|
cb = (..._callback: any) => {
|
|
527
519
|
/* Empty */
|
|
528
520
|
}
|
|
529
521
|
) => {
|
|
530
522
|
runClientSqlRequest
|
|
531
|
-
.bind(this)({
|
|
532
|
-
type: "socket",
|
|
533
|
-
socket,
|
|
534
|
-
query,
|
|
535
|
-
args: params,
|
|
536
|
-
options,
|
|
537
|
-
})
|
|
523
|
+
.bind(this)(sqlRequestData, { socket })
|
|
538
524
|
.then((res) => {
|
|
539
525
|
cb(null, res);
|
|
540
526
|
})
|