@posiwise/common-services 0.2.24 → 0.2.26

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.
@@ -2,24 +2,24 @@ import * as i0 from '@angular/core';
2
2
  import { DOCUMENT, Inject, Injectable, isDevMode, inject, NgModule, ViewEncapsulation } from '@angular/core';
3
3
  import * as i3 from '@angular/router';
4
4
  import { NavigationEnd } from '@angular/router';
5
- import * as i1 from '@posiwise/app-config-service';
5
+ import * as i2 from '@posiwise/app-config-service';
6
6
  import { AppConfigService } from '@posiwise/app-config-service';
7
- import * as i1$2 from '@angular/common/http';
7
+ import * as i1$1 from '@angular/common/http';
8
8
  import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
9
9
  import { throwError, of, BehaviorSubject, tap, timer } from 'rxjs';
10
10
  import { catchError, take, tap as tap$1, switchMap, map, mergeMap, distinctUntilChanged } from 'rxjs/operators';
11
11
  import { HelperService } from '@posiwise/helper-service';
12
- import * as i1$1 from 'ngx-toastr';
12
+ import * as i1 from 'ngx-toastr';
13
13
  import { CommonModule } from '@angular/common';
14
14
  import { getUser, SetUser, UserActionTypes, appReducers } from '@posiwise/app-store';
15
- import * as i1$3 from '@ngrx/effects';
15
+ import * as i1$2 from '@ngrx/effects';
16
16
  import { Actions, createEffect, ofType, EffectsModule } from '@ngrx/effects';
17
- import * as i2 from '@ngrx/store';
17
+ import * as i3$1 from '@ngrx/store';
18
18
  import { StoreModule } from '@ngrx/store';
19
- import { INTEGRATIONS_API_PREFIX, MAIN_API_PREFIX, PROJECT_PATH, USER_PATH, TOKEN_HEADER_KEY, NEWSLETTER_CONFIRMATION_PATH, NEWSLETTER_UNSUBSCRIBE_PATH, CAPTCHA_VALIDATION_PATH, SOCIAL_LOGIN_PATH, TOKEN_KEY, PERMISSION_NAMES, ADMIN_SUB_MENU_WHITELIST, AB_TEST_ACTIONS, GEO_PATH, PRODUCT_PATH, CONTACT_US_PATH, INCIDENTS_PATH, INCIDENTS_PATH_ADMIN, NEWSLETTERS_PATH, NEWSLETTER_SUBSCRIPTION_PATH, ADMIN_FAQS_PATH, FAQS_PATH, ORGANIZATIONS_PATH, GLOBAL_SUBSCRIPTION_CONFIGS_PATH, GLOBAL_CONFIGS_PATH, USER_LOGIN_NOTIFICATION, FEEDBACK_QUESTIONS_PATH, USER_FEEDBACKS_PATH, CUSTOMER_SUPPORT_PATH, ADMIN_TAG_PATH, ADMIN_TAG_CATEGORIES_PATH, ADMIN_PATH, QUALIFICATIONS_PATH, SOCKET_TYPE, BRAIN_API_PREFIX } from '@posiwise/common-utilities';
19
+ import { INTEGRATIONS_API_PREFIX, MAIN_API_PREFIX, PROJECT_PATH, USER_PATH, TOKEN_HEADER_KEY, NEWSLETTER_CONFIRMATION_PATH, NEWSLETTER_UNSUBSCRIBE_PATH, CAPTCHA_VALIDATION_PATH, SOCIAL_LOGIN_PATH, TOKEN_KEY, PERMISSION_NAMES, ADMIN_SUB_MENU_WHITELIST, AB_TEST_ACTIONS, GEO_PATH, PRODUCT_PATH, CONTACT_US_PATH, INCIDENTS_PATH, INCIDENTS_PATH_ADMIN, NEWSLETTERS_PATH, NEWSLETTER_SUBSCRIPTION_PATH, ADMIN_FAQS_PATH, FAQS_PATH, ORGANIZATIONS_PATH, GLOBAL_SUBSCRIPTION_CONFIGS_PATH, GLOBAL_CONFIGS_PATH, USER_LOGIN_NOTIFICATION, FEEDBACK_QUESTIONS_PATH, USER_FEEDBACKS_PATH, CUSTOMER_SUPPORT_PATH, ADMIN_TAG_PATH, ADMIN_TAG_CATEGORIES_PATH, ADMIN_PATH, QUALIFICATIONS_PATH, BRAIN_API_PREFIX, SOCKET_TYPE } from '@posiwise/common-utilities';
20
20
  import swal from 'sweetalert2';
21
21
  import moment from 'moment';
