prostgles-server 4.2.159 → 4.2.161

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 (107) hide show
  1. package/dist/Auth/setEmailProvider.js +2 -2
  2. package/dist/Auth/setEmailProvider.js.map +1 -1
  3. package/lib/Auth/AuthHandler.ts +436 -0
  4. package/lib/Auth/AuthTypes.ts +280 -0
  5. package/lib/Auth/getSafeReturnURL.ts +35 -0
  6. package/lib/Auth/sendEmail.ts +83 -0
  7. package/lib/Auth/setAuthProviders.ts +128 -0
  8. package/lib/Auth/setEmailProvider.ts +85 -0
  9. package/lib/Auth/setupAuthRoutes.ts +161 -0
  10. package/lib/DBEventsManager.ts +178 -0
  11. package/lib/DBSchemaBuilder.ts +225 -0
  12. package/lib/DboBuilder/DboBuilder.ts +319 -0
  13. package/lib/DboBuilder/DboBuilderTypes.ts +361 -0
  14. package/lib/DboBuilder/QueryBuilder/Functions.ts +1153 -0
  15. package/lib/DboBuilder/QueryBuilder/QueryBuilder.ts +288 -0
  16. package/lib/DboBuilder/QueryBuilder/getJoinQuery.ts +263 -0
  17. package/lib/DboBuilder/QueryBuilder/getNewQuery.ts +271 -0
  18. package/lib/DboBuilder/QueryBuilder/getSelectQuery.ts +136 -0
  19. package/lib/DboBuilder/QueryBuilder/prepareHaving.ts +22 -0
  20. package/lib/DboBuilder/QueryStreamer.ts +250 -0
  21. package/lib/DboBuilder/TableHandler/DataValidator.ts +428 -0
  22. package/lib/DboBuilder/TableHandler/TableHandler.ts +205 -0
  23. package/lib/DboBuilder/TableHandler/delete.ts +115 -0
  24. package/lib/DboBuilder/TableHandler/insert.ts +183 -0
  25. package/lib/DboBuilder/TableHandler/insertTest.ts +78 -0
  26. package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +62 -0
  27. package/lib/DboBuilder/TableHandler/runInsertUpdateQuery.ts +134 -0
  28. package/lib/DboBuilder/TableHandler/update.ts +126 -0
  29. package/lib/DboBuilder/TableHandler/updateBatch.ts +49 -0
  30. package/lib/DboBuilder/TableHandler/updateFile.ts +48 -0
  31. package/lib/DboBuilder/TableHandler/upsert.ts +34 -0
  32. package/lib/DboBuilder/ViewHandler/ViewHandler.ts +393 -0
  33. package/lib/DboBuilder/ViewHandler/count.ts +38 -0
  34. package/lib/DboBuilder/ViewHandler/find.ts +153 -0
  35. package/lib/DboBuilder/ViewHandler/getExistsCondition.ts +73 -0
  36. package/lib/DboBuilder/ViewHandler/getExistsFilters.ts +74 -0
  37. package/lib/DboBuilder/ViewHandler/getInfo.ts +32 -0
  38. package/lib/DboBuilder/ViewHandler/getTableJoinQuery.ts +84 -0
  39. package/lib/DboBuilder/ViewHandler/parseComplexFilter.ts +96 -0
  40. package/lib/DboBuilder/ViewHandler/parseFieldFilter.ts +105 -0
  41. package/lib/DboBuilder/ViewHandler/parseJoinPath.ts +208 -0
  42. package/lib/DboBuilder/ViewHandler/prepareSortItems.ts +163 -0
  43. package/lib/DboBuilder/ViewHandler/prepareWhere.ts +90 -0
  44. package/lib/DboBuilder/ViewHandler/size.ts +37 -0
  45. package/lib/DboBuilder/ViewHandler/subscribe.ts +118 -0
  46. package/lib/DboBuilder/ViewHandler/validateViewRules.ts +70 -0
  47. package/lib/DboBuilder/dboBuilderUtils.ts +222 -0
  48. package/lib/DboBuilder/getColumns.ts +114 -0
  49. package/lib/DboBuilder/getCondition.ts +201 -0
  50. package/lib/DboBuilder/getSubscribeRelatedTables.ts +190 -0
  51. package/lib/DboBuilder/getTablesForSchemaPostgresSQL.ts +426 -0
  52. package/lib/DboBuilder/insertNestedRecords.ts +355 -0
  53. package/lib/DboBuilder/parseUpdateRules.ts +187 -0
  54. package/lib/DboBuilder/prepareShortestJoinPaths.ts +186 -0
  55. package/lib/DboBuilder/runSQL.ts +182 -0
  56. package/lib/DboBuilder/runTransaction.ts +50 -0
  57. package/lib/DboBuilder/sqlErrCodeToMsg.ts +254 -0
  58. package/lib/DboBuilder/uploadFile.ts +69 -0
  59. package/lib/Event_Trigger_Tags.ts +118 -0
  60. package/lib/FileManager/FileManager.ts +358 -0
  61. package/lib/FileManager/getValidatedFileType.ts +69 -0
  62. package/lib/FileManager/initFileManager.ts +187 -0
  63. package/lib/FileManager/upload.ts +62 -0
  64. package/lib/FileManager/uploadStream.ts +79 -0
  65. package/lib/Filtering.ts +463 -0
  66. package/lib/JSONBValidation/validate_jsonb_schema_sql.ts +502 -0
  67. package/lib/JSONBValidation/validation.ts +143 -0
  68. package/lib/Logging.ts +127 -0
  69. package/lib/PostgresNotifListenManager.ts +143 -0
  70. package/lib/Prostgles.ts +485 -0
  71. package/lib/ProstglesTypes.ts +196 -0
  72. package/lib/PubSubManager/PubSubManager.ts +609 -0
  73. package/lib/PubSubManager/addSub.ts +138 -0
  74. package/lib/PubSubManager/addSync.ts +141 -0
  75. package/lib/PubSubManager/getCreatePubSubManagerError.ts +72 -0
  76. package/lib/PubSubManager/getPubSubManagerInitQuery.ts +662 -0
  77. package/lib/PubSubManager/initPubSubManager.ts +79 -0
  78. package/lib/PubSubManager/notifListener.ts +173 -0
  79. package/lib/PubSubManager/orphanTriggerCheck.ts +70 -0
  80. package/lib/PubSubManager/pushSubData.ts +55 -0
  81. package/lib/PublishParser/PublishParser.ts +162 -0
  82. package/lib/PublishParser/getFileTableRules.ts +124 -0
  83. package/lib/PublishParser/getSchemaFromPublish.ts +141 -0
  84. package/lib/PublishParser/getTableRulesWithoutFileTable.ts +177 -0
  85. package/lib/PublishParser/publishTypesAndUtils.ts +399 -0
  86. package/lib/RestApi.ts +127 -0
  87. package/lib/SchemaWatch/SchemaWatch.ts +90 -0
  88. package/lib/SchemaWatch/createSchemaWatchEventTrigger.ts +3 -0
  89. package/lib/SchemaWatch/getValidatedWatchSchemaType.ts +45 -0
  90. package/lib/SchemaWatch/getWatchSchemaTagList.ts +27 -0
  91. package/lib/SyncReplication.ts +557 -0
  92. package/lib/TableConfig/TableConfig.ts +468 -0
  93. package/lib/TableConfig/getColumnDefinitionQuery.ts +111 -0
  94. package/lib/TableConfig/getConstraintDefinitionQueries.ts +95 -0
  95. package/lib/TableConfig/getFutureTableSchema.ts +64 -0
  96. package/lib/TableConfig/getPGIndexes.ts +53 -0
  97. package/lib/TableConfig/getTableColumnQueries.ts +129 -0
  98. package/lib/TableConfig/initTableConfig.ts +326 -0
  99. package/lib/index.ts +13 -0
  100. package/lib/initProstgles.ts +319 -0
  101. package/lib/onSocketConnected.ts +102 -0
  102. package/lib/runClientRequest.ts +129 -0
  103. package/lib/shortestPath.ts +122 -0
  104. package/lib/typeTests/DBoGenerated.d.ts +320 -0
  105. package/lib/typeTests/dboTypeCheck.ts +81 -0
  106. package/lib/utils.ts +15 -0
  107. package/package.json +1 -1
