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.
Files changed (143) hide show
  1. package/dist/Auth/AuthHandler.d.ts +8 -13
  2. package/dist/Auth/AuthHandler.d.ts.map +1 -1
  3. package/dist/Auth/AuthHandler.js +34 -89
  4. package/dist/Auth/AuthHandler.js.map +1 -1
  5. package/dist/Auth/AuthTypes.d.ts +16 -6
  6. package/dist/Auth/AuthTypes.d.ts.map +1 -1
  7. package/dist/Auth/authProviders/setOAuthProviders.js +1 -1
  8. package/dist/Auth/authProviders/setOAuthProviders.js.map +1 -1
  9. package/dist/Auth/endpoints/getConfirmEmailRequestHandler.js +1 -1
  10. package/dist/Auth/endpoints/getConfirmEmailRequestHandler.js.map +1 -1
  11. package/dist/Auth/endpoints/getRegisterRequestHandler.js +1 -1
  12. package/dist/Auth/endpoints/getRegisterRequestHandler.js.map +1 -1
  13. package/dist/Auth/setupAuthRoutes.d.ts.map +1 -1
  14. package/dist/Auth/setupAuthRoutes.js +16 -10
  15. package/dist/Auth/setupAuthRoutes.js.map +1 -1
  16. package/dist/Auth/utils/getUserFromRequest.d.ts +7 -0
  17. package/dist/Auth/utils/getUserFromRequest.d.ts.map +1 -0
  18. package/dist/Auth/utils/getUserFromRequest.js +66 -0
  19. package/dist/Auth/utils/getUserFromRequest.js.map +1 -0
  20. package/dist/DboBuilder/DboBuilder.d.ts +1 -1
  21. package/dist/DboBuilder/DboBuilder.d.ts.map +1 -1
  22. package/dist/DboBuilder/DboBuilder.js +6 -1
  23. package/dist/DboBuilder/DboBuilder.js.map +1 -1
  24. package/dist/DboBuilder/DboBuilderTypes.d.ts +15 -7
  25. package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
  26. package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
  27. package/dist/DboBuilder/QueryBuilder/getNewQuery.js +2 -2
  28. package/dist/DboBuilder/QueryBuilder/getNewQuery.js.map +1 -1
  29. package/dist/DboBuilder/QueryStreamer.js +1 -1
  30. package/dist/DboBuilder/QueryStreamer.js.map +1 -1
  31. package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
  32. package/dist/DboBuilder/TableHandler/TableHandler.js +2 -3
  33. package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
  34. package/dist/DboBuilder/TableHandler/insert.js +2 -2
  35. package/dist/DboBuilder/TableHandler/update.js +1 -1
  36. package/dist/DboBuilder/TableHandler/update.js.map +1 -1
  37. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +0 -4
  38. package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
  39. package/dist/DboBuilder/ViewHandler/ViewHandler.js +37 -24
  40. package/dist/DboBuilder/ViewHandler/ViewHandler.js.map +1 -1
  41. package/dist/DboBuilder/ViewHandler/find.js +1 -1
  42. package/dist/DboBuilder/ViewHandler/find.js.map +1 -1
  43. package/dist/DboBuilder/ViewHandler/getExistsCondition.js +4 -4
  44. package/dist/DboBuilder/ViewHandler/getExistsCondition.js.map +1 -1
  45. package/dist/DboBuilder/ViewHandler/subscribe.d.ts.map +1 -1
  46. package/dist/DboBuilder/ViewHandler/subscribe.js +9 -15
  47. package/dist/DboBuilder/ViewHandler/subscribe.js.map +1 -1
  48. package/dist/DboBuilder/dboBuilderUtils.d.ts.map +1 -1
  49. package/dist/DboBuilder/dboBuilderUtils.js +3 -1
  50. package/dist/DboBuilder/dboBuilderUtils.js.map +1 -1
  51. package/dist/DboBuilder/insertNestedRecords.d.ts +4 -3
  52. package/dist/DboBuilder/insertNestedRecords.d.ts.map +1 -1
  53. package/dist/DboBuilder/insertNestedRecords.js +12 -12
  54. package/dist/DboBuilder/insertNestedRecords.js.map +1 -1
  55. package/dist/DboBuilder/runSQL.d.ts +3 -2
  56. package/dist/DboBuilder/runSQL.d.ts.map +1 -1
  57. package/dist/DboBuilder/runSQL.js +12 -15
  58. package/dist/DboBuilder/runSQL.js.map +1 -1
  59. package/dist/FileManager/initFileManager.d.ts.map +1 -1
  60. package/dist/FileManager/initFileManager.js +5 -4
  61. package/dist/FileManager/initFileManager.js.map +1 -1
  62. package/dist/Prostgles.d.ts +3 -2
  63. package/dist/Prostgles.d.ts.map +1 -1
  64. package/dist/Prostgles.js +8 -16
  65. package/dist/Prostgles.js.map +1 -1
  66. package/dist/ProstglesTypes.d.ts +2 -2
  67. package/dist/ProstglesTypes.d.ts.map +1 -1
  68. package/dist/ProstglesTypes.js +1 -6
  69. package/dist/ProstglesTypes.js.map +1 -1
  70. package/dist/PubSubManager/PubSubManager.js +2 -2
  71. package/dist/PubSubManager/PubSubManager.js.map +1 -1
  72. package/dist/PubSubManager/addSync.d.ts.map +1 -1
  73. package/dist/PubSubManager/addSync.js +1 -3
  74. package/dist/PubSubManager/addSync.js.map +1 -1
  75. package/dist/PublishParser/PublishParser.d.ts +11 -18
  76. package/dist/PublishParser/PublishParser.d.ts.map +1 -1
  77. package/dist/PublishParser/PublishParser.js +28 -27
  78. package/dist/PublishParser/PublishParser.js.map +1 -1
  79. package/dist/PublishParser/getFileTableRules.d.ts +2 -3
  80. package/dist/PublishParser/getFileTableRules.d.ts.map +1 -1
  81. package/dist/PublishParser/getFileTableRules.js +18 -20
  82. package/dist/PublishParser/getFileTableRules.js.map +1 -1
  83. package/dist/PublishParser/getSchemaFromPublish.d.ts +2 -9
  84. package/dist/PublishParser/getSchemaFromPublish.d.ts.map +1 -1
  85. package/dist/PublishParser/getSchemaFromPublish.js +5 -5
  86. package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
  87. package/dist/PublishParser/getTableRulesWithoutFileTable.d.ts +1 -1
  88. package/dist/PublishParser/getTableRulesWithoutFileTable.d.ts.map +1 -1
  89. package/dist/PublishParser/getTableRulesWithoutFileTable.js +30 -33
  90. package/dist/PublishParser/getTableRulesWithoutFileTable.js.map +1 -1
  91. package/dist/PublishParser/publishTypesAndUtils.d.ts +6 -11
  92. package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
  93. package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
  94. package/dist/RestApi.d.ts +1 -1
  95. package/dist/RestApi.d.ts.map +1 -1
  96. package/dist/RestApi.js +19 -16
  97. package/dist/RestApi.js.map +1 -1
  98. package/dist/initProstgles.d.ts.map +1 -1
  99. package/dist/initProstgles.js +11 -15
  100. package/dist/initProstgles.js.map +1 -1
  101. package/dist/onSocketConnected.d.ts.map +1 -1
  102. package/dist/onSocketConnected.js +5 -5
  103. package/dist/onSocketConnected.js.map +1 -1
  104. package/dist/runClientRequest.d.ts +14 -29
  105. package/dist/runClientRequest.d.ts.map +1 -1
  106. package/dist/runClientRequest.js +20 -34
  107. package/dist/runClientRequest.js.map +1 -1
  108. package/lib/Auth/AuthHandler.ts +45 -103
  109. package/lib/Auth/AuthTypes.ts +19 -8
  110. package/lib/Auth/authProviders/setOAuthProviders.ts +1 -1
  111. package/lib/Auth/endpoints/getConfirmEmailRequestHandler.ts +1 -1
  112. package/lib/Auth/endpoints/getRegisterRequestHandler.ts +1 -1
  113. package/lib/Auth/setupAuthRoutes.ts +17 -13
  114. package/lib/Auth/utils/getUserFromRequest.ts +71 -0
  115. package/lib/DboBuilder/DboBuilder.ts +7 -3
  116. package/lib/DboBuilder/DboBuilderTypes.ts +19 -17
  117. package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +2 -2
  118. package/lib/DboBuilder/QueryStreamer.ts +1 -1
  119. package/lib/DboBuilder/TableHandler/TableHandler.ts +2 -3
  120. package/lib/DboBuilder/TableHandler/insert.ts +2 -2
  121. package/lib/DboBuilder/TableHandler/update.ts +1 -1
  122. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +38 -37
  123. package/lib/DboBuilder/ViewHandler/find.ts +1 -1
  124. package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +4 -4
  125. package/lib/DboBuilder/ViewHandler/subscribe.ts +22 -41
  126. package/lib/DboBuilder/dboBuilderUtils.ts +3 -1
  127. package/lib/DboBuilder/insertNestedRecords.ts +18 -16
  128. package/lib/DboBuilder/runSQL.ts +14 -16
  129. package/lib/FileManager/initFileManager.ts +16 -12
  130. package/lib/Prostgles.ts +10 -24
  131. package/lib/ProstglesTypes.ts +9 -31
  132. package/lib/PubSubManager/PubSubManager.ts +3 -3
  133. package/lib/PubSubManager/addSync.ts +1 -3
  134. package/lib/PublishParser/PublishParser.ts +35 -45
  135. package/lib/PublishParser/getFileTableRules.ts +24 -48
  136. package/lib/PublishParser/getSchemaFromPublish.ts +12 -23
  137. package/lib/PublishParser/getTableRulesWithoutFileTable.ts +30 -41
  138. package/lib/PublishParser/publishTypesAndUtils.ts +8 -21
  139. package/lib/RestApi.ts +43 -31
  140. package/lib/initProstgles.ts +51 -64
  141. package/lib/onSocketConnected.ts +12 -9
  142. package/lib/runClientRequest.ts +50 -66
  143. package/package.json +3 -3
