{"version":3,"file":"ngx-auth.mjs","sources":["../../src/auth.service.ts","../../src/auth.interceptor.ts","../../src/protected.guard.ts","../../src/public.guard.ts","../../src/providers.ts","../../src/ngx-auth.ts"],"sourcesContent":["import { type HttpErrorResponse, type HttpRequest } from '@angular/common/http';\nimport { InjectionToken } from '@angular/core';\nimport { type Observable } from 'rxjs';\n\n/**\n * Essential service for authentication\n */\nexport abstract class NgxAuthService {\n  /**\n   * Get access token\n   * Should return access token in Observable from e.g.\n   * localStorage\n   */\n  abstract getAccessToken(): Promise<string | null> | Observable<string | null>;\n\n  /**\n   * Add token to headers, dependent on server\n   * set-up, by default adds a bearer token.\n   * Called by interceptor.\n   * To change behavior, override this method.\n   */\n  abstract getHeaders?(token: string): Record<string, string | string[]>;\n\n  /**\n   * Check, if user already authorized.\n   * Should return Observable with true or false values\n   */\n  abstract isAuthenticated(): Promise<boolean> | Observable<boolean>;\n\n  /**\n   * Function, checks response of failed request to determine,\n   * whether token be refreshed or not.\n   *\n   * Essentially checks status\n   */\n  abstract refreshShouldHappen(response: HttpErrorResponse, request?: HttpRequest<any>): Promise<boolean> | Observable<boolean> | boolean;\n\n  /**\n   * Function, that should perform refresh token\n   * Should be successfully completed so interceptor\n   * can execute pending requests or retry original one\n   */\n  abstract refreshToken(): Promise<any> | Observable<any>;\n\n  /**\n   * Saves last interrupted url inside of the service for further reusage,\n   * e.g. restoring interrupted page after logging in\n   */\n  abstract setInterruptedUrl?(url: string): void;\n\n  /**\n   * Checks if request must be skipped by interceptor.\n   * Useful for requests such as request token which doesn't require token in headers\n   */\n  abstract skipRequest(request: HttpRequest<any>): boolean;\n}\n\nexport const AUTH_SERVICE = new InjectionToken<NgxAuthService>('ngx-auth--service');\n","import { HttpClient, type HttpErrorResponse, type HttpHandlerFn, type HttpInterceptorFn, type HttpRequest } from '@angular/common/http';\nimport { inject, signal } from '@angular/core';\nimport { catchError, combineLatest, first, from, map, Subject, switchMap, throwError } from 'rxjs';\n\nimport { AUTH_SERVICE, type NgxAuthService } from './auth.service';\n\nexport const NgxRefreshInProgress = signal(false);\nconst delay$ = new Subject<boolean>();\n\nexport const ngxAuthInterceptor: HttpInterceptorFn = (req: HttpRequest<unknown>, next: HttpHandlerFn) => {\n  const authService = inject(AUTH_SERVICE);\n  const http = inject(HttpClient);\n\n  if (authService.skipRequest(req)) {\n    return next(req);\n  }\n\n  const request$ = NgxRefreshInProgress()\n    ? delayRequest(authService, req)\n    : addToken(authService, req);\n\n  return request$.pipe(\n    switchMap(req => next(req)),\n    catchError(res => responseError(authService, http, req, res)),\n  );\n};\n\n/**\n * Add access token to headers or the request\n */\nfunction addToken(authService: NgxAuthService, req: HttpRequest<any>) {\n  return from(authService.getAccessToken())\n    .pipe(\n      first(),\n      map(token => {\n        if (token) {\n          return req.clone({\n            setHeaders: authService.getHeaders?.(token) ?? { Authorization: `Bearer ${token}` },\n          });\n        }\n\n        return req;\n      }),\n    );\n}\n\n/**\n * Delay request, by subscribing on refresh event, once it finished, process it\n * otherwise throw error\n */\nfunction delayRequest(authService: NgxAuthService, req: HttpRequest<any>) {\n  return delay$.pipe(\n    first(),\n    switchMap(canDelay => canDelay\n      ? addToken(authService, req)\n      : throwError(() => req),\n    ),\n  );\n}\n\n/**\n * Failed request interceptor, check if it has to be processed with refresh\n */\nfunction responseError(\n  authService: NgxAuthService,\n  http: HttpClient,\n  req: HttpRequest<any>,\n  res: HttpErrorResponse,\n) {\n  const refreshShouldHappen$ = authService.refreshShouldHappen(res, req);\n\n  return combineLatest([\n    from(typeof refreshShouldHappen$ === 'boolean'\n      ? Promise.resolve(refreshShouldHappen$)\n      : refreshShouldHappen$,\n    ),\n    from(authService.isAuthenticated()),\n  ])\n    .pipe(\n      switchMap(([refreshShouldHappen, isAuthenticated]) => {\n        if (refreshShouldHappen && isAuthenticated && !NgxRefreshInProgress()) {\n          NgxRefreshInProgress.set(true);\n\n          from(authService.refreshToken())\n            .subscribe({\n              error: () => {\n                NgxRefreshInProgress.set(false);\n                delay$.next(false);\n              },\n              next: () => {\n                NgxRefreshInProgress.set(false);\n                delay$.next(true);\n              },\n            });\n        }\n\n        if (refreshShouldHappen && isAuthenticated && NgxRefreshInProgress()) {\n          return delay$.pipe(\n            first(),\n            switchMap(canRetry => canRetry\n              ? http.request(req)\n              : throwError(() => res || req),\n            ),\n          );\n        }\n\n        return throwError(() => res);\n      }),\n    );\n}\n","import { inject, InjectionToken } from '@angular/core';\nimport { type ActivatedRouteSnapshot, type CanActivateFn, Router, type RouterStateSnapshot } from '@angular/router';\nimport { from, tap } from 'rxjs';\n\nimport { AUTH_SERVICE } from './auth.service';\n\nexport const PUBLIC_REDIRECT_URI = new InjectionToken<string>('ngx-auth--public-redirect-uri');\n\n/**\n * Guard, checks access token availability and allows or disallows access to page,\n * and redirects out\n */\nexport const ngxProtectedGuard: CanActivateFn = (_: ActivatedRouteSnapshot, state: RouterStateSnapshot) => {\n  const authService = inject(AUTH_SERVICE);\n  const publicUri = inject(PUBLIC_REDIRECT_URI);\n  const router = inject(Router);\n\n  return from(authService.isAuthenticated()).pipe(\n    tap(async isAllowed => {\n      if (isAllowed) {\n        return;\n      }\n\n      authService.setInterruptedUrl?.(state.url);\n      await router.navigateByUrl(publicUri);\n    }),\n  );\n};\n","import { inject, InjectionToken } from '@angular/core';\nimport { type CanActivateFn, Router } from '@angular/router';\nimport { from, map, tap } from 'rxjs';\n\nimport { AUTH_SERVICE } from './auth.service';\n\nexport const PROTECTED_REDIRECT_URI = new InjectionToken<string>('ngx-auth--protected-redirect-uri');\n\n/**\n * Guard, checks access token availability and allows or disallows access to page,\n * and redirects out\n */\nexport const ngxPublicGuard: CanActivateFn = () => {\n  const authService = inject(AUTH_SERVICE);\n  const protectedUri = inject(PROTECTED_REDIRECT_URI);\n  const router = inject(Router);\n\n  return from(authService.isAuthenticated()).pipe(\n    map(isAuthenticated => !isAuthenticated),\n    tap(async isAllowed => {\n      if (isAllowed) {\n        return;\n      }\n\n      await router.navigateByUrl(protectedUri);\n    }),\n  );\n};\n","import { makeEnvironmentProviders, type Type } from '@angular/core';\n\nimport { AUTH_SERVICE, type NgxAuthService } from './auth.service';\nimport { PUBLIC_REDIRECT_URI } from './protected.guard';\nimport { PROTECTED_REDIRECT_URI } from './public.guard';\n\nexport function provideNgxAuthProviders(options: {\n  authService: Type<NgxAuthService>;\n  protectedRedirectUri: string;\n  publicRedirectUri: string;\n}) {\n  return makeEnvironmentProviders([\n    {\n      provide: AUTH_SERVICE,\n      useExisting: options.authService,\n    },\n    {\n      provide: PROTECTED_REDIRECT_URI,\n      useValue: options.protectedRedirectUri,\n    },\n    {\n      provide: PUBLIC_REDIRECT_URI,\n      useValue: options.publicRedirectUri,\n    },\n  ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAIA;;AAEG;MACmB,cAAc,CAAA;AAgDnC;MAEY,YAAY,GAAG,IAAI,cAAc,CAAiB,mBAAmB;;MCnDrE,oBAAoB,GAAG,MAAM,CAAC,KAAK;AAChD,MAAM,MAAM,GAAG,IAAI,OAAO,EAAW;MAExB,kBAAkB,GAAsB,CAAC,GAAyB,EAAE,IAAmB,KAAI;AACtG,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;AACxC,IAAA,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC;AAE/B,IAAA,IAAI,WAAW,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE;AAChC,QAAA,OAAO,IAAI,CAAC,GAAG,CAAC;IAClB;IAEA,MAAM,QAAQ,GAAG,oBAAoB;AACnC,UAAE,YAAY,CAAC,WAAW,EAAE,GAAG;AAC/B,UAAE,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC;AAE9B,IAAA,OAAO,QAAQ,CAAC,IAAI,CAClB,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,EAC3B,UAAU,CAAC,GAAG,IAAI,aAAa,CAAC,WAAW,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAC9D;AACH;AAEA;;AAEG;AACH,SAAS,QAAQ,CAAC,WAA2B,EAAE,GAAqB,EAAA;AAClE,IAAA,OAAO,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE;SACrC,IAAI,CACH,KAAK,EAAE,EACP,GAAG,CAAC,KAAK,IAAG;QACV,IAAI,KAAK,EAAE;YACT,OAAO,GAAG,CAAC,KAAK,CAAC;AACf,gBAAA,UAAU,EAAE,WAAW,CAAC,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,aAAa,EAAE,CAAA,OAAA,EAAU,KAAK,EAAE,EAAE;AACpF,aAAA,CAAC;QACJ;AAEA,QAAA,OAAO,GAAG;IACZ,CAAC,CAAC,CACH;AACL;AAEA;;;AAGG;AACH,SAAS,YAAY,CAAC,WAA2B,EAAE,GAAqB,EAAA;AACtE,IAAA,OAAO,MAAM,CAAC,IAAI,CAChB,KAAK,EAAE,EACP,SAAS,CAAC,QAAQ,IAAI;AACpB,UAAE,QAAQ,CAAC,WAAW,EAAE,GAAG;UACzB,UAAU,CAAC,MAAM,GAAG,CAAC,CACxB,CACF;AACH;AAEA;;AAEG;AACH,SAAS,aAAa,CACpB,WAA2B,EAC3B,IAAgB,EAChB,GAAqB,EACrB,GAAsB,EAAA;IAEtB,MAAM,oBAAoB,GAAG,WAAW,CAAC,mBAAmB,CAAC,GAAG,EAAE,GAAG,CAAC;AAEtE,IAAA,OAAO,aAAa,CAAC;AACnB,QAAA,IAAI,CAAC,OAAO,oBAAoB,KAAK;AACnC,cAAE,OAAO,CAAC,OAAO,CAAC,oBAAoB;cACpC,oBAAoB,CACvB;AACD,QAAA,IAAI,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC;KACpC;SACE,IAAI,CACH,SAAS,CAAC,CAAC,CAAC,mBAAmB,EAAE,eAAe,CAAC,KAAI;QACnD,IAAI,mBAAmB,IAAI,eAAe,IAAI,CAAC,oBAAoB,EAAE,EAAE;AACrE,YAAA,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC;AAE9B,YAAA,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE;AAC5B,iBAAA,SAAS,CAAC;gBACT,KAAK,EAAE,MAAK;AACV,oBAAA,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/B,oBAAA,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;gBACpB,CAAC;gBACD,IAAI,EAAE,MAAK;AACT,oBAAA,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC;AAC/B,oBAAA,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC;gBACnB,CAAC;AACF,aAAA,CAAC;QACN;AAEA,QAAA,IAAI,mBAAmB,IAAI,eAAe,IAAI,oBAAoB,EAAE,EAAE;AACpE,YAAA,OAAO,MAAM,CAAC,IAAI,CAChB,KAAK,EAAE,EACP,SAAS,CAAC,QAAQ,IAAI;AACpB,kBAAE,IAAI,CAAC,OAAO,CAAC,GAAG;AAClB,kBAAE,UAAU,CAAC,MAAM,GAAG,IAAI,GAAG,CAAC,CAC/B,CACF;QACH;AAEA,QAAA,OAAO,UAAU,CAAC,MAAM,GAAG,CAAC;IAC9B,CAAC,CAAC,CACH;AACL;;MCvGa,mBAAmB,GAAG,IAAI,cAAc,CAAS,+BAA+B;AAE7F;;;AAGG;MACU,iBAAiB,GAAkB,CAAC,CAAyB,EAAE,KAA0B,KAAI;AACxG,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;AACxC,IAAA,MAAM,SAAS,GAAG,MAAM,CAAC,mBAAmB,CAAC;AAC7C,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAE7B,IAAA,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAC7C,GAAG,CAAC,OAAM,SAAS,KAAG;QACpB,IAAI,SAAS,EAAE;YACb;QACF;QAEA,WAAW,CAAC,iBAAiB,GAAG,KAAK,CAAC,GAAG,CAAC;AAC1C,QAAA,MAAM,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC;IACvC,CAAC,CAAC,CACH;AACH;;MCrBa,sBAAsB,GAAG,IAAI,cAAc,CAAS,kCAAkC;AAEnG;;;AAGG;AACI,MAAM,cAAc,GAAkB,MAAK;AAChD,IAAA,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;AACxC,IAAA,MAAM,YAAY,GAAG,MAAM,CAAC,sBAAsB,CAAC;AACnD,IAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;IAE7B,OAAO,IAAI,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC,CAAC,IAAI,CAC7C,GAAG,CAAC,eAAe,IAAI,CAAC,eAAe,CAAC,EACxC,GAAG,CAAC,OAAM,SAAS,KAAG;QACpB,IAAI,SAAS,EAAE;YACb;QACF;AAEA,QAAA,MAAM,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC;IAC1C,CAAC,CAAC,CACH;AACH;;ACrBM,SAAU,uBAAuB,CAAC,OAIvC,EAAA;AACC,IAAA,OAAO,wBAAwB,CAAC;AAC9B,QAAA;AACE,YAAA,OAAO,EAAE,YAAY;YACrB,WAAW,EAAE,OAAO,CAAC,WAAW;AACjC,SAAA;AACD,QAAA;AACE,YAAA,OAAO,EAAE,sBAAsB;YAC/B,QAAQ,EAAE,OAAO,CAAC,oBAAoB;AACvC,SAAA;AACD,QAAA;AACE,YAAA,OAAO,EAAE,mBAAmB;YAC5B,QAAQ,EAAE,OAAO,CAAC,iBAAiB;AACpC,SAAA;AACF,KAAA,CAAC;AACJ;;ACzBA;;AAEG;;;;"}