22
- import * as i1$4 from '@angular/platform-browser';
22
+ import * as i1$3 from '@angular/platform-browser';
23
23
  import cloneDeep from 'lodash/cloneDeep';
24
24
  import pickBy from 'lodash/pickBy';
25
25
  import * as i2$1 from 'ngx-cookie';
@@ -227,12 +227,12 @@ class GoogleAnalyticsService {
227
227
  this.subscription.unsubscribe();
228
228
  }
229
229
  }
230
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GoogleAnalyticsService, deps: [{ token: i3.Router }, { token: ScriptLoaderService }, { token: i1.AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
230
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GoogleAnalyticsService, deps: [{ token: i3.Router }, { token: ScriptLoaderService }, { token: i2.AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
231
231
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GoogleAnalyticsService }); }
232
232
  }
233
233
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: GoogleAnalyticsService, decorators: [{
234
234
  type: Injectable
235
- }], ctorParameters: () => [{ type: i3.Router }, { type: ScriptLoaderService }, { type: i1.AppConfigService }] });
235
+ }], ctorParameters: () => [{ type: i3.Router }, { type: ScriptLoaderService }, { type: i2.AppConfigService }] });
236
236
 
237
237
  class CustomToastService {
238
238
  constructor(toastr) {
@@ -304,7 +304,7 @@ class CustomToastService {
304
304
  this.error(message);
305
305
  }
306
306
  }
307
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CustomToastService, deps: [{ token: i1$1.ToastrService }], target: i0.ɵɵFactoryTarget.Injectable }); }
307
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CustomToastService, deps: [{ token: i1.ToastrService }], target: i0.ɵɵFactoryTarget.Injectable }); }
308
308
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CustomToastService, providedIn: 'root' }); }
309
309
  }
310
310
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CustomToastService, decorators: [{
@@ -312,7 +312,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
312
312
  args: [{
313
313
  providedIn: 'root'
314
314
  }]
315
- }], ctorParameters: () => [{ type: i1$1.ToastrService }] });
315
+ }], ctorParameters: () => [{ type: i1.ToastrService }] });
316
316
 
317
317
  /* eslint-disable @typescript-eslint/no-explicit-any */
