prostgles-server 4.2.192 → 4.2.194

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 +46 -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,21 @@
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,
18
+ AuthResultWithSID,
15
19
  BasicSession,
16
20
  ExpressReq,
17
21
  ExpressRes,
@@ -23,6 +27,7 @@ import { getProviders } from "./setAuthProviders";
23
27
  import { setupAuthRoutes } from "./setupAuthRoutes";
24
28
  import { getClientRequestIPsInfo } from "./utils/getClientRequestIPsInfo";
25
29
  import { getReturnUrl } from "./utils/getReturnUrl";
30
+ import { getUserFromRequest } from "./utils/getUserFromRequest";
26
31
 
27
32
  export { getClientRequestIPsInfo };
28
33
  export const HTTP_FAIL_CODES = {
@@ -141,23 +146,35 @@ export class AuthHandler {
141
146
  }
142
147
  };
143
148
 
144
- getUser = async (clientReq: { httpReq: ExpressReq }): Promise<AuthResult> => {
145
- const sid = clientReq.httpReq.cookies?.[this.sidKeyName];
149
+ getUserAndHandleError = async (localParams: AuthClientRequest): Promise<AuthResultWithSID> => {
150
+ const sid = this.getSID(localParams);
146
151
  if (!sid) return undefined;
147
-
152
+ const handlerError = (code: AuthFailure["code"]) => {
153
+ if (localParams.httpReq) {
154
+ localParams.res
155
+ .status(HTTP_FAIL_CODES.BAD_REQUEST)
156
+ .json({ success: false, code, error: code });
157
+ }
158
+ throw code;
159
+ };
148
160
  try {
149
- return this.throttledFunc(async () => {
150
- return this.opts!.getUser(
161
+ const userOrErrorCode = await this.throttledFunc(async () => {
162
+ return this.opts.getUser(
151
163
  this.validateSid(sid),
152
164
  this.dbo as any,
153
165
  this.db,
154
- getClientRequestIPsInfo(clientReq)
166
+ getClientRequestIPsInfo(localParams)
155
167
  );
156
168
  }, 50);
157
- } catch (err) {
158
- console.error(err);
169
+
170
+ if (typeof userOrErrorCode === "string") {
171
+ return handlerError(userOrErrorCode);
172
+ }
173
+
174
+ return { sid, ...userOrErrorCode };
175
+ } catch (_err) {
176
+ return handlerError("server-error");
159
177
  }
160
- return undefined;
161
178
  };
162
179
 
163
180
  init = setupAuthRoutes.bind(this);
@@ -265,7 +282,7 @@ export class AuthHandler {
265
282
  const start = Date.now();
266
283
  const errCodeOrSession = await this.loginThrottledAndValidate(
267
284
  loginParams,
268
- getClientRequestIPsInfo({ httpReq: req })
285
+ getClientRequestIPsInfo({ httpReq: req, res })
269
286
  );
270
287
  const loginResponse =
271
288
  typeof errCodeOrSession === "string" ?
@@ -292,21 +309,22 @@ export class AuthHandler {
292
309
  * query params
293
310
  * Based on sid names in auth
294
311
  */
295
- getSID(localParams: LocalParams | undefined): string | undefined {
296
- if (!localParams) return undefined;
312
+ getSID(maybeClientReq: AuthClientRequest | undefined): string | undefined {
313
+ if (!maybeClientReq) return undefined;
297
314
  const { sidKeyName } = this;
298
- if (localParams.socket) {
299
- const { handshake } = localParams.socket;
315
+ if (maybeClientReq.socket) {
316
+ const { handshake } = maybeClientReq.socket;
300
317
  const querySid = handshake.auth?.[sidKeyName] || handshake.query?.[sidKeyName];
301
318
  let rawSid = querySid;
302
319
  if (!rawSid) {
303
- const cookie_str = localParams.socket.handshake.headers?.cookie;
320
+ const cookie_str = maybeClientReq.socket.handshake.headers?.cookie;
304
321
  const cookie = parseCookieStr(cookie_str);
305
322
  rawSid = cookie[sidKeyName];
306
323
  }
307
324
  return this.validateSid(rawSid);
308
- } else if (localParams.httpReq) {
309
- const [tokenType, base64Token] = localParams.httpReq.headers.authorization?.split(" ") ?? [];
325
+ } else {
326
+ const [tokenType, base64Token] =
327
+ maybeClientReq.httpReq.headers.authorization?.split(" ") ?? [];
310
328
  let bearerSid: string | undefined;
311
329
  if (tokenType && base64Token) {
312
330
  if (tokenType.trim() !== "Bearer") {
@@ -314,8 +332,8 @@ export class AuthHandler {
314
332
  }
315
333
  bearerSid = Buffer.from(base64Token, "base64").toString();
316
334
  }
317
- return this.validateSid(bearerSid ?? localParams.httpReq.cookies?.[sidKeyName]);
318
- } else throw "socket OR httpReq missing from localParams";
335
+ return this.validateSid(bearerSid ?? maybeClientReq.httpReq.cookies?.[sidKeyName]);
336
+ }
319
337
 
320
338
  function parseCookieStr(cookie_str: string | undefined): any {
321
339
  if (!cookie_str || typeof cookie_str !== "string") {
@@ -336,91 +354,16 @@ export class AuthHandler {
336
354
  /**
337
355
  * Used for logging
338
356
  */
339
- getSIDNoError = (localParams: LocalParams | undefined): string | undefined => {
340
- if (!localParams) return undefined;
357
+ getSIDNoError = (clientReq: AuthClientRequest | undefined): string | undefined => {
358
+ if (!clientReq) return undefined;
341
359
  try {
342
- return this.getSID(localParams);
360
+ return this.getSID(clientReq);
343
361
  } catch {
344
362
  return undefined;
345
363
  }
346
364
  };
347
365
 
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
- }
366
+ getUserFromRequest = getUserFromRequest.bind(this);
424
367
 
425
368
  isNonExpiredSocketSession = (
426
369
  socket: PRGLIOSocket,
@@ -442,8 +385,8 @@ export class AuthHandler {
442
385
  };
443
386
 
444
387
  getClientAuth = async (
445
- clientReq: Pick<LocalParams, "socket" | "httpReq">
446
- ): Promise<{ auth: AuthSocketSchema; userData: AuthResult }> => {
388
+ clientReq: AuthClientRequest
389
+ ): Promise<{ auth: AuthSocketSchema; userData: AuthResultOrError }> => {
447
390
  let pathGuard = false;
448
391
  if (this.opts.expressConfig?.publicRoutes && !this.opts.expressConfig.disableSocketAuthGuard) {
449
392
  pathGuard = true;
@@ -473,7 +416,7 @@ export class AuthHandler {
473
416
  pathname &&
474
417
  typeof pathname === "string" &&
475
418
  this.isUserRoute(pathname) &&
476
- !(await this.getClientInfo({ socket }))?.user
419
+ !(await this.getUserFromRequest({ socket }))?.user
477
420
  ) {
478
421
  cb(null, { shouldReload: true });
479
422
  } else {
@@ -488,7 +431,7 @@ export class AuthHandler {
488
431
  }
489
432
  }
490
433
 
491
- const userData = await this.getClientInfo(clientReq);
434
+ const userData = await this.getUserFromRequest(clientReq);
492
435
  const { email } = this.opts.expressConfig?.registrations ?? {};
493
436
  const auth: AuthSocketSchema = {
494
437
  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<AuthResultWithSID<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,