underpost 2.8.872 → 2.8.874

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 (56) hide show
  1. package/.env.development +2 -1
  2. package/.env.production +2 -1
  3. package/.env.test +2 -1
  4. package/.github/workflows/ghpkg.ci.yml +1 -1
  5. package/.github/workflows/npmpkg.ci.yml +1 -1
  6. package/.github/workflows/pwa-microservices-template-page.cd.yml +1 -1
  7. package/.github/workflows/pwa-microservices-template-test.ci.yml +1 -1
  8. package/.github/workflows/release.cd.yml +2 -4
  9. package/README.md +24 -2
  10. package/bin/build.js +4 -0
  11. package/bin/deploy.js +4 -0
  12. package/cli.md +5 -2
  13. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  14. package/manifests/deployment/dd-test-development/deployment.yaml +174 -0
  15. package/manifests/deployment/dd-test-development/proxy.yaml +51 -0
  16. package/package.json +5 -1
  17. package/src/api/core/core.router.js +2 -1
  18. package/src/api/default/default.controller.js +6 -1
  19. package/src/api/default/default.router.js +6 -2
  20. package/src/api/default/default.service.js +10 -1
  21. package/src/api/file/file.router.js +2 -1
  22. package/src/api/test/test.router.js +1 -1
  23. package/src/api/user/postman_collection.json +216 -0
  24. package/src/api/user/user.controller.js +25 -60
  25. package/src/api/user/user.model.js +29 -7
  26. package/src/api/user/user.router.js +9 -4
  27. package/src/api/user/user.service.js +84 -32
  28. package/src/cli/baremetal.js +33 -3
  29. package/src/cli/cloud-init.js +11 -0
  30. package/src/cli/deploy.js +44 -22
  31. package/src/cli/index.js +2 -0
  32. package/src/cli/lxd.js +7 -0
  33. package/src/cli/run.js +17 -5
  34. package/src/cli/ssh.js +20 -6
  35. package/src/client/components/core/AgGrid.js +28 -6
  36. package/src/client/components/core/Auth.js +99 -55
  37. package/src/client/components/core/LogIn.js +16 -23
  38. package/src/client/components/core/LogOut.js +5 -1
  39. package/src/client/components/core/Pagination.js +202 -9
  40. package/src/client/components/core/Router.js +30 -3
  41. package/src/client/components/core/SignUp.js +1 -2
  42. package/src/client/components/default/LogInDefault.js +0 -6
  43. package/src/client/components/default/LogOutDefault.js +0 -16
  44. package/src/client/services/core/core.service.js +5 -1
  45. package/src/client/services/default/default.management.js +115 -18
  46. package/src/client/services/default/default.service.js +9 -4
  47. package/src/client/services/user/user.management.js +6 -0
  48. package/src/client/services/user/user.service.js +11 -4
  49. package/src/index.js +24 -2
  50. package/src/runtime/lampp/Lampp.js +89 -2
  51. package/src/runtime/xampp/Xampp.js +48 -1
  52. package/src/server/auth.js +518 -155
  53. package/src/server/conf.js +19 -1
  54. package/src/server/runtime.js +64 -228
  55. package/src/server/ssr.js +85 -0
  56. package/src/server/valkey.js +2 -1
@@ -557,7 +557,7 @@ const buildPortProxyRouter = (port, proxyRouter) => {
557
557
  // build router
558
558
  Object.keys(hosts).map((hostKey) => {
559
559
  let { host, path, target, proxy, peer } = hosts[hostKey];
560
- if (process.env.NODE_ENV === 'development') host = `localhost`;
560
+ if (process.env.NODE_ENV === 'development' && process.argv.includes('localhost')) host = `localhost`;
561
561
 
562
562
  if (!proxy.includes(port)) {
563
563
  logger.warn('Proxy port not set on conf', { port, host, path, proxy, target });
@@ -926,6 +926,23 @@ const buildCliDoc = (program, oldVersion, newVersion) => {
926
926
  );
927
927
  };
928
928
 
929
+ const getInstanceContext = async (options = { singleReplica, replicas, redirect: '' }) => {
930
+ const { singleReplica, replicas, redirect } = options;
931
+
932
+ if (singleReplica && replicas && replicas.length > 0)
933
+ return {
934
+ singleReplicaHost: true,
935
+ };
936
+
937
+ const redirectTarget = redirect
938
+ ? redirect[redirect.length - 1] === '/'
939
+ ? redirect.slice(0, -1)
940
+ : redirect
941
+ : undefined;
942
+
943
+ return { redirectTarget };
944
+ };
945
+
929
946
  export {
930
947
  Cmd,
931
948
  Config,
@@ -958,4 +975,5 @@ export {
958
975
  awaitDeployMonitor,
959
976
  rebuildConfFactory,
960
977
  buildCliDoc,
978
+ getInstanceContext,
961
979
  };
@@ -1,26 +1,24 @@
1
1
  import fs from 'fs-extra';
2
2
  import express from 'express';
3
- import cors from 'cors';
4
3
  import dotenv from 'dotenv';
5
4
  import fileUpload from 'express-fileupload';
6
5
  import swaggerUi from 'swagger-ui-express';
7
6
  import * as promClient from 'prom-client';
8
7
  import compression from 'compression';
9
8
 
10
- import { createServer } from 'http';
11
- import { getRootDirectory } from './process.js';
12
9
  import UnderpostStartUp from './start.js';
10
+ import { createServer } from 'http';
13
11
  import { loggerFactory, loggerMiddleware } from './logger.js';
14
12
  import { getCapVariableName, newInstance } from '../client/components/core/CommonJs.js';
15
- import { Xampp } from '../runtime/xampp/Xampp.js';
16
13
  import { MailerProvider } from '../mailer/MailerProvider.js';
17
14
  import { DataBaseProvider } from '../db/DataBaseProvider.js';
18
- // import { createProxyMiddleware } from 'http-proxy-middleware';
19
15
  import { createPeerServer } from './peer.js';
20
16
  import { Lampp } from '../runtime/lampp/Lampp.js';
21
- import { JSONweb, ssrFactory } from './client-formatted.js';
22
- import Underpost from '../index.js';
17
+ import { Xampp } from '../runtime/xampp/Xampp.js';
23
18
  import { createValkeyConnection } from './valkey.js';
19
+ import { applySecurity, authMiddlewareFactory } from './auth.js';
20
+ import { getInstanceContext } from './conf.js';
21
+ import { ssrMiddlewareFactory } from './ssr.js';
24
22
 
25
23
  dotenv.config();
26
24
 
@@ -38,8 +36,6 @@ const buildRuntime = async () => {
38
36
  labelNames: ['instance', 'method', 'status_code'],
39
37
  };
40
38
 
41
- // logger.info('promCounterOption', promCounterOption);
42
-
43
39
  const requestCounter = new promClient.Counter(promCounterOption);
44
40
  const initPort = parseInt(process.env.PORT) + 1;
45
41
  let currentPort = initPort;
@@ -47,9 +43,8 @@ const buildRuntime = async () => {
47
43
  const confSSR = JSON.parse(fs.readFileSync(`./conf/conf.ssr.json`, 'utf8'));
48
44
  const singleReplicaHosts = [];
49
45
  for (const host of Object.keys(confServer)) {
50
- if (singleReplicaHosts.length > 0 && !singleReplicaHosts.includes(host)) {
46
+ if (singleReplicaHosts.length > 0)
51
47
  currentPort += singleReplicaHosts.reduce((accumulator, currentValue) => accumulator + currentValue.replicas, 0);
52
- }
53
48
  const rootHostPath = `/public/${host}`;
54
49
  for (const path of Object.keys(confServer[host])) {
55
50
  confServer[host][path].port = newInstance(currentPort);
@@ -70,7 +65,14 @@ const buildRuntime = async () => {
70
65
  valkey,
71
66
  } = confServer[host][path];
72
67
 
73
- if (singleReplica && replicas && replicas.length > 0 && !singleReplicaHosts.includes(host)) {
68
+ const { redirectTarget, singleReplicaHost } = await getInstanceContext({
69
+ redirect,
70
+ singleReplicaHosts,
71
+ singleReplica,
72
+ replicas,
73
+ });
74
+
75
+ if (singleReplicaHost) {
74
76
  singleReplicaHosts.push({
75
77
  host,
76
78
  replicas: replicas.length,
@@ -87,161 +89,7 @@ const buildRuntime = async () => {
87
89
  apis,
88
90
  };
89
91
 
90
- const redirectTarget = redirect
91
- ? redirect[redirect.length - 1] === '/'
92
- ? redirect.slice(0, -1)
93
- : redirect
94
- : undefined;
95
-
96
- // if (redirect) logger.info('redirect', new URL(redirect));
97
-
98
92
  switch (runtime) {
99
- case 'lampp':
100
- if (!Lampp.enabled()) continue;
101
- if (!Lampp.ports.includes(port)) Lampp.ports.push(port);
102
- if (currentPort === initPort) Lampp.removeRouter();
103
- Lampp.appendRouter(`
104
-
105
- Listen ${port}
106
-
107
- <VirtualHost *:${port}>
108
- DocumentRoot "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}"
109
- ServerName ${host}:${port}
110
-
111
- <Directory "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}">
112
- Options Indexes FollowSymLinks MultiViews
113
- AllowOverride All
114
- Require all granted
115
- </Directory>
116
-
117
- ${
118
- redirect
119
- ? `
120
- RewriteEngine on
121
-
122
- RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
123
- RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
124
- `
125
- : ''
126
- }
127
-
128
- ErrorDocument 400 ${path === '/' ? '' : path}/400.html
129
- ErrorDocument 404 ${path === '/' ? '' : path}/400.html
130
- ErrorDocument 500 ${path === '/' ? '' : path}/500.html
131
- ErrorDocument 502 ${path === '/' ? '' : path}/500.html
132
- ErrorDocument 503 ${path === '/' ? '' : path}/500.html
133
- ErrorDocument 504 ${path === '/' ? '' : path}/500.html
134
-
135
- </VirtualHost>
136
-
137
- `);
138
- // ERR too many redirects:
139
- // Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
140
- // Check: wp-config.php
141
- // if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
142
- // $_SERVER['HTTPS'] = 'on';
143
- // }
144
- // For plugins:
145
- // define( 'FS_METHOD', 'direct' );
146
-
147
- // ErrorDocument 404 /custom_404.html
148
- // ErrorDocument 500 /custom_50x.html
149
- // ErrorDocument 502 /custom_50x.html
150
- // ErrorDocument 503 /custom_50x.html
151
- // ErrorDocument 504 /custom_50x.html
152
-
153
- // Respond When Error Pages are Directly Requested
154
-
155
- // <Files "custom_404.html">
156
- // <If "-z %{ENV:REDIRECT_STATUS}">
157
- // RedirectMatch 404 ^/custom_404.html$
158
- // </If>
159
- // </Files>
160
-
161
- // <Files "custom_50x.html">
162
- // <If "-z %{ENV:REDIRECT_STATUS}">
163
- // RedirectMatch 404 ^/custom_50x.html$
164
- // </If>
165
- // </Files>
166
-
167
- // Add www or https with htaccess rewrite
168
-
169
- // Options +FollowSymLinks
170
- // RewriteEngine On
171
- // RewriteCond %{HTTP_HOST} ^ejemplo.com [NC]
172
- // RewriteRule ^(.*)$ http://ejemplo.com/$1 [R=301,L]
173
-
174
- // Redirect http to https with htaccess rewrite
175
-
176
- // RewriteEngine On
177
- // RewriteCond %{SERVER_PORT} 80
178
- // RewriteRule ^(.*)$ https://www.ejemplo.com/$1 [R,L]
179
-
180
- // Redirect to HTTPS with www subdomain
181
-
182
- // RewriteEngine On
183
- // RewriteCond %{HTTPS} off [OR]
184
- // RewriteCond %{HTTP_HOST} ^www\. [NC]
185
- // RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
186
- // RewriteRule ^ https://%1%{REQUEST_URI} [L,NE,R=301]
187
-
188
- await UnderpostStartUp.API.listenPortController(
189
- UnderpostStartUp.API.listenServerFactory(),
190
- port,
191
- runningData,
192
- );
193
- break;
194
- case 'xampp':
195
- if (!Xampp.enabled()) continue;
196
- if (!Xampp.ports.includes(port)) Xampp.ports.push(port);
197
- if (currentPort === initPort) Xampp.removeRouter();
198
- Xampp.appendRouter(`
199
-
200
- Listen ${port}
201
-
202
- <VirtualHost *:${port}>
203
- DocumentRoot "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}"
204
- ServerName ${host}:${port}
205
-
206
- <Directory "${directory ? directory : `${getRootDirectory()}${rootHostPath}`}">
207
- Options Indexes FollowSymLinks MultiViews
208
- AllowOverride All
209
- Require all granted
210
- </Directory>
211
-
212
- ${
213
- redirect
214
- ? `
215
- RewriteEngine on
216
-
217
- RewriteCond %{REQUEST_URI} !^/.well-known/acme-challenge
218
- RewriteRule ^(.*)$ ${redirectTarget}%{REQUEST_URI} [R=302,L]
219
- `
220
- : ''
221
- }
222
-
223
- ErrorDocument 400 ${path === '/' ? '' : path}/400.html
224
- ErrorDocument 404 ${path === '/' ? '' : path}/400.html
225
- ErrorDocument 500 ${path === '/' ? '' : path}/500.html
226
- ErrorDocument 502 ${path === '/' ? '' : path}/500.html
227
- ErrorDocument 503 ${path === '/' ? '' : path}/500.html
228
- ErrorDocument 504 ${path === '/' ? '' : path}/500.html
229
-
230
- </VirtualHost>
231
-
232
- `);
233
- // ERR too many redirects:
234
- // Check: SELECT * FROM database.wp_options where option_name = 'siteurl' or option_name = 'home';
235
- // Check: wp-config.php
236
- // if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
237
- // $_SERVER['HTTPS'] = 'on';
238
- // }
239
- await UnderpostStartUp.API.listenPortController(
240
- UnderpostStartUp.API.listenServerFactory(),
241
- port,
242
- runningData,
243
- );
244
- break;
245
93
  case 'nodejs':
246
94
  const app = express();
247
95
 
@@ -315,14 +163,12 @@ const buildRuntime = async () => {
315
163
  return next();
316
164
  });
317
165
 
318
- // cors
319
- const originPayload = {
166
+ // security
167
+ applySecurity(app, {
320
168
  origin: origins.concat(
321
169
  apis && process.env.NODE_ENV === 'development' ? [`http://localhost:${currentPort + 2}`] : [],
322
170
  ),
323
- };
324
- // logger.info('originPayload', originPayload);
325
- app.use(cors(originPayload));
171
+ });
326
172
 
327
173
  if (redirect) {
328
174
  app.use(function (req = express.Request, res = express.Response, next = express.NextFunction) {
@@ -374,73 +220,22 @@ const buildRuntime = async () => {
374
220
  });
375
221
  }
376
222
  if (apis) {
223
+ const authMiddleware = authMiddlewareFactory({ host, path });
224
+
377
225
  const apiPath = `${path === '/' ? '' : path}/${process.env.BASE_API}`;
378
226
  for (const api of apis)
379
227
  await (async () => {
380
228
  const { ApiRouter } = await import(`../api/${api}/${api}.router.js`);
381
- const router = ApiRouter({ host, path, apiPath, mailer, db });
229
+ const router = ApiRouter({ host, path, apiPath, mailer, db, authMiddleware });
382
230
  // router.use(cors({ origin: origins }));
383
231
  // logger.info('Load api router', { host, path: apiPath, api });
384
232
  app.use(`${apiPath}/${api}`, router);
385
233
  })();
386
234
  }
387
235
 
388
- const Render = await ssrFactory();
389
- const ssrPath = path === '/' ? path : `${path}/`;
390
-
391
- const defaultHtmlSrc404 = Render({
392
- title: '404 Not Found',
393
- ssrPath,
394
- ssrHeadComponents: '',
395
- ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/404.js`))(),
396
- renderPayload: {
397
- apiBasePath: process.env.BASE_API,
398
- version: Underpost.version,
399
- },
400
- renderApi: {
401
- JSONweb,
402
- },
403
- });
404
- const path404 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/404/index.html`;
405
- const page404 = fs.existsSync(path404) ? `${path === '/' ? '' : path}/404` : undefined;
406
- app.use(function (req, res, next) {
407
- // if /<path>/home redirect to /<path>
408
- const homeRedirectPath = `${path === '/' ? '' : path}/home`;
409
- if (req.url.startsWith(homeRedirectPath)) {
410
- const redirectUrl = req.url.replace('/home', '');
411
- return res.redirect(redirectUrl.startsWith('/') ? redirectUrl : `/${redirectUrl}`);
412
- }
413
-
414
- if (page404) return res.status(404).redirect(page404);
415
- else {
416
- res.set('Content-Type', 'text/html');
417
- return res.status(404).send(defaultHtmlSrc404);
418
- }
419
- });
420
-
421
- const defaultHtmlSrc500 = Render({
422
- title: '500 Server Error',
423
- ssrPath,
424
- ssrHeadComponents: '',
425
- ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/500.js`))(),
426
- renderPayload: {
427
- apiBasePath: process.env.BASE_API,
428
- version: Underpost.version,
429
- },
430
- renderApi: {
431
- JSONweb,
432
- },
433
- });
434
- const path500 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/500/index.html`;
435
- const page500 = fs.existsSync(path500) ? `${path === '/' ? '' : path}/500` : undefined;
436
- app.use(function (err, req, res, next) {
437
- logger.error(err, err.stack);
438
- if (page500) return res.status(500).redirect(page500);
439
- else {
440
- res.set('Content-Type', 'text/html');
441
- return res.status(500).send(defaultHtmlSrc500);
442
- }
443
- });
236
+ // load ssr
237
+ const ssr = await ssrMiddlewareFactory({ app, directory, rootHostPath, path });
238
+ for (const [_, ssrMiddleware] of Object.entries(ssr)) app.use(ssrMiddleware);
444
239
 
445
240
  // instance server
446
241
  const server = createServer({}, app);
@@ -489,6 +284,47 @@ const buildRuntime = async () => {
489
284
  await UnderpostStartUp.API.listenPortController(server, port, runningData);
490
285
 
491
286
  break;
287
+
288
+ case 'lampp':
289
+ {
290
+ const { disabled } = await Lampp.createApp({
291
+ port,
292
+ host,
293
+ path,
294
+ directory,
295
+ rootHostPath,
296
+ redirect,
297
+ redirectTarget,
298
+ resetRouter: currentPort === initPort,
299
+ });
300
+ if (disabled) continue;
301
+ await UnderpostStartUp.API.listenPortController(
302
+ UnderpostStartUp.API.listenServerFactory(),
303
+ port,
304
+ runningData,
305
+ );
306
+ }
307
+ break;
308
+ case 'xampp':
309
+ {
310
+ const { disabled } = await Xampp.createApp({
311
+ port,
312
+ host,
313
+ path,
314
+ directory,
315
+ rootHostPath,
316
+ redirect,
317
+ redirectTarget,
318
+ resetRouter: currentPort === initPort,
319
+ });
320
+ if (disabled) continue;
321
+ await UnderpostStartUp.API.listenPortController(
322
+ UnderpostStartUp.API.listenServerFactory(),
323
+ port,
324
+ runningData,
325
+ );
326
+ }
327
+ break;
492
328
  default:
493
329
  break;
494
330
  }
@@ -0,0 +1,85 @@
1
+ import fs from 'fs-extra';
2
+ import dotenv from 'dotenv';
3
+ import Underpost from '../index.js';
4
+
5
+ import { ssrFactory, JSONweb } from './client-formatted.js';
6
+ import { loggerFactory } from './logger.js';
7
+ import { getRootDirectory } from './process.js';
8
+
9
+ dotenv.config();
10
+
11
+ const logger = loggerFactory(import.meta);
12
+
13
+ const ssrMiddlewareFactory = async ({ app, directory, rootHostPath, path }) => {
14
+ const Render = await ssrFactory();
15
+ const ssrPath = path === '/' ? path : `${path}/`;
16
+
17
+ // Build default html src for 404 and 500
18
+
19
+ const defaultHtmlSrc404 = Render({
20
+ title: '404 Not Found',
21
+ ssrPath,
22
+ ssrHeadComponents: '',
23
+ ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/404.js`))(),
24
+ renderPayload: {
25
+ apiBasePath: process.env.BASE_API,
26
+ version: Underpost.version,
27
+ },
28
+ renderApi: {
29
+ JSONweb,
30
+ },
31
+ });
32
+ const path404 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/404/index.html`;
33
+ const page404 = fs.existsSync(path404) ? `${path === '/' ? '' : path}/404` : undefined;
34
+
35
+ const defaultHtmlSrc500 = Render({
36
+ title: '500 Server Error',
37
+ ssrPath,
38
+ ssrHeadComponents: '',
39
+ ssrBodyComponents: (await ssrFactory(`./src/client/ssr/body/500.js`))(),
40
+ renderPayload: {
41
+ apiBasePath: process.env.BASE_API,
42
+ version: Underpost.version,
43
+ },
44
+ renderApi: {
45
+ JSONweb,
46
+ },
47
+ });
48
+ const path500 = `${directory ? directory : `${getRootDirectory()}${rootHostPath}`}/500/index.html`;
49
+ const page500 = fs.existsSync(path500) ? `${path === '/' ? '' : path}/500` : undefined;
50
+
51
+ const sanitizeHtml = (res, req, html) => {
52
+ const nonce = res.locals.nonce;
53
+
54
+ return html
55
+ .replace(/<script(?=\s|>)/gi, `<script nonce="${nonce}"`)
56
+ .replace(/<style(?=\s|>)/gi, `<style nonce="${nonce}"`);
57
+ };
58
+
59
+ return {
60
+ error500: function (err, req, res, next) {
61
+ logger.error(err, err.stack);
62
+ if (page500) return res.status(500).redirect(page500);
63
+ else {
64
+ res.set('Content-Type', 'text/html');
65
+ return res.status(500).send(sanitizeHtml(res, req, defaultHtmlSrc500));
66
+ }
67
+ },
68
+ error400: function (req, res, next) {
69
+ // if /<path>/home redirect to /<path>
70
+ const homeRedirectPath = `${path === '/' ? '' : path}/home`;
71
+ if (req.url.startsWith(homeRedirectPath)) {
72
+ const redirectUrl = req.url.replace('/home', '');
73
+ return res.redirect(redirectUrl.startsWith('/') ? redirectUrl : `/${redirectUrl}`);
74
+ }
75
+
76
+ if (page404) return res.status(404).redirect(page404);
77
+ else {
78
+ res.set('Content-Type', 'text/html');
79
+ return res.status(404).send(sanitizeHtml(res, req, defaultHtmlSrc404));
80
+ }
81
+ },
82
+ };
83
+ };
84
+
85
+ export { ssrMiddlewareFactory };
@@ -148,7 +148,7 @@ const updateValkeyObject = async (options = { host: '', path: '' }, key = '', pa
148
148
  return await setValkeyObject(options, key, { ...base, ...payload });
149
149
  };
150
150
 
151
- const valkeyObjectFactory = async (options = { host: 'localhost', object: {} }, model = '') => {
151
+ const valkeyObjectFactory = async (options = { host: 'localhost', path: '', object: {} }, model = '') => {
152
152
  const idoDate = new Date().toISOString();
153
153
  options.object = options.object || {};
154
154
  const { object } = options;
@@ -173,6 +173,7 @@ const valkeyObjectFactory = async (options = { host: 'localhost', object: {} },
173
173
  emailConfirmed: false,
174
174
  recoverTimeOut: null,
175
175
  lastLoginDate: null,
176
+ activeSessions: [],
176
177
  };
177
178
  }
178
179
  default: