@nauth-toolkit/client-angular 0.1.59 → 0.1.60

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.
@@ -1,6 +1,6 @@
1
1
  import { Observable } from 'rxjs';
2
2
  import { AngularHttpAdapter } from './http-adapter';
3
- import { NAuthClient, NAuthClientConfig, ChallengeResponse, AuthResponse, TokenResponse, AuthUser, ConfirmForgotPasswordResponse, ForgotPasswordResponse, UpdateProfileRequest, GetChallengeDataResponse, GetSetupDataResponse, MFAStatus, MFADevice, AuthEvent, SocialProvider, SocialLoginOptions, LinkedAccountsResponse, SocialVerifyRequest, AuditHistoryResponse } from '@nauth-toolkit/client';
3
+ import { NAuthClient, NAuthClientConfig, ChallengeResponse, AuthResponse, TokenResponse, AuthUser, ConfirmForgotPasswordResponse, ForgotPasswordResponse, ResetPasswordWithCodeResponse, UpdateProfileRequest, GetChallengeDataResponse, GetSetupDataResponse, MFAStatus, MFADevice, AuthEvent, SocialProvider, SocialLoginOptions, LinkedAccountsResponse, SocialVerifyRequest, AuditHistoryResponse } from '@nauth-toolkit/client';
4
4
  import * as i0 from "@angular/core";
5
5
  /**
6
6
  * Angular wrapper around NAuthClient that provides promise-based auth methods and reactive state.
@@ -199,6 +199,28 @@ export declare class AuthService {
199
199
  * ```
200
200
  */
201
201
  confirmForgotPassword(identifier: string, code: string, newPassword: string): Promise<ConfirmForgotPasswordResponse>;
202
+ /**
203
+ * Reset password with code or token (generic method for both admin and user-initiated resets).
204
+ *
205
+ * Accepts either:
206
+ * - code: Short numeric code from email/SMS (6-10 digits)
207
+ * - token: Long hex token from reset link (64 chars)
208
+ *
209
+ * @param identifier - User identifier (email, username, phone)
210
+ * @param codeOrToken - Verification code OR token from link
211
+ * @param newPassword - New password
212
+ * @returns Promise with success response
213
+ *
214
+ * @example
215
+ * ```typescript
216
+ * // With code from email
217
+ * await this.auth.resetPasswordWithCode('user@example.com', '123456', 'NewPass123!');
218
+ *
219
+ * // With token from link
220
+ * await this.auth.resetPasswordWithCode('user@example.com', '64-char-token', 'NewPass123!');
221
+ * ```
222
+ */
223
+ resetPasswordWithCode(identifier: string, codeOrToken: string, newPassword: string): Promise<ResetPasswordWithCodeResponse>;
202
224
  /**
203
225
  * Change user password (requires current password).
204
226
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nauth-toolkit/client-angular",
3
- "version": "0.1.59",
3
+ "version": "0.1.60",
4
4
  "description": "Angular adapter for nauth-toolkit client SDK",
5
5
  "keywords": [
6
6
  "nauth",
@@ -24,7 +24,7 @@
24
24
  "peerDependencies": {
25
25
  "@angular/common": ">=17.0.0",
26
26
  "@angular/core": ">=17.0.0",
27
- "@nauth-toolkit/client": "^0.1.59",
27
+ "@nauth-toolkit/client": "^0.1.60",
28
28
  "rxjs": "^7.0.0 || ^8.0.0"
29
29
  },
30
30
  "dependencies": {
@@ -3,11 +3,8 @@
3
3
  *
4
4
  * This entry point is for standalone component-based Angular apps (Angular 14+).
5
5
  * For NgModule apps, use: @nauth-toolkit/client-angular
6
+ *
7
+ * NOTE: This simply re-exports the main entry point since both share the same code for now.
8
+ * The split allows future additions like `provideNAuth()` for standalone apps.
6
9
  */