318
318
  class BaseHttpService {
@@ -323,8 +323,14 @@ class BaseHttpService {
323
323
  this.getConfig();
324
324
  this.toast = injector.get(CustomToastService);
325
325
  }
326
+ buildUrl(url) {
327
+ // Collapse any run of 2+ slashes (arises when baseUrl ends with '/'
328
+ // and the caller path also starts with '/', sometimes twice) down to
329
+ // one, while preserving the '://' of an absolute URL scheme.
330
+ return `${this.baseUrl}${url}`.replace(/([^:]\/)\/+/g, '$1');
331
+ }
326
332
  get(url) {
327
- return this.http.get(`${this.baseUrl}${url}`).pipe(catchError(error => {
333
+ return this.http.get(this.buildUrl(url)).pipe(catchError(error => {
328
334
  this.handleError(error);
329
335
  return throwError(() => new HttpErrorResponse(error));
330
336
  }));
@@ -338,31 +344,31 @@ class BaseHttpService {
338
344
  delete params[k];
339
345
  }
340
346
  }
341
- return this.http.get(`${this.baseUrl}${url}`, { params }).pipe(catchError(error => {
347
+ return this.http.get(this.buildUrl(url), { params }).pipe(catchError(error => {
342
348
  this.handleError(error);
343
349
  return throwError(() => new HttpErrorResponse(error));
344
350
  }));
345
351
  }
346
352
  post(url, params = {}) {
347
- return this.http.post(`${this.baseUrl}${url}`, params).pipe(catchError(error => {
353
+ return this.http.post(this.buildUrl(url), params).pipe(catchError(error => {
348
354
  this.handleError(error);
349
355
  return throwError(() => new HttpErrorResponse(error));
350
356
  }));
351
357
  }
352
358
  put(url, params = {}) {
353
- return this.http.put(`${this.baseUrl}${url}`, params).pipe(catchError(error => {
359
+ return this.http.put(this.buildUrl(url), params).pipe(catchError(error => {
354
360
  this.handleError(error);
355
361
  return throwError(() => new HttpErrorResponse(error));
356
362
  }));
357
363
  }
358
364
  patch(url, params = {}) {
359
- return this.http.patch(`${this.baseUrl}${url}`, params).pipe(catchError(error => {
365
+ return this.http.patch(this.buildUrl(url), params).pipe(catchError(error => {
360
366
  this.handleError(error);
361
367
  return throwError(() => new HttpErrorResponse(error));
362
368
  }));
363
369
  }
364
370
  delete(url, option = {}) {
365
- return this.http.delete(`${this.baseUrl}${url}`, option).pipe(catchError(error => {
371
+ return this.http.delete(this.buildUrl(url), option).pipe(catchError(error => {
366
372
  this.handleError(error);
367
373
  return throwError(() => new HttpErrorResponse(error));
368
374
  }));
@@ -371,7 +377,7 @@ class BaseHttpService {
371
377
  const formData = new FormData();
372
378
  formData.append(param, file);
373
379
  const headers = new HttpHeaders({ enctype: 'multipart/form-data' });
374
- return this.http.put(`${this.baseUrl}${url}`, formData, { headers }).pipe(catchError(error => {
380
+ return this.http.put(this.buildUrl(url), formData, { headers }).pipe(catchError(error => {
375
381
  this.handleError(error);
376
382
  return throwError(() => new HttpErrorResponse(error));
377
383
  }));
@@ -385,7 +391,7 @@ class BaseHttpService {
385
391
  }
386
392
  }
387
393
  const headers = new HttpHeaders({ enctype: 'multipart/form-data' });
388
- return this.http.post(`${this.baseUrl}${url}`, formData, { headers }).pipe(catchError(error => {
394
+ return this.http.post(this.buildUrl(url), formData, { headers }).pipe(catchError(error => {
389
395
  this.handleError(error);
390
396
  return throwError(() => new HttpErrorResponse(error));
391
397
  }));
@@ -398,12 +404,12 @@ class BaseHttpService {
398
404
  this.toast.showToast(error);
399
405
  }
400
406
  }
401
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BaseHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
407
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BaseHttpService, deps: [{ token: i1$1.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
402
408
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BaseHttpService }); }
403
409
  }
404
410
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BaseHttpService, decorators: [{
405
411
  type: Injectable
406
- }], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
412
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: i0.Injector }] });
407
413
 
408
414
  class IntegrationsApiHttpService extends BaseHttpService {
409
415
  constructor(http, injector) {
@@ -416,7 +422,7 @@ class IntegrationsApiHttpService extends BaseHttpService {
416
422
  : config?.['links']?.integrations_api;
417
423
  });
418
424
  }
419
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: IntegrationsApiHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
425
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: IntegrationsApiHttpService, deps: [{ token: i1$1.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
420
426
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: IntegrationsApiHttpService, providedIn: 'root' }); }
421
427
  }
422
428
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: IntegrationsApiHttpService, decorators: [{
@@ -424,7 +430,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
424
430
  args: [{
425
431
  providedIn: 'root'
426
432
  }]
427
- }], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
433
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: i0.Injector }] });
428
434
 
429
435
  class LocalStorage {
430
436
  getItem$(key) {
@@ -464,7 +470,7 @@ class MainApiHttpService extends BaseHttpService {
464
470
  this.baseUrl = isDevMode() ? MAIN_API_PREFIX : config?.['links']?.main_api;
465
471
  });
466
472
  }
467
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MainApiHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
473
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MainApiHttpService, deps: [{ token: i1$1.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
468
474
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MainApiHttpService, providedIn: 'root' }); }
469
475
  }
470
476
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MainApiHttpService, decorators: [{
@@ -472,7 +478,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
472
478
  args: [{
473
479
  providedIn: 'root'
474
480
  }]
475
- }], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
481
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: i0.Injector }] });
476
482
 
477
483
  /**
478
484
  * Secure Token Storage Service
@@ -698,11 +704,11 @@ class SecureTokenStorageService {
698
704
  }
699
705
  return null;
700
706
  }
701
- /**
702
- * Delete cookie
703
- */
707
+ // Attributes MUST mirror setSecureCookie — browsers require matching
708
+ // Secure + SameSite for the delete to take effect on HTTPS.
704
709
  deleteCookie(name) {
705
- this.document.cookie = `${name}=; Path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
710
+ const isSecure = this.document.location.protocol === 'https:';
711
+ this.document.cookie = `${name}=; Path=/; ${isSecure ? 'Secure; ' : ''}SameSite=Strict; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
706
712
  }
707
713
  /**
708
714
  * Initialize tokens from storage on service startup
@@ -1007,7 +1013,7 @@ class UserService {
1007
1013
  refreshUserApiTokens() {
1008
1014
  return this.api.get(`${this.endpoint}/refresh_user_api_tokens`);
1009
1015
  }
1010
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserService, deps: [{ token: MainApiHttpService }, { token: i2.Store }, { token: i3.Router }, { token: i1.AppConfigService }, { token: ProfileService }, { token: CustomToastService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1016
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserService, deps: [{ token: MainApiHttpService }, { token: i3$1.Store }, { token: i3.Router }, { token: i2.AppConfigService }, { token: ProfileService }, { token: CustomToastService }], target: i0.ɵɵFactoryTarget.Injectable }); }
1011
1017
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserService, providedIn: 'root' }); }
1012
1018
  }
1013
1019
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: UserService, decorators: [{
@@ -1015,7 +1021,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
1015
1021
  args: [{
1016
1022
  providedIn: 'root'
1017
1023
  }]
1018
- }], ctorParameters: () => [{ type: MainApiHttpService }, { type: i2.Store }, { type: i3.Router }, { type: i1.AppConfigService }, { type: ProfileService }, { type: CustomToastService }] });
1024
+ }], ctorParameters: () => [{ type: MainApiHttpService }, { type: i3$1.Store }, { type: i3.Router }, { type: i2.AppConfigService }, { type: ProfileService }, { type: CustomToastService }] });
1019
1025
 
1020
1026
  class AuthService {
1021
1027
  constructor(localStorage, secureTokenStorage, router, http, userService, toastr, appConfigService, integrationsApi, document) {
@@ -1157,6 +1163,7 @@ class AuthService {
1157
1163
  }
1158
1164
  return this.http.delete('session', options).pipe(tap$1(() => {
1159
1165
  this.secureTokenStorage.clearTokens().subscribe();
1166
+ this.clearBrainChatStorage();
1160
1167
  // Reset Crisp session on logout so next visitor is anonymous again
1161
1168
  if (typeof window?.$crisp?.push === 'function') {
1162
1169
  window.$crisp.push(['do', 'session:reset']);
@@ -1167,6 +1174,25 @@ class AuthService {
1167
1174
  }
1168
1175
  }));
1169
1176
  }
1177
+ /**
1178
+ * Wipe every `pw-brain.*` localStorage key on logout so the next user
1179
+ * on a shared browser doesn't inherit the previous user's chat thread
1180
+ * (ticket #4167). Best-effort: private-browsing / quota throws are
1181
+ * swallowed so logout never breaks.
1182
+ */
1183
+ clearBrainChatStorage() {
1184
+ try {
1185
+ for (let i = localStorage.length - 1; i >= 0; i--) {
1186
+ const key = localStorage.key(i);
1187
+ if (key?.startsWith('pw-brain.')) {
1188
+ localStorage.removeItem(key);
1189
+ }
1190
+ }
1191
+ }
1192
+ catch {
1193
+ // ignored — best-effort cleanup
1194
+ }
1195
+ }
1170
1196
  /**
1171
1197
  * Clear all authentication tokens
1172
1198
  */
@@ -1374,12 +1400,12 @@ class AuthService {
1374
1400
  }
1375
1401
  });
1376
1402
  }
1377
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AuthService, deps: [{ token: LocalStorage }, { token: SecureTokenStorageService }, { token: i3.Router }, { token: MainApiHttpService }, { token: UserService }, { token: CustomToastService }, { token: i1.AppConfigService }, { token: IntegrationsApiHttpService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
1403
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AuthService, deps: [{ token: LocalStorage }, { token: SecureTokenStorageService }, { token: i3.Router }, { token: MainApiHttpService }, { token: UserService }, { token: CustomToastService }, { token: i2.AppConfigService }, { token: IntegrationsApiHttpService }, { token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
1378
1404
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AuthService }); }
1379
1405
  }
1380
1406
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AuthService, decorators: [{
1381
1407
  type: Injectable
1382
- }], ctorParameters: () => [{ type: LocalStorage }, { type: SecureTokenStorageService }, { type: i3.Router }, { type: MainApiHttpService }, { type: UserService }, { type: CustomToastService }, { type: i1.AppConfigService }, { type: IntegrationsApiHttpService }, { type: Document, decorators: [{
1408
+ }], ctorParameters: () => [{ type: LocalStorage }, { type: SecureTokenStorageService }, { type: i3.Router }, { type: MainApiHttpService }, { type: UserService }, { type: CustomToastService }, { type: i2.AppConfigService }, { type: IntegrationsApiHttpService }, { type: Document, decorators: [{
1383
1409
  type: Inject,
1384
1410
  args: [DOCUMENT]
1385
1411
  }] }] });
@@ -1406,7 +1432,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
1406
1432
 
1407
1433
  class CommonServicesModule {
1408
1434
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CommonServicesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
1409
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.6", ngImport: i0, type: CommonServicesModule, imports: [CommonModule, i1$3.EffectsRootModule, i2.StoreRootModule] }); }
1435
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.6", ngImport: i0, type: CommonServicesModule, imports: [CommonModule, i1$2.EffectsRootModule, i3$1.StoreRootModule] }); }
1410
1436
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CommonServicesModule, providers: [AuthService], imports: [CommonModule, EffectsModule.forRoot([UserEffects]), StoreModule.forRoot(appReducers)] }); }
1411
1437
  }
