{"version":3,"file":"session-expiration-alert.mjs","sources":["../../../projects/session-expiration-alert/src/lib/services/session-interrupt.service.ts","../../../projects/session-expiration-alert/src/lib/models/session-expiration-config.ts","../../../projects/session-expiration-alert/src/lib/services/session-timer.service.ts","../../../projects/session-expiration-alert/src/lib/components/session-expiration-alert/session-expiration-alert.component.ts","../../../projects/session-expiration-alert/src/lib/components/session-expiration-alert/session-expiration-alert.component.html","../../../projects/session-expiration-alert/src/lib/services/session-timer-http-interceptor.ts","../../../projects/session-expiration-alert/src/lib/session-expiration-alert.module.ts","../../../projects/session-expiration-alert/src/public-api.ts","../../../projects/session-expiration-alert/src/session-expiration-alert.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\r\n\r\n@Injectable()\r\nexport class SessionInterruptService {\r\n  constructor() {}\r\n\r\n  /**\r\n   * Method to refresh session cookie. Normally, this method issue a quick API call to server.\r\n   *\r\n   * @memberof SessionInterruptService\r\n   */\r\n  continueSession() {\r\n    console.log('You clicked continue session.');\r\n  }\r\n\r\n  /**\r\n   * Method to remove session cookie. Normally, this method redirect to website logout endpoint.\r\n   *\r\n   * @memberof SessionInterruptService\r\n   */\r\n  stopSession() {\r\n    console.log('You clicked logout.');\r\n  }\r\n\r\n  /**\r\n   * Method to handle expiration event. Can be empty.\r\n   */\r\n  onExpire() {\r\n    console.log('Session expired.');\r\n  }\r\n}\r\n","import { InjectionToken } from '@angular/core';\r\n\r\nexport interface SessionExpirationConfig {\r\n  totalMinutes: number;\r\n}\r\n\r\nexport const ConfigToken = new InjectionToken<SessionExpirationConfig>(\r\n  'config'\r\n);\r\n","import { Inject, Injectable } from '@angular/core';\r\nimport { interval, Observable, Subject, Subscription } from 'rxjs';\r\nimport {\r\n  ConfigToken,\r\n  SessionExpirationConfig,\r\n} from '../models/session-expiration-config';\r\n\r\n@Injectable()\r\nexport class SessionTimerService {\r\n  private readonly _timeoutSeconds: number;\r\n  private _count: number = 0;\r\n  private timerSubscription!: Subscription;\r\n  private timer: Observable<number> = interval(1000);\r\n  private _remainSeconds = new Subject<number>();\r\n  /**\r\n   * Observable to get session remaining time (in seconds).\r\n   *\r\n   * Subscribers need to unsubscribe to it before hosting element is destroyed.\r\n   *\r\n   * @memberof SessionTimerService\r\n   */\r\n  remainSeconds$ = this._remainSeconds.asObservable();\r\n\r\n  constructor(@Inject(ConfigToken) readonly config: SessionExpirationConfig) {\r\n    this._timeoutSeconds = config.totalMinutes * 60;\r\n  }\r\n\r\n  startTimer() {\r\n    this.stopTimer();\r\n    this._count = this._timeoutSeconds;\r\n    this.timerSubscription = this.timer.subscribe((n) => {\r\n      if (this._count > 0) {\r\n        this._count--;\r\n        this._remainSeconds.next(this._count);\r\n      }\r\n    });\r\n  }\r\n\r\n  stopTimer() {\r\n    if (this.timerSubscription) {\r\n      this.timerSubscription.unsubscribe();\r\n    }\r\n  }\r\n\r\n  resetTimer() {\r\n    this.startTimer();\r\n  }\r\n}\r\n","import {\r\n  ChangeDetectionStrategy,\r\n  Component,\r\n  ElementRef,\r\n  HostListener,\r\n  Input,\r\n  OnChanges,\r\n  OnDestroy,\r\n  OnInit,\r\n  SimpleChanges,\r\n} from '@angular/core';\r\nimport { Subscription } from 'rxjs';\r\nimport { SessionInterruptService } from '../../services/session-interrupt.service';\r\nimport { SessionTimerService } from '../../services/session-timer.service';\r\n\r\n@Component({\r\n  selector: 'session-expiration-alert',\r\n  templateUrl: './session-expiration-alert.component.html',\r\n  styleUrls: ['./session-expiration-alert.component.css', './btn.css'],\r\n  changeDetection: ChangeDetectionStrategy.OnPush,\r\n  standalone: false,\r\n})\r\nexport class SessionExpirationAlertComponent\r\n  implements OnInit, OnChanges, OnDestroy\r\n{\r\n  /**\r\n   * Should start the timer or not. Usually, you can set it to true if a user is authenticated.\r\n   */\r\n  @Input() startTimer? = true;\r\n\r\n  /**\r\n   * Count down seconds.\r\n   */\r\n  @Input() alertAt? = 60;\r\n\r\n  showModal = false;\r\n  expired = false;\r\n  private sessionTimerSubscription!: Subscription;\r\n\r\n  constructor(\r\n    private el: ElementRef,\r\n    private sessionInterrupter: SessionInterruptService,\r\n    public sessionTimer: SessionTimerService\r\n  ) {}\r\n\r\n  ngOnInit() {\r\n    if (!this.sessionTimerSubscription && this.startTimer) {\r\n      this.trackSessionTime();\r\n    }\r\n    // move element to bottom of page (just before </body>)\r\n    // so it can be displayed above everything else\r\n    document.body.appendChild(this.el.nativeElement);\r\n  }\r\n  ngOnChanges(changes: SimpleChanges): void {\r\n    if (changes['startTimer']) {\r\n      this.cleanUp();\r\n      if (changes['startTimer'].currentValue) {\r\n        this.trackSessionTime();\r\n      }\r\n    }\r\n  }\r\n\r\n  private trackSessionTime() {\r\n    this.sessionTimer.startTimer();\r\n    this.expired = false;\r\n    this.sessionTimerSubscription = this.sessionTimer.remainSeconds$.subscribe(\r\n      (t) => {\r\n        if (t === this.alertAt) {\r\n          this.open();\r\n        }\r\n        if (t === 0) {\r\n          this.expired = true;\r\n          this.cleanUp();\r\n          this.sessionInterrupter.onExpire();\r\n        }\r\n      }\r\n    );\r\n  }\r\n  continue() {\r\n    this.sessionInterrupter.continueSession();\r\n    this.sessionTimer.resetTimer();\r\n    this.close();\r\n  }\r\n  logout() {\r\n    this.sessionTimer.stopTimer();\r\n    this.close();\r\n    this.sessionInterrupter.stopSession();\r\n  }\r\n\r\n  open(): void {\r\n    this.showModal = true;\r\n    document.body.classList.add('sea-modal-open');\r\n  }\r\n\r\n  close(): void {\r\n    this.showModal = false;\r\n    document.body.classList.remove('sea-modal-open');\r\n  }\r\n\r\n  cleanUp() {\r\n    this.sessionTimer.stopTimer();\r\n    if (this.sessionTimerSubscription) {\r\n      this.sessionTimerSubscription.unsubscribe();\r\n    }\r\n  }\r\n  reload() {\r\n    this.close();\r\n    location.reload();\r\n  }\r\n\r\n  ngOnDestroy(): void {\r\n    this.el.nativeElement.remove();\r\n    this.cleanUp();\r\n  }\r\n\r\n  @HostListener('document:keydown.tab', ['$event'])\r\n  handleTabKey(e: KeyboardEvent) {\r\n    const modal = document.querySelector('#session-expiration-alert');\r\n    if (modal) {\r\n      const btn1 = modal.querySelector<HTMLButtonElement>('button.btn-primary');\r\n      const btn2 = modal.querySelector<HTMLButtonElement>(\r\n        'button.btn-secondary'\r\n      );\r\n      if (document.activeElement === btn1) {\r\n        btn2?.focus();\r\n        e.preventDefault();\r\n      }\r\n    }\r\n  }\r\n  @HostListener('document:keydown.shift.tab', ['$event'])\r\n  handleShiftTabKey(e: KeyboardEvent) {\r\n    const modal = document.querySelector('#session-expiration-alert');\r\n    if (modal) {\r\n      const btn1 = modal.querySelector<HTMLButtonElement>('button.btn-primary');\r\n      const btn2 = modal.querySelector<HTMLButtonElement>(\r\n        'button.btn-secondary'\r\n      );\r\n      if (document.activeElement === btn2) {\r\n        btn1?.focus();\r\n        e.preventDefault();\r\n      }\r\n    }\r\n  }\r\n}\r\n","<div\r\n  class=\"sea-modal\"\r\n  id=\"session-expiration-alert\"\r\n  role=\"dialog\"\r\n  tabindex=\"-1\"\r\n  aria-modal=\"true\"\r\n  aria-label=\"session-expiration-alert\"\r\n  [hidden]=\"!showModal\"\r\n>\r\n  <div role=\"document\" class=\"sea-modal-content\" id=\"expiring\" *ngIf=\"!expired\">\r\n    <div class=\"sea-modal-header\">Session is about to expire</div>\r\n    <div class=\"sea-modal-body\">\r\n      <p>\r\n        Your session will expire in\r\n        {{ sessionTimer.remainSeconds$ | async }} seconds.\r\n      </p>\r\n    </div>\r\n    <div class=\"sea-modal-footer\">\r\n      <button type=\"button\" class=\"btn btn-secondary\" (click)=\"logout()\">\r\n        Logout\r\n      </button>\r\n      <button type=\"button\" class=\"btn btn-primary\" (click)=\"continue()\">\r\n        Continue Session\r\n      </button>\r\n    </div>\r\n  </div>\r\n  <div role=\"document\" class=\"sea-modal-content\" id=\"expired\" *ngIf=\"expired\">\r\n    <div class=\"sea-modal-header\">Session expired</div>\r\n    <div class=\"sea-modal-body\">\r\n      <p>\r\n        The current page is idle due to lack of activity. You can try to reload\r\n        this page or log out of the website.\r\n      </p>\r\n    </div>\r\n    <div class=\"sea-modal-footer\">\r\n      <button type=\"button\" class=\"btn btn-secondary\" (click)=\"logout()\">\r\n        Logout\r\n      </button>\r\n      <button type=\"button\" class=\"btn btn-primary\" (click)=\"reload()\">\r\n        Reload Page\r\n      </button>\r\n    </div>\r\n  </div>\r\n</div>\r\n<div class=\"sea-modal-background\" [hidden]=\"!showModal\"></div>\r\n","import { HttpEvent, HttpHandlerFn, HttpRequest } from '@angular/common/http';\r\nimport { inject } from '@angular/core';\r\nimport { Observable } from 'rxjs';\r\nimport { SessionTimerService } from '../services/session-timer.service';\r\n\r\nexport function sessionTimerHttpInterceptor(\r\n  req: HttpRequest<unknown>,\r\n  next: HttpHandlerFn\r\n): Observable<HttpEvent<unknown>> {\r\n  const timerService = inject(SessionTimerService);\r\n  timerService.resetTimer();\r\n  return next(req);\r\n}\r\n","import { CommonModule } from '@angular/common';\r\nimport { provideHttpClient, withInterceptors } from '@angular/common/http';\r\nimport { ModuleWithProviders, NgModule } from '@angular/core';\r\n\r\nimport { SessionExpirationAlertComponent } from './components/session-expiration-alert/session-expiration-alert.component';\r\nimport {\r\n  ConfigToken,\r\n  SessionExpirationConfig,\r\n} from './models/session-expiration-config';\r\nimport { SessionInterruptService } from './services/session-interrupt.service';\r\nimport { sessionTimerHttpInterceptor } from './services/session-timer-http-interceptor';\r\nimport { SessionTimerService } from './services/session-timer.service';\r\n\r\n@NgModule({\r\n  imports: [CommonModule],\r\n  declarations: [SessionExpirationAlertComponent],\r\n  providers: [\r\n    SessionTimerService,\r\n    provideHttpClient(withInterceptors([sessionTimerHttpInterceptor])),\r\n    SessionInterruptService,\r\n  ],\r\n  exports: [SessionExpirationAlertComponent],\r\n})\r\nexport class SessionExpirationAlert {\r\n  /**\r\n   *\r\n   * @param config  SessionExpirationConfig, default value: { totalMinutes: 20 }\r\n   *\r\n   */\r\n  static forRoot(\r\n    config: SessionExpirationConfig = {\r\n      totalMinutes: 20,\r\n    }\r\n  ): ModuleWithProviders<SessionExpirationAlert> {\r\n    return {\r\n      ngModule: SessionExpirationAlert,\r\n      providers: [\r\n        {\r\n          provide: ConfigToken,\r\n          useValue: config,\r\n        },\r\n      ],\r\n    };\r\n  }\r\n}\r\n","/*\r\n * Public API Surface of session-expiration-alert\r\n */\r\n\r\nexport * from './lib/session-expiration-alert.module';\r\nexport * from './lib/models/session-expiration-config';\r\nexport * from './lib/services/session-interrupt.service';\r\nexport * from './lib/services/session-timer-http-interceptor';\r\nexport * from './lib/services/session-timer.service';\r\nexport * from './lib/components/session-expiration-alert/session-expiration-alert.component';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.SessionInterruptService","i2.SessionTimerService"],"mappings":"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"}