@@ -68,9 +68,9 @@ async function setEmailProvider(app) {
68
68
  }
69
69
  exports.setEmailProvider = setEmailProvider;
70
70
  const checkDmarc = async (websiteUrl) => {
71
- const { host } = new URL(websiteUrl);
71
+ const { host, hostname } = new URL(websiteUrl);
72
72
  const ignoredHosts = ["localhost", "127.0.0.1"];
73
- if (!host || ignoredHosts.includes(host)) {
73
+ if (!hostname || ignoredHosts.includes(hostname)) {
74
74
  return;
75
75
  }
76
76
  const dmarc = await node_dns_1.promises.resolveTxt(`_dmarc.${host}`);
@@ -1 +1 @@
1
- {"version":3,"file":"setEmailProvider.js","sourceRoot":"","sources":["../../lib/Auth/setEmailProvider.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"setEmailProvider.js","sourceRoot":"","sources":["../../lib/Auth/setEmailProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,436 @@
1
+ import { AnyObject, AuthGuardLocation, AuthGuardLocationResponse, CHANNELS, AuthSocketSchema } from "prostgles-types";
2
+ import { LocalParams, PRGLIOSocket } from "../DboBuilder/DboBuilder";
3
+ import { DBOFullyTyped } from "../DBSchemaBuilder";
4
+ import { removeExpressRoute } from "../FileManager/FileManager";
5
+ import { DB, DBHandlerServer, Prostgles } from "../Prostgles";
6
+ import { Auth, AuthClientRequest, AuthResult, BasicSession, ExpressReq, ExpressRes, LoginClientInfo, LoginParams } from "./AuthTypes"
7
+ import { getSafeReturnURL } from "./getSafeReturnURL";
8
+ import { setupAuthRoutes } from "./setupAuthRoutes";
9
+ import { getProviders } from "./setAuthProviders";
10
+
11
+ export const HTTPCODES = {
12
+ AUTH_ERROR: 401,
13
+ NOT_FOUND: 404,
14
+ BAD_REQUEST: 400,
15
+ INTERNAL_SERVER_ERROR: 500,
16
+ };
17
+
18
+ export const getLoginClientInfo = (req: AuthClientRequest): AuthClientRequest & LoginClientInfo => {
19
+ if("httpReq" in req){
20
+ const ip_address = req.httpReq.ip;
21
+ if(!ip_address) throw new Error("ip_address missing from req.httpReq");
22
+ const user_agent = req.httpReq.headers["user-agent"];
23
+ return {
24
+ ...req,
25
+ ip_address,
26
+ ip_address_remote: req.httpReq.connection.remoteAddress,
27
+ x_real_ip: req.httpReq.headers['x-real-ip'] as any,
28
+ user_agent,
29
+ };
30
+ } else {
31
+ return {
32
+ ...req,
33
+ ip_address: req.socket.handshake.address,
34
+ ip_address_remote: req.socket.request.connection.remoteAddress,
35
+ x_real_ip: req.socket.handshake.headers?.["x-real-ip"],
36
+ user_agent: req.socket.handshake.headers?.['user-agent'],
37
+ }
38
+ }
39
+ }
40
+
41
+ export const AUTH_ROUTES_AND_PARAMS = {
42
+ login: "/login",
43
+ loginWithProvider: "/auth",
44
+ emailSignup: "/register",
45
+ returnUrlParamName: "returnURL",
46
+ sidKeyName: "session_id",
47
+ logoutGetPath: "/logout",
48
+ magicLinksRoute: "/magic-link",
49
+ magicLinksExpressRoute: "/magic-link/:id",
50
+ confirmEmail: "/confirm-email",
51
+ confirmEmailExpressRoute: "/confirm-email/:id",
52
+ catchAll: "*",
53
+ } as const;
54
+
55
+ export class AuthHandler {
56
+ protected prostgles: Prostgles;
57
+ protected opts?: Auth;
58
+ dbo: DBHandlerServer;
59
+ db: DB;
60
+
61
+ constructor(prostgles: Prostgles) {
62
+ this.prostgles = prostgles;
63
+ this.opts = prostgles.opts.auth as any;
64
+ if(!prostgles.dbo || !prostgles.db) throw "dbo or db missing";
65
+ this.dbo = prostgles.dbo;
66
+ this.db = prostgles.db;
67
+ }
68
+
69
+ get sidKeyName() {
70
+ return this.opts?.sidKeyName ?? AUTH_ROUTES_AND_PARAMS.sidKeyName;
71
+ }
72
+
73
+ validateSid = (sid: string | undefined) => {
74
+ if (!sid) return undefined;
75
+ if (typeof sid !== "string") throw "sid missing or not a string";
76
+ return sid;
77
+ }
78
+
79
+ matchesRoute = (route: string | undefined, clientFullRoute: string) => {
80
+ return route && clientFullRoute && (
81
+ route === clientFullRoute ||
82
+ clientFullRoute.startsWith(route) && ["/", "?", "#"].includes(clientFullRoute[route.length] ?? "")
83
+ )
84
+ }
85
+
86
+ isUserRoute = (pathname: string) => {
87
+ const { login, logoutGetPath, magicLinksRoute, loginWithProvider } = AUTH_ROUTES_AND_PARAMS;
88
+ const pubRoutes = [
89
+ ...this.opts?.expressConfig?.publicRoutes || [],
90
+ login, logoutGetPath, magicLinksRoute, loginWithProvider,
91
+ ].filter(publicRoute => publicRoute);
92
+
93
+ return !pubRoutes.some(publicRoute => {
94
+ return this.matchesRoute(publicRoute, pathname);
95
+ });
96
+ }
97
+
98
+ setCookieAndGoToReturnURLIFSet = (cookie: { sid: string; expires: number; }, r: { req: ExpressReq; res: ExpressRes }) => {
99
+ const { sid, expires } = cookie;
100
+ const { res, req } = r;
101
+ if (sid) {
102
+ const maxAgeOneDay = 60 * 60 * 24; // 24 hours;
103
+ type CD = { maxAge: number } | { expires: Date }
104
+ let cookieDuration: CD = {
105
+ maxAge: maxAgeOneDay
106
+ }
107
+ if(expires && Number.isFinite(expires) && !isNaN(+ new Date(expires))){
108
+ // const maxAge = (+new Date(expires)) - Date.now();
109
+ cookieDuration = { expires: new Date(expires) };
110
+ const days = (+cookieDuration.expires - Date.now())/(24 * 60 * 60e3);
111
+ if(days >= 400){
112
+ console.warn(`Cookie expiration is higher than the Chrome 400 day limit: ${days}days`)
113
+ }
114
+ }
115
+
116
+ const cookieOpts = {
117
+ ...cookieDuration,
118
+ httpOnly: true, // The cookie only accessible by the web server
119
+ //signed: true // Indicates if the cookie should be signed
120
+ secure: true,
121
+ sameSite: "strict" as const,
122
+ ...(this.opts?.expressConfig?.cookieOptions || {})
123
+ };
124
+ const cookieData = sid;
125
+ res.cookie(this.sidKeyName, cookieData, cookieOpts);
126
+ const successURL = this.getReturnUrl(req) || "/";
127
+ res.redirect(successURL);
128
+
129
+ } else {
130
+ throw ("no user or session")
131
+ }
132
+ }
133
+
134
+ getUser = async (clientReq: { httpReq: ExpressReq; }): Promise<AuthResult> => {
135
+ if(!this.opts?.getUser) {
136
+ throw "this.opts.getUser missing";
137
+ }
138
+ const sid = clientReq.httpReq?.cookies?.[this.sidKeyName];
139
+ if (!sid) return undefined;
140
+
141
+ try {
142
+ return this.throttledFunc(async () => {
143
+ return this.opts!.getUser(this.validateSid(sid), this.dbo as any, this.db, getLoginClientInfo(clientReq));
144
+ }, 50)
145
+ } catch (err) {
146
+ console.error(err);
147
+ }
148
+ return undefined;
149
+ }
150
+
151
+ init = setupAuthRoutes.bind(this);
152
+
153
+ getReturnUrl = (req: ExpressReq) => {
154
+ const { returnUrlParamName } = AUTH_ROUTES_AND_PARAMS;
155
+ if (returnUrlParamName && req?.query?.[returnUrlParamName]) {
156
+ const returnURL = decodeURIComponent(req?.query?.[returnUrlParamName] as string);
157
+
158
+ return getSafeReturnURL(returnURL, returnUrlParamName);
159
+ }
160
+ return null;
161
+ }
162
+
163
+ destroy = () => {
164
+ const app = this.opts?.expressConfig?.app;
165
+ const { login, logoutGetPath, magicLinksExpressRoute, catchAll, loginWithProvider, emailSignup, magicLinksRoute, confirmEmail, confirmEmailExpressRoute } = AUTH_ROUTES_AND_PARAMS;
166
+ removeExpressRoute(app, [login, logoutGetPath, magicLinksExpressRoute, catchAll, loginWithProvider, emailSignup, magicLinksRoute, confirmEmail, confirmEmailExpressRoute]);
167
+ }
168
+
169
+ throttledFunc = <T>(func: () => Promise<T>, throttle = 500): Promise<T> => {
170
+
171
+ return new Promise(async (resolve, reject) => {
172
+
173
+ let result: any, error: any, finished = false;
174
+
175
+ /**
176
+ * Throttle reject response times to prevent timing attacks
177
+ */
178
+ const interval = setInterval(() => {
179
+ if (finished) {
180
+ clearInterval(interval);
181
+ if (error) {
182
+ reject(error);
183
+ } else {
184
+ resolve(result)
185
+ }
186
+ }
187
+ }, throttle);
188
+
189
+
190
+ try {
191
+ result = await func();
192
+ resolve(result);
193
+ clearInterval(interval);
194
+ } catch (err) {
195
+ console.log(err)
196
+ error = err;
197
+ }
198
+
199
+ finished = true;
200
+ })
201
+ }
202
+
203
+ loginThrottled = async (params: LoginParams, client: LoginClientInfo): Promise<BasicSession> => {
204
+ if (!this.opts?.login) throw "Auth login config missing";
205
+ const { responseThrottle = 500 } = this.opts;
206
+
207
+ return this.throttledFunc(async () => {
208
+ const result = await this.opts?.login?.(params, this.dbo as DBOFullyTyped, this.db, client);
209
+ const err = {
210
+ msg: "Bad login result type. \nExpecting: undefined | null | { sid: string; expires: number } but got: " + JSON.stringify(result)
211
+ }
212
+
213
+ if(!result) throw err;
214
+ if(result && (typeof result.sid !== "string" || typeof result.expires !== "number") || !result && ![undefined, null].includes(result)) {
215
+ throw err
216
+ }
217
+ if(result && result.expires < Date.now()){
218
+ throw { msg: "auth.login() is returning an expired session. Can only login with a session.expires greater than Date.now()" }
219
+ }
220
+
221
+ return result;
222
+ }, responseThrottle);
223
+
224
+ };
225
+
226
+ loginThrottledAndSetCookie = async (req: ExpressReq, res: ExpressRes, loginParams: LoginParams) => {
227
+ const start = Date.now();
228
+ const { sid, expires } = await this.loginThrottled(loginParams, getLoginClientInfo({ httpReq: req })) || {};
229
+ await this.prostgles.opts.onLog?.({
230
+ type: "auth",
231
+ command: "login",
232
+ duration: Date.now() - start,
233
+ sid,
234
+ socketId: undefined,
235
+ });
236
+
237
+ if (sid) {
238
+
239
+ this.setCookieAndGoToReturnURLIFSet({ sid, expires }, { req, res });
240
+
241
+ } else {
242
+ throw ("Internal error: no user or session")
243
+ }
244
+ }
245
+
246
+
247
+ /**
248
+ * Will return first sid value found in:
249
+ * Bearer header
250
+ * http cookie
251
+ * query params
252
+ * Based on sid names in auth
253
+ */
254
+ getSID(localParams: LocalParams): string | undefined {
255
+ if (!this.opts) return undefined;
256
+
257
+ if (!localParams) return undefined;
258
+ const { sidKeyName } = this;
259
+ if (localParams.socket) {
260
+ const { handshake } = localParams.socket;
261
+ const querySid = handshake?.auth?.[sidKeyName] || handshake?.query?.[sidKeyName];
262
+ let rawSid = querySid;
263
+ if (!rawSid) {
264
+ const cookie_str = localParams.socket?.handshake?.headers?.cookie;
265
+ const cookie = parseCookieStr(cookie_str);
266
+ rawSid = cookie[sidKeyName];
267
+ }
268
+ return this.validateSid(rawSid);
269
+
270
+ } else if (localParams.httpReq) {
271
+ const [tokenType, base64Token] = localParams.httpReq.headers.authorization?.split(' ') ?? [];
272
+ let bearerSid: string | undefined;
273
+ if(tokenType && base64Token){
274
+ if(tokenType.trim() !== "Bearer"){
275
+ throw "Only Bearer Authorization header allowed";
276
+ }
277
+ bearerSid = Buffer.from(base64Token, 'base64').toString();
278
+ }
279
+ return this.validateSid(bearerSid ?? localParams.httpReq?.cookies?.[sidKeyName]);
280
+
281
+ } else throw "socket OR httpReq missing from localParams";
282
+
283
+ function parseCookieStr(cookie_str: string | undefined): any {
284
+ if (!cookie_str || typeof cookie_str !== "string") {
285
+ return {}
286
+ }
287
+
288
+ return cookie_str.replace(/\s/g, '')
289
+ .split(";")
290
+ .reduce<AnyObject>((prev, current) => {
291
+ const [name, value] = current.split('=');
292
+ prev[name!] = value;
293
+ return prev;
294
+ }, {});
295
+ }
296
+ }
297
+
298
+ /**
299
+ * Used for logging
300
+ */
301
+ getSIDNoError = (localParams: LocalParams | undefined): string | undefined => {
302
+ if(!localParams) return undefined;
303
+ try {
304
+ return this.getSID(localParams);
305
+ } catch {
306
+ return undefined;
307
+ }
308
+ }
309
+
310
+ async getClientInfo(localParams: Pick<LocalParams, "socket" | "httpReq">): Promise<AuthResult> {
311
+ if (!this.opts) return {};
312
+
313
+ const getSession = this.opts.cacheSession?.getSession;
314
+ const isSocket = "socket" in localParams;
315
+ if(isSocket){
316
+ if(getSession && localParams.socket?.__prglCache){
317
+ const { session, user, clientUser } = localParams.socket.__prglCache;
318
+ const isValid = this.isValidSocketSession(localParams.socket, session)
319
+ if(isValid){
320
+
321
+ return {
322
+ sid: session.sid,
323
+ user,
324
+ clientUser,
325
+ }
326
+ } else return {
327
+ sid: session.sid
328
+ };
329
+ }
330
+ }
331
+
332
+ const authStart = Date.now();
333
+ const res = await this.throttledFunc(async () => {
334
+
335
+ const { getUser } = this.opts ?? {};
336
+
337
+ if (getUser && localParams && (localParams.httpReq || localParams.socket)) {
338
+ const sid = this.getSID(localParams);
339
+ const clientReq = localParams.httpReq? { httpReq: localParams.httpReq } : { socket: localParams.socket! };
340
+ let user, clientUser;
341
+ if(sid){
342
+ const res = await getUser(sid, this.dbo as any, this.db, getLoginClientInfo(clientReq)) as any;
343
+ user = res?.user;
344
+ clientUser = res?.clientUser;
345
+ }
346
+ if(getSession && isSocket){
347
+ const session = await getSession(sid, this.dbo as any, this.db)
348
+ if(session?.expires && user && clientUser && localParams.socket){
349
+ localParams.socket.__prglCache = {
350
+ session,
351
+ user,
352
+ clientUser,
353
+ }
354
+ }
355
+ }
356
+ if(sid) {
357
+ return { sid, user, clientUser }
358
+ }
359
+ }
360
+
361
+ return {};
362
+ }, 5);
363
+
364
+ await this.prostgles.opts.onLog?.({
365
+ type: "auth",
366
+ command: "getClientInfo",
367
+ duration: Date.now() - authStart,
368
+ sid: res.sid,
369
+ socketId: localParams.socket?.id,
370
+ });
371
+ return res;
372
+ }
373
+
374
+ isValidSocketSession = (socket: PRGLIOSocket, session: BasicSession): boolean => {
375
+ const hasExpired = Boolean(session && session.expires <= Date.now())
376
+ if(this.opts?.expressConfig?.publicRoutes && !this.opts.expressConfig?.disableSocketAuthGuard){
377
+ const error = "Session has expired";
378
+ if(hasExpired){
379
+ if(session.onExpiration === "redirect")
380
+ socket.emit(CHANNELS.AUTHGUARD, {
381
+ shouldReload: session.onExpiration === "redirect",
382
+ error
383
+ });
384
+ throw error;
385
+ }
386
+ }
387
+ return Boolean(session && !hasExpired);
388
+ }
389
+
390
+ getClientAuth = async (clientReq: Pick<LocalParams, "socket" | "httpReq">): Promise<{ auth: AuthSocketSchema; userData: AuthResult; }> => {
391
+
392
+ let pathGuard = false;
393
+ if (this.opts?.expressConfig?.publicRoutes && !this.opts.expressConfig?.disableSocketAuthGuard) {
394
+
395
+ pathGuard = true;
396
+
397
+ if("socket" in clientReq && clientReq.socket){
398
+ const { socket } = clientReq;
399
+ socket.removeAllListeners(CHANNELS.AUTHGUARD)
400
+ socket.on(CHANNELS.AUTHGUARD, async (params: AuthGuardLocation, cb = (_err: any, _res?: AuthGuardLocationResponse) => { /** EMPTY */ }) => {
401
+
402
+ try {
403
+
404
+ const { pathname, origin } = typeof params === "string" ? JSON.parse(params) : (params || {});
405
+ if (pathname && typeof pathname !== "string") {
406
+ console.warn("Invalid pathname provided for AuthGuardLocation: ", pathname);
407
+ }
408
+
409
+ /** These origins */
410
+ const IGNORED_API_ORIGINS = ["file://"]
411
+ if (!IGNORED_API_ORIGINS.includes(origin) && pathname && typeof pathname === "string" && this.isUserRoute(pathname) && !(await this.getClientInfo({ socket }))?.user) {
412
+ cb(null, { shouldReload: true });
413
+ } else {
414
+ cb(null, { shouldReload: false });
415
+ }
416
+
417
+ } catch (err) {
418
+ console.error("AUTHGUARD err: ", err);
419
+ cb(err)
420
+ }
421
+ });
422
+
423
+ }
424
+ }
425
+
426
+ const userData = await this.getClientInfo(clientReq);
427
+ const auth: AuthSocketSchema = {
428
+ providers: getProviders.bind(this)(),
429
+ register: this.opts?.expressConfig?.registrations?.email && { type: this.opts?.expressConfig?.registrations?.email.signupType, url: AUTH_ROUTES_AND_PARAMS.emailSignup },
430
+ user: userData?.clientUser,
431
+ loginType: this.opts?.expressConfig?.registrations?.email?.signupType,
432
+ pathGuard,
433
+ };
434
+ return { auth, userData };
435
+ }
436
+ }