1412
1438
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: CommonServicesModule, decorators: [{
@@ -1446,7 +1472,7 @@ class SeoService {
1446
1472
  this.meta.updateTag({ name: 'twitter:description', content: description });
1447
1473
  this.meta.updateTag({ name: 'twitter:card', content: 'summary' });
1448
1474
  }
1449
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SeoService, deps: [{ token: i1$4.Meta }, { token: i1$4.Title }], target: i0.ɵɵFactoryTarget.Injectable }); }
1475
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SeoService, deps: [{ token: i1$3.Meta }, { token: i1$3.Title }], target: i0.ɵɵFactoryTarget.Injectable }); }
1450
1476
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SeoService, providedIn: 'root' }); }
1451
1477
  }
1452
1478
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SeoService, decorators: [{
@@ -1454,7 +1480,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
1454
1480
  args: [{
1455
1481
  providedIn: 'root'
1456
1482
  }]
1457
- }], ctorParameters: () => [{ type: i1$4.Meta }, { type: i1$4.Title }] });
1483
+ }], ctorParameters: () => [{ type: i1$3.Meta }, { type: i1$3.Title }] });
1458
1484
 
1459
1485
  /**
1460
1486
  * Centralized feature flag evaluation service.
@@ -1912,7 +1938,7 @@ class AbTestService {
1912
1938
  ? this.injector.get(service)
1913
1939
  : this.injector.get(MainApiHttpService);
1914
1940
  }
1915
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AbTestService, deps: [{ token: i0.Injector }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
1941
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AbTestService, deps: [{ token: i0.Injector }, { token: i1$1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
1916
1942
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AbTestService, providedIn: 'root' }); }
1917
1943
  }
1918
1944
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AbTestService, decorators: [{
@@ -1920,7 +1946,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
1920
1946
  args: [{
1921
1947
  providedIn: 'root'
1922
1948
  }]
1923
- }], ctorParameters: () => [{ type: i0.Injector }, { type: i1$2.HttpClient }] });
1949
+ }], ctorParameters: () => [{ type: i0.Injector }, { type: i1$1.HttpClient }] });
1924
1950
 
1925
1951
  class GeoService {
1926
1952
  constructor(api, cookieService) {
@@ -2024,8 +2050,8 @@ class SubscriptionService {
2024
2050
  toggleAdmin(id, data) {
2025
2051
  return this.api.put(`/subscriptions/${id}/toggle_admin`, data);
2026
2052
  }
2027
- updateSubscriptionAPIKey(id) {
2028
- return this.api.put(`/subscriptions/${id}/update_api_key`);
2053
+ updateSubscriptionAPIKey(id, productId) {
2054
+ return this.api.put(`/subscriptions/${id}/update_api_key`, { product_id: productId });
2029
2055
  }
2030
2056
  refreshApiTokens(id) {
2031
2057
  return this.api.get(`/subscriptions/${id}/refresh_api_tokens`);
@@ -2229,11 +2255,17 @@ class AhoyService {
2229
2255
  this.ahoy = '/ahoy';
2230
2256
  this.toast = injector.get(CustomToastService);
2231
2257
  }
2258
+ // AhoyService does not extend BaseHttpService, so it needs its own
2259
+ // slash normalization: the micro-service base URL ends with '/' and the
2260
+ // path segments below start with '/', producing '/main-api/v1//versions'.
2261
+ buildUrl(url) {
2262
+ return url.replace(/([^:]\/)\/+/g, '$1');
2263
+ }
2232
2264
  getAhoyEvents(params, service, paging) {
2233
2265
  const baseUrl = HelperService.getBaseUrlMicroService(service);
2234
2266
  const page = HelperService.getPagingParams(paging);
2235
2267
  return this.http
2236
- .get(`${baseUrl}${this.ahoy}/events`, {
2268
+ .get(this.buildUrl(`${baseUrl}${this.ahoy}/events`), {
2237
2269
  params: { ...page, ...params }
2238
2270
  })
2239
2271
  .pipe(catchError(error => {
@@ -2245,7 +2277,7 @@ class AhoyService {
2245
2277
  const baseUrl = HelperService.getBaseUrlMicroService(service);
2246
2278
  const page = HelperService.getPagingParams(paging);
2247
2279
  return this.http
2248
- .get(`${baseUrl}${this.ahoy}/messages`, {
2280
+ .get(this.buildUrl(`${baseUrl}${this.ahoy}/messages`), {
2249
2281
  params: { ...page, ...params }
2250
2282
  })
2251
2283
  .pipe(catchError(error => {
@@ -2257,7 +2289,7 @@ class AhoyService {
2257
2289
  const baseUrl = HelperService.getBaseUrlMicroService(service);
2258
2290
  const page = HelperService.getPagingParams(paging);
2259
2291
  return this.http
2260
- .get(`${baseUrl}${this.ahoy}/visits`, {
2292
+ .get(this.buildUrl(`${baseUrl}${this.ahoy}/visits`), {
2261
2293
  params: { ...page, ...params }
2262
2294
  })
2263
2295
  .pipe(catchError(error => {
@@ -2269,7 +2301,7 @@ class AhoyService {
2269
2301
  const baseUrl = HelperService.getBaseUrlMicroService(service);
2270
2302
  const page = HelperService.getPagingParams(paging);
2271
2303
  return this.http
2272
- .get(`${baseUrl}/versions/get_all`, {
2304
+ .get(this.buildUrl(`${baseUrl}/versions/get_all`), {
2273
2305
  params: { ...page, ...params }
2274
2306
  })
2275
2307
  .pipe(catchError(error => {
@@ -2281,7 +2313,7 @@ class AhoyService {
2281
2313
  const baseUrl = HelperService.getBaseUrlMicroService(service);
2282
2314
  const page = HelperService.getPagingParams(paging);
2283
2315
  return this.http
2284
- .get(`${baseUrl}/events/get_all`, {
2316
+ .get(this.buildUrl(`${baseUrl}/events/get_all`), {
2285
2317
  params: { ...page, ...params }
2286
2318
  })
2287
2319
  .pipe(catchError(error => {
@@ -2297,7 +2329,7 @@ class AhoyService {
2297
2329
  this.toast.showToast(error);
2298
2330
  }
2299
2331
  }
2300
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AhoyService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
2332
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AhoyService, deps: [{ token: i1$1.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
2301
2333
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AhoyService, providedIn: 'root' }); }
2302
2334
  }
2303
2335
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: AhoyService, decorators: [{
@@ -2305,7 +2337,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
2305
2337
  args: [{
2306
2338
  providedIn: 'root'
2307
2339
  }]
2308
- }], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
2340
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: i0.Injector }] });
2309
2341
 
2310
2342
  class CommonService {
2311
2343
  constructor(api) {
@@ -2348,7 +2380,7 @@ class CommonService {
2348
2380
  return this.api.put(`${NEWSLETTER_SUBSCRIPTION_PATH}/${newsletterId}/toggle`, param);
2349
2381
  }
2350
2382
  unsubscribeNewsletter(token) {
2351
- return this.api.get(`/${NEWSLETTER_UNSUBSCRIBE_PATH}?token=${token}`);
2383
+ return this.api.get(`${NEWSLETTER_UNSUBSCRIBE_PATH}?token=${token}`);
2352
2384
  }
2353
2385
  // FAQ
2354
2386
  getFaq(params) {
@@ -2958,7 +2990,7 @@ class McpJsonRpcService {
2958
2990
  return res.result;
2959
2991
  }));
2960
2992
  }
2961
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: McpJsonRpcService, deps: [{ token: i1$2.HttpClient }, { token: i1.AppConfigService }, { token: i2.Store }], target: i0.ɵɵFactoryTarget.Injectable }); }
2993
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: McpJsonRpcService, deps: [{ token: i1$1.HttpClient }, { token: i2.AppConfigService }, { token: i3$1.Store }], target: i0.ɵɵFactoryTarget.Injectable }); }
2962
2994
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: McpJsonRpcService, providedIn: 'root' }); }
2963
2995
  }
2964
2996
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: McpJsonRpcService, decorators: [{
@@ -2966,7 +2998,99 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
2966
2998
  args: [{
2967
2999
  providedIn: 'root'
2968
3000
  }]
2969
- }], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i1.AppConfigService }, { type: i2.Store }] });
3001
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: i2.AppConfigService }, { type: i3$1.Store }] });
3002
+
3003
+ /* eslint-disable @typescript-eslint/no-explicit-any */
3004
+ class MCPOrchestratorService {
3005
+ /**
3006
+ * Dev base — `BRAIN_API_PREFIX` = '/brain-api/v1/'. In prod the
3007
+ * orchestrator is reached via the API-gateway public hostname; we read
3008
+ * it from `links.brain_api` in app config (same convention as
3009
+ * `BrainApiHttpService`).
3010
+ */
3011
+ constructor(http, appConfigService, store) {
3012
+ this.http = http;
3013
+ this.appConfigService = appConfigService;
3014
+ this.store = store;
3015
+ }
3016
+ execute(body) {
3017
+ return this.post('mcp/execute', body);
3018
+ }
3019
+ interpret(body) {
3020
+ return this.post('mcp/interpret', body);
3021
+ }
3022
+ confirm(body) {
3023
+ return this.post('mcp/confirm', body);
3024
+ }
3025
+ post(path, body) {
3026
+ const base$ = isDevMode()
3027
+ ? of(BRAIN_API_PREFIX.replace(/\/$/, ''))
3028
+ : this.appConfigService.appConfig$.pipe(take(1), switchMap(c => {
3029
+ const url = c?.links?.['brain_api'];
3030
+ if (typeof url === 'string' && url.trim()) {
3031
+ return of(url.trim().replace(/\/$/, ''));
3032
+ }
3033
+ return throwError(() => new Error('Brain API is not configured: set links.brain_api in app configuration.'));
3034
+ }));
3035
+ return base$.pipe(switchMap(base => this.store.pipe(take(1), map((app) => this.pickApiCredentials(app.user?.currentUser ?? null)), switchMap(creds => {
3036
+ if (!creds) {
3037
+ return throwError(() => new Error('PosiWise Brain needs API credentials. Go to /account/details to set or rotate your API keys, then open the active subscription from /account/subscriptions to refresh its credentials.'));
3038
+ }
3039
+ return this.http.post(`${base}/${path}`, body, {
3040
+ headers: this.buildHeaders(creds)
3041
+ });
3042
+ }))));
3043
+ }
3044
+ /**
3045
+ * Pull `(token, userId, clientId?)` for the active session.
3046
+ *
3047
+ * `clientId` comes from `PermissionService.selectedSubscription` — the
3048
+ * canonical "currently-active subscription" on this frontend, set when
3049
+ * the user picks/lands on a subscription. Every other place in the
3050
+ * codebase that needs subscription context (mailbox, chatbox, search,
3051
+ * dashboard, admin lists) reads from the same static. Without it,
3052
+ * downstream MCP tools that require subscription scope (e.g.
3053
+ * `cloudolive-api.count_reconciled_account_inputs`) reject the call
3054
+ * with `McpError: This tool requires subscription context. Please
3055
+ * provide api_client_id parameter`.
3056
+ *
3057
+ * `api_client_id` does NOT live on the `User` interface — it's a
3058
+ * property of `Subscription` (`subscription.interface.ts`). Reading
3059
+ * from the user object would always return `undefined` and silently
3060
+ * drop the header.
3061
+ */
3062
+ pickApiCredentials(user) {
3063
+ if (!user) {
3064
+ return null;
3065
+ }
3066
+ const token = user.api_user_token ?? user.api_keys?.api_user_token;
3067
+ const userId = user.api_user_id ?? user.api_keys?.api_user_id;
3068
+ if (!token || !userId) {
3069
+ return null;
3070
+ }
3071
+ const clientId = PermissionService.selectedSubscription?.api_client_id;
3072
+ return { token, userId, clientId };
3073
+ }
3074
+ buildHeaders(creds) {
3075
+ let h = new HttpHeaders({
3076
+ 'Content-Type': 'application/json',
3077
+ 'X-API-USER-TOKEN': creds.token,
3078
+ 'X-API-USER-ID': creds.userId
3079
+ });
3080
+ if (creds.clientId) {
3081
+ h = h.set('X-API-CLIENT-ID', creds.clientId);
3082
+ }
3083
+ return h;
3084
+ }
3085
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MCPOrchestratorService, deps: [{ token: i1$1.HttpClient }, { token: i2.AppConfigService }, { token: i3$1.Store }], target: i0.ɵɵFactoryTarget.Injectable }); }
3086
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MCPOrchestratorService, providedIn: 'root' }); }
3087
+ }
3088
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: MCPOrchestratorService, decorators: [{
3089
+ type: Injectable,
3090
+ args: [{
3091
+ providedIn: 'root'
3092
+ }]
3093
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: i2.AppConfigService }, { type: i3$1.Store }] });
2970
3094
 
