@propmix/profet-common-header 3.2.0-beta.1 → 3.2.0-beta.2

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.
@@ -218,6 +218,8 @@ class Utilities {
218
218
  class CommonHeaderService {
219
219
  constructor(config) {
220
220
  this.config = config;
221
+ this.SESSION_EXPIRED_KEY = 'session_expired';
222
+ this.LAST_ACTIVE_SESSION_KEY = 'lastActiveSessionTime';
221
223
  this.baseUrl = '';
222
224
  this.isSessionExpiryDialogOpen = false;
223
225
  this._apiGatewayService = inject(ApiGatewayService);
@@ -311,6 +313,63 @@ class CommonHeaderService {
311
313
  let url = `${this.baseUrl + EndPoints.API_URLS.updateLastAccessedApplication}`;
312
314
  return this._apiGatewayService.doPost(url, reqBody);
313
315
  }
316
+ /**
317
+ * Helper to get the root domain (e.g. .profet.ai) to share cookies across subdomains/ports.
318
+ * If on localhost or an IP, it falls back to the hostname.
319
+ */
320
+ getRootDomain() {
321
+ const hostname = window.location.hostname;
322
+ const parts = hostname.split('.');
323
+ if (parts.length > 2 && !/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname)) {
324
+ // If we have 4+ parts (e.g. app1.local.profet.ai), we want to include the environment (local.profet.ai)
325
+ // to avoid sharing cookies with app1.dev.profet.ai or app1.profet.ai.
326
+ if (parts.length > 3) {
327
+ return '.' + parts.slice(-3).join('.');
328
+ }
329
+ // For standard 3 parts (app1.profet.ai), share on .profet.ai
330
+ return '.' + parts.slice(-2).join('.');
331
+ }
332
+ return hostname;
333
+ }
334
+ /**
335
+ * Generates a unique cookie name based on the environment root domain.
336
+ * e.g. 'lastActive' on .qa.profet.ai -> 'lastActive_qa_profet_ai'
337
+ * @param name Base cookie name
338
+ */
339
+ getSuffixedCookieName(name) {
340
+ const rootDomain = this.getRootDomain();
341
+ // Replace dots with underscores to create a clean suffix
342
+ const suffix = rootDomain.replace(/\./g, '_');
343
+ return `${name}${suffix}`;
344
+ }
345
+ setCookie(name, value, days) {
346
+ const uniqueName = this.getSuffixedCookieName(name);
347
+ let expires = "";
348
+ if (days) {
349
+ const date = new Date();
350
+ date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
351
+ expires = "; expires=" + date.toUTCString();
352
+ }
353
+ // Important: set domain to allow sharing across subdomains
354
+ const domain = "; domain=" + this.getRootDomain();
355
+ document.cookie = uniqueName + "=" + (value || "") + expires + domain + "; path=/";
356
+ }
357
+ getCookie(name) {
358
+ const uniqueName = this.getSuffixedCookieName(name);
359
+ const nameEQ = uniqueName + "=";
360
+ const ca = document.cookie.split(';');
361
+ for (let i = 0; i < ca.length; i++) {
362
+ let c = ca[i];
363
+ while (c.charAt(0) == ' ')
364
+ c = c.substring(1, c.length);
365
+ if (c.indexOf(nameEQ) == 0)
366
+ return c.substring(nameEQ.length, c.length);
367
+ }
368
+ return null;
369
+ }
370
+ deleteCookie(name) {
371
+ this.setCookie(name, '', -1);
372
+ }
314
373
  }
315
374
  CommonHeaderService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CommonHeaderService, deps: [{ token: 'headerConfig' }], target: i0.ɵɵFactoryTarget.Injectable });
316
375
  CommonHeaderService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: CommonHeaderService, providedIn: 'root' });
@@ -445,74 +504,20 @@ class HeaderComponent {
445
504
  // }
446
505
  this.resetTimer();
447
506
  // Clear any stale logout signal on init
448
- this.setCookie('session_expired', '', -1);
507
+ this._headerSer.setCookie(this._headerSer.SESSION_EXPIRED_KEY, '', -1);
449
508
  this.startLogoutCheck();
450
509
  }