@@ -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 { LocalParams, PRGLIOSocket } from "../DboBuilder/DboBuilder";
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
- getUser = async (clientReq: { httpReq: ExpressReq }): Promise<AuthResult> => {
145
- const sid = clientReq.httpReq.cookies?.[this.sidKeyName];
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
- return this.throttledFunc(async () => {
150
- return this.opts!.getUser(
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(clientReq)
165
+ getClientRequestIPsInfo(localParams)
155
166
  );
156
167
  }, 50);
157
- } catch (err) {
158
- console.error(err);
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(localParams: LocalParams | undefined): string | undefined {
296
- if (!localParams) return undefined;
311
+ getSID(maybeClientReq: AuthClientRequest | undefined): string | undefined {
312
+ if (!maybeClientReq) return undefined;
297
313
  const { sidKeyName } = this;
298
- if (localParams.socket) {
299
- const { handshake } = localParams.socket;
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 = localParams.socket.handshake.headers?.cookie;
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 if (localParams.httpReq) {
309
- const [tokenType, base64Token] = localParams.httpReq.headers.authorization?.split(" ") ?? [];
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 ?? localParams.httpReq.cookies?.[sidKeyName]);
318
- } else throw "socket OR httpReq missing from localParams";
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 = (localParams: LocalParams | undefined): string | undefined => {
340
- if (!localParams) return undefined;
356
+ getSIDNoError = (clientReq: AuthClientRequest | undefined): string | undefined => {
357
+ if (!clientReq) return undefined;
341
358
  try {
342
- return this.getSID(localParams);
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: Pick<LocalParams, "socket" | "httpReq">
446
- ): Promise<{ auth: AuthSocketSchema; userData: AuthResult }> => {
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.getClientInfo({ socket }))?.user
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.getClientInfo(clientReq);
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)(),
@@ -46,9 +46,10 @@ export type BasicSession = {
46
46
  /** On expired */
47
47
  onExpiration: "redirect" | "show_error";
48
48
  };
49
- export type AuthClientRequest =
50
- | { socket: PRGLIOSocket; httpReq?: undefined }
51
- | { httpReq: ExpressReq; socket?: undefined };
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 AuthResult<SU = SessionUser> =
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<AuthResult<SUser>>;
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<AuthResult<SUser>>;
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.getUser({ httpReq: req }) as any,
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 = this.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(clientReq);
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(clientReq))) {
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: () => getUser(clientReq),
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.UNAUTHORIZED).json({
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?: 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, localP) =>
329
- this.runSQL(q, args, opts, { tx: { dbTX, t }, ...(localP ?? {}) });
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 { BasicSession, ExpressReq } from "../Auth/AuthTypes";
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: SQLHandler;
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?: SQLHandler;
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
- func?: () => any;
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
- /** Used for count/size queries */
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 && (localParams.socket || localParams.httpReq)) {
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,