2971
3095
  class WebsocketService {
2972
3096
  constructor(appConfigService, authService) {
@@ -2979,7 +3103,7 @@ class WebsocketService {
2979
3103
  this.webSocket$ = this.webSocketSubject.asObservable().pipe(distinctUntilChanged());
2980
3104
  });
2981
3105
  }
2982
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: WebsocketService, deps: [{ token: i1.AppConfigService }, { token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3106
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: WebsocketService, deps: [{ token: i2.AppConfigService }, { token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable }); }
2983
3107
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: WebsocketService, providedIn: 'root' }); }
2984
3108
  }
2985
3109
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: WebsocketService, decorators: [{
@@ -2987,7 +3111,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
2987
3111
  args: [{
2988
3112
  providedIn: 'root'
2989
3113
  }]
2990
- }], ctorParameters: () => [{ type: i1.AppConfigService }, { type: AuthService }] });
3114
+ }], ctorParameters: () => [{ type: i2.AppConfigService }, { type: AuthService }] });
2991
3115
 
2992
3116
  class NotificationService {
2993
3117
  constructor(api, toastrService, socketService) {
@@ -3535,7 +3659,7 @@ class SentryErrorHandler {
3535
3659
  console.error(error, e);
3536
3660
  }
3537
3661
  }
3538
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SentryErrorHandler, deps: [{ token: i1.AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3662
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SentryErrorHandler, deps: [{ token: i2.AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
3539
3663
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SentryErrorHandler, providedIn: 'root' }); }
3540
3664
  }
3541
3665
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: SentryErrorHandler, decorators: [{
@@ -3543,7 +3667,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
3543
3667
  args: [{
3544
3668
  providedIn: 'root'
3545
3669
  }]
3546
- }], ctorParameters: () => [{ type: i1.AppConfigService }] });
3670
+ }], ctorParameters: () => [{ type: i2.AppConfigService }] });
3547
3671
 