451
- /**
452
- * Helper to get the root domain (e.g. .mycom.ai) to share cookies across subdomains/ports.
453
- * If on localhost or an IP, it falls back to the hostname.
454
- */
455
- getRootDomain() {
456
- const hostname = window.location.hostname;
457
- const parts = hostname.split('.');
458
- if (parts.length > 2 && !/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(hostname)) {
459
- // If we have 4+ parts (e.g. app1.local.profet.ai), we want to include the environment (local.profet.ai)
460
- // to avoid sharing cookies with app1.dev.profet.ai or app1.profet.ai.
461
- if (parts.length > 3) {
462
- return '.' + parts.slice(-3).join('.');
463
- }
464
- // For standard 3 parts (app1.profet.ai), share on .profet.ai
465
- return '.' + parts.slice(-2).join('.');
466
- }
467
- return hostname;
468
- }
469
- /**
470
- * Generates a unique cookie name based on the environment root domain.
471
- * e.g. 'lastActive' on .qa.profet.ai -> 'lastActive_qa_profet_ai'
472
- * @param name Base cookie name
473
- */
474
- getSuffixedCookieName(name) {
475
- const rootDomain = this.getRootDomain();
476
- // Replace dots with underscores to create a clean suffix
477
- const suffix = rootDomain.replace(/\./g, '_');
478
- return `${name}${suffix}`;
479
- }
480
- setCookie(name, value, days) {
481
- const uniqueName = this.getSuffixedCookieName(name);
482
- let expires = "";
483
- if (days) {
484
- const date = new Date();
485
- date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
486
- expires = "; expires=" + date.toUTCString();
487
- }
488
- // Important: set domain to allow sharing across subdomains
489
- const domain = "; domain=" + this.getRootDomain();
490
- document.cookie = uniqueName + "=" + (value || "") + expires + domain + "; path=/";
491
- }
492
- getCookie(name) {
493
- const uniqueName = this.getSuffixedCookieName(name);
494
- const nameEQ = uniqueName + "=";
495
- const ca = document.cookie.split(';');
496
- for (let i = 0; i < ca.length; i++) {
497
- let c = ca[i];
498
- while (c.charAt(0) == ' ')
499
- c = c.substring(1, c.length);
500
- if (c.indexOf(nameEQ) == 0)
501
- return c.substring(nameEQ.length, c.length);
502
- }
503
- return null;
504
- }
505
510
  resetTimer(isUserActivity = true) {
506
511
  clearTimeout(this.inactivityTimeout);
507
512
  // Update global activity timestamp in cookie ONLY if triggered by user activity
508
513
  if (isUserActivity) {
509
514
  // Use a short expiry (e.g. 1 day) or sync with session length
510
- this.setCookie('lastActiveSessionTime', Date.now().toString(), 1);
515
+ this._headerSer.setCookie(this._headerSer.LAST_ACTIVE_SESSION_KEY, Date.now().toString(), 1);
511
516
  }
512
517
  // if (!this._headerSer.isSessionExpiryDialogOpen) {
513
518
  this.inactivityTimeout = setTimeout(() => {
514
519
  // Check global activity before logging out
515
- const lastActive = this.getCookie('lastActiveSessionTime');
520
+ const lastActive = this._headerSer.getCookie(this._headerSer.LAST_ACTIVE_SESSION_KEY);
516
521
  const now = Date.now();
517
522
  const lastActiveTime = lastActive ? parseInt(lastActive, 10) : 0;
518
523
  const elapsed = now - lastActiveTime;
@@ -534,11 +539,11 @@ class HeaderComponent {
534
539
  startLogoutCheck() {
535
540
  // Poll for the logout signal cookie (works across ports/subdomains)
536
541
  this.logoutCheckInterval = setInterval(() => {
537
- if (this.getCookie('session_expired')) {
542
+ if (this._headerSer.getCookie(this._headerSer.SESSION_EXPIRED_KEY)) {
538
543
  // Check if tab still "active" according to the shared time
539
544
  // If tab is active but receiving a logout signal, it implies a MANUAL logout from another tab.
540
545
  // If tab is inactive and receiving a logout signal, it implies a TIMEOUT.
541
- const lastActive = this.getCookie('lastActiveSessionTime');
546
+ const lastActive = this._headerSer.getCookie(this._headerSer.LAST_ACTIVE_SESSION_KEY);
542
547
  const now = Date.now();
543
548
  const lastActiveTime = lastActive ? parseInt(lastActive, 10) : 0;
544
549
  const elapsed = now - lastActiveTime;
@@ -554,15 +559,18 @@ class HeaderComponent {
554
559
  // }
555
560
  if (broadcast) {
556
561
  // Set a cookie to signal other tabs/ports
557
- this.setCookie('session_expired', 'true', 1);
562
+ this._headerSer.setCookie(this._headerSer.SESSION_EXPIRED_KEY, 'true', 1);
558
563
  }
559
564
  this.logoutEvent.emit();
560
565
  let sessionUrl = this._headerSer.headerConfig.signOutUrl;
566
+ if (this._headerSer.headerConfig.enableLastUrlRedirection) {
567
+ const separator = sessionUrl.includes('?') ? '&' : '?';
568
+ sessionUrl = sessionUrl + separator + 'returnUrl=' + encodeURIComponent(window.location.href);
569
+ }
561
570
  // Only add sessionExpired params if it is NOT a manual logout
562
571
  if (!isManual) {
563
- let appUrl = this._headerSer.headerConfig.signOutUrl;
564
- let separator = appUrl.includes('?') ? '&' : '?';
565
- sessionUrl = appUrl + separator + 'sessionExpired=true&timeout=' + this.INACTIVITY_LIMIT;
572
+ const separator = sessionUrl.includes('?') ? '&' : '?';
573
+ sessionUrl = sessionUrl + separator + 'sessionExpired=true&timeout=' + this.INACTIVITY_LIMIT;
566
574
  }
567
575
  signOut({ global: true, oauth: { redirectUrl: sessionUrl } })
568
576
  .then(() => {
@@ -672,22 +680,27 @@ class HeaderComponent {
672
680
  onLogoutClick() {
673
681
  this.menuTrigger.closeMenu();
674
682
  // Sync with other tabs
675
- this.setCookie('session_expired', 'true', 1);
683
+ this._headerSer.setCookie(this._headerSer.SESSION_EXPIRED_KEY, 'true', 1);
676
684
  // Clear timers
677
685
  if (this.inactivityTimeout)
678
686
  clearTimeout(this.inactivityTimeout);
679
687
  if (this.logoutCheckInterval)
680
688
  clearInterval(this.logoutCheckInterval);
681
689
  this.logoutEvent.emit();
682
- signOut({ global: true, oauth: { redirectUrl: this._headerSer.headerConfig.signOutUrl } })
690
+ let sessionUrl = this._headerSer.headerConfig.signOutUrl;
691
+ if (this._headerSer.headerConfig.enableLastUrlRedirection) {
692
+ const separator = sessionUrl.includes('?') ? '&' : '?';
693
+ sessionUrl = sessionUrl + separator + 'returnUrl=' + encodeURIComponent(window.location.href);
694
+ }
695
+ signOut({ global: true, oauth: { redirectUrl: sessionUrl } })
683
696
  .then((data) => {
684
- window.open(this._headerSer.headerConfig.signOutUrl, '_self');
697
+ window.open(sessionUrl, '_self');
685
698
  })
686
699
  .catch((err) => {
687
700
  console.log(err);
688
- signOut({ global: true, oauth: { redirectUrl: this._headerSer.headerConfig.signOutUrl } })
701
+ signOut({ global: true, oauth: { redirectUrl: sessionUrl } })
689
702
  .then(() => {
690
- window.open(this._headerSer.headerConfig.signOutUrl, '_self');
703
+ window.open(sessionUrl, '_self');
691
704
  })
692
705
  .catch((error) => console.log(error));
693
706
  });