@posiwise/common-services 0.1.75 → 0.1.77
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.
- package/esm2022/index.mjs +2 -2
- package/esm2022/lib/auth.service.mjs +33 -22
- package/esm2022/lib/brain.service.mjs +1 -1
- package/esm2022/lib/permission.service.mjs +158 -3
- package/esm2022/lib/secure-token-storage.service.mjs +264 -0
- package/esm2022/lib/sentry.service.mjs +2 -2
- package/esm2022/lib/subscription.service.mjs +4 -1
- package/fesm2022/posiwise-common-services.mjs +475 -81
- package/fesm2022/posiwise-common-services.mjs.map +1 -1
- package/index.d.ts +1 -1
- package/lib/auth.service.d.ts +8 -2
- package/lib/brain.service.d.ts +1 -1
- package/lib/permission.service.d.ts +27 -0
- package/lib/secure-token-storage.service.d.ts +94 -0
- package/lib/subscription.service.d.ts +1 -0
- package/package.json +1 -1
- package/esm2022/lib/jquery.service.mjs +0 -35
- package/lib/jquery.service.d.ts +0 -14
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
2
|
import { Injectable, Inject, isDevMode, inject, NgModule, ViewEncapsulation } from '@angular/core';
|
|
3
|
-
import * as
|
|
3
|
+
import * as i3 from '@angular/router';
|
|
4
4
|
import { NavigationEnd } from '@angular/router';
|
|
5
|
-
import * as i1
|
|
5
|
+
import * as i1 from '@posiwise/app-config-service';
|
|
6
6
|
import { AppConfigService } from '@posiwise/app-config-service';
|
|
7
7
|
import { DOCUMENT, CommonModule } from '@angular/common';
|
|
8
|
-
import * as i1$
|
|
8
|
+
import * as i1$2 from '@angular/common/http';
|
|
9
9
|
import { HttpErrorResponse, HttpHeaders } from '@angular/common/http';
|
|
10
|
-
import { throwError, of,
|
|
10
|
+
import { throwError, of, BehaviorSubject, tap, timer } from 'rxjs';
|
|
11
11
|
import { catchError, switchMap, map, mergeMap, tap as tap$1, distinctUntilChanged } from 'rxjs/operators';
|
|
12
12
|
import { HelperService } from '@posiwise/helper-service';
|
|
13
|
-
import * as i1$
|
|
13
|
+
import * as i1$1 from 'ngx-toastr';
|
|
14
14
|
import { getUser, UserActionTypes, SetUser, appReducers } from '@posiwise/app-store';
|
|
15
|
-
import * as i1$
|
|
15
|
+
import * as i1$3 from '@ngrx/effects';
|
|
16
16
|
import { Actions, createEffect, ofType, EffectsModule } from '@ngrx/effects';
|
|
17
17
|
import * as i2 from '@ngrx/store';
|
|
18
18
|
import { StoreModule } from '@ngrx/store';
|
|
19
|
-
import { INTEGRATIONS_API_PREFIX, MAIN_API_PREFIX, USER_PATH,
|
|
19
|
+
import { INTEGRATIONS_API_PREFIX, MAIN_API_PREFIX, 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, PROJECT_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';
|
|
20
20
|
import swal from 'sweetalert2';
|
|
21
21
|
import cloneDeep from 'lodash/cloneDeep';
|
|
22
22
|
import pickBy from 'lodash/pickBy';
|
|
@@ -212,12 +212,12 @@ class GoogleAnalyticsService {
|
|
|
212
212
|
this.subscription.unsubscribe();
|
|
213
213
|
}
|
|
214
214
|
}
|
|
215
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: GoogleAnalyticsService, deps: [{ token:
|
|
215
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: GoogleAnalyticsService, deps: [{ token: i3.Router }, { token: ScriptLoaderService }, { token: i1.AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
216
216
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: GoogleAnalyticsService }); }
|
|
217
217
|
}
|
|
218
218
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: GoogleAnalyticsService, decorators: [{
|
|
219
219
|
type: Injectable
|
|
220
|
-
}], ctorParameters: () => [{ type:
|
|
220
|
+
}], ctorParameters: () => [{ type: i3.Router }, { type: ScriptLoaderService }, { type: i1.AppConfigService }] });
|
|
221
221
|
|
|
222
222
|
class CustomToastService {
|
|
223
223
|
constructor(toastr) {
|
|
@@ -289,7 +289,7 @@ class CustomToastService {
|
|
|
289
289
|
this.error(message);
|
|
290
290
|
}
|
|
291
291
|
}
|
|
292
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CustomToastService, deps: [{ token: i1$
|
|
292
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CustomToastService, deps: [{ token: i1$1.ToastrService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
293
293
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CustomToastService, providedIn: 'root' }); }
|
|
294
294
|
}
|
|
295
295
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CustomToastService, decorators: [{
|
|
@@ -297,7 +297,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
297
297
|
args: [{
|
|
298
298
|
providedIn: 'root'
|
|
299
299
|
}]
|
|
300
|
-
}], ctorParameters: () => [{ type: i1$
|
|
300
|
+
}], ctorParameters: () => [{ type: i1$1.ToastrService }] });
|
|
301
301
|
|
|
302
302
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
303
303
|
class BaseHttpService {
|
|
@@ -383,12 +383,12 @@ class BaseHttpService {
|
|
|
383
383
|
this.toast.showToast(error);
|
|
384
384
|
}
|
|
385
385
|
}
|
|
386
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BaseHttpService, deps: [{ token: i1$
|
|
386
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BaseHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
387
387
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BaseHttpService }); }
|
|
388
388
|
}
|
|
389
389
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BaseHttpService, decorators: [{
|
|
390
390
|
type: Injectable
|
|
391
|
-
}], ctorParameters: () => [{ type: i1$
|
|
391
|
+
}], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
|
|
392
392
|
|
|
393
393
|
class IntegrationsApiHttpService extends BaseHttpService {
|
|
394
394
|
constructor(http, injector) {
|
|
@@ -401,7 +401,7 @@ class IntegrationsApiHttpService extends BaseHttpService {
|
|
|
401
401
|
: config?.['links']?.integrations_api;
|
|
402
402
|
});
|
|
403
403
|
}
|
|
404
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: IntegrationsApiHttpService, deps: [{ token: i1$
|
|
404
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: IntegrationsApiHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
405
405
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: IntegrationsApiHttpService, providedIn: 'root' }); }
|
|
406
406
|
}
|
|
407
407
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: IntegrationsApiHttpService, decorators: [{
|
|
@@ -409,7 +409,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
409
409
|
args: [{
|
|
410
410
|
providedIn: 'root'
|
|
411
411
|
}]
|
|
412
|
-
}], ctorParameters: () => [{ type: i1$
|
|
412
|
+
}], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
|
|
413
413
|
|
|
414
414
|
class LocalStorage {
|
|
415
415
|
getItem$(key) {
|
|
@@ -449,7 +449,7 @@ class MainApiHttpService extends BaseHttpService {
|
|
|
449
449
|
this.baseUrl = isDevMode() ? MAIN_API_PREFIX : config?.['links']?.main_api;
|
|
450
450
|
});
|
|
451
451
|
}
|
|
452
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: MainApiHttpService, deps: [{ token: i1$
|
|
452
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: MainApiHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
453
453
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: MainApiHttpService, providedIn: 'root' }); }
|
|
454
454
|
}
|
|
455
455
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: MainApiHttpService, decorators: [{
|
|
@@ -457,7 +457,267 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
457
457
|
args: [{
|
|
458
458
|
providedIn: 'root'
|
|
459
459
|
}]
|
|
460
|
-
}], ctorParameters: () => [{ type: i1$
|
|
460
|
+
}], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Secure Token Storage Service
|
|
464
|
+
*
|
|
465
|
+
* This service provides secure token storage using memory + secure cookies.
|
|
466
|
+
* NO localStorage usage - tokens are stored only in memory and secure cookies.
|
|
467
|
+
*
|
|
468
|
+
* Security Features:
|
|
469
|
+
* - Memory storage (primary) - not persistent across refreshes
|
|
470
|
+
* - Secure cookies (backup) - with SameSite=Strict protection
|
|
471
|
+
* - No localStorage - prevents XSS token theft
|
|
472
|
+
* - Secure flag for HTTPS
|
|
473
|
+
* - CSRF protection via SameSite cookies
|
|
474
|
+
*/
|
|
475
|
+
class SecureTokenStorageService {
|
|
476
|
+
constructor(document) {
|
|
477
|
+
this.document = document;
|
|
478
|
+
this.TOKEN_COOKIE_NAME = 'auth_token';
|
|
479
|
+
this.IMPERSONATED_TOKEN_COOKIE_NAME = 'user_impersonated_token';
|
|
480
|
+
this.PHONEGAP_TOKEN_COOKIE_NAME = 'user_impersonated_phonegap_token';
|
|
481
|
+
// In-memory fallback for development or when cookies are not available
|
|
482
|
+
this.memoryStorage = new Map();
|
|
483
|
+
this.tokenSubject = new BehaviorSubject(null);
|
|
484
|
+
this.impersonatedTokenSubject = new BehaviorSubject(null);
|
|
485
|
+
this.phonegapTokenSubject = new BehaviorSubject(null);
|
|
486
|
+
this.initializeTokens();
|
|
487
|
+
}
|
|
488
|
+
/**
|
|
489
|
+
* Store authentication token securely
|
|
490
|
+
*/
|
|
491
|
+
storeToken(token) {
|
|
492
|
+
try {
|
|
493
|
+
// Store ONLY in memory and secure cookie - NO localStorage
|
|
494
|
+
this.memoryStorage.set(this.TOKEN_COOKIE_NAME, token);
|
|
495
|
+
this.setSecureCookie(this.TOKEN_COOKIE_NAME, token);
|
|
496
|
+
this.tokenSubject.next(token);
|
|
497
|
+
return of(true);
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
console.warn('Failed to store token, using memory fallback:', error);
|
|
501
|
+
this.memoryStorage.set(this.TOKEN_COOKIE_NAME, token);
|
|
502
|
+
this.tokenSubject.next(token);
|
|
503
|
+
return of(true);
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
/**
|
|
507
|
+
* Store impersonated user token
|
|
508
|
+
*/
|
|
509
|
+
storeImpersonatedToken(token) {
|
|
510
|
+
try {
|
|
511
|
+
// Store ONLY in memory and secure cookie - NO localStorage
|
|
512
|
+
this.memoryStorage.set(this.IMPERSONATED_TOKEN_COOKIE_NAME, token);
|
|
513
|
+
this.setSecureCookie(this.IMPERSONATED_TOKEN_COOKIE_NAME, token);
|
|
514
|
+
this.impersonatedTokenSubject.next(token);
|
|
515
|
+
return of(true);
|
|
516
|
+
}
|
|
517
|
+
catch (error) {
|
|
518
|
+
console.warn('Failed to store impersonated token, using memory fallback:', error);
|
|
519
|
+
this.memoryStorage.set(this.IMPERSONATED_TOKEN_COOKIE_NAME, token);
|
|
520
|
+
this.impersonatedTokenSubject.next(token);
|
|
521
|
+
return of(true);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
/**
|
|
525
|
+
* Store phonegap impersonated token
|
|
526
|
+
*/
|
|
527
|
+
storePhonegapToken(token) {
|
|
528
|
+
try {
|
|
529
|
+
// Store ONLY in memory and secure cookie - NO localStorage
|
|
530
|
+
this.memoryStorage.set(this.PHONEGAP_TOKEN_COOKIE_NAME, token);
|
|
531
|
+
this.setSecureCookie(this.PHONEGAP_TOKEN_COOKIE_NAME, token);
|
|
532
|
+
this.phonegapTokenSubject.next(token);
|
|
533
|
+
return of(true);
|
|
534
|
+
}
|
|
535
|
+
catch (error) {
|
|
536
|
+
console.warn('Failed to store phonegap token, using memory fallback:', error);
|
|
537
|
+
this.memoryStorage.set(this.PHONEGAP_TOKEN_COOKIE_NAME, token);
|
|
538
|
+
this.phonegapTokenSubject.next(token);
|
|
539
|
+
return of(true);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
/**
|
|
543
|
+
* Get authentication token
|
|
544
|
+
*/
|
|
545
|
+
getToken() {
|
|
546
|
+
// Try memory storage first (primary storage)
|
|
547
|
+
const memoryToken = this.memoryStorage.get(this.TOKEN_COOKIE_NAME);
|
|
548
|
+
if (memoryToken) {
|
|
549
|
+
return memoryToken;
|
|
550
|
+
}
|
|
551
|
+
// Try cookie as backup
|
|
552
|
+
const cookieToken = this.getCookieValue(this.TOKEN_COOKIE_NAME);
|
|
553
|
+
if (cookieToken) {
|
|
554
|
+
// Restore to memory storage
|
|
555
|
+
this.memoryStorage.set(this.TOKEN_COOKIE_NAME, cookieToken);
|
|
556
|
+
return cookieToken;
|
|
557
|
+
}
|
|
558
|
+
return null;
|
|
559
|
+
}
|
|
560
|
+
/**
|
|
561
|
+
* Get impersonated token
|
|
562
|
+
*/
|
|
563
|
+
getImpersonatedToken() {
|
|
564
|
+
const memoryToken = this.memoryStorage.get(this.IMPERSONATED_TOKEN_COOKIE_NAME);
|
|
565
|
+
if (memoryToken) {
|
|
566
|
+
return memoryToken;
|
|
567
|
+
}
|
|
568
|
+
const cookieToken = this.getCookieValue(this.IMPERSONATED_TOKEN_COOKIE_NAME);
|
|
569
|
+
if (cookieToken) {
|
|
570
|
+
this.memoryStorage.set(this.IMPERSONATED_TOKEN_COOKIE_NAME, cookieToken);
|
|
571
|
+
return cookieToken;
|
|
572
|
+
}
|
|
573
|
+
return null;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* Get phonegap token
|
|
577
|
+
*/
|
|
578
|
+
getPhonegapToken() {
|
|
579
|
+
const memoryToken = this.memoryStorage.get(this.PHONEGAP_TOKEN_COOKIE_NAME);
|
|
580
|
+
if (memoryToken) {
|
|
581
|
+
return memoryToken;
|
|
582
|
+
}
|
|
583
|
+
const cookieToken = this.getCookieValue(this.PHONEGAP_TOKEN_COOKIE_NAME);
|
|
584
|
+
if (cookieToken) {
|
|
585
|
+
this.memoryStorage.set(this.PHONEGAP_TOKEN_COOKIE_NAME, cookieToken);
|
|
586
|
+
return cookieToken;
|
|
587
|
+
}
|
|
588
|
+
return null;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Get token as Observable
|
|
592
|
+
*/
|
|
593
|
+
getToken$() {
|
|
594
|
+
return this.tokenSubject.asObservable();
|
|
595
|
+
}
|
|
596
|
+
/**
|
|
597
|
+
* Get impersonated token as Observable
|
|
598
|
+
*/
|
|
599
|
+
getImpersonatedToken$() {
|
|
600
|
+
return this.impersonatedTokenSubject.asObservable();
|
|
601
|
+
}
|
|
602
|
+
/**
|
|
603
|
+
* Get phonegap token as Observable
|
|
604
|
+
*/
|
|
605
|
+
getPhonegapToken$() {
|
|
606
|
+
return this.phonegapTokenSubject.asObservable();
|
|
607
|
+
}
|
|
608
|
+
/**
|
|
609
|
+
* Remove all tokens
|
|
610
|
+
*/
|
|
611
|
+
clearTokens() {
|
|
612
|
+
try {
|
|
613
|
+
// Clear cookies
|
|
614
|
+
this.deleteCookie(this.TOKEN_COOKIE_NAME);
|
|
615
|
+
this.deleteCookie(this.IMPERSONATED_TOKEN_COOKIE_NAME);
|
|
616
|
+
this.deleteCookie(this.PHONEGAP_TOKEN_COOKIE_NAME);
|
|
617
|
+
}
|
|
618
|
+
catch (error) {
|
|
619
|
+
console.warn('Failed to clear cookies:', error);
|
|
620
|
+
}
|
|
621
|
+
// Clear memory storage
|
|
622
|
+
this.memoryStorage.delete(this.TOKEN_COOKIE_NAME);
|
|
623
|
+
this.memoryStorage.delete(this.IMPERSONATED_TOKEN_COOKIE_NAME);
|
|
624
|
+
this.memoryStorage.delete(this.PHONEGAP_TOKEN_COOKIE_NAME);
|
|
625
|
+
// Update subjects
|
|
626
|
+
this.tokenSubject.next(null);
|
|
627
|
+
this.impersonatedTokenSubject.next(null);
|
|
628
|
+
this.phonegapTokenSubject.next(null);
|
|
629
|
+
return of(true);
|
|
630
|
+
}
|
|
631
|
+
/**
|
|
632
|
+
* Remove specific token
|
|
633
|
+
*/
|
|
634
|
+
removeToken() {
|
|
635
|
+
try {
|
|
636
|
+
this.deleteCookie(this.TOKEN_COOKIE_NAME);
|
|
637
|
+
}
|
|
638
|
+
catch (error) {
|
|
639
|
+
console.warn('Failed to remove token:', error);
|
|
640
|
+
}
|
|
641
|
+
this.memoryStorage.delete(this.TOKEN_COOKIE_NAME);
|
|
642
|
+
this.tokenSubject.next(null);
|
|
643
|
+
return of(true);
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Remove impersonated tokens
|
|
647
|
+
*/
|
|
648
|
+
removeImpersonatedTokens() {
|
|
649
|
+
try {
|
|
650
|
+
this.deleteCookie(this.IMPERSONATED_TOKEN_COOKIE_NAME);
|
|
651
|
+
this.deleteCookie(this.PHONEGAP_TOKEN_COOKIE_NAME);
|
|
652
|
+
}
|
|
653
|
+
catch (error) {
|
|
654
|
+
console.warn('Failed to remove impersonated tokens:', error);
|
|
655
|
+
}
|
|
656
|
+
this.memoryStorage.delete(this.IMPERSONATED_TOKEN_COOKIE_NAME);
|
|
657
|
+
this.memoryStorage.delete(this.PHONEGAP_TOKEN_COOKIE_NAME);
|
|
658
|
+
this.impersonatedTokenSubject.next(null);
|
|
659
|
+
this.phonegapTokenSubject.next(null);
|
|
660
|
+
return of(true);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Set secure cookie
|
|
664
|
+
* Note: HttpOnly cannot be set from client-side JavaScript
|
|
665
|
+
* For maximum security, backend should set httpOnly cookies
|
|
666
|
+
*/
|
|
667
|
+
setSecureCookie(name, value) {
|
|
668
|
+
const isSecure = this.document.location.protocol === 'https:';
|
|
669
|
+
// Set cookie with maximum security possible from client-side
|
|
670
|
+
const cookieString = `${name}=${value}; Path=/; ${isSecure ? 'Secure; ' : ''}SameSite=Strict; Max-Age=86400`;
|
|
671
|
+
this.document.cookie = cookieString;
|
|
672
|
+
// Log warning about security limitations
|
|
673
|
+
console.warn('⚠️ SECURITY WARNING: Cookie is not httpOnly. For maximum security, backend should set httpOnly cookies.');
|
|
674
|
+
}
|
|
675
|
+
/**
|
|
676
|
+
* Get cookie value
|
|
677
|
+
*/
|
|
678
|
+
getCookieValue(name) {
|
|
679
|
+
const value = `; ${this.document.cookie}`;
|
|
680
|
+
const parts = value.split(`; ${name}=`);
|
|
681
|
+
if (parts.length === 2) {
|
|
682
|
+
return parts.pop()?.split(';').shift() || null;
|
|
683
|
+
}
|
|
684
|
+
return null;
|
|
685
|
+
}
|
|
686
|
+
/**
|
|
687
|
+
* Delete cookie
|
|
688
|
+
*/
|
|
689
|
+
deleteCookie(name) {
|
|
690
|
+
this.document.cookie = `${name}=; Path=/; expires=Thu, 01 Jan 1970 00:00:01 GMT;`;
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* Initialize tokens from storage on service startup
|
|
694
|
+
*/
|
|
695
|
+
initializeTokens() {
|
|
696
|
+
const token = this.getToken();
|
|
697
|
+
const impersonatedToken = this.getImpersonatedToken();
|
|
698
|
+
const phonegapToken = this.getPhonegapToken();
|
|
699
|
+
if (token) {
|
|
700
|
+
this.tokenSubject.next(token);
|
|
701
|
+
}
|
|
702
|
+
if (impersonatedToken) {
|
|
703
|
+
this.impersonatedTokenSubject.next(impersonatedToken);
|
|
704
|
+
}
|
|
705
|
+
if (phonegapToken) {
|
|
706
|
+
this.phonegapTokenSubject.next(phonegapToken);
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SecureTokenStorageService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
710
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SecureTokenStorageService, providedIn: 'root' }); }
|
|
711
|
+
}
|
|
712
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SecureTokenStorageService, decorators: [{
|
|
713
|
+
type: Injectable,
|
|
714
|
+
args: [{
|
|
715
|
+
providedIn: 'root'
|
|
716
|
+
}]
|
|
717
|
+
}], ctorParameters: () => [{ type: Document, decorators: [{
|
|
718
|
+
type: Inject,
|
|
719
|
+
args: [DOCUMENT]
|
|
720
|
+
}] }] });
|
|
461
721
|
|
|
462
722
|
class UserService {
|
|
463
723
|
constructor(api, store, router) {
|
|
@@ -549,7 +809,7 @@ class UserService {
|
|
|
549
809
|
postTipsDisregarded(data) {
|
|
550
810
|
return this.api.post('/users/user_tips', data);
|
|
551
811
|
}
|
|
552
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: UserService, deps: [{ token: MainApiHttpService }, { token: i2.Store }, { token:
|
|
812
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: UserService, deps: [{ token: MainApiHttpService }, { token: i2.Store }, { token: i3.Router }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
553
813
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: UserService, providedIn: 'root' }); }
|
|
554
814
|
}
|
|
555
815
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: UserService, decorators: [{
|
|
@@ -557,11 +817,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
557
817
|
args: [{
|
|
558
818
|
providedIn: 'root'
|
|
559
819
|
}]
|
|
560
|
-
}], ctorParameters: () => [{ type: MainApiHttpService }, { type: i2.Store }, { type:
|
|
820
|
+
}], ctorParameters: () => [{ type: MainApiHttpService }, { type: i2.Store }, { type: i3.Router }] });
|
|
561
821
|
|
|
562
822
|
class AuthService {
|
|
563
|
-
constructor(localStorage, router, http, userService, toastr, appConfigService, integrationsApi, document) {
|
|
823
|
+
constructor(localStorage, secureTokenStorage, router, http, userService, toastr, appConfigService, integrationsApi, document) {
|
|
564
824
|
this.localStorage = localStorage;
|
|
825
|
+
this.secureTokenStorage = secureTokenStorage;
|
|
565
826
|
this.router = router;
|
|
566
827
|
this.http = http;
|
|
567
828
|
this.userService = userService;
|
|
@@ -578,20 +839,20 @@ class AuthService {
|
|
|
578
839
|
this.setHeaderKey();
|
|
579
840
|
}
|
|
580
841
|
getToken() {
|
|
581
|
-
if (this.
|
|
842
|
+
if (this.secureTokenStorage.getImpersonatedToken()) {
|
|
582
843
|
this.isUserPersonated = true;
|
|
583
|
-
return this.
|
|
844
|
+
return this.secureTokenStorage.getImpersonatedToken();
|
|
584
845
|
}
|
|
585
|
-
if (this.
|
|
846
|
+
if (this.secureTokenStorage.getPhonegapToken()) {
|
|
586
847
|
this.isUserPersonated = true;
|
|
587
|
-
return this.
|
|
848
|
+
return this.secureTokenStorage.getPhonegapToken();
|
|
588
849
|
}
|
|
589
850
|
this.isUserPersonated = false;
|
|
590
|
-
return this.
|
|
851
|
+
return this.secureTokenStorage.getToken();
|
|
591
852
|
}
|
|
592
853
|
getImpersonatedToken() {
|
|
593
|
-
return (this.
|
|
594
|
-
this.
|
|
854
|
+
return (this.secureTokenStorage.getImpersonatedToken() ||
|
|
855
|
+
this.secureTokenStorage.getPhonegapToken());
|
|
595
856
|
}
|
|
596
857
|
setHeaderKey() {
|
|
597
858
|
// Mobile: app
|
|
@@ -680,7 +941,7 @@ class AuthService {
|
|
|
680
941
|
return this.http.post('session', formData);
|
|
681
942
|
}
|
|
682
943
|
storeToken(token) {
|
|
683
|
-
return this.
|
|
944
|
+
return this.secureTokenStorage.storeToken(token);
|
|
684
945
|
}
|
|
685
946
|
storePlatform(plat) {
|
|
686
947
|
return this.localStorage.setItem$('platform', plat);
|
|
@@ -694,10 +955,18 @@ class AuthService {
|
|
|
694
955
|
phonegap: true
|
|
695
956
|
};
|
|
696
957
|
}
|
|
958
|
+
// Clear all tokens securely
|
|
959
|
+
this.secureTokenStorage.clearTokens().subscribe();
|
|
697
960
|
return this.http.delete('session', options);
|
|
698
961
|
}
|
|
962
|
+
/**
|
|
963
|
+
* Clear all authentication tokens
|
|
964
|
+
*/
|
|
965
|
+
clearTokens() {
|
|
966
|
+
return this.secureTokenStorage.clearTokens();
|
|
967
|
+
}
|
|
699
968
|
getToken$() {
|
|
700
|
-
return this.
|
|
969
|
+
return this.secureTokenStorage.getToken$();
|
|
701
970
|
}
|
|
702
971
|
getNewsletterSubscription(token) {
|
|
703
972
|
return this.http.get(`${NEWSLETTER_CONFIRMATION_PATH}?token=${token}`);
|
|
@@ -778,10 +1047,10 @@ class AuthService {
|
|
|
778
1047
|
}
|
|
779
1048
|
return this.http.post('/session/impersonate_user', data).pipe(map(x => {
|
|
780
1049
|
if (x?.auth_token) {
|
|
781
|
-
this.
|
|
1050
|
+
this.secureTokenStorage.storeImpersonatedToken(x.auth_token);
|
|
782
1051
|
}
|
|
783
1052
|
if (x?.phonegap_token) {
|
|
784
|
-
this.
|
|
1053
|
+
this.secureTokenStorage.storePhonegapToken(x.phonegap_token);
|
|
785
1054
|
}
|
|
786
1055
|
return x;
|
|
787
1056
|
}));
|
|
@@ -832,12 +1101,12 @@ class AuthService {
|
|
|
832
1101
|
}
|
|
833
1102
|
});
|
|
834
1103
|
}
|
|
835
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AuthService, deps: [{ token: LocalStorage }, { token:
|
|
1104
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", 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 }); }
|
|
836
1105
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AuthService }); }
|
|
837
1106
|
}
|
|
838
1107
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AuthService, decorators: [{
|
|
839
1108
|
type: Injectable
|
|
840
|
-
}], ctorParameters: () => [{ type: LocalStorage }, { type:
|
|
1109
|
+
}], ctorParameters: () => [{ type: LocalStorage }, { type: SecureTokenStorageService }, { type: i3.Router }, { type: MainApiHttpService }, { type: UserService }, { type: CustomToastService }, { type: i1.AppConfigService }, { type: IntegrationsApiHttpService }, { type: Document, decorators: [{
|
|
841
1110
|
type: Inject,
|
|
842
1111
|
args: [DOCUMENT]
|
|
843
1112
|
}] }] });
|
|
@@ -864,7 +1133,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
864
1133
|
|
|
865
1134
|
class CommonServicesModule {
|
|
866
1135
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CommonServicesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
867
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: CommonServicesModule, imports: [CommonModule, i1$
|
|
1136
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.11", ngImport: i0, type: CommonServicesModule, imports: [CommonModule, i1$3.EffectsRootModule, i2.StoreRootModule] }); }
|
|
868
1137
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CommonServicesModule, providers: [AuthService], imports: [CommonModule, EffectsModule.forRoot([UserEffects]), StoreModule.forRoot(appReducers)] }); }
|
|
869
1138
|
}
|
|
870
1139
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: CommonServicesModule, decorators: [{
|
|
@@ -1002,8 +1271,8 @@ class PermissionService {
|
|
|
1002
1271
|
}
|
|
1003
1272
|
expr = this.handleNonBooleanPermissions(permission, expr, productKey, permission_key, productSlug);
|
|
1004
1273
|
// Now expr is made of true/false values with &&, ||, ()
|
|
1005
|
-
//
|
|
1006
|
-
return
|
|
1274
|
+
// Safe evaluation of boolean expressions without using eval()
|
|
1275
|
+
return this.evaluateBooleanExpression(expr);
|
|
1007
1276
|
}
|
|
1008
1277
|
handleNonBooleanPermissions(permission, expr, productKey, permission_key, productSlug) {
|
|
1009
1278
|
if (typeof permission !== 'boolean') {
|
|
@@ -1110,6 +1379,161 @@ class PermissionService {
|
|
|
1110
1379
|
getCurrentProduct() {
|
|
1111
1380
|
return JSON.parse(localStorage.getItem('product'));
|
|
1112
1381
|
}
|
|
1382
|
+
/**
|
|
1383
|
+
* Safely evaluates boolean expressions without using eval()
|
|
1384
|
+
* Supports: true, false, &&, ||, (, )
|
|
1385
|
+
* @param expr - Boolean expression string like "true && false || (true && false)"
|
|
1386
|
+
* @returns boolean result
|
|
1387
|
+
*/
|
|
1388
|
+
evaluateBooleanExpression(expr) {
|
|
1389
|
+
if (!expr || typeof expr !== 'string') {
|
|
1390
|
+
return false;
|
|
1391
|
+
}
|
|
1392
|
+
try {
|
|
1393
|
+
// Clean up the expression - remove extra spaces and normalize
|
|
1394
|
+
const cleanExpr = expr.trim().replace(/\s+/g, ' ');
|
|
1395
|
+
// Simple tokenizer for boolean expressions
|
|
1396
|
+
const tokens = this.tokenizeBooleanExpression(cleanExpr);
|
|
1397
|
+
// Parse and evaluate the expression
|
|
1398
|
+
return this.parseBooleanExpression(tokens);
|
|
1399
|
+
}
|
|
1400
|
+
catch (error) {
|
|
1401
|
+
console.warn('Error evaluating boolean expression:', expr, error);
|
|
1402
|
+
return false;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
/**
|
|
1406
|
+
* Tokenizes a boolean expression string
|
|
1407
|
+
*/
|
|
1408
|
+
tokenizeBooleanExpression(expr) {
|
|
1409
|
+
const tokens = [];
|
|
1410
|
+
let i = 0;
|
|
1411
|
+
while (i < expr.length) {
|
|
1412
|
+
const char = expr[i];
|
|
1413
|
+
if (this.isWhitespace(char)) {
|
|
1414
|
+
i++;
|
|
1415
|
+
}
|
|
1416
|
+
else if (this.isParenthesis(char)) {
|
|
1417
|
+
tokens.push(char);
|
|
1418
|
+
i++;
|
|
1419
|
+
}
|
|
1420
|
+
else if (this.isDoubleOperator(expr, i, '&')) {
|
|
1421
|
+
tokens.push('&&');
|
|
1422
|
+
i += 2;
|
|
1423
|
+
}
|
|
1424
|
+
else if (this.isDoubleOperator(expr, i, '|')) {
|
|
1425
|
+
tokens.push('||');
|
|
1426
|
+
i += 2;
|
|
1427
|
+
}
|
|
1428
|
+
else {
|
|
1429
|
+
const token = this.collectToken(expr, i);
|
|
1430
|
+
if (token.value) {
|
|
1431
|
+
tokens.push(token.value);
|
|
1432
|
+
}
|
|
1433
|
+
i = token.nextIndex;
|
|
1434
|
+
}
|
|
1435
|
+
}
|
|
1436
|
+
return tokens;
|
|
1437
|
+
}
|
|
1438
|
+
isWhitespace(char) {
|
|
1439
|
+
return char === ' ';
|
|
1440
|
+
}
|
|
1441
|
+
isParenthesis(char) {
|
|
1442
|
+
return char === '(' || char === ')';
|
|
1443
|
+
}
|
|
1444
|
+
isDoubleOperator(expr, index, operator) {
|
|
1445
|
+
return expr[index] === operator && expr[index + 1] === operator;
|
|
1446
|
+
}
|
|
1447
|
+
collectToken(expr, startIndex) {
|
|
1448
|
+
let current = '';
|
|
1449
|
+
let i = startIndex;
|
|
1450
|
+
while (i < expr.length && ![' ', '(', ')', '&', '|'].includes(expr[i])) {
|
|
1451
|
+
current += expr[i];
|
|
1452
|
+
i++;
|
|
1453
|
+
}
|
|
1454
|
+
return { value: current, nextIndex: i };
|
|
1455
|
+
}
|
|
1456
|
+
/**
|
|
1457
|
+
* Parses and evaluates boolean expression tokens
|
|
1458
|
+
*/
|
|
1459
|
+
parseBooleanExpression(tokens) {
|
|
1460
|
+
// Handle simple cases first
|
|
1461
|
+
if (tokens.length === 1) {
|
|
1462
|
+
return tokens[0] === 'true';
|
|
1463
|
+
}
|
|
1464
|
+
// Convert to postfix notation and evaluate
|
|
1465
|
+
const postfix = this.infixToPostfix(tokens);
|
|
1466
|
+
return this.evaluatePostfix(postfix);
|
|
1467
|
+
}
|
|
1468
|
+
/**
|
|
1469
|
+
* Converts infix notation to postfix (Reverse Polish Notation)
|
|
1470
|
+
*/
|
|
1471
|
+
infixToPostfix(tokens) {
|
|
1472
|
+
const output = [];
|
|
1473
|
+
const operators = [];
|
|
1474
|
+
const precedence = { '||': 1, '&&': 2 };
|
|
1475
|
+
for (const token of tokens) {
|
|
1476
|
+
if (token === 'true' || token === 'false') {
|
|
1477
|
+
output.push(token);
|
|
1478
|
+
}
|
|
1479
|
+
else if (token === '(') {
|
|
1480
|
+
operators.push(token);
|
|
1481
|
+
}
|
|
1482
|
+
else if (token === ')') {
|
|
1483
|
+
while (operators.length > 0 && operators[operators.length - 1] !== '(') {
|
|
1484
|
+
const op = operators.pop();
|
|
1485
|
+
if (op)
|
|
1486
|
+
output.push(op);
|
|
1487
|
+
}
|
|
1488
|
+
operators.pop(); // Remove '('
|
|
1489
|
+
}
|
|
1490
|
+
else if (token === '&&' || token === '||') {
|
|
1491
|
+
while (operators.length > 0 &&
|
|
1492
|
+
operators[operators.length - 1] !== '(' &&
|
|
1493
|
+
precedence[operators[operators.length - 1]] >= precedence[token]) {
|
|
1494
|
+
const op = operators.pop();
|
|
1495
|
+
if (op)
|
|
1496
|
+
output.push(op);
|
|
1497
|
+
}
|
|
1498
|
+
operators.push(token);
|
|
1499
|
+
}
|
|
1500
|
+
}
|
|
1501
|
+
while (operators.length > 0) {
|
|
1502
|
+
const op = operators.pop();
|
|
1503
|
+
if (op)
|
|
1504
|
+
output.push(op);
|
|
1505
|
+
}
|
|
1506
|
+
return output;
|
|
1507
|
+
}
|
|
1508
|
+
/**
|
|
1509
|
+
* Evaluates postfix boolean expression
|
|
1510
|
+
*/
|
|
1511
|
+
evaluatePostfix(postfix) {
|
|
1512
|
+
const stack = [];
|
|
1513
|
+
for (const token of postfix) {
|
|
1514
|
+
if (token === 'true') {
|
|
1515
|
+
stack.push(true);
|
|
1516
|
+
}
|
|
1517
|
+
else if (token === 'false') {
|
|
1518
|
+
stack.push(false);
|
|
1519
|
+
}
|
|
1520
|
+
else if (token === '&&') {
|
|
1521
|
+
const b = stack.pop();
|
|
1522
|
+
const a = stack.pop();
|
|
1523
|
+
if (a !== undefined && b !== undefined) {
|
|
1524
|
+
stack.push(a && b);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
else if (token === '||') {
|
|
1528
|
+
const b = stack.pop();
|
|
1529
|
+
const a = stack.pop();
|
|
1530
|
+
if (a !== undefined && b !== undefined) {
|
|
1531
|
+
stack.push(a || b);
|
|
1532
|
+
}
|
|
1533
|
+
}
|
|
1534
|
+
}
|
|
1535
|
+
return stack[0] || false;
|
|
1536
|
+
}
|
|
1113
1537
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PermissionService, deps: [{ token: MainApiHttpService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1114
1538
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: PermissionService, providedIn: 'root' }); }
|
|
1115
1539
|
}
|
|
@@ -1229,7 +1653,7 @@ class AbTestService {
|
|
|
1229
1653
|
console.log(typeof service);
|
|
1230
1654
|
return service ? this.injector.get(service) : this.injector.get(MainApiHttpService); // fallback to Core Microservice
|
|
1231
1655
|
}
|
|
1232
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AbTestService, deps: [{ token: i0.Injector }, { token: i1$
|
|
1656
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AbTestService, deps: [{ token: i0.Injector }, { token: i1$2.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1233
1657
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AbTestService, providedIn: 'root' }); }
|
|
1234
1658
|
}
|
|
1235
1659
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AbTestService, decorators: [{
|
|
@@ -1237,7 +1661,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
1237
1661
|
args: [{
|
|
1238
1662
|
providedIn: 'root'
|
|
1239
1663
|
}]
|
|
1240
|
-
}], ctorParameters: () => [{ type: i0.Injector }, { type: i1$
|
|
1664
|
+
}], ctorParameters: () => [{ type: i0.Injector }, { type: i1$2.HttpClient }] });
|
|
1241
1665
|
|
|
1242
1666
|
class GeoService {
|
|
1243
1667
|
constructor(api, cookieService) {
|
|
@@ -1403,6 +1827,9 @@ class SubscriptionService {
|
|
|
1403
1827
|
updateSubscriptionAPIKey(id) {
|
|
1404
1828
|
return this.api.put(`/subscriptions/${id}/update_api_key`);
|
|
1405
1829
|
}
|
|
1830
|
+
refreshApiTokens(id) {
|
|
1831
|
+
return this.api.get(`/subscriptions/${id}/refresh_api_tokens`);
|
|
1832
|
+
}
|
|
1406
1833
|
addFullLogo(id, data) {
|
|
1407
1834
|
return this.api.upload(`/subscriptions/${id}`, data, 'full_logo');
|
|
1408
1835
|
}
|
|
@@ -1651,7 +2078,7 @@ class AhoyService {
|
|
|
1651
2078
|
this.toast.showToast(error);
|
|
1652
2079
|
}
|
|
1653
2080
|
}
|
|
1654
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AhoyService, deps: [{ token: i1$
|
|
2081
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AhoyService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1655
2082
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AhoyService, providedIn: 'root' }); }
|
|
1656
2083
|
}
|
|
1657
2084
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: AhoyService, decorators: [{
|
|
@@ -1659,7 +2086,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
1659
2086
|
args: [{
|
|
1660
2087
|
providedIn: 'root'
|
|
1661
2088
|
}]
|
|
1662
|
-
}], ctorParameters: () => [{ type: i1$
|
|
2089
|
+
}], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
|
|
1663
2090
|
|
|
1664
2091
|
class CommonService {
|
|
1665
2092
|
constructor(api) {
|
|
@@ -2257,7 +2684,7 @@ class WebsocketService {
|
|
|
2257
2684
|
this.webSocket$ = this.webSocketSubject.asObservable().pipe(distinctUntilChanged());
|
|
2258
2685
|
});
|
|
2259
2686
|
}
|
|
2260
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: WebsocketService, deps: [{ token: i1
|
|
2687
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: WebsocketService, deps: [{ token: i1.AppConfigService }, { token: AuthService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2261
2688
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: WebsocketService, providedIn: 'root' }); }
|
|
2262
2689
|
}
|
|
2263
2690
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: WebsocketService, decorators: [{
|
|
@@ -2265,7 +2692,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
2265
2692
|
args: [{
|
|
2266
2693
|
providedIn: 'root'
|
|
2267
2694
|
}]
|
|
2268
|
-
}], ctorParameters: () => [{ type: i1
|
|
2695
|
+
}], ctorParameters: () => [{ type: i1.AppConfigService }, { type: AuthService }] });
|
|
2269
2696
|
|
|
2270
2697
|
class NotificationService {
|
|
2271
2698
|
constructor(api, toastrService, socketService) {
|
|
@@ -2492,7 +2919,7 @@ class SentryErrorHandler {
|
|
|
2492
2919
|
});
|
|
2493
2920
|
}
|
|
2494
2921
|
// Check if it's a non-error exception
|
|
2495
|
-
const isNonErrorException = event?.exception?.values?.[0]?.value?.startsWith('Non-Error exception captured')
|
|
2922
|
+
const isNonErrorException = event?.exception?.values?.[0]?.value?.startsWith('Non-Error exception captured') ??
|
|
2496
2923
|
hint?.originalException?.message?.startsWith('Non-Error exception captured');
|
|
2497
2924
|
if (isNonErrorException) {
|
|
2498
2925
|
// We want to ignore those kinds of errors
|
|
@@ -2749,7 +3176,7 @@ class SentryErrorHandler {
|
|
|
2749
3176
|
console.error(error, e);
|
|
2750
3177
|
}
|
|
2751
3178
|
}
|
|
2752
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SentryErrorHandler, deps: [{ token: i1
|
|
3179
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SentryErrorHandler, deps: [{ token: i1.AppConfigService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2753
3180
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SentryErrorHandler, providedIn: 'root' }); }
|
|
2754
3181
|
}
|
|
2755
3182
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: SentryErrorHandler, decorators: [{
|
|
@@ -2757,7 +3184,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
2757
3184
|
args: [{
|
|
2758
3185
|
providedIn: 'root'
|
|
2759
3186
|
}]
|
|
2760
|
-
}], ctorParameters: () => [{ type: i1
|
|
3187
|
+
}], ctorParameters: () => [{ type: i1.AppConfigService }] });
|
|
2761
3188
|
|
|
2762
3189
|
class LogoCacheService {
|
|
2763
3190
|
constructor() {
|
|
@@ -2873,7 +3300,7 @@ class BrainApiHttpService extends BaseHttpService {
|
|
|
2873
3300
|
this.baseUrl = isDevMode() ? BRAIN_API_PREFIX : config?.['links']['brain_api'] ?? '';
|
|
2874
3301
|
});
|
|
2875
3302
|
}
|
|
2876
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BrainApiHttpService, deps: [{ token: i1$
|
|
3303
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BrainApiHttpService, deps: [{ token: i1$2.HttpClient }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2877
3304
|
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BrainApiHttpService, providedIn: 'root' }); }
|
|
2878
3305
|
}
|
|
2879
3306
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: BrainApiHttpService, decorators: [{
|
|
@@ -2881,7 +3308,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
2881
3308
|
args: [{
|
|
2882
3309
|
providedIn: 'root'
|
|
2883
3310
|
}]
|
|
2884
|
-
}], ctorParameters: () => [{ type: i1$
|
|
3311
|
+
}], ctorParameters: () => [{ type: i1$2.HttpClient }, { type: i0.Injector }] });
|
|
2885
3312
|
|
|
2886
3313
|
class BrainApiService {
|
|
2887
3314
|
constructor(api) {
|
|
@@ -2900,39 +3327,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
2900
3327
|
}]
|
|
2901
3328
|
}], ctorParameters: () => [{ type: BrainApiHttpService }] });
|
|
2902
3329
|
|
|
2903
|
-
class JQueryService {
|
|
2904
|
-
constructor() {
|
|
2905
|
-
this.loadPromise = null;
|
|
2906
|
-
}
|
|
2907
|
-
ensure() {
|
|
2908
|
-
if (!this.loadPromise) {
|
|
2909
|
-
this.loadPromise = import('jquery')
|
|
2910
|
-
.then((mod) => {
|
|
2911
|
-
const $ = (mod.default ?? mod);
|
|
2912
|
-
// Only assign if not already set
|
|
2913
|
-
if (!window.$) {
|
|
2914
|
-
window.$ = $;
|
|
2915
|
-
}
|
|
2916
|
-
if (!window.jQuery) {
|
|
2917
|
-
window.jQuery = $;
|
|
2918
|
-
}
|
|
2919
|
-
return $;
|
|
2920
|
-
})
|
|
2921
|
-
.catch(err => {
|
|
2922
|
-
console.error('Failed to load jQuery:', err);
|
|
2923
|
-
throw err;
|
|
2924
|
-
});
|
|
2925
|
-
}
|
|
2926
|
-
return this.loadPromise;
|
|
2927
|
-
}
|
|
2928
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: JQueryService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2929
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: JQueryService, providedIn: 'root' }); }
|
|
2930
|
-
}
|
|
2931
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImport: i0, type: JQueryService, decorators: [{
|
|
2932
|
-
type: Injectable,
|
|
2933
|
-
args: [{ providedIn: 'root' }]
|
|
2934
|
-
}] });
|
|
2935
|
-
|
|
2936
3330
|
/*
|
|
2937
3331
|
* Public API Surface of pw-services
|
|
2938
3332
|
*/
|
|
@@ -2941,5 +3335,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.11", ngImpo
|
|
|
2941
3335
|
* Generated bundle index. Do not edit.
|
|
2942
3336
|
*/
|
|
2943
3337
|
|
|
2944
|
-
export { AbTestService, AhoyService, AuthService, BaseHttpService, BrainApiHttpService, BrainApiService, CommonService, CommonServicesModule, CustomPreloadingStrategy, CustomToastService, DashboardService, DataService, FormHelperService, GeoService, GoogleAnalyticsService, GroupService, HopscotchService, IntegrationsApiHttpService,
|
|
3338
|
+
export { AbTestService, AhoyService, AuthService, BaseHttpService, BrainApiHttpService, BrainApiService, CommonService, CommonServicesModule, CustomPreloadingStrategy, CustomToastService, DashboardService, DataService, FormHelperService, GeoService, GoogleAnalyticsService, GroupService, HopscotchService, IntegrationsApiHttpService, LinkService, LocalStorage, LogoCacheService, MailBoxService, MainApiHttpService, NgbDateCustomParserFormatter, NotificationService, NumberPickerService, PermissionService, PrimeNgHelper, ProductService, ProfileService, QualificationService, ScriptLoaderService, SecureTokenStorageService, SentryErrorHandler, SubscriptionService, TagService, TipsService, UserEffects, UserService, ValidationService, WebsocketService, WindowService };
|
|
2945
3339
|
//# sourceMappingURL=posiwise-common-services.mjs.map
|