3548
3672
  class LogoCacheService {
3549
3673
  constructor() {
@@ -3659,7 +3783,7 @@ class BrainApiHttpService extends BaseHttpService {
3659
3783
  this.baseUrl = isDevMode() ? BRAIN_API_PREFIX : config?.['links']['brain_api'] ?? '';
3660
3784
  });
3661
3785
  }
3662
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BrainApiHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
3786
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BrainApiHttpService, deps: [{ token: i1$1.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
3663
3787
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BrainApiHttpService, providedIn: 'root' }); }
3664
3788
  }
3665
3789
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImport: i0, type: BrainApiHttpService, decorators: [{
@@ -3667,7 +3791,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
3667
3791
  args: [{
3668
3792
  providedIn: 'root'
3669
3793
  }]
3670
- }], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
3794
+ }], ctorParameters: () => [{ type: i1$1.HttpClient }, { type: i0.Injector }] });
3671
3795
 
3672
3796
  class BrainApiService {
3673
3797
  constructor(api) {
@@ -3694,5 +3818,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.6", ngImpor
3694
3818
  * Generated bundle index. Do not edit.
3695
3819
  */
3696
3820
 
3697
- export { AbTestService, AhoyService, AuthService, BaseHttpService, BrainApiHttpService, BrainApiService, CommonService, CommonServicesModule, CustomPreloadingStrategy, CustomToastService, DashboardService, DataService, FeatureFlagService, FormHelperService, GeoService, GoogleAnalyticsService, GroupService, HopscotchService, IntegrationsApiHttpService, LinkService, LocalStorage, LogoCacheService, MailBoxService, MainApiHttpService, McpJsonRpcService, NgbDateCustomParserFormatter, NotificationService, NumberPickerService, PermissionService, PrimeNgHelper, ProductService, ProfileService, QualificationService, ScriptLoaderService, SecureTokenStorageService, SentryErrorHandler, SeoService, SubscriptionService, TagService, TipsService, UserEffects, UserService, ValidationService, WebsocketService, WindowService };
3821
+ export { AbTestService, AhoyService, AuthService, BaseHttpService, BrainApiHttpService, BrainApiService, CommonService, CommonServicesModule, CustomPreloadingStrategy, CustomToastService, DashboardService, DataService, FeatureFlagService, FormHelperService, GeoService, GoogleAnalyticsService, GroupService, HopscotchService, IntegrationsApiHttpService, LinkService, LocalStorage, LogoCacheService, MCPOrchestratorService, MailBoxService, MainApiHttpService, McpJsonRpcService, NgbDateCustomParserFormatter, NotificationService, NumberPickerService, PermissionService, PrimeNgHelper, ProductService, ProfileService, QualificationService, ScriptLoaderService, SecureTokenStorageService, SentryErrorHandler, SeoService, SubscriptionService, TagService, TipsService, UserEffects, UserService, ValidationService, WebsocketService, WindowService };
3698
3822
  //# sourceMappingURL=posiwise-common-services.mjs.map