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
@@ -8,12 +8,14 @@ import { SignUp } from './SignUp.js';
8
8
  import { Translate } from './Translate.js';
9
9
  import { s } from './VanillaJs.js';
10
10
 
11
- const logger = loggerFactory(import.meta);
11
+ const logger = loggerFactory(import.meta, { trace: true });
12
12
 
13
13
  const token = Symbol('token');
14
14
 
15
15
  const guestToken = Symbol('guestToken');
16
16
 
17
+ const refreshTimeout = Symbol('refreshTimeout');
18
+
17
19
  const Auth = {
18
20
  [token]: '',
19
21
  [guestToken]: '',
@@ -35,50 +37,65 @@ const Auth = {
35
37
  getGuestToken: function () {
36
38
  return this[guestToken];
37
39
  },
38
- // jwt
39
40
  getJWT: function () {
40
- return `Bearer ${this.getToken() ? this.getToken() : this.getGuestToken()}`;
41
+ if (Auth.getToken()) return `Bearer ${Auth.getToken()}`;
42
+ if (Auth.getGuestToken()) return `Bearer ${Auth.getGuestToken()}`;
43
+ return '';
41
44
  },
42
- signUpToken: async function (
43
- result = {
44
- data: {
45
- token: '',
46
- user: null,
47
- },
48
- },
49
- ) {
45
+ decodeJwt: function (token) {
50
46
  try {
51
- localStorage.setItem('jwt', result.data.token);
52
- await SignUp.Trigger(result.data);
53
- await Auth.sessionIn();
54
- } catch (error) {
55
- logger.error(error);
56
- localStorage.removeItem('jwt');
47
+ return JSON.parse(atob(token.split('.')[1]));
48
+ } catch (e) {
49
+ return null;
57
50
  }
58
51
  },
52
+ scheduleTokenRefresh: function () {
53
+ if (this[refreshTimeout]) {
54
+ clearTimeout(this[refreshTimeout]);
55
+ }
56
+
57
+ const currentToken = Auth.getToken();
58
+ if (!currentToken) return;
59
+
60
+ const payload = Auth.decodeJwt(currentToken);
61
+ if (!payload || !payload.refreshExpiresAt) return;
62
+
63
+ const expiresIn = payload.refreshExpiresAt - Date.now();
64
+ const refreshBuffer = 2 * 60 * 1000; // 2 minutes
65
+ const refreshIn = expiresIn - refreshBuffer;
66
+
67
+ logger.info(`Token refresh in ${refreshIn / (1000 * 60)} minutes`);
68
+
69
+ if (refreshIn <= 0) return; // Already expired or close to it
70
+
71
+ this[refreshTimeout] = setTimeout(async () => {
72
+ const { data, status } = await UserService.get({ id: 'auth' });
73
+ if (status === 'success') {
74
+ logger.info('Refreshed access token.');
75
+ Auth.setToken(data.token);
76
+ localStorage.setItem('jwt', data.token);
77
+ Auth.scheduleTokenRefresh();
78
+ } else Auth.sessionOut();
79
+ }, refreshIn);
80
+ },
59
81
  sessionIn: async function (userServicePayload) {
60
82
  try {
61
83
  const token = userServicePayload?.data?.token ? userServicePayload.data.token : localStorage.getItem('jwt');
62
-
63
84
  if (token) {
64
- this.setToken(token);
85
+ Auth.setToken(token);
86
+
65
87
  const result = userServicePayload
66
- ? userServicePayload
67
- : await (async () => {
68
- const _result = await UserService.get({ id: 'auth' });
69
- return {
70
- status: _result.status,
71
- message: _result.message,
72
- data: {
73
- user: _result.data,
74
- },
75
- };
76
- })();
88
+ ? userServicePayload // From login/signup
89
+ : await UserService.get({ id: 'auth' });
90
+
77
91
  const { status, data, message } = result;
78
92
  if (status === 'success') {
93
+ Auth.setToken(data.token);
79
94
  localStorage.setItem('jwt', token);
95
+ Auth.renderSessionUI();
80
96
  await LogIn.Trigger({ user: data.user });
81
97
  await Account.updateForm(data.user);
98
+ Auth.scheduleTokenRefresh();
82
99
  return { user: data.user };
83
100
  }
84
101
  if (message && message.match('expired'))
@@ -89,41 +106,68 @@ const Auth = {
89
106
  status: 'warning',
90
107
  });
91
108
  });
92
- return await Auth.sessionOut();
93
109
  }
94
-
95
- // anon guest session
96
- this.deleteToken();
110
+ // Important delete session token if guest token already exists
111
+ Auth.deleteToken();
97
112
  localStorage.removeItem('jwt');
98
- let guestToken = localStorage.getItem('jwt.g');
99
113
 
100
- if (!guestToken) {
101
- const result = await UserService.post({ id: 'guest' });
102
- localStorage.setItem('jwt.g', result.data.token);
103
- guestToken = result.data.token;
104
- }
105
-
106
- this.setGuestToken(guestToken);
107
- let { data, status, message } = await UserService.get({ id: 'auth' });
108
- if (status === 'error') {
109
- if (message && message.match('expired')) {
110
- localStorage.removeItem('jwt.g');
111
- return await Auth.sessionOut();
112
- } else throw new Error(message);
114
+ // Anon guest session
115
+ let guestToken = localStorage.getItem('jwt.g');
116
+ if (guestToken) {
117
+ Auth.setGuestToken(guestToken);
118
+ let { data, status, message } = await UserService.get({ id: 'auth' });
119
+ if (status === 'success') {
120
+ await LogIn.Trigger(data);
121
+ await Account.updateForm(data.user);
122
+ return data;
123
+ } else logger.error(message);
113
124
  }
114
- await Account.updateForm(data);
115
- return { user: data };
125
+ return await Auth.sessionOut();
116
126
  } catch (error) {
117
127
  logger.error(error);
118
128
  return { user: UserMock.default };
119
129
  }
120
130
  },
121
131
  sessionOut: async function () {
122
- this.deleteToken();
123
- localStorage.removeItem('jwt');
124
- const result = await this.sessionIn();
125
- await LogOut.Trigger(result);
126
- return result;
132
+ {
133
+ const result = await UserService.delete({ id: 'logout' });
134
+ localStorage.removeItem('jwt');
135
+ Auth.deleteToken();
136
+ if (this[refreshTimeout]) {
137
+ clearTimeout(this[refreshTimeout]);
138
+ }
139
+ Auth.renderGuestUi();
140
+ LogIn.Scope.user.main.model.user = {};
141
+ await LogOut.Trigger(result);
142
+ }
143
+ {
144
+ localStorage.removeItem('jwt.g');
145
+ Auth.deleteGuestToken();
146
+ const result = await UserService.post({ id: 'guest' });
147
+ localStorage.setItem('jwt.g', result.data.token);
148
+ Auth.setGuestToken(result.data.token);
149
+ return await Auth.sessionIn();
150
+ }
151
+ },
152
+ renderSessionUI: function () {
153
+ s(`.main-btn-log-in`).style.display = 'none';
154
+ s(`.main-btn-sign-up`).style.display = 'none';
155
+ s(`.main-btn-log-out`).style.display = null;
156
+ s(`.main-btn-account`).style.display = null;
157
+ setTimeout(() => {
158
+ if (s(`.modal-log-in`)) s(`.btn-close-modal-log-in`).click();
159
+ if (s(`.modal-sign-up`)) s(`.btn-close-modal-sign-up`).click();
160
+ });
161
+ },
162
+ renderGuestUi: function () {
163
+ s(`.main-btn-log-in`).style.display = null;
164
+ s(`.main-btn-sign-up`).style.display = null;
165
+ s(`.main-btn-log-out`).style.display = 'none';
166
+ s(`.main-btn-account`).style.display = 'none';
167
+ setTimeout(() => {
168
+ if (s(`.modal-log-out`)) s(`.btn-close-modal-log-out`).click();
169
+ if (s(`.modal-account`)) s(`.btn-close-modal-account`).click();
170
+ });
127
171
  },
128
172
  };