7
- export * from '@nauth-toolkit/client';
8
- export * from './tokens';
9
- export * from './auth.service';
10
- export * from './http-adapter';
11
- export * from './auth.interceptor';
12
- export * from './auth.guard';
13
- export * from './social-redirect-callback.guard';
10
+ export * from '@nauth-toolkit/client-angular';
@@ -1,102 +0,0 @@
1
- import { __decorate, __param } from "tslib";
2
- import { inject, Inject, Optional } from '@angular/core';
3
- import { Router } from '@angular/router';
4
- import { AuthService } from './auth.service';
5
- import { NAUTH_CLIENT_CONFIG } from './tokens';
6
- /**
7
- * Functional route guard for authentication (Angular 17+).
8
- *
9
- * Protects routes by checking if user is authenticated.
10
- * Redirects to configured session expired route (or login) if not authenticated.
11
- *
12
- * @param redirectTo - Optional path to redirect to if not authenticated. If not provided, uses `redirects.sessionExpired` from config (defaults to '/login')
13
- * @returns CanActivateFn guard function
14
- *
15
- * @example
16
- * ```typescript
17
- * // In route configuration - uses config.redirects.sessionExpired
18
- * const routes: Routes = [
19
- * {
20
- * path: 'home',
21
- * component: HomeComponent,
22
- * canActivate: [authGuard()]
23
- * }
24
- * ];
25
- *
26
- * // Override with custom route
27
- * const routes: Routes = [
28
- * {
29
- * path: 'admin',
30
- * component: AdminComponent,
31
- * canActivate: [authGuard('/admin/login')]
32
- * }
33
- * ];
34
- * ```
35
- */
36
- export function authGuard(redirectTo) {
37
- return () => {
38
- const auth = inject(AuthService);
39
- const router = inject(Router);
40
- const config = inject(NAUTH_CLIENT_CONFIG, { optional: true });
41
- if (auth.isAuthenticated()) {
42
- return true;
43
- }
44
- // Use provided redirectTo, or config.redirects.sessionExpired, or default to '/login'
45
- const redirectPath = redirectTo ?? config?.redirects?.sessionExpired ?? '/login';
46
- return router.createUrlTree([redirectPath]);
47
- };
48
- }
49
- /**
50
- * Class-based authentication guard for NgModule compatibility.
51
- *
52
- * @example
53
- * ```typescript
54
- * // In route configuration (NgModule)
55
- * const routes: Routes = [
56
- * {
57
- * path: 'home',
58
- * component: HomeComponent,
59
- * canActivate: [AuthGuard]
60
- * }
61
- * ];
62
- *
63
- * // In module providers
64
- * @NgModule({
65
- * providers: [AuthGuard]
66
- * })
67
- * ```
68
- */
69
- let AuthGuard = class AuthGuard {
70
- auth;
71
- router;
72
- config;
73
- /**
74
- * @param auth - Authentication service
75
- * @param router - Angular router
76
- * @param config - Optional client configuration (injected automatically)
77
- */
78
- constructor(auth, router, config) {
79
- this.auth = auth;
80
- this.router = router;
81
- this.config = config;
82
- }
83
- /**
84
- * Check if route can be activated.
85
- *
86
- * @returns True if authenticated, otherwise redirects to configured session expired route (or '/login')
87
- */
88
- canActivate() {
89
- if (this.auth.isAuthenticated()) {
90
- return true;
91
- }
92
- // Use config.redirects.sessionExpired or default to '/login'
93
- const redirectPath = this.config?.redirects?.sessionExpired ?? '/login';
94
- return this.router.createUrlTree([redirectPath]);
95
- }
96
- };
97
- AuthGuard = __decorate([
98
- __param(2, Optional()),
99
- __param(2, Inject(NAUTH_CLIENT_CONFIG))
100
- ], AuthGuard);
101
- export { AuthGuard };
102
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5ndWFyZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3N0YW5kYWxvbmUvYXV0aC5ndWFyZC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3pELE9BQU8sRUFBaUIsTUFBTSxFQUFXLE1BQU0saUJBQWlCLENBQUM7QUFDakUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUcvQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E2Qkc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLFVBQW1CO0lBQzNDLE9BQU8sR0FBc0IsRUFBRTtRQUM3QixNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDakMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQzlCLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBRS9ELElBQUksSUFBSSxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7WUFDM0IsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBRUQsc0ZBQXNGO1FBQ3RGLE1BQU0sWUFBWSxHQUNoQixVQUFVLElBQUksTUFBTSxFQUFFLFNBQVMsRUFBRSxjQUFjLElBQUksUUFBUSxDQUFDO1FBRTlELE9BQU8sTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDOUMsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBbUJHO0FBQ0ksSUFBTSxTQUFTLEdBQWYsTUFBTSxTQUFTO0lBT1Y7SUFDQTtJQUN5QztJQVJuRDs7OztPQUlHO0lBQ0gsWUFDVSxJQUFpQixFQUNqQixNQUFjLEVBQzJCLE1BQTBCO1FBRm5FLFNBQUksR0FBSixJQUFJLENBQWE7UUFDakIsV0FBTSxHQUFOLE1BQU0sQ0FBUTtRQUMyQixXQUFNLEdBQU4sTUFBTSxDQUFvQjtJQUMxRSxDQUFDO0lBRUo7Ozs7T0FJRztJQUNILFdBQVc7UUFDVCxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLEVBQUUsQ0FBQztZQUNoQyxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFFRCw2REFBNkQ7UUFDN0QsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxTQUFTLEVBQUUsY0FBYyxJQUFJLFFBQVEsQ0FBQztRQUV4RSxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQztJQUNuRCxDQUFDO0NBQ0YsQ0FBQTtBQTNCWSxTQUFTO0lBU2pCLFdBQUEsUUFBUSxFQUFFLENBQUE7SUFBRSxXQUFBLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxDQUFBO0dBVC9CLFNBQVMsQ0EyQnJCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBJbmplY3QsIE9wdGlvbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDYW5BY3RpdmF0ZUZuLCBSb3V0ZXIsIFVybFRyZWUgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuL2F1dGguc2VydmljZSc7XG5pbXBvcnQgeyBOQVVUSF9DTElFTlRfQ09ORklHIH0gZnJvbSAnLi90b2tlbnMnO1xuaW1wb3J0IHR5cGUgeyBOQXV0aENsaWVudENvbmZpZyB9IGZyb20gJ0BuYXV0aC10b29sa2l0L2NsaWVudCc7XG5cbi8qKlxuICogRnVuY3Rpb25hbCByb3V0ZSBndWFyZCBmb3IgYXV0aGVudGljYXRpb24gKEFuZ3VsYXIgMTcrKS5cbiAqXG4gKiBQcm90ZWN0cyByb3V0ZXMgYnkgY2hlY2tpbmcgaWYgdXNlciBpcyBhdXRoZW50aWNhdGVkLlxuICogUmVkaXJlY3RzIHRvIGNvbmZpZ3VyZWQgc2Vzc2lvbiBleHBpcmVkIHJvdXRlIChvciBsb2dpbikgaWYgbm90IGF1dGhlbnRpY2F0ZWQuXG4gKlxuICogQHBhcmFtIHJlZGlyZWN0VG8gLSBPcHRpb25hbCBwYXRoIHRvIHJlZGlyZWN0IHRvIGlmIG5vdCBhdXRoZW50aWNhdGVkLiBJZiBub3QgcHJvdmlkZWQsIHVzZXMgYHJlZGlyZWN0cy5zZXNzaW9uRXhwaXJlZGAgZnJvbSBjb25maWcgKGRlZmF1bHRzIHRvICcvbG9naW4nKVxuICogQHJldHVybnMgQ2FuQWN0aXZhdGVGbiBndWFyZCBmdW5jdGlvblxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiAvLyBJbiByb3V0ZSBjb25maWd1cmF0aW9uIC0gdXNlcyBjb25maWcucmVkaXJlY3RzLnNlc3Npb25FeHBpcmVkXG4gKiBjb25zdCByb3V0ZXM6IFJvdXRlcyA9IFtcbiAqICAge1xuICogICAgIHBhdGg6ICdob21lJyxcbiAqICAgICBjb21wb25lbnQ6IEhvbWVDb21wb25lbnQsXG4gKiAgICAgY2FuQWN0aXZhdGU6IFthdXRoR3VhcmQoKV1cbiAqICAgfVxuICogXTtcbiAqXG4gKiAvLyBPdmVycmlkZSB3aXRoIGN1c3RvbSByb3V0ZVxuICogY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gKiAgIHtcbiAqICAgICBwYXRoOiAnYWRtaW4nLFxuICogICAgIGNvbXBvbmVudDogQWRtaW5Db21wb25lbnQsXG4gKiAgICAgY2FuQWN0aXZhdGU6IFthdXRoR3VhcmQoJy9hZG1pbi9sb2dpbicpXVxuICogICB9XG4gKiBdO1xuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhdXRoR3VhcmQocmVkaXJlY3RUbz86IHN0cmluZyk6IENhbkFjdGl2YXRlRm4ge1xuICByZXR1cm4gKCk6IGJvb2xlYW4gfCBVcmxUcmVlID0+IHtcbiAgICBjb25zdCBhdXRoID0gaW5qZWN0KEF1dGhTZXJ2aWNlKTtcbiAgICBjb25zdCByb3V0ZXIgPSBpbmplY3QoUm91dGVyKTtcbiAgICBjb25zdCBjb25maWcgPSBpbmplY3QoTkFVVEhfQ0xJRU5UX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcblxuICAgIGlmIChhdXRoLmlzQXV0aGVudGljYXRlZCgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBVc2UgcHJvdmlkZWQgcmVkaXJlY3RUbywgb3IgY29uZmlnLnJlZGlyZWN0cy5zZXNzaW9uRXhwaXJlZCwgb3IgZGVmYXVsdCB0byAnL2xvZ2luJ1xuICAgIGNvbnN0IHJlZGlyZWN0UGF0aCA9XG4gICAgICByZWRpcmVjdFRvID8/IGNvbmZpZz8ucmVkaXJlY3RzPy5zZXNzaW9uRXhwaXJlZCA/PyAnL2xvZ2luJztcblxuICAgIHJldHVybiByb3V0ZXIuY3JlYXRlVXJsVHJlZShbcmVkaXJlY3RQYXRoXSk7XG4gIH07XG59XG5cbi8qKlxuICogQ2xhc3MtYmFzZWQgYXV0aGVudGljYXRpb24gZ3VhcmQgZm9yIE5nTW9kdWxlIGNvbXBhdGliaWxpdHkuXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIEluIHJvdXRlIGNvbmZpZ3VyYXRpb24gKE5nTW9kdWxlKVxuICogY29uc3Qgcm91dGVzOiBSb3V0ZXMgPSBbXG4gKiAgIHtcbiAqICAgICBwYXRoOiAnaG9tZScsXG4gKiAgICAgY29tcG9uZW50OiBIb21lQ29tcG9uZW50LFxuICogICAgIGNhbkFjdGl2YXRlOiBbQXV0aEd1YXJkXVxuICogICB9XG4gKiBdO1xuICpcbiAqIC8vIEluIG1vZHVsZSBwcm92aWRlcnNcbiAqIEBOZ01vZHVsZSh7XG4gKiAgIHByb3ZpZGVyczogW0F1dGhHdWFyZF1cbiAqIH0pXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGNsYXNzIEF1dGhHdWFyZCB7XG4gIC8qKlxuICAgKiBAcGFyYW0gYXV0aCAtIEF1dGhlbnRpY2F0aW9uIHNlcnZpY2VcbiAgICogQHBhcmFtIHJvdXRlciAtIEFuZ3VsYXIgcm91dGVyXG4gICAqIEBwYXJhbSBjb25maWcgLSBPcHRpb25hbCBjbGllbnQgY29uZmlndXJhdGlvbiAoaW5qZWN0ZWQgYXV0b21hdGljYWxseSlcbiAgICovXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgYXV0aDogQXV0aFNlcnZpY2UsXG4gICAgcHJpdmF0ZSByb3V0ZXI6IFJvdXRlcixcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KE5BVVRIX0NMSUVOVF9DT05GSUcpIHByaXZhdGUgY29uZmlnPzogTkF1dGhDbGllbnRDb25maWcsXG4gICkge31cblxuICAvKipcbiAgICogQ2hlY2sgaWYgcm91dGUgY2FuIGJlIGFjdGl2YXRlZC5cbiAgICpcbiAgICogQHJldHVybnMgVHJ1ZSBpZiBhdXRoZW50aWNhdGVkLCBvdGhlcndpc2UgcmVkaXJlY3RzIHRvIGNvbmZpZ3VyZWQgc2Vzc2lvbiBleHBpcmVkIHJvdXRlIChvciAnL2xvZ2luJylcbiAgICovXG4gIGNhbkFjdGl2YXRlKCk6IGJvb2xlYW4gfCBVcmxUcmVlIHtcbiAgICBpZiAodGhpcy5hdXRoLmlzQXV0aGVudGljYXRlZCgpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBVc2UgY29uZmlnLnJlZGlyZWN0cy5zZXNzaW9uRXhwaXJlZCBvciBkZWZhdWx0IHRvICcvbG9naW4nXG4gICAgY29uc3QgcmVkaXJlY3RQYXRoID0gdGhpcy5jb25maWc/LnJlZGlyZWN0cz8uc2Vzc2lvbkV4cGlyZWQgPz8gJy9sb2dpbic7XG5cbiAgICByZXR1cm4gdGhpcy5yb3V0ZXIuY3JlYXRlVXJsVHJlZShbcmVkaXJlY3RQYXRoXSk7XG4gIH1cbn1cbiJdfQ==
@@ -1,158 +0,0 @@
1
- import { inject, PLATFORM_ID } from '@angular/core';
2
- import { isPlatformBrowser } from '@angular/common';
3
- import { HttpClient, HttpErrorResponse } from '@angular/common/http';
4
- import { Router } from '@angular/router';
5
- import { catchError, switchMap, throwError, filter, take, BehaviorSubject, from } from 'rxjs';
6
- import { NAUTH_CLIENT_CONFIG } from './tokens';
7
- import { AuthService } from './auth.service';
8
- /**
9
- * Refresh state management.
10
- * BehaviorSubject pattern is the industry-standard for token refresh.
11
- */
12
- let isRefreshing = false;
13
- const refreshTokenSubject = new BehaviorSubject(null);
14
- /**
15
- * Track retried requests to prevent infinite loops.
16
- */
17
- const retriedRequests = new WeakSet();
18
- /**
19
- * Get CSRF token from cookie.
20
- */
21
- function getCsrfToken(cookieName) {
22
- if (typeof document === 'undefined')
23
- return null;
24
- const match = document.cookie.match(new RegExp(`(^| )${cookieName}=([^;]+)`));
25
- return match ? decodeURIComponent(match[2]) : null;
26
- }
27
- /**
28
- * Angular HTTP interceptor for nauth-toolkit.
29
- *
30
- * Handles:
31
- * - Cookies mode: withCredentials + CSRF tokens + refresh via POST
32
- * - JSON mode: refresh via SDK, retry with new token
33
- */
34
- export const authInterceptor = (req, next) => {
35
- const config = inject(NAUTH_CLIENT_CONFIG);
36
- const http = inject(HttpClient);
37
- const authService = inject(AuthService);
38
- const platformId = inject(PLATFORM_ID);
39
- const router = inject(Router);
40
- const isBrowser = isPlatformBrowser(platformId);
41
- if (!isBrowser) {
42
- return next(req);
43
- }
44
- const tokenDelivery = config.tokenDelivery;
45
- const baseUrl = config.baseUrl;
46
- const endpoints = config.endpoints ?? {};
47
- const refreshPath = endpoints.refresh ?? '/refresh';
48
- const loginPath = endpoints.login ?? '/login';
49
- const signupPath = endpoints.signup ?? '/signup';
50
- const socialExchangePath = endpoints.socialExchange ?? '/social/exchange';
51
- const refreshUrl = `${baseUrl}${refreshPath}`;
52
- const isAuthApiRequest = req.url.includes(baseUrl);
53
- const isRefreshEndpoint = req.url.includes(refreshPath);
54
- const isPublicEndpoint = req.url.includes(loginPath) || req.url.includes(signupPath) || req.url.includes(socialExchangePath);
55
- // Build request with credentials (cookies mode only)
56
- let authReq = req;
57
- if (tokenDelivery === 'cookies') {
58
- authReq = authReq.clone({ withCredentials: true });
59
- if (['POST', 'PUT', 'PATCH', 'DELETE'].includes(req.method)) {
60
- const csrfCookieName = config.csrf?.cookieName ?? 'nauth_csrf_token';
61
- const csrfHeaderName = config.csrf?.headerName ?? 'x-csrf-token';
62
- const csrfToken = getCsrfToken(csrfCookieName);
63
- if (csrfToken) {
64
- authReq = authReq.clone({ setHeaders: { [csrfHeaderName]: csrfToken } });
65
- }
66
- }
67
- }
68
- return next(authReq).pipe(catchError((error) => {
69
- const shouldHandle = error instanceof HttpErrorResponse &&
70
- error.status === 401 &&
71
- isAuthApiRequest &&
72
- !isRefreshEndpoint &&
73
- !isPublicEndpoint &&
74
- !retriedRequests.has(req);
75
- if (!shouldHandle) {
76
- return throwError(() => error);
77
- }
78
- if (config.debug) {
79
- console.warn('[nauth-interceptor] 401 detected:', req.url);
80
- }
81
- if (!isRefreshing) {
82
- isRefreshing = true;
83
- refreshTokenSubject.next(null);
84
- if (config.debug) {
85
- console.warn('[nauth-interceptor] Starting refresh...');
86
- }
87
- // Refresh based on mode
88
- const refresh$ = tokenDelivery === 'cookies'
89
- ? http.post(refreshUrl, {}, { withCredentials: true })
90
- : from(authService.refresh());
91
- return refresh$.pipe(switchMap((response) => {
92
- if (config.debug) {
93
- console.warn('[nauth-interceptor] Refresh successful');
94
- }
95
- isRefreshing = false;
96
- // Get new token (JSON mode) or signal success (cookies mode)
97
- const newToken = 'accessToken' in response ? response.accessToken : 'success';
98
- refreshTokenSubject.next(newToken ?? 'success');
99
- // Build retry request
100
- const retryReq = buildRetryRequest(authReq, tokenDelivery, newToken);
101
- retriedRequests.add(retryReq);
102
- if (config.debug) {
103
- console.warn('[nauth-interceptor] Retrying:', req.url);
104
- }
105
- return next(retryReq);
106
- }), catchError((err) => {
107
- if (config.debug) {
108
- console.error('[nauth-interceptor] Refresh failed:', err);
109
- }
110
- isRefreshing = false;
111
- refreshTokenSubject.next(null);
112
- // Handle session expiration - redirect to configured URL
113
- if (config.redirects?.sessionExpired) {
114
- router.navigateByUrl(config.redirects.sessionExpired).catch((navError) => {
115
- if (config.debug) {
116
- console.error('[nauth-interceptor] Navigation failed:', navError);
117
- }
118
- });
119
- }
120
- return throwError(() => err);
121
- }));
122
- }
123
- else {
124
- // Wait for ongoing refresh
125
- if (config.debug) {
126
- console.warn('[nauth-interceptor] Waiting for refresh...');
127
- }
128
- return refreshTokenSubject.pipe(filter((token) => token !== null), take(1), switchMap((token) => {
129
- if (config.debug) {
130
- console.warn('[nauth-interceptor] Refresh done, retrying:', req.url);
131
- }
132
- const retryReq = buildRetryRequest(authReq, tokenDelivery, token);
133
- retriedRequests.add(retryReq);
134
- return next(retryReq);
135
- }));
136
- }
137
- }));
138
- };
139
- /**
140
- * Build retry request with appropriate auth.
141
- */
142
- function buildRetryRequest(originalReq, tokenDelivery, newToken) {
143
- if (tokenDelivery === 'json' && newToken && newToken !== 'success') {
144
- return originalReq.clone({
145
- setHeaders: { Authorization: `Bearer ${newToken}` },
146
- });
147
- }
148
- return originalReq.clone();
149
- }
150
- /**
151
- * Class-based interceptor for NgModule compatibility.
152
- */
153
- export class AuthInterceptor {
154
- intercept(req, next) {
155
- return authInterceptor(req, next);
156
- }
157
- }
158
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5pbnRlcmNlcHRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3N0YW5kYWxvbmUvYXV0aC5pbnRlcmNlcHRvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNwRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNwRCxPQUFPLEVBQWlELFVBQVUsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3BILE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRSxlQUFlLEVBQUUsSUFBSSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzlGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0M7OztHQUdHO0FBQ0gsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0FBQ3pCLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxlQUFlLENBQWdCLElBQUksQ0FBQyxDQUFDO0FBRXJFOztHQUVHO0FBQ0gsTUFBTSxlQUFlLEdBQUcsSUFBSSxPQUFPLEVBQXdCLENBQUM7QUFFNUQ7O0dBRUc7QUFDSCxTQUFTLFlBQVksQ0FBQyxVQUFrQjtJQUN0QyxJQUFJLE9BQU8sUUFBUSxLQUFLLFdBQVc7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNqRCxNQUFNLEtBQUssR0FBRyxRQUFRLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxRQUFRLFVBQVUsVUFBVSxDQUFDLENBQUMsQ0FBQztJQUM5RSxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsS0FBSyxD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SSxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDbkUsT0FBTyxXQUFXLENBQUMsS0FBSyxDQUFDO1lBQ3ZCLFVBQVUsRUFBRSxFQUFFLGFBQWEsRUFBRSxVQUFVLFFBQVEsRUFBRSxFQUFFO1NBQ3BELENBQUMsQ0FBQztJQUNMLENBQUM7SUFDRCxPQUFPLFdBQVcsQ0FBQyxLQUFLLEVBQUUsQ0FBQztBQUM3QixDQUFDO0FBRUQ7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZTtJQUMxQixTQUFTLENBQUMsR0FBeUIsRUFBRSxJQUFtQjtRQUN0RCxPQUFPLGVBQWUsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDcEMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgaW5qZWN0LCBQTEFURk9STV9JRCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgaXNQbGF0Zm9ybUJyb3dzZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSHR0cEhhbmRsZXJGbiwgSHR0cEludGVyY2VwdG9yRm4sIEh0dHBSZXF1ZXN0LCBIdHRwQ2xpZW50LCBIdHRwRXJyb3JSZXNwb25zZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBzd2l0Y2hNYXAsIHRocm93RXJyb3IsIGZpbHRlciwgdGFrZSwgQmVoYXZpb3JTdWJqZWN0LCBmcm9tIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBOQVVUSF9DTElFTlRfQ09ORklHIH0gZnJvbSAnLi90b2tlbnMnO1xuaW1wb3J0IHsgQXV0aFNlcnZpY2UgfSBmcm9tICcuL2F1dGguc2VydmljZSc7XG5cbi8qKlxuICogUmVmcmVzaCBzdGF0ZSBtYW5hZ2VtZW50LlxuICogQmVoYXZpb3JTdWJqZWN0IHBhdHRlcm4gaXMgdGhlIGluZHVzdHJ5LXN0YW5kYXJkIGZvciB0b2tlbiByZWZyZXNoLlxuICovXG5sZXQgaXNSZWZyZXNoaW5nID0gZmFsc2U7XG5jb25zdCByZWZyZXNoVG9rZW5TdWJqZWN0ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuLyoqXG4gKiBUcmFjayByZXRyaWVkIHJlcXVlc3RzIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcHMuXG4gKi9cbmNvbnN0IHJldHJpZWRSZXF1ZXN0cyA9IG5ldyBXZWFrU2V0PEh0dHBSZXF1ZXN0PHVua25vd24+PigpO1xuXG4vKipcbiAqIEdldCBDU1JGIHRva2VuIGZyb20gY29va2llLlxuICovXG5mdW5jdGlvbiBnZXRDc3JmVG9rZW4oY29va2llTmFtZTogc3RyaW5nKTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgPT09ICd1bmRlZmluZWQnKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgbWF0Y2ggPSBkb2N1bWVudC5jb29raWUubWF0Y2gobmV3IFJlZ0V4cChgKF58ICkke2Nvb2tpZU5hbWV9PShbXjtdKylgKSk7XG4gIHJldHVybiBtYXRjaCA/IGRlY29kZVVSSUNvbXBvbmVudChtYXRjaFsyXSkgOiBudWxsO1xufVxuXG4vKipcbiAqIEFuZ3VsYXIgSFRUUCBpbnRlcmNlcHRvciBmb3IgbmF1dGgtdG9vbGtpdC5cbiAqXG4gKiBIYW5kbGVzOlxuICogLSBDb29raWVzIG1vZGU6IHdpdGhDcmVkZW50aWFscyArIENTUkYgdG9rZW5zICsgcmVmcmVzaCB2aWEgUE9TVFxuICogLSBKU09OIG1vZGU6IHJlZnJlc2ggdmlhIFNESywgcmV0cnkgd2l0aCBuZXcgdG9rZW5cbiAqL1xuZXhwb3J0IGNvbnN0IGF1dGhJbnRlcmNlcHRvcjogSHR0cEludGVyY2VwdG9yRm4gPSAocmVxOiBIdHRwUmVxdWVzdDx1bmtub3duPiwgbmV4dDogSHR0cEhhbmRsZXJGbikgPT4ge1xuICBjb25zdCBjb25maWcgPSBpbmplY3QoTkFVVEhfQ0xJRU5UX0NPTkZJRyk7XG4gIGNvbnN0IGh0dHAgPSBpbmplY3QoSHR0cENsaWVudCk7XG4gIGNvbnN0IGF1dGhTZXJ2aWNlID0gaW5qZWN0KEF1dGhTZXJ2aWNlKTtcbiAgY29uc3QgcGxhdGZvcm1JZCA9IGluamVjdChQTEFURk9STV9JRCk7XG4gIGNvbnN0IHJvdXRlciA9IGluamVjdChSb3V0ZXIpO1xuICBjb25zdCBpc0Jyb3dzZXIgPSBpc1BsYXRmb3JtQnJvd3NlcihwbGF0Zm9ybUlkKTtcblxuICBpZiAoIWlzQnJvd3Nlcikge1xuICAgIHJldHVybiBuZXh0KHJlcSk7XG4gIH1cblxuICBjb25zdCB0b2tlbkRlbGl2ZXJ5ID0gY29uZmlnLnRva2VuRGVsaXZlcnk7XG4gIGNvbnN0IGJhc2VVcmwgPSBjb25maWcuYmFzZVVybDtcbiAgY29uc3QgZW5kcG9pbnRzID0gY29uZmlnLmVuZHBvaW50cyA/PyB7fTtcbiAgY29uc3QgcmVmcmVzaFBhdGggPSBlbmRwb2ludHMucmVmcmVzaCA/PyAnL3JlZnJlc2gnO1xuICBjb25zdCBsb2dpblBhdGggPSBlbmRwb2ludHMubG9naW4gPz8gJy9sb2dpbic7XG4gIGNvbnN0IHNpZ251cFBhdGggPSBlbmRwb2ludHMuc2lnbnVwID8/ICcvc2lnbnVwJztcbiAgY29uc3Qgc29jaWFsRXhjaGFuZ2VQYXRoID0gZW5kcG9pbnRzLnNvY2lhbEV4Y2hhbmdlID8/ICcvc29jaWFsL2V4Y2hhbmdlJztcbiAgY29uc3QgcmVmcmVzaFVybCA9IGAke2Jhc2VVcmx9JHtyZWZyZXNoUGF0aH1gO1xuXG4gIGNvbnN0IGlzQXV0aEFwaVJlcXVlc3QgPSByZXEudXJsLmluY2x1ZGVzKGJhc2VVcmwpO1xuICBjb25zdCBpc1JlZnJlc2hFbmRwb2ludCA9IHJlcS51cmwuaW5jbHVkZXMocmVmcmVzaFBhdGgpO1xuICBjb25zdCBpc1B1YmxpY0VuZHBvaW50ID1cbiAgICByZXEudXJsLmluY2x1ZGVzKGxvZ2luUGF0aCkgfHwgcmVxLnVybC5pbmNsdWRlcyhzaWdudXBQYXRoKSB8fCByZXEudXJsLmluY2x1ZGVzKHNvY2lhbEV4Y2hhbmdlUGF0aCk7XG5cbiAgLy8gQnVpbGQgcmVxdWVzdCB3aXRoIGNyZWRlbnRpYWxzIChjb29raWVzIG1vZGUgb25seSlcbiAgbGV0IGF1dGhSZXEgPSByZXE7XG4gIGlmICh0b2tlbkRlbGl2ZXJ5ID09PSAnY29va2llcycpIHtcbiAgICBhdXRoUmVxID0gYXV0aFJlcS5jbG9uZSh7IHdpdGhDcmVkZW50aWFsczogdHJ1ZSB9KTtcblxuICAgIGlmIChbJ1BPU1QnLCAnUFVUJywgJ1BBVENIJywgJ0RFTEVURSddLmluY2x1ZGVzKHJlcS5tZXRob2QpKSB7XG4gICAgICBjb25zdCBjc3JmQ29va2llTmFtZSA9IGNvbmZpZy5jc3JmPy5jb29raWVOYW1lID8/ICduYXV0aF9jc3JmX3Rva2VuJztcbiAgICAgIGNvbnN0IGNzcmZIZWFkZXJOYW1lID0gY29uZmlnLmNzcmY/LmhlYWRlck5hbWUgPz8gJ3gtY3NyZi10b2tlbic7XG4gICAgICBjb25zdCBjc3JmVG9rZW4gPSBnZXRDc3JmVG9rZW4oY3NyZkNvb2tpZU5hbWUpO1xuICAgICAgaWYgKGNzcmZUb2tlbikge1xuICAgICAgICBhdXRoUmVxID0gYXV0aFJlcS5jbG9uZSh7IHNldEhlYWRlcnM6IHsgW2NzcmZIZWFkZXJOYW1lXTogY3NyZlRva2VuIH0gfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5leHQoYXV0aFJlcSkucGlwZShcbiAgICBjYXRjaEVycm9yKChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgY29uc3Qgc2hvdWxkSGFuZGxlID1cbiAgICAgICAgZXJyb3IgaW5zdGFuY2VvZiBIdHRwRXJyb3JSZXNwb25zZSAmJlxuICAgICAgICBlcnJvci5zdGF0dXMgPT09IDQwMSAmJlxuICAgICAgICBpc0F1dGhBcGlSZXF1ZXN0ICYmXG4gICAgICAgICFpc1JlZnJlc2hFbmRwb2ludCAmJlxuICAgICAgICAhaXNQdWJsaWNFbmRwb2ludCAmJlxuICAgICAgICAhcmV0cmllZFJlcXVlc3RzLmhhcyhyZXEpO1xuXG4gICAgICBpZiAoIXNob3VsZEhhbmRsZSkge1xuICAgICAgICByZXR1cm4gdGhyb3dFcnJvcigoKSA9PiBlcnJvcik7XG4gICAgICB9XG5cbiAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgY29uc29sZS53YXJuKCdbbmF1dGgtaW50ZXJjZXB0b3JdIDQwMSBkZXRlY3RlZDonLCByZXEudXJsKTtcbiAgICAgIH1cblxuICAgICAgaWYgKCFpc1JlZnJlc2hpbmcpIHtcbiAgICAgICAgaXNSZWZyZXNoaW5nID0gdHJ1ZTtcbiAgICAgICAgcmVmcmVzaFRva2VuU3ViamVjdC5uZXh0KG51bGwpO1xuXG4gICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oJ1tuYXV0aC1pbnRlcmNlcHRvcl0gU3RhcnRpbmcgcmVmcmVzaC4uLicpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gUmVmcmVzaCBiYXNlZCBvbiBtb2RlXG4gICAgICAgIGNvbnN0IHJlZnJlc2gkID1cbiAgICAgICAgICB0b2tlbkRlbGl2ZXJ5ID09PSAnY29va2llcydcbiAgICAgICAgICAgID8gaHR0cC5wb3N0PHsgYWNjZXNzVG9rZW4/OiBzdHJpbmcgfT4ocmVmcmVzaFVybCwge30sIHsgd2l0aENyZWRlbnRpYWxzOiB0cnVlIH0pXG4gICAgICAgICAgICA6IGZyb20oYXV0aFNlcnZpY2UucmVmcmVzaCgpKTtcblxuICAgICAgICByZXR1cm4gcmVmcmVzaCQucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKHJlc3BvbnNlKSA9PiB7XG4gICAgICAgICAgICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybignW25hdXRoLWludGVyY2VwdG9yXSBSZWZyZXNoIHN1Y2Nlc3NmdWwnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzUmVmcmVzaGluZyA9IGZhbHNlO1xuXG4gICAgICAgICAgICAvLyBHZXQgbmV3IHRva2VuIChKU09OIG1vZGUpIG9yIHNpZ25hbCBzdWNjZXNzIChjb29raWVzIG1vZGUpXG4gICAgICAgICAgICBjb25zdCBuZXdUb2tlbiA9ICdhY2Nlc3NUb2tlbicgaW4gcmVzcG9uc2UgPyByZXNwb25zZS5hY2Nlc3NUb2tlbiA6ICdzdWNjZXNzJztcbiAgICAgICAgICAgIHJlZnJlc2hUb2tlblN1YmplY3QubmV4dChuZXdUb2tlbiA/PyAnc3VjY2VzcycpO1xuXG4gICAgICAgICAgICAvLyBCdWlsZCByZXRyeSByZXF1ZXN0XG4gICAgICAgICAgICBjb25zdCByZXRyeVJlcSA9IGJ1aWxkUmV0cnlSZXF1ZXN0KGF1dGhSZXEsIHRva2VuRGVsaXZlcnksIG5ld1Rva2VuKTtcbiAgICAgICAgICAgIHJldHJpZWRSZXF1ZXN0cy5hZGQocmV0cnlSZXEpO1xuXG4gICAgICAgICAgICBpZiAoY29uZmlnLmRlYnVnKSB7XG4gICAgICAgICAgICAgIGNvbnNvbGUud2FybignW25hdXRoLWludGVyY2VwdG9yXSBSZXRyeWluZzonLCByZXEudXJsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBuZXh0KHJldHJ5UmVxKTtcbiAgICAgICAgICB9KSxcbiAgICAgICAgICBjYXRjaEVycm9yKChlcnIpID0+IHtcbiAgICAgICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgICAgY29uc29sZS5lcnJvcignW25hdXRoLWludGVyY2VwdG9yXSBSZWZyZXNoIGZhaWxlZDonLCBlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXNSZWZyZXNoaW5nID0gZmFsc2U7XG4gICAgICAgICAgICByZWZyZXNoVG9rZW5TdWJqZWN0Lm5leHQobnVsbCk7XG5cbiAgICAgICAgICAgIC8vIEhhbmRsZSBzZXNzaW9uIGV4cGlyYXRpb24gLSByZWRpcmVjdCB0byBjb25maWd1cmVkIFVSTFxuICAgICAgICAgICAgaWYgKGNvbmZpZy5yZWRpcmVjdHM/LnNlc3Npb25FeHBpcmVkKSB7XG4gICAgICAgICAgICAgIHJvdXRlci5uYXZpZ2F0ZUJ5VXJsKGNvbmZpZy5yZWRpcmVjdHMuc2Vzc2lvbkV4cGlyZWQpLmNhdGNoKChuYXZFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ1tuYXV0aC1pbnRlcmNlcHRvcl0gTmF2aWdhdGlvbiBmYWlsZWQ6JywgbmF2RXJyb3IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiB0aHJvd0Vycm9yKCgpID0+IGVycik7XG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBXYWl0IGZvciBvbmdvaW5nIHJlZnJlc2hcbiAgICAgICAgaWYgKGNvbmZpZy5kZWJ1Zykge1xuICAgICAgICAgIGNvbnNvbGUud2FybignW25hdXRoLWludGVyY2VwdG9yXSBXYWl0aW5nIGZvciByZWZyZXNoLi4uJyk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlZnJlc2hUb2tlblN1YmplY3QucGlwZShcbiAgICAgICAgICBmaWx0ZXIoKHRva2VuKTogdG9rZW4gaXMgc3RyaW5nID0+IHRva2VuICE9PSBudWxsKSxcbiAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgIHN3aXRjaE1hcCgodG9rZW4pID0+IHtcbiAgICAgICAgICAgIGlmIChjb25maWcuZGVidWcpIHtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbbmF1dGgtaW50ZXJjZXB0b3JdIFJlZnJlc2ggZG9uZSwgcmV0cnlpbmc6JywgcmVxLnVybCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCByZXRyeVJlcSA9IGJ1aWxkUmV0cnlSZXF1ZXN0KGF1dGhSZXEsIHRva2VuRGVsaXZlcnksIHRva2VuKTtcbiAgICAgICAgICAgIHJldHJpZWRSZXF1ZXN0cy5hZGQocmV0cnlSZXEpO1xuICAgICAgICAgICAgcmV0dXJuIG5leHQocmV0cnlSZXEpO1xuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0pLFxuICApO1xufTtcblxuLyoqXG4gKiBCdWlsZCByZXRyeSByZXF1ZXN0IHdpdGggYXBwcm9wcmlhdGUgYXV0aC5cbiAqL1xuZnVuY3Rpb24gYnVpbGRSZXRyeVJlcXVlc3QoXG4gIG9yaWdpbmFsUmVxOiBIdHRwUmVxdWVzdDx1bmtub3duPixcbiAgdG9rZW5EZWxpdmVyeTogc3RyaW5nLFxuICBuZXdUb2tlbj86IHN0cmluZyxcbik6IEh0dHBSZXF1ZXN0PHVua25vd24+IHtcbiAgaWYgKHRva2VuRGVsaXZlcnkgPT09ICdqc29uJyAmJiBuZXdUb2tlbiAmJiBuZXdUb2tlbiAhPT0gJ3N1Y2Nlc3MnKSB7XG4gICAgcmV0dXJuIG9yaWdpbmFsUmVxLmNsb25lKHtcbiAgICAgIHNldEhlYWRlcnM6IHsgQXV0aG9yaXphdGlvbjogYEJlYXJlciAke25ld1Rva2VufWAgfSxcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gb3JpZ2luYWxSZXEuY2xvbmUoKTtcbn1cblxuLyoqXG4gKiBDbGFzcy1iYXNlZCBpbnRlcmNlcHRvciBmb3IgTmdNb2R1bGUgY29tcGF0aWJpbGl0eS5cbiAqL1xuZXhwb3J0IGNsYXNzIEF1dGhJbnRlcmNlcHRvciB7XG4gIGludGVyY2VwdChyZXE6IEh0dHBSZXF1ZXN0PHVua25vd24+LCBuZXh0OiBIdHRwSGFuZGxlckZuKSB7XG4gICAgcmV0dXJuIGF1dGhJbnRlcmNlcHRvcihyZXEsIG5leHQpO1xuICB9XG59XG4iXX0=