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
package/lib/Auth/AuthHandler.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AnyObject,
|
|
3
|
+
AuthFailure,
|
|
3
4
|
AuthGuardLocation,
|
|
4
5
|
AuthGuardLocationResponse,
|
|
5
6
|
AuthSocketSchema,
|
|
6
7
|
CHANNELS,
|
|
7
8
|
} from "prostgles-types";
|
|
8
|
-
import {
|
|
9
|
+
import { PRGLIOSocket } from "../DboBuilder/DboBuilder";
|
|
9
10
|
import { DBOFullyTyped } from "../DBSchemaBuilder";
|
|
10
11
|
import { removeExpressRoute } from "../FileManager/FileManager";
|
|
11
12
|
import { DB, DBHandlerServer, Prostgles } from "../Prostgles";
|
|
12
13
|
import {
|
|
13
14
|
Auth,
|
|
15
|
+
AuthClientRequest,
|
|
14
16
|
AuthResult,
|
|
17
|
+
AuthResultOrError,
|
|
15
18
|
BasicSession,
|
|
16
19
|
ExpressReq,
|
|
17
20
|
ExpressRes,
|
|
@@ -23,6 +26,7 @@ import { getProviders } from "./setAuthProviders";
|
|
|
23
26
|
import { setupAuthRoutes } from "./setupAuthRoutes";
|
|
24
27
|
import { getClientRequestIPsInfo } from "./utils/getClientRequestIPsInfo";
|
|
25
28
|
import { getReturnUrl } from "./utils/getReturnUrl";
|
|
29
|
+
import { getUserFromRequest } from "./utils/getUserFromRequest";
|
|
26
30
|
|
|
27
31
|
export { getClientRequestIPsInfo };
|
|
28
32
|
export const HTTP_FAIL_CODES = {
|
|
@@ -141,23 +145,35 @@ export class AuthHandler {
|
|
|
141
145
|
}
|
|
142
146
|
};
|
|
143
147
|
|
|
144
|
-
|
|
145
|
-
const sid =
|
|
148
|
+
getUserAndHandleError = async (localParams: AuthClientRequest): Promise<AuthResult> => {
|
|
149
|
+
const sid = this.getSID(localParams);
|
|
146
150
|
if (!sid) return undefined;
|
|
147
|
-
|
|
151
|
+
const handlerError = (code: AuthFailure["code"]) => {
|
|
152
|
+
if (localParams.httpReq) {
|
|
153
|
+
localParams.res
|
|
154
|
+
.status(HTTP_FAIL_CODES.BAD_REQUEST)
|
|
155
|
+
.json({ success: false, code, error: code });
|
|
156
|
+
}
|
|
157
|
+
throw code;
|
|
158
|
+
};
|
|
148
159
|
try {
|
|
149
|
-
|
|
150
|
-
return this.opts
|
|
160
|
+
const userOrErrorCode = await this.throttledFunc(async () => {
|
|
161
|
+
return this.opts.getUser(
|
|
151
162
|
this.validateSid(sid),
|
|
152
163
|
this.dbo as any,
|
|
153
164
|
this.db,
|
|
154
|
-
getClientRequestIPsInfo(
|
|
165
|
+
getClientRequestIPsInfo(localParams)
|
|
155
166
|
);
|
|
156
167
|
}, 50);
|
|
157
|
-
|
|
158
|
-
|
|
168
|
+
|
|
169
|
+
if (typeof userOrErrorCode === "string") {
|
|
170
|
+
return handlerError(userOrErrorCode);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return userOrErrorCode;
|
|
174
|
+
} catch (_err) {
|
|
175
|
+
return handlerError("server-error");
|
|
159
176
|
}
|
|
160
|
-
return undefined;
|
|
161
177
|
};
|
|
162
178
|
|
|
163
179
|
init = setupAuthRoutes.bind(this);
|
|
@@ -265,7 +281,7 @@ export class AuthHandler {
|
|
|
265
281
|
const start = Date.now();
|
|
266
282
|
const errCodeOrSession = await this.loginThrottledAndValidate(
|
|
267
283
|
loginParams,
|
|
268
|
-
getClientRequestIPsInfo({ httpReq: req })
|
|
284
|
+
getClientRequestIPsInfo({ httpReq: req, res })
|
|
269
285
|
);
|
|
270
286
|
const loginResponse =
|
|
271
287
|
typeof errCodeOrSession === "string" ?
|
|
@@ -292,21 +308,22 @@ export class AuthHandler {
|
|
|
292
308
|
* query params
|
|
293
309
|
* Based on sid names in auth
|
|
294
310
|
*/
|
|
295
|
-
getSID(
|
|
296
|
-
if (!
|
|
311
|
+
getSID(maybeClientReq: AuthClientRequest | undefined): string | undefined {
|
|
312
|
+
if (!maybeClientReq) return undefined;
|
|
297
313
|
const { sidKeyName } = this;
|
|
298
|
-
if (
|
|
299
|
-
const { handshake } =
|
|
314
|
+
if (maybeClientReq.socket) {
|
|
315
|
+
const { handshake } = maybeClientReq.socket;
|
|
300
316
|
const querySid = handshake.auth?.[sidKeyName] || handshake.query?.[sidKeyName];
|
|
301
317
|
let rawSid = querySid;
|
|
302
318
|
if (!rawSid) {
|
|
303
|
-
const cookie_str =
|
|
319
|
+
const cookie_str = maybeClientReq.socket.handshake.headers?.cookie;
|
|
304
320
|
const cookie = parseCookieStr(cookie_str);
|
|
305
321
|
rawSid = cookie[sidKeyName];
|
|
306
322
|
}
|
|
307
323
|
return this.validateSid(rawSid);
|
|
308
|
-
} else
|
|
309
|
-
const [tokenType, base64Token] =
|
|
324
|
+
} else {
|
|
325
|
+
const [tokenType, base64Token] =
|
|
326
|
+
maybeClientReq.httpReq.headers.authorization?.split(" ") ?? [];
|
|
310
327
|
let bearerSid: string | undefined;
|
|
311
328
|
if (tokenType && base64Token) {
|
|
312
329
|
if (tokenType.trim() !== "Bearer") {
|
|
@@ -314,8 +331,8 @@ export class AuthHandler {
|
|
|
314
331
|
}
|
|
315
332
|
bearerSid = Buffer.from(base64Token, "base64").toString();
|
|
316
333
|
}
|
|
317
|
-
return this.validateSid(bearerSid ??
|
|
318
|
-
}
|
|
334
|
+
return this.validateSid(bearerSid ?? maybeClientReq.httpReq.cookies?.[sidKeyName]);
|
|
335
|
+
}
|
|
319
336
|
|
|
320
337
|
function parseCookieStr(cookie_str: string | undefined): any {
|
|
321
338
|
if (!cookie_str || typeof cookie_str !== "string") {
|
|
@@ -336,91 +353,16 @@ export class AuthHandler {
|
|
|
336
353
|
/**
|
|
337
354
|
* Used for logging
|
|
338
355
|
*/
|
|
339
|
-
getSIDNoError = (
|
|
340
|
-
if (!
|
|
356
|
+
getSIDNoError = (clientReq: AuthClientRequest | undefined): string | undefined => {
|
|
357
|
+
if (!clientReq) return undefined;
|
|
341
358
|
try {
|
|
342
|
-
return this.getSID(
|
|
359
|
+
return this.getSID(clientReq);
|
|
343
360
|
} catch {
|
|
344
361
|
return undefined;
|
|
345
362
|
}
|
|
346
363
|
};
|
|
347
364
|
|
|
348
|
-
|
|
349
|
-
* For a given sid return the user data if available
|
|
350
|
-
*/
|
|
351
|
-
async getClientInfo(
|
|
352
|
-
localParams: Pick<LocalParams, "socket" | "httpReq">
|
|
353
|
-
): Promise<AuthResult<any>> {
|
|
354
|
-
/**
|
|
355
|
-
* Get cached session if available
|
|
356
|
-
*/
|
|
357
|
-
const getSession = this.opts.cacheSession?.getSession;
|
|
358
|
-
const isSocket = "socket" in localParams;
|
|
359
|
-
if (isSocket && getSession && localParams.socket?.__prglCache) {
|
|
360
|
-
const { session, user, clientUser } = localParams.socket.__prglCache;
|
|
361
|
-
const isValid = this.isNonExpiredSocketSession(localParams.socket, session);
|
|
362
|
-
if (isValid) {
|
|
363
|
-
return {
|
|
364
|
-
sid: session.sid,
|
|
365
|
-
user,
|
|
366
|
-
clientUser,
|
|
367
|
-
};
|
|
368
|
-
} else
|
|
369
|
-
return {
|
|
370
|
-
sid: session.sid,
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Get sid from request and fetch user data
|
|
376
|
-
*/
|
|
377
|
-
const authStart = Date.now();
|
|
378
|
-
const clientInfo = await this.throttledFunc(async () => {
|
|
379
|
-
const { getUser } = this.opts;
|
|
380
|
-
|
|
381
|
-
if (localParams.httpReq || localParams.socket) {
|
|
382
|
-
const sid = this.getSID(localParams);
|
|
383
|
-
const clientReq =
|
|
384
|
-
localParams.httpReq ? { httpReq: localParams.httpReq } : { socket: localParams.socket! };
|
|
385
|
-
let user, clientUser;
|
|
386
|
-
if (sid) {
|
|
387
|
-
const clientInfo = await getUser(
|
|
388
|
-
sid,
|
|
389
|
-
this.dbo as any,
|
|
390
|
-
this.db,
|
|
391
|
-
getClientRequestIPsInfo(clientReq)
|
|
392
|
-
);
|
|
393
|
-
if (typeof clientInfo === "string") throw clientInfo;
|
|
394
|
-
user = clientInfo?.user;
|
|
395
|
-
clientUser = clientInfo?.clientUser;
|
|
396
|
-
}
|
|
397
|
-
if (getSession && isSocket) {
|
|
398
|
-
const session = await getSession(sid, this.dbo as any, this.db);
|
|
399
|
-
if (session && session.expires && user && clientUser && localParams.socket) {
|
|
400
|
-
localParams.socket.__prglCache = {
|
|
401
|
-
session,
|
|
402
|
-
user,
|
|
403
|
-
clientUser,
|
|
404
|
-
};
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
if (sid) {
|
|
408
|
-
return { sid, user, clientUser };
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
return {};
|
|
413
|
-
}, 5);
|
|
414
|
-
|
|
415
|
-
await this.prostgles.opts.onLog?.({
|
|
416
|
-
type: "auth",
|
|
417
|
-
command: "getClientInfo",
|
|
418
|
-
duration: Date.now() - authStart,
|
|
419
|
-
sid: clientInfo.sid,
|
|
420
|
-
socketId: localParams.socket?.id,
|
|
421
|
-
});
|
|
422
|
-
return clientInfo;
|
|
423
|
-
}
|
|
365
|
+
getUserFromRequest = getUserFromRequest.bind(this);
|
|
424
366
|
|
|
425
367
|
isNonExpiredSocketSession = (
|
|
426
368
|
socket: PRGLIOSocket,
|
|
@@ -442,8 +384,8 @@ export class AuthHandler {
|
|
|
442
384
|
};
|
|
443
385
|
|
|
444
386
|
getClientAuth = async (
|
|
445
|
-
clientReq:
|
|
446
|
-
): Promise<{ auth: AuthSocketSchema; userData:
|
|
387
|
+
clientReq: AuthClientRequest
|
|
388
|
+
): Promise<{ auth: AuthSocketSchema; userData: AuthResultOrError }> => {
|
|
447
389
|
let pathGuard = false;
|
|
448
390
|
if (this.opts.expressConfig?.publicRoutes && !this.opts.expressConfig.disableSocketAuthGuard) {
|
|
449
391
|
pathGuard = true;
|
|
@@ -473,7 +415,7 @@ export class AuthHandler {
|
|
|
473
415
|
pathname &&
|
|
474
416
|
typeof pathname === "string" &&
|
|
475
417
|
this.isUserRoute(pathname) &&
|
|
476
|
-
!(await this.
|
|
418
|
+
!(await this.getUserFromRequest({ socket }))?.user
|
|
477
419
|
) {
|
|
478
420
|
cb(null, { shouldReload: true });
|
|
479
421
|
} else {
|
|
@@ -488,7 +430,7 @@ export class AuthHandler {
|
|
|
488
430
|
}
|
|
489
431
|
}
|
|
490
432
|
|
|
491
|
-
const userData = await this.
|
|
433
|
+
const userData = await this.getUserFromRequest(clientReq);
|
|
492
434
|
const { email } = this.opts.expressConfig?.registrations ?? {};
|
|
493
435
|
const auth: AuthSocketSchema = {
|
|
494
436
|
providers: getProviders.bind(this)(),
|
package/lib/Auth/AuthTypes.ts
CHANGED
|
@@ -46,9 +46,10 @@ export type BasicSession = {
|
|
|
46
46
|
/** On expired */
|
|
47
47
|
onExpiration: "redirect" | "show_error";
|
|
48
48
|
};
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
49
|
+
|
|
50
|
+
type SocketClientRequest = { socket: PRGLIOSocket; httpReq?: undefined };
|
|
51
|
+
type HttpClientRequest = { httpReq: ExpressReq; res: ExpressRes; socket?: undefined };
|
|
52
|
+
export type AuthClientRequest = SocketClientRequest | HttpClientRequest;
|
|
52
53
|
|
|
53
54
|
type ThirdPartyProviders = {
|
|
54
55
|
facebook?: Pick<FacebookStrategy, "clientID" | "clientSecret"> & {
|
|
@@ -239,20 +240,30 @@ export type SessionUser<
|
|
|
239
240
|
clientUser: ClientUser;
|
|
240
241
|
};
|
|
241
242
|
|
|
242
|
-
export type
|
|
243
|
-
| AuthFailure["code"]
|
|
243
|
+
export type AuthResultWithSID<SU = SessionUser> =
|
|
244
244
|
| (SU & { sid: string })
|
|
245
245
|
| {
|
|
246
|
+
sid?: string | undefined;
|
|
246
247
|
user?: undefined;
|
|
248
|
+
sessionFields?: undefined;
|
|
249
|
+
clientUser?: undefined;
|
|
250
|
+
}
|
|
251
|
+
| undefined;
|
|
252
|
+
|
|
253
|
+
export type AuthResult<SU = SessionUser> =
|
|
254
|
+
| SU
|
|
255
|
+
| {
|
|
256
|
+
user?: undefined;
|
|
257
|
+
sessionFields?: undefined;
|
|
247
258
|
clientUser?: undefined;
|
|
248
|
-
sid?: string | undefined;
|
|
249
259
|
}
|
|
250
260
|
| undefined;
|
|
261
|
+
export type AuthResultOrError<SU = SessionUser> = AuthFailure["code"] | AuthResult<SU>;
|
|
251
262
|
|
|
252
263
|
export type AuthRequestParams<S, SUser extends SessionUser> = {
|
|
253
264
|
db: DB;
|
|
254
265
|
dbo: DBOFullyTyped<S>;
|
|
255
|
-
getUser: () => Promise<
|
|
266
|
+
getUser: () => Promise<AuthResultOrError<SUser>>;
|
|
256
267
|
};
|
|
257
268
|
|
|
258
269
|
export type Auth<S = void, SUser extends SessionUser = SessionUser> = {
|
|
@@ -270,7 +281,7 @@ export type Auth<S = void, SUser extends SessionUser = SessionUser> = {
|
|
|
270
281
|
dbo: DBOFullyTyped<S>,
|
|
271
282
|
db: DB,
|
|
272
283
|
client: AuthClientRequest & LoginClientInfo
|
|
273
|
-
) => Awaitable<
|
|
284
|
+
) => Awaitable<AuthResultOrError<SUser>>;
|
|
274
285
|
|
|
275
286
|
/**
|
|
276
287
|
* Will setup auth routes
|
|
@@ -56,7 +56,7 @@ export function setOAuthProviders(
|
|
|
56
56
|
|
|
57
57
|
app.get(callbackPath, async (req, res) => {
|
|
58
58
|
try {
|
|
59
|
-
const clientInfo = getClientRequestIPsInfo({ httpReq: req });
|
|
59
|
+
const clientInfo = getClientRequestIPsInfo({ httpReq: req, res });
|
|
60
60
|
const db = this.db;
|
|
61
61
|
const dbo = this.dbo as any;
|
|
62
62
|
const args = { provider: providerName, req, res, clientInfo, db, dbo };
|
|
@@ -23,7 +23,7 @@ export const getConfirmEmailRequestHandler = (
|
|
|
23
23
|
if (!id || typeof id !== "string") {
|
|
24
24
|
return res.send({ success: false, code: "something-went-wrong", message: "Invalid code" });
|
|
25
25
|
}
|
|
26
|
-
const { httpReq, ...clientInfo } = getClientRequestIPsInfo({ httpReq: req });
|
|
26
|
+
const { httpReq, ...clientInfo } = getClientRequestIPsInfo({ httpReq: req, res });
|
|
27
27
|
await emailAuthConfig.onEmailConfirmation({
|
|
28
28
|
confirmationCode: id,
|
|
29
29
|
clientInfo,
|
|
@@ -40,7 +40,7 @@ export const getRegisterRequestHandler = ({
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
try {
|
|
43
|
-
const { httpReq, ...clientInfo } = getClientRequestIPsInfo({ httpReq: req });
|
|
43
|
+
const { httpReq, ...clientInfo } = getClientRequestIPsInfo({ httpReq: req, res });
|
|
44
44
|
const { smtp } = emailAuthConfig;
|
|
45
45
|
const errCodeOrResult =
|
|
46
46
|
emailAuthConfig.signupType === "withPassword" ?
|
|
@@ -2,7 +2,7 @@ import { RequestHandler, Response } from "express";
|
|
|
2
2
|
import { AuthResponse } from "prostgles-types";
|
|
3
3
|
import { DBOFullyTyped } from "../DBSchemaBuilder";
|
|
4
4
|
import { AUTH_ROUTES_AND_PARAMS, AuthHandler, HTTP_FAIL_CODES } from "./AuthHandler";
|
|
5
|
-
import { AuthClientRequest, ExpressReq, ExpressRes, LoginParams } from "./AuthTypes";
|
|
5
|
+
import { Auth, AuthClientRequest, ExpressReq, ExpressRes, LoginParams } from "./AuthTypes";
|
|
6
6
|
import { setAuthProviders, upsertNamedExpressMiddleware } from "./setAuthProviders";
|
|
7
7
|
import { getClientRequestIPsInfo } from "./utils/getClientRequestIPsInfo";
|
|
8
8
|
import { getReturnUrl } from "./utils/getReturnUrl";
|
|
@@ -33,7 +33,7 @@ export async function setupAuthRoutes(this: AuthHandler) {
|
|
|
33
33
|
req,
|
|
34
34
|
res,
|
|
35
35
|
next,
|
|
36
|
-
getUser: () => this.
|
|
36
|
+
getUser: () => this.getUserAndHandleError({ httpReq: req, res }),
|
|
37
37
|
dbo: this.dbo as DBOFullyTyped,
|
|
38
38
|
db: this.db,
|
|
39
39
|
});
|
|
@@ -61,7 +61,7 @@ export async function setupAuthRoutes(this: AuthHandler) {
|
|
|
61
61
|
id,
|
|
62
62
|
this.dbo as any,
|
|
63
63
|
this.db,
|
|
64
|
-
getClientRequestIPsInfo({ httpReq: req })
|
|
64
|
+
getClientRequestIPsInfo({ httpReq: req, res })
|
|
65
65
|
);
|
|
66
66
|
});
|
|
67
67
|
if (!response.session) {
|
|
@@ -108,8 +108,15 @@ export async function setupAuthRoutes(this: AuthHandler) {
|
|
|
108
108
|
|
|
109
109
|
/* Redirect if not logged in and requesting non public content */
|
|
110
110
|
app.get(AUTH_ROUTES_AND_PARAMS.catchAll, async (req: ExpressReq, res: ExpressRes, next) => {
|
|
111
|
-
const clientReq: AuthClientRequest = { httpReq: req };
|
|
112
|
-
const getUser =
|
|
111
|
+
const clientReq: AuthClientRequest = { httpReq: req, res };
|
|
112
|
+
const getUser = async () => {
|
|
113
|
+
const userOrCode = await this.getUserAndHandleError(clientReq);
|
|
114
|
+
if (typeof userOrCode === "string") {
|
|
115
|
+
res.status(HTTP_FAIL_CODES.BAD_REQUEST).json({ success: false, code: userOrCode });
|
|
116
|
+
throw userOrCode;
|
|
117
|
+
}
|
|
118
|
+
return userOrCode;
|
|
119
|
+
};
|
|
113
120
|
if (this.prostgles.restApi) {
|
|
114
121
|
if (
|
|
115
122
|
Object.values(this.prostgles.restApi.routes).some((restRoute) =>
|
|
@@ -137,7 +144,7 @@ export async function setupAuthRoutes(this: AuthHandler) {
|
|
|
137
144
|
*/
|
|
138
145
|
if (this.isUserRoute(req.path)) {
|
|
139
146
|
/* Check auth. Redirect to login if unauthorized */
|
|
140
|
-
const u = await getUser(
|
|
147
|
+
const u = await getUser();
|
|
141
148
|
if (!u) {
|
|
142
149
|
res.redirect(
|
|
143
150
|
`${AUTH_ROUTES_AND_PARAMS.login}?returnURL=${encodeURIComponent(req.originalUrl)}`
|
|
@@ -146,21 +153,18 @@ export async function setupAuthRoutes(this: AuthHandler) {
|
|
|
146
153
|
}
|
|
147
154
|
|
|
148
155
|
/* If authorized and going to returnUrl then redirect. Otherwise serve file */
|
|
149
|
-
} else if (returnURL && (await getUser(
|
|
156
|
+
} else if (returnURL && (await getUser())) {
|
|
150
157
|
res.redirect(returnURL);
|
|
151
158
|
return;
|
|
152
159
|
|
|
153
160
|
/** If Logged in and requesting login then redirect to main page */
|
|
154
|
-
} else if (
|
|
155
|
-
this.matchesRoute(AUTH_ROUTES_AND_PARAMS.login, req.path) &&
|
|
156
|
-
(await getUser(clientReq))
|
|
157
|
-
) {
|
|
161
|
+
} else if (this.matchesRoute(AUTH_ROUTES_AND_PARAMS.login, req.path) && (await getUser())) {
|
|
158
162
|
res.redirect("/");
|
|
159
163
|
return;
|
|
160
164
|
}
|
|
161
165
|
|
|
162
166
|
onGetRequestOK?.(req, res, {
|
|
163
|
-
getUser
|
|
167
|
+
getUser,
|
|
164
168
|
dbo: this.dbo as DBOFullyTyped,
|
|
165
169
|
db: this.db,
|
|
166
170
|
});
|
|
@@ -170,7 +174,7 @@ export async function setupAuthRoutes(this: AuthHandler) {
|
|
|
170
174
|
typeof error === "string" ? error
|
|
171
175
|
: error instanceof Error ? error.message
|
|
172
176
|
: "";
|
|
173
|
-
res.status(HTTP_FAIL_CODES.
|
|
177
|
+
res.status(HTTP_FAIL_CODES.BAD_REQUEST).json({
|
|
174
178
|
error:
|
|
175
179
|
"Something went wrong when processing your request" +
|
|
176
180
|
(errorMessage ? ": " + errorMessage : ""),
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { AuthHandler, getClientRequestIPsInfo } from "../AuthHandler";
|
|
2
|
+
import { AuthClientRequest, AuthResultWithSID } from "../AuthTypes";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* For a given sid return the user data if available
|
|
6
|
+
*/
|
|
7
|
+
export async function getUserFromRequest(
|
|
8
|
+
this: AuthHandler,
|
|
9
|
+
maybeClientReq: AuthClientRequest | undefined
|
|
10
|
+
): Promise<AuthResultWithSID> {
|
|
11
|
+
if (!maybeClientReq) return undefined;
|
|
12
|
+
/**
|
|
13
|
+
* Get cached session if available
|
|
14
|
+
*/
|
|
15
|
+
const getSession = this.opts.cacheSession?.getSession;
|
|
16
|
+
if (maybeClientReq.socket && getSession && maybeClientReq.socket.__prglCache) {
|
|
17
|
+
const { session, user, clientUser } = maybeClientReq.socket.__prglCache;
|
|
18
|
+
const isValid = this.isNonExpiredSocketSession(maybeClientReq.socket, session);
|
|
19
|
+
if (isValid) {
|
|
20
|
+
return {
|
|
21
|
+
sid: session.sid,
|
|
22
|
+
user,
|
|
23
|
+
clientUser,
|
|
24
|
+
};
|
|
25
|
+
} else
|
|
26
|
+
return {
|
|
27
|
+
sid: session.sid,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get sid from request and fetch user data
|
|
33
|
+
*/
|
|
34
|
+
const authStart = Date.now();
|
|
35
|
+
const result = await this.throttledFunc(async () => {
|
|
36
|
+
const { getUser } = this.opts;
|
|
37
|
+
|
|
38
|
+
const sid = this.getSID(maybeClientReq);
|
|
39
|
+
const clientInfoOrErr =
|
|
40
|
+
!sid ? undefined : (
|
|
41
|
+
await getUser(sid, this.dbo as any, this.db, getClientRequestIPsInfo(maybeClientReq))
|
|
42
|
+
);
|
|
43
|
+
if (typeof clientInfoOrErr === "string") throw clientInfoOrErr;
|
|
44
|
+
const clientInfo = clientInfoOrErr;
|
|
45
|
+
if (getSession && maybeClientReq.socket) {
|
|
46
|
+
const session = await getSession(sid, this.dbo as any, this.db);
|
|
47
|
+
if (session && session.expires && clientInfo?.user) {
|
|
48
|
+
maybeClientReq.socket.__prglCache = {
|
|
49
|
+
session,
|
|
50
|
+
user: clientInfo.user,
|
|
51
|
+
clientUser: clientInfo.clientUser,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (clientInfo?.user && sid) {
|
|
57
|
+
return { sid, ...clientInfo };
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return { sid };
|
|
61
|
+
}, 5);
|
|
62
|
+
|
|
63
|
+
await this.prostgles.opts.onLog?.({
|
|
64
|
+
type: "auth",
|
|
65
|
+
command: "getClientInfo",
|
|
66
|
+
duration: Date.now() - authStart,
|
|
67
|
+
sid: result.sid,
|
|
68
|
+
socketId: maybeClientReq.socket?.id,
|
|
69
|
+
});
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
@@ -188,7 +188,7 @@ export class DboBuilder {
|
|
|
188
188
|
query: string,
|
|
189
189
|
params: any,
|
|
190
190
|
options: SQLOptions | undefined,
|
|
191
|
-
localParams
|
|
191
|
+
localParams: LocalParams | undefined
|
|
192
192
|
) => {
|
|
193
193
|
return runSQL
|
|
194
194
|
.bind(this)(query, params, options, localParams)
|
|
@@ -325,8 +325,12 @@ export class DboBuilder {
|
|
|
325
325
|
const handlerClass = tov.is_view ? ViewHandler : TableHandler;
|
|
326
326
|
dbTX[tov.name] = new handlerClass(this.db, tov, this, { t, dbTX }, this.shortestJoinPaths);
|
|
327
327
|
});
|
|
328
|
-
dbTX.sql = (q, args, opts,
|
|
329
|
-
|
|
328
|
+
dbTX.sql = (q, args, opts, localParams) => {
|
|
329
|
+
if (localParams?.tx) {
|
|
330
|
+
throw "Cannot run transaction within transaction";
|
|
331
|
+
}
|
|
332
|
+
return this.runSQL(q, args, opts, { ...localParams, tx: { dbTX, t } });
|
|
333
|
+
};
|
|
330
334
|
|
|
331
335
|
return cb(dbTX, t);
|
|
332
336
|
});
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
TableInfo as TInfo,
|
|
16
16
|
UserLike,
|
|
17
17
|
} from "prostgles-types";
|
|
18
|
-
import {
|
|
18
|
+
import { AuthClientRequest, BasicSession } from "../Auth/AuthTypes";
|
|
19
19
|
import { BasicCallback } from "../PubSubManager/PubSubManager";
|
|
20
20
|
import { PublishAllOrNothing } from "../PublishParser/PublishParser";
|
|
21
21
|
import { FieldSpec } from "./QueryBuilder/Functions";
|
|
@@ -105,21 +105,15 @@ export type DbTxTableHandlers = {
|
|
|
105
105
|
[key: string]: Omit<Partial<TableHandler>, "dbTx"> | Omit<TableHandler, "dbTx">;
|
|
106
106
|
};
|
|
107
107
|
|
|
108
|
+
type SQLHandlerServer = SQLHandler<LocalParams>;
|
|
109
|
+
|
|
108
110
|
export type DBHandlerServerExtra<TH = TableHandlers, WithTransactions = true> = {
|
|
109
|
-
sql:
|
|
111
|
+
sql: SQLHandlerServer;
|
|
110
112
|
} & (WithTransactions extends true ? { tx: TX<TH> } : Record<string, never>);
|
|
111
113
|
|
|
112
|
-
// export type DBHandlerServer<TH = TableHandlers> =
|
|
113
|
-
// TH &
|
|
114
|
-
// Partial<DbJoinMaker> & {
|
|
115
|
-
// sql?: SQLHandler
|
|
116
|
-
// } & {
|
|
117
|
-
// tx?: TX<TH>
|
|
118
|
-
// }
|
|
119
|
-
|
|
120
114
|
export type DBHandlerServer<TH = TableHandlers> = TH &
|
|
121
115
|
Partial<DbJoinMaker> & {
|
|
122
|
-
sql?:
|
|
116
|
+
sql?: SQLHandlerServer;
|
|
123
117
|
} & {
|
|
124
118
|
tx?: TX<TH>;
|
|
125
119
|
};
|
|
@@ -187,16 +181,15 @@ export type PRGLIOSocket = {
|
|
|
187
181
|
};
|
|
188
182
|
|
|
189
183
|
export type LocalParams = {
|
|
190
|
-
httpReq?: ExpressReq;
|
|
191
|
-
socket?: PRGLIOSocket;
|
|
192
|
-
|
|
184
|
+
// httpReq?: ExpressReq;
|
|
185
|
+
// socket?: PRGLIOSocket;
|
|
186
|
+
clientReq?: AuthClientRequest | undefined;
|
|
193
187
|
isRemoteRequest?: {
|
|
194
188
|
user?: UserLike | undefined;
|
|
195
189
|
};
|
|
190
|
+
func?: () => any;
|
|
196
191
|
testRule?: boolean;
|
|
197
192
|
tableAlias?: string;
|
|
198
|
-
// subOne?: boolean;
|
|
199
|
-
|
|
200
193
|
tx?: {
|
|
201
194
|
dbTX: TableHandlers;
|
|
202
195
|
t: pgPromise.ITask<{}>;
|
|
@@ -207,9 +200,18 @@ export type LocalParams = {
|
|
|
207
200
|
|
|
208
201
|
returnQuery?: boolean | "noRLS" | "where-condition";
|
|
209
202
|
returnNewQuery?: boolean;
|
|
210
|
-
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Used for count/size queries
|
|
206
|
+
* */
|
|
211
207
|
bypassLimit?: boolean;
|
|
212
208
|
|
|
209
|
+
/**
|
|
210
|
+
* Used to allow inserting linked data.
|
|
211
|
+
* For example, if we have users( id, name ) and user_emails( id, user_id, email )
|
|
212
|
+
* and we want to insert a user and an email in a single transaction we can just:
|
|
213
|
+
* db.users.insert({ name: "John", emails: [{ email: "john@abc.com" }] })
|
|
214
|
+
*/
|
|
213
215
|
nestedInsert?: {
|
|
214
216
|
depth: number;
|
|
215
217
|
previousData: AnyObject;
|
|
@@ -173,12 +173,12 @@ export async function getNewQuery(
|
|
|
173
173
|
}
|
|
174
174
|
|
|
175
175
|
let isLocal = true;
|
|
176
|
-
if (localParams &&
|
|
176
|
+
if (localParams && localParams.clientReq) {
|
|
177
177
|
isLocal = false;
|
|
178
178
|
j_tableRules = await _this.dboBuilder.publishParser?.getValidatedRequestRuleWusr({
|
|
179
179
|
tableName: jTable,
|
|
180
180
|
command: "find",
|
|
181
|
-
localParams,
|
|
181
|
+
clientReq: localParams.clientReq,
|
|
182
182
|
});
|
|
183
183
|
}
|
|
184
184
|
|
|
@@ -112,7 +112,7 @@ export class QueryStreamer {
|
|
|
112
112
|
|
|
113
113
|
const errorWithoutQuery = getSerializedClientErrorFromPGError(rawError, {
|
|
114
114
|
type: "sql",
|
|
115
|
-
localParams: { socket },
|
|
115
|
+
localParams: { clientReq: { socket } },
|
|
116
116
|
});
|
|
117
117
|
// For some reason query is not present on the error object from sql stream mode
|
|
118
118
|
const error = { ...errorWithoutQuery, query: query.query };
|
|
@@ -146,8 +146,8 @@ export class TableHandler extends ViewHandler {
|
|
|
146
146
|
}
|
|
147
147
|
|
|
148
148
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
149
|
-
if (!localParams) throw "Sync not allowed within the server code";
|
|
150
|
-
const { socket } = localParams;
|
|
149
|
+
if (!localParams.clientReq) throw "Sync not allowed within the server code";
|
|
150
|
+
const { socket } = localParams.clientReq;
|
|
151
151
|
if (!socket) throw "socket missing";
|
|
152
152
|
|
|
153
153
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
@@ -212,7 +212,6 @@ export class TableHandler extends ViewHandler {
|
|
|
212
212
|
condition,
|
|
213
213
|
id_fields,
|
|
214
214
|
synced_field,
|
|
215
|
-
// allow_delete,
|
|
216
215
|
socket,
|
|
217
216
|
table_rules,
|
|
218
217
|
filter: { ...filter },
|
|
@@ -23,8 +23,8 @@ export async function insert(
|
|
|
23
23
|
const ACTION = "insert";
|
|
24
24
|
const start = Date.now();
|
|
25
25
|
try {
|
|
26
|
-
const { removeDisallowedFields = false } = insertParams
|
|
27
|
-
const { returnQuery = false, nestedInsert } = localParams
|
|
26
|
+
const { removeDisallowedFields = false } = insertParams ?? {};
|
|
27
|
+
const { returnQuery = false, nestedInsert } = localParams ?? {};
|
|
28
28
|
|
|
29
29
|
const finalDBtx = this.getFinalDBtx(localParams);
|
|
30
30
|
const rule = tableRules?.[ACTION];
|
|
@@ -115,7 +115,7 @@ export async function update(
|
|
|
115
115
|
throw `nestedInsert Tablehandler not found for ${nestedInsert.tableName}`;
|
|
116
116
|
const refTableRules =
|
|
117
117
|
!localParams ? undefined : (
|
|
118
|
-
await getInsertTableRules(this, nestedInsert.tableName, localParams)
|
|
118
|
+
await getInsertTableRules(this, nestedInsert.tableName, localParams.clientReq)
|
|
119
119
|
);
|
|
120
120
|
const nestedLocalParams: LocalParams = {
|
|
121
121
|
...localParams,
|