129
173
 
@@ -24,8 +24,9 @@ const LogIn = {
24
24
  Event: {},
25
25
  Trigger: async function (options) {
26
26
  const { user } = options;
27
- await Webhook.register({ user });
28
27
  for (const eventKey of Object.keys(this.Event)) await this.Event[eventKey](options);
28
+ if (!user || user.role === 'guest') return;
29
+ await Webhook.register({ user });
29
30
  if (s(`.session`))
30
31
  htmls(
31
32
  `.session`,
@@ -72,19 +73,18 @@ const LogIn = {
72
73
  imageSrc,
73
74
  };
74
75
  }
76
+ htmls(
77
+ `.action-btn-profile-log-in-render`,
78
+ html`<div class="abs center top-box-profile-img-container">
79
+ <img
80
+ class="abs center top-box-profile-img"
81
+ ${this.Scope.user.main.model.user.profileImage
82
+ ? `src="${this.Scope.user.main.model.user.profileImage.imageSrc}"`
83
+ : ``}
84
+ />
85
+ </div>`,
86
+ );
75
87
  }
76
-
77
- htmls(
78
- `.action-btn-profile-log-in-render`,
79
- html`<div class="abs center top-box-profile-img-container">
80
- <img
81
- class="abs center top-box-profile-img"
82
- ${this.Scope.user.main.model.user.profileImage
83
- ? `src="${this.Scope.user.main.model.user.profileImage.imageSrc}"`
84
- : ``}
85
- />
86
- </div>`,
87
- );
88
88
  },
89
89
  Render: async function () {
90
90
  setTimeout(async () => {
@@ -103,13 +103,7 @@ const LogIn = {
103
103
  if ('model' in inputData) body[inputData.model] = s(`.${inputData.id}`).value;
104
104
  }
105
105
  const result = await UserService.post({ id: 'auth', body });
106
- if (result.status === 'success') {
107
- await Auth.sessionIn(result);
108
- setTimeout(() => {
109
- if (s(`.modal-log-in`)) s(`.btn-close-modal-log-in`).click();
110
- if (s(`.modal-sign-up`)) s(`.btn-close-modal-sign-up`).click();
111
- });
112
- }
106
+
113
107
  if (result.status === 'error' && result.message.match('attempts')) {
114
108
  htmls(`.login-attempt-warn-value`, result.message.split(':')[1]);
115
109
  s(`.login-attempt-warn-container`).classList.remove('hide');
@@ -119,6 +113,8 @@ const LogIn = {
119
113
  htmls(`.login-attempt-warn-value0`, result.message.split(':')[1]);
120
114
  s(`.login-attempt-warn-container0`).classList.remove('hide');
121
115
  } else s(`.login-attempt-warn-container0`).classList.add('hide');
116
+
117
+ if (result.status === 'success') await Auth.sessionIn(result);
122
118
  NotificationManager.Push({
123
119
  html: result.status === 'success' ? Translate.Render(`${result.status}-user-log-in`) : result.message,
124
120
  status: result.status,
@@ -189,9 +185,6 @@ const LogIn = {
189
185
  </form>
190
186
  `;
191
187
  },
192
- cleanMainUser: () => {
193
- LogIn.Scope.user.main.model.user = {};
194
- },
195
188
  };
196
189
 
197
190
  export { LogIn };
@@ -4,11 +4,11 @@ import { LogIn } from './LogIn.js';
4
4
  import { Translate } from './Translate.js';
5
5
  import { htmls, s } from './VanillaJs.js';
6
6
  import { Webhook } from './Webhook.js';
7
+ import { NotificationManager } from './NotificationManager.js';
7
8
 
8
9
  const LogOut = {
9
10
  Event: {},
10
11
  Trigger: async function (options) {
11
- LogIn.cleanMainUser();
12
12
  await Webhook.unregister();
13
13
  for (const eventKey of Object.keys(this.Event)) await this.Event[eventKey](options);
14
14
  if (s(`.session`))
@@ -41,6 +41,10 @@ const LogOut = {
41
41
  s('.btn-log-out').onclick = async (e) => {
42
42
  e.preventDefault();
43
43
  await Auth.sessionOut();
44
+ NotificationManager.Push({
45
+ html: Translate.Render(`success-logout`),
46
+ status: 'success',
47
+ });
44
48
  };
45
49
  });
46
50
  // Translate.Render('confirm-logout')
@@ -1,14 +1,207 @@
1
- const Pagination = {
2
- Render: async ({ id }) => {
3
- return html`
1
+ import { getQueryParams, setQueryParams } from './Router.js';
2
+
3
+ class AgPagination extends HTMLElement {
4
+ constructor() {
5
+ super();
6
+ this.attachShadow({ mode: 'open' });
7
+ this._gridId = null;
8
+ const queryParams = getQueryParams();
9
+ this._currentPage = parseInt(queryParams.page, 10) || 1;
10
+ this._limit = parseInt(queryParams.limit, 10) || 10;
11
+ this._totalPages = 1;
12
+ this._totalItems = 0;
13
+ this.handlePageChange = this.handlePageChange.bind(this);
14
+ this.handleLimitChange = this.handleLimitChange.bind(this);
15
+ }
16
+
17
+ static get observedAttributes() {
18
+ return ['grid-id', 'current-page', 'total-pages', 'total-items', 'limit'];
19
+ }
20
+
21
+ attributeChangedCallback(name, oldValue, newValue) {
22
+ switch (name) {
23
+ case 'grid-id':
24
+ this._gridId = newValue;
25
+ break;
26
+ case 'current-page':
27
+ this._currentPage = parseInt(newValue, 10) || this._currentPage;
28
+ break;
29
+ case 'total-pages':
30
+ this._totalPages = parseInt(newValue, 10) || 1;
31
+ break;
32
+ case 'total-items':
33
+ this._totalItems = parseInt(newValue, 10) || 0;
34
+ break;
35
+ case 'limit':
36
+ this._limit = parseInt(newValue, 10) || this._limit;
37
+ break;
38
+ }
39
+ this.update();
40
+ }
41
+
42
+ connectedCallback() {
43
+ this.render();
44
+ this.addEventListeners();
45
+ this.update();
46
+ }
47
+
48
+ disconnectedCallback() {
49
+ // Event listeners on shadow DOM are garbage collected with the component
50
+ }
51
+
52
+ handlePageChange(newPage) {
53
+ if (newPage < 1 || newPage > this._totalPages || newPage === this._currentPage) {
54
+ return;
55
+ }
56
+ this._currentPage = newPage;
57
+ setQueryParams({ page: newPage, limit: this._limit });
58
+ this.dispatchEvent(new CustomEvent('page-change', { detail: { page: newPage } }));
59
+ }
60
+
61
+ handleLimitChange(event) {
62
+ const newLimit = parseInt(event.target.value, 10);
63
+ if (newLimit === this._limit) {
64
+ return;
65
+ }
66
+ this._limit = newLimit;
67
+ this._currentPage = 1; // Reset to first page on limit change
68
+ setQueryParams({ page: 1, limit: newLimit });
69
+ this.dispatchEvent(new CustomEvent('limit-change', { detail: { limit: newLimit } }));
70
+ }
71
+
72
+ update() {
73
+ if (!this.shadowRoot.querySelector('#page-info')) return;
74
+
75
+ const isFirstPage = this._currentPage === 1;
76
+ const isLastPage = this._currentPage === this._totalPages;
77
+
78
+ this.shadowRoot.querySelector('#first-page').disabled = isFirstPage;
79
+ this.shadowRoot.querySelector('#prev-page').disabled = isFirstPage;
80
+ this.shadowRoot.querySelector('#next-page').disabled = isLastPage;
81
+ this.shadowRoot.querySelector('#last-page').disabled = isLastPage;
82
+
83
+ const startItem = this._totalItems > 0 ? (this._currentPage - 1) * this._limit + 1 : 0;
84
+ const endItem = Math.min(this._currentPage * this._limit, this._totalItems);
85
+
86
+ this.shadowRoot.querySelector('#summary-info').textContent = `${startItem} - ${endItem} of ${this._totalItems}`;
87
+ this.shadowRoot.querySelector('#page-info').textContent = `Page ${this._currentPage} of ${this._totalPages}`;
88
+
89
+ const limitSelector = this.shadowRoot.querySelector('#limit-selector');
90
+ if (limitSelector.value != this._limit) {
91
+ limitSelector.value = this._limit;
92
+ }
93
+
94
+ this.renderPageButtons();
95
+ }
96
+
97
+ renderPageButtons() {
98
+ const pageButtonsContainer = this.shadowRoot.querySelector('#page-buttons');
99
+ pageButtonsContainer.innerHTML = '';
100
+
101
+ const maxButtons = 5;
102
+ let startPage = Math.max(1, this._currentPage - Math.floor(maxButtons / 2));
103
+ let endPage = Math.min(this._totalPages, startPage + maxButtons - 1);
104
+
105
+ if (endPage - startPage + 1 < maxButtons) {
106
+ startPage = Math.max(1, endPage - maxButtons + 1);
107
+ }
108
+
109
+ for (let i = startPage; i <= endPage; i++) {
110
+ const button = document.createElement('button');
111
+ button.textContent = i;
112
+ button.disabled = i === this._currentPage;
113
+ if (i === this._currentPage) {
114
+ button.classList.add('active');
115
+ }
116
+ button.addEventListener('click', () => this.handlePageChange(i));
117
+ pageButtonsContainer.appendChild(button);
118
+ }
119
+ }
120
+
121
+ addEventListeners() {
122
+ this.shadowRoot.querySelector('#first-page').addEventListener('click', () => this.handlePageChange(1));
123
+ this.shadowRoot
124
+ .querySelector('#prev-page')
125
+ .addEventListener('click', () => this.handlePageChange(this._currentPage - 1));
126
+ this.shadowRoot
127
+ .querySelector('#next-page')
128
+ .addEventListener('click', () => this.handlePageChange(this._currentPage + 1));
129
+ this.shadowRoot
130
+ .querySelector('#last-page')
131
+ .addEventListener('click', () => this.handlePageChange(this._totalPages));
132
+ this.shadowRoot.querySelector('#limit-selector').addEventListener('change', this.handleLimitChange);
133
+ }
134
+
135
+ render() {
136
+ this.shadowRoot.innerHTML = html`
4
137
  <style>
5
- .pagination-container-${id} {
138
+ :host {
139
+ display: flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ padding: 8px;
143
+ font-family: sans-serif;
144
+ font-size: 14px;
145
+ gap: 8px;
146
+ }
147
+ button {
148
+ border: 1px solid #ccc;
149
+ background-color: #f0f0f0;
150
+ padding: 6px 12px;
151
+ cursor: pointer;
152
+ border-radius: 4px;
153
+ }
154
+ button:disabled {
155
+ cursor: not-allowed;
156
+ opacity: 0.5;
157
+ }
158
+ button.active {
159
+ border-color: #007bff;
160
+ background-color: #007bff;
161
+ color: white;
162
+ }
163
+ #page-info {
164
+ min-width: 80px;
165
+ text-align: center;
166
+ }
167
+ #page-buttons {
168
+ display: flex;
169
+ gap: 4px;
170
+ }
171
+ .summary-panel,
172
+ .page-summary-panel {
173
+ display: flex;
174
+ align-items: center;
175
+ gap: 8px;
176
+ }
177
+ #limit-selector {
178
+ border: 1px solid #ccc;
179
+ background-color: #f0f0f0;
180
+ padding: 6px 12px;
181
+ border-radius: 4px;
6
182
  }
7
183
  </style>
8
-
9
- <div class="in pagination-container-${id}">test pagination</div>
184
+ <div class="summary-panel">
185
+ <span id="summary-info"></span>
186
+ </div>
187
+ <button id="first-page">First</button>
188
+ <button id="prev-page">Previous</button>
189
+ <div class="page-summary-panel">
190
+ <div id="page-buttons"></div>
191
+ <span id="page-info"></span>
192
+ </div>
193
+ <button id="next-page">Next</button>
194
+ <button id="last-page">Last</button>
195
+ <select id="limit-selector">
196
+ <option value="10">10</option>
197
+ <option value="20">20</option>
198
+ <option value="50">50</option>
199
+ <option value="100">100</option>
200
+ </select>
10
201
  `;
11
- },
12
- };
202
+ }
203
+ }
204
+
205
+ customElements.define('ag-pagination', AgPagination);
13
206
 
14
- export { Pagination };
207
+ export { AgPagination };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Vanilla JavaScript module for manipulating the DOM.
2
+ * Router module for handling routing in a PWA application.
3
3
  * @module src/client/components/core/Router.js
4
4
  * @namespace PwaRouter
5
5
  */
@@ -245,7 +245,8 @@ const closeModalRouteChangeEvent = (options = {}) => {
245
245
 
246
246
  for (const event of Object.keys(closeModalRouteChangeEvents)) closeModalRouteChangeEvents[event]();
247
247
  if (topModalId) Modal.setTopModalCallback(topModalId);
248
- setPath(`${getProxyPath()}${Modal.Data[topModalId]?.options?.route || 'home'}`);
248
+ setPath(`${getProxyPath()}${Modal.Data[topModalId]?.options?.route ?? ''}`);
249
+ setDocTitle(Modal.Data[topModalId]?.options?.route ?? '');
249
250
  };
250
251
 
251
252
  /**
@@ -255,7 +256,7 @@ const closeModalRouteChangeEvent = (options = {}) => {
255
256
  * @param {string} options.route - The route associated with the modal view.
256
257
  * @memberof PwaRouter
257
258
  */
258
- const handleModalViewRoute = (options = { route: 'home' }) => {
259
+ const handleModalViewRoute = (options = { route: '' }) => {
259
260
  const { route } = options;
260
261
  if (!route) return;
261
262
 
@@ -270,6 +271,31 @@ const handleModalViewRoute = (options = { route: 'home' }) => {
270
271
  }
271
272
  };
272
273
 
274
+ /**
275
+ * Sets or updates query parameters in the URL.
276
+ * It preserves the existing path, hash, and other query parameters.
277
+ *
278
+ * @param {Object.<string, string|number>} newParams - An object of query parameters to set or update.
279
+ * If a value is `null` or `undefined`, the parameter will be removed.
280
+ * @param {object} [options={ replace: true }] - Options for history manipulation.
281
+ * @param {boolean} [options.replace=true] - If true, uses `history.replaceState` instead of `history.pushState`.
282
+ * @memberof PwaRouter
283
+ */
284
+ const setQueryParams = (newParams, options = { replace: true }) => {
285
+ const url = new URL(window.location.href);
286
+ Object.entries(newParams).forEach(([key, value]) => {
287
+ if (value === null || value === undefined) {
288
+ url.searchParams.delete(key);
289
+ } else {
290
+ url.searchParams.set(key, value);
291
+ }
292
+ });
293
+
294
+ const newPath = url.pathname + url.search + url.hash;
295
+
296
+ history.pushState(history.state, '', newPath);
297
+ };
298
+
273
299
  export {
274
300
  RouterEvents,
275
301
  closeModalRouteChangeEvents,
@@ -284,4 +310,5 @@ export {
284
310
  getQueryParams,
285
311
  getProxyPath,
286
312
  setPath,
313
+ setQueryParams,
287
314
  };
@@ -53,8 +53,7 @@ const SignUp = {
53
53
  status: result.status,
54
54
  });
55
55
  if (result.status === 'success') {
56
- await Auth.sessionOut();
57
- await Auth.signUpToken(result);
56
+ await Auth.sessionIn(result);
58
57
  s(`.btn-close-${options.idModal}`).click();
59
58
  }
60
59
  });
@@ -1,17 +1,11 @@
1
- import { UserService } from '../../services/user/user.service.js';
2
1
  import { Auth } from '../core/Auth.js';
3
2
  import { LogIn } from '../core/LogIn.js';
4
- import { s } from '../core/VanillaJs.js';
5
3
  import { ElementsDefault } from './ElementsDefault.js';
6
4
 
7
5
  const LogInDefault = async function () {
8
6
  LogIn.Event['LogInDefault'] = async (options) => {
9
7
  const { token, user } = options;
10
8
  ElementsDefault.Data.user.main.model.user = user;
11
- s(`.main-btn-log-in`).style.display = 'none';
12
- s(`.main-btn-sign-up`).style.display = 'none';
13
- s(`.main-btn-log-out`).style.display = null;
14
- s(`.main-btn-account`).style.display = null;
15
9
  };
16
10
  const { user } = await Auth.sessionIn();
17
11
  ElementsDefault.Data.user.main.model.user = user;
@@ -1,25 +1,9 @@
1
- import { Auth } from '../core/Auth.js';
2
1
  import { LogOut } from '../core/LogOut.js';
3
- import { NotificationManager } from '../core/NotificationManager.js';
4
- import { Translate } from '../core/Translate.js';
5
- import { s } from '../core/VanillaJs.js';
6
2
  import { ElementsDefault } from './ElementsDefault.js';
7
3
 
8
4
  const LogOutDefault = async function () {
9
5
  LogOut.Event['LogOutDefault'] = async (result = { user: { _id: '' } }) => {
10
6
  ElementsDefault.Data.user.main.model.user = result.user;
11
-
12
- s(`.main-btn-log-out`).style.display = 'none';
13
- s(`.main-btn-account`).style.display = 'none';
14
- s(`.main-btn-log-in`).style.display = null;
15
- s(`.main-btn-sign-up`).style.display = null;
16
- if (s(`.modal-log-out`)) s(`.btn-close-modal-log-out`).click();
17
- if (s(`.modal-account`)) s(`.btn-close-modal-account`).click();
18
-
19
- NotificationManager.Push({
20
- html: Translate.Render(`success-logout`),
21
- status: 'success',
22
- });
23
7
  };
24
8
  };
25
9
 
@@ -33,7 +33,11 @@ const getWsBaseUrl = (options = { id: '', endpoint: '', wsBasePath: '' }) =>
33
33
  }${options?.endpoint ? options.endpoint : ''}${options?.id ? `/${options.id}` : ''}`;
34
34
 
35
35
  const headersFactory = (headerId = '') => {
36
- const headers = { Authorization: Auth.getJWT() }; // , mode: 'no-cors'
36
+ const headers = {
37
+ Authorization: Auth.getJWT(),
38
+ withCredentials: true,
39
+ credentials: 'include', // no cors: 'same-origin'
40
+ };
37
41
  switch (headerId) {
38
42
  case 'file':
39
43
  return headers;