@hichchi/ngx-auth 0.0.3 → 0.0.4
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/README.md +195 -102
- package/fesm2022/hichchi-ngx-auth.mjs +67 -5
- package/fesm2022/hichchi-ngx-auth.mjs.map +1 -1
- package/package.json +5 -5
- package/types/hichchi-ngx-auth.d.ts +65 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hichchi-ngx-auth.mjs","sources":["../../../../libs/ngx-auth/src/lib/tokens.ts","../../../../libs/ngx-auth/src/lib/constants.ts","../../../../libs/ngx-auth/src/lib/services/auth.service.ts","../../../../libs/ngx-auth/src/lib/state/auth.state.ts","../../../../libs/ngx-auth/src/lib/components/auth-form/auth-form.component.ts","../../../../libs/ngx-auth/src/lib/components/auth-form/auth-form.component.html","../../../../libs/ngx-auth/src/lib/directives/permission.directive.ts","../../../../libs/ngx-auth/src/lib/enums/auth-guard-condition.enum.ts","../../../../libs/ngx-auth/src/lib/utils/route.utils.ts","../../../../libs/ngx-auth/src/lib/guards/auth.guard.ts","../../../../libs/ngx-auth/src/lib/guards/role.guard.ts","../../../../libs/ngx-auth/src/lib/interceptors/auth.interceptor.ts","../../../../libs/ngx-auth/src/lib/auth.module.ts","../../../../libs/ngx-auth/src/hichchi-ngx-auth.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\nimport { AuthConfig } from \"./interfaces\";\n\n/**\n * Injection token for the ngx-auth runtime configuration.\n *\n * This token is bound in `NgxHichchiAuthModule.forRoot(config)` as:\n * `{ provide: AUTH_CONFIG, useValue: config }`.\n * Consumers can inject it to access the same `AuthConfig` object\n * (for example `apiBaseURL` and optional `authField`).\n *\n * @example\n * ```typescript\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: \"https://api.example.com\",\n * });\n * ```\n *\n * @example\n * ```typescript\n * @Injectable()\n * export class ExampleService {\n * constructor(@Inject(AUTH_CONFIG) private readonly config: AuthConfig) {\n * console.log(this.config.apiBaseURL);\n * }\n * }\n * ```\n *\n * @see {@link AuthConfig} Configuration contract provided through this token\n */\nexport const AUTH_CONFIG = new InjectionToken<AuthConfig>(\"AUTH_CONFIG\");\n","/**\r\n * Width of the Google OAuth authentication popup window in pixels\r\n *\r\n * This constant defines the width of the popup window that opens during Google OAuth\r\n * authentication. The width is optimized to provide a good user experience while\r\n * ensuring the Google sign-in interface is fully visible and usable.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used internally in AuthService.googleSignIn()\r\n * const popup = window.open(\r\n * googleAuthUrl,\r\n * 'google-login-popup',\r\n * `width=${GOOGLE_AUTH_POPUP_WIDTH}, height=${GOOGLE_AUTH_POPUP_HEIGHT}`\r\n * );\r\n * ```\r\n *\r\n * @see {@link AuthService.googleSignIn} Method that uses this constant\r\n * @see {@link GOOGLE_AUTH_POPUP_HEIGHT} Related constant for popup height\r\n */\r\nexport const GOOGLE_AUTH_POPUP_WIDTH = 500;\r\n\r\n/**\r\n * Height of the Google OAuth authentication popup window in pixels\r\n *\r\n * This constant defines the height of the popup window that opens during Google OAuth\r\n * authentication. The height is optimized to accommodate the Google sign-in interface\r\n * and provide sufficient space for user interaction.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used internally in AuthService.googleSignIn()\r\n * const popup = window.open(\r\n * googleAuthUrl,\r\n * 'google-login-popup',\r\n * `width=${GOOGLE_AUTH_POPUP_WIDTH}, height=${GOOGLE_AUTH_POPUP_HEIGHT}`\r\n * );\r\n * ```\r\n *\r\n * @see {@link AuthService.googleSignIn} Method that uses this constant\r\n * @see {@link GOOGLE_AUTH_POPUP_WIDTH} Related constant for popup width\r\n */\r\nexport const GOOGLE_AUTH_POPUP_HEIGHT = 600;\r\n\r\n/**\r\n * Polling interval for checking Google OAuth popup status in milliseconds\r\n *\r\n * This constant defines how frequently (in milliseconds) the AuthService checks\r\n * the status of the Google OAuth popup window. The polling is used to detect\r\n * when the authentication process is complete or if the user has closed the popup.\r\n *\r\n * A shorter interval provides more responsive detection but uses more CPU resources.\r\n * The current value of 100ms provides a good balance between responsiveness and\r\n * performance.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used internally in AuthService.googleSignIn()\r\n * const interval = setInterval(() => {\r\n * // Check popup status\r\n * if (popup?.closed) {\r\n * clearInterval(interval);\r\n * }\r\n * // Check for authentication completion\r\n * }, POPUP_POLLING_INTERVAL_MS);\r\n * ```\r\n *\r\n * @see {@link AuthService.googleSignIn} Method that uses this constant for popup polling\r\n */\r\nexport const POPUP_POLLING_INTERVAL_MS = 100;\r\n\r\n/**\r\n * Key used to store authentication guard options in route data\r\n *\r\n * This constant defines the property name used to store authentication guard\r\n * configuration in Angular route data. It allows routes to specify custom\r\n * authentication requirements and behaviors.\r\n *\r\n * @example\r\n * ```typescript\r\n * // In route configuration\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [AuthGuard],\r\n * data: {\r\n * [AUTH_GUARD_OPTIONS_KEY]: {\r\n * requiredPermissions: ['admin.read'],\r\n * redirectTo: '/unauthorized'\r\n * }\r\n * }\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthGuardOption} Interface defining the structure of guard options\r\n */\r\nexport const AUTH_GUARD_OPTIONS_KEY = \"authGuardOptions\";\r\n","// noinspection JSUnusedGlobalSymbols\r\n\r\nimport { Inject, Injectable } from \"@angular/core\";\r\nimport { map, Observable, take } from \"rxjs\";\r\nimport {\r\n AccessToken,\r\n AuthEndpoint,\r\n AuthResponse,\r\n RefreshToken,\r\n SignInBody,\r\n SignUpBody,\r\n TokenResponse,\r\n User,\r\n} from \"@hichchi/nest-connector/auth\";\r\nimport { Endpoint, SuccessResponse } from \"@hichchi/nest-connector\";\r\nimport { AUTH_CONFIG } from \"../tokens\";\r\nimport { AuthConfig } from \"../interfaces\";\r\nimport { GOOGLE_AUTH_POPUP_HEIGHT, GOOGLE_AUTH_POPUP_WIDTH, POPUP_POLLING_INTERVAL_MS } from \"../constants\";\r\nimport { CrudHttpService, skipNotifyContext } from \"@hichchi/ngx-utils\";\r\n\r\n/**\r\n * Angular authentication service for client-side authentication operations\r\n *\r\n * This service provides methods for handling authentication operations in Angular applications,\r\n * including user sign-in, sign-up, Google OAuth authentication, token management, and sign-out.\r\n * It communicates with the backend authentication API and handles the client-side aspects\r\n * of the authentication flow.\r\n *\r\n * The service is configured through the AuthConfig interface and automatically handles\r\n * token expiration date parsing and HTTP request management. It integrates seamlessly\r\n * with the @hichchi/nest-auth backend module.\r\n *\r\n * Key features:\r\n * - Local authentication (email/username and password)\r\n * - Google OAuth authentication with popup flow\r\n * - Token refresh functionality\r\n * - User registration\r\n * - Automatic token expiration handling\r\n * - RESTful API communication\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class LoginComponent {\r\n * constructor(private authService: AuthService) {}\r\n *\r\n * async signIn() {\r\n * try {\r\n * const response = await this.authService.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }).toPromise();\r\n * console.log('Signed in:', response.user);\r\n * } catch (error) {\r\n * console.error('Sign in failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthConfig} Configuration interface for the authentication service\r\n * @see {@link NgxHichchiAuthModule} Module that provides this service\r\n * @see {@link AuthState} State management service for authentication\r\n * @see {@link AuthResponse} Response interface for authentication operations\r\n */\r\n@Injectable({\n providedIn: \"root\",\n})\n/**\n * HTTP client wrapper for authentication and token lifecycle endpoints.\n */\nexport class AuthService extends CrudHttpService {\n /**\r\n * Creates an instance of AuthService\r\n *\r\n * @param config - The authentication configuration injected from AUTH_CONFIG token\r\n *\r\n * @see {@link AUTH_CONFIG} Injection token for authentication configuration\r\n * @see {@link AuthConfig} Interface defining the configuration structure\r\n */\r\n // eslint-disable-next-line @angular-eslint/prefer-inject\r\n constructor(@Inject(AUTH_CONFIG) private readonly config: AuthConfig) {\r\n super();\r\n }\r\n\r\n /**\r\n * Authenticates a user with email/username and password\r\n *\r\n * This method sends a sign-in request to the backend authentication API with the provided\r\n * credentials. It automatically converts the token expiration timestamps from the response\r\n * into JavaScript Date objects for easier handling in the client application.\r\n *\r\n * @param dto - The sign-in data containing user credentials\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the authentication response with user data and tokens\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign in with email and password\r\n * this.authService.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }).subscribe({\r\n * next: (response) => {\r\n * console.log('User signed in:', response.user);\r\n * console.log('Access token expires:', response.accessTokenExpiresOn);\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign in failed:', error);\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @see {@link SignInBody} Interface for sign-in request data\r\n * @see {@link AuthResponse} Interface for authentication response\r\n * @see {@link AuthEndpoint.SIGN_IN} Backend endpoint for user authentication\r\n */\r\n signIn(dto: SignInBody, skipNotify?: boolean): Observable<AuthResponse> {\r\n return this.post<AuthResponse>(`${Endpoint.AUTH}/${AuthEndpoint.SIGN_IN}`, dto, { skipNotify }).pipe(\r\n take(1),\r\n map(res => ({\r\n ...res,\r\n accessTokenExpiresOn: new Date(res.accessTokenExpiresOn),\r\n refreshTokenExpiresOn: new Date(res.refreshTokenExpiresOn),\r\n })),\r\n );\r\n }\r\n\r\n /**\r\n * Initiates Google OAuth authentication using a popup window\r\n *\r\n * This method opens a popup window that navigates to the Google OAuth authentication\r\n * endpoint. It handles the OAuth flow by monitoring the popup window and extracting\r\n * the access token from the callback URL when authentication is successful.\r\n *\r\n * The popup is automatically positioned in the center of the screen and has predefined\r\n * dimensions for optimal user experience. The method polls the popup window to detect\r\n * when authentication is complete or if the user closes the popup.\r\n *\r\n * @returns Promise that resolves with the access token when authentication succeeds\r\n *\r\n * @throws {Error} If authentication fails or the popup is blocked\r\n *\r\n * @example\r\n * ```typescript\r\n * // Initiate Google sign-in\r\n * try {\r\n * const accessToken = await this.authService.googleSignIn();\r\n * console.log('Google authentication successful:', accessToken);\r\n *\r\n * // Use the token to get full auth response\r\n * const authResponse = await this.authService.getAuthResponse(accessToken).toPromise();\r\n * console.log('User data:', authResponse.user);\r\n * } catch (error) {\r\n * console.error('Google authentication failed:', error);\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component with error handling\r\n * async signInWithGoogle() {\r\n * try {\r\n * const token = await this.authService.googleSignIn();\r\n * // Handle successful authentication\r\n * this.router.navigate(['/dashboard']);\r\n * } catch (error) {\r\n * if (error.message.includes('popup')) {\r\n * this.showError('Please allow popups for Google sign-in');\r\n * } else {\r\n * this.showError('Google sign-in failed. Please try again.');\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link getAuthResponse} Method to get full authentication response using the access token\r\n * @see {@link AuthEndpoint.GOOGLE_SIGN_IN} Backend endpoint for Google OAuth initiation\r\n * @see {@link GOOGLE_AUTH_POPUP_WIDTH} Constant defining popup window width\r\n * @see {@link GOOGLE_AUTH_POPUP_HEIGHT} Constant defining popup window height\r\n * @see {@link POPUP_POLLING_INTERVAL_MS} Constant defining popup polling interval\r\n */\r\n googleSignIn(): Promise<AccessToken> {\r\n return new Promise((resolve: (token: AccessToken) => void, reject: (error: unknown) => void): void => {\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n const left = (window.screen.width - GOOGLE_AUTH_POPUP_WIDTH) / 2;\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n const top = (window.screen.height - GOOGLE_AUTH_POPUP_HEIGHT) / 2;\r\n\r\n const popup = window.open(\r\n `${this.config.apiBaseURL}/${Endpoint.AUTH}/${AuthEndpoint.GOOGLE_SIGN_IN}?redirectUrl=${window.location.origin}`,\r\n \"google-login-popup\",\r\n // eslint-disable-next-line prefer-template\r\n \"resizable=no, location=no, toolbar=false, width=\" +\r\n GOOGLE_AUTH_POPUP_WIDTH +\r\n \", height=\" +\r\n GOOGLE_AUTH_POPUP_HEIGHT +\r\n \", top=\" +\r\n top +\r\n \", left=\" +\r\n left,\r\n );\r\n\r\n const interval = setInterval(() => {\r\n if (popup?.closed) {\r\n clearInterval(interval);\r\n }\r\n\r\n try {\r\n if (popup?.location.href !== \"about:blank\" && popup?.location?.search?.includes(\"?token=e\")) {\r\n const token = popup.location.search.split(\"=\")[1] as AccessToken;\r\n clearInterval(interval);\r\n popup.close();\r\n resolve(token);\r\n }\r\n } catch (error) {\r\n if (!String(error).includes(\"SecurityError\")) {\r\n clearInterval(interval);\r\n reject(error);\r\n }\r\n }\r\n }, POPUP_POLLING_INTERVAL_MS);\r\n });\r\n }\r\n\r\n /**\r\n * Retrieves the complete authentication response using an access token\r\n *\r\n * This method exchanges an access token for a complete authentication response\r\n * containing user information and token details. It's typically used after\r\n * Google OAuth authentication to get the full user profile and session data.\r\n *\r\n * The method automatically converts token expiration timestamps to JavaScript\r\n * Date objects for easier handling in the client application.\r\n *\r\n * @param accessToken - The access token to exchange for authentication response\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the complete authentication response\r\n *\r\n * @example\r\n * ```typescript\r\n * // Get auth response after Google sign-in\r\n * const accessToken = await this.authService.googleSignIn();\r\n * this.authService.getAuthResponse(accessToken).subscribe({\r\n * next: (response) => {\r\n * console.log('User:', response.user);\r\n * console.log('Tokens:', {\r\n * access: response.accessToken,\r\n * refresh: response.refreshToken\r\n * });\r\n * },\r\n * error: (error) => {\r\n * console.error('Failed to get auth response:', error);\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @see {@link AccessToken} Type representing access tokens\r\n * @see {@link AuthResponse} Interface for complete authentication response\r\n * @see {@link AuthEndpoint.GET_AUTH_RESPONSE} Backend endpoint for token exchange\r\n * @see {@link googleSignIn} Method that provides access tokens for this operation\r\n */\r\n getAuthResponse(accessToken: AccessToken, skipNotify?: boolean): Observable<AuthResponse> {\r\n return this.http\r\n .post<AuthResponse>(\r\n `${Endpoint.AUTH}/${AuthEndpoint.GET_AUTH_RESPONSE}`,\r\n {\r\n accessToken,\r\n },\r\n skipNotifyContext(skipNotify),\r\n )\r\n .pipe(\r\n take(1),\r\n map(res => ({\r\n ...res,\r\n accessTokenExpiresOn: new Date(res.accessTokenExpiresOn),\r\n refreshTokenExpiresOn: new Date(res.refreshTokenExpiresOn),\r\n })),\r\n );\r\n }\r\n\r\n /**\r\n * Registers a new user account\r\n *\r\n * This method sends a registration request to the backend API with the provided\r\n * user information. It creates a new user account and returns the user data\r\n * upon successful registration.\r\n *\r\n * Note that this method only creates the user account and does not automatically\r\n * sign the user in. After successful registration, you may need to call signIn\r\n * or handle email verification depending on your application's configuration.\r\n *\r\n * @param dto - The sign-up data containing user registration information\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the newly created user data\r\n *\r\n * @example\r\n * ```typescript\r\n * // Register a new user\r\n * this.authService.signUp({\r\n * email: 'newuser@example.com',\r\n * password: 'securePassword123',\r\n * firstName: 'John',\r\n * lastName: 'Doe'\r\n * }).subscribe({\r\n * next: (user) => {\r\n * console.log('User registered successfully:', user);\r\n * // Optionally redirect to sign-in or email verification page\r\n * this.router.navigate(['/verify-email']);\r\n * },\r\n * error: (error) => {\r\n * console.error('Registration failed:', error);\r\n * // Handle registration errors (email already exists, etc.)\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @see {@link SignUpBody} Interface for user registration data\r\n * @see {@link User} Interface for user data returned after registration\r\n * @see {@link AuthEndpoint.SIGN_UP} Backend endpoint for user registration\r\n * @see {@link signIn} Method to authenticate user after registration\r\n */\r\n signUp(dto: SignUpBody, skipNotify?: boolean): Observable<User> {\r\n return this.http\r\n .post<User>(`${Endpoint.AUTH}/${AuthEndpoint.SIGN_UP}`, dto, skipNotifyContext(skipNotify))\r\n .pipe(take(1));\r\n }\r\n\r\n /**\r\n * Refreshes an expired access token using a refresh token\r\n *\r\n * This method exchanges a valid refresh token for a new set of access and refresh tokens.\r\n * It's typically used when the current access token has expired but the refresh token\r\n * is still valid, allowing the user to maintain their session without re-authenticating.\r\n *\r\n * The refresh token mechanism provides a secure way to maintain long-lived sessions\r\n * while keeping access tokens short-lived for better security.\r\n *\r\n * @param refreshToken - The refresh token to exchange for new tokens\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the new token response\r\n *\r\n * @example\r\n * ```typescript\r\n * // Refresh tokens when access token expires\r\n * const storedRefreshToken = localStorage.getItem('refreshToken');\r\n * if (storedRefreshToken) {\r\n * this.authService.refreshToken(storedRefreshToken).subscribe({\r\n * next: (tokenResponse) => {\r\n * console.log('Tokens refreshed successfully');\r\n * // Store new tokens\r\n * localStorage.setItem('accessToken', tokenResponse.accessToken);\r\n * localStorage.setItem('refreshToken', tokenResponse.refreshToken);\r\n * },\r\n * error: (error) => {\r\n * console.error('Token refresh failed:', error);\r\n * // Redirect to login page\r\n * this.router.navigate(['/login']);\r\n * }\r\n * });\r\n * }\r\n * ```\r\n *\r\n * @see {@link RefreshToken} Type representing refresh tokens\r\n * @see {@link TokenResponse} Interface for token refresh response\r\n * @see {@link AuthEndpoint.REFRESH_TOKEN} Backend endpoint for token refresh\r\n * @see {@link signIn} Method to get initial tokens through authentication\r\n */\r\n refreshToken(refreshToken: RefreshToken, skipNotify?: boolean): Observable<TokenResponse> {\r\n return this.http\r\n .post<AuthResponse>(\r\n `${Endpoint.AUTH}/${AuthEndpoint.REFRESH_TOKEN}`,\r\n {\r\n refreshToken,\r\n },\r\n skipNotifyContext(skipNotify),\r\n )\r\n .pipe(take(1));\r\n }\r\n\r\n /**\r\n * Signs out the current user and invalidates their session\r\n *\r\n * This method sends a sign-out request to the backend API to invalidate the user's\r\n * current session and tokens. It effectively logs the user out of the application\r\n * and clears their authentication state on the server.\r\n *\r\n * After calling this method, you should also clear any client-side authentication\r\n * data such as tokens stored in localStorage, sessionStorage, or application state.\r\n *\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits a success response when sign-out is complete\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign out the current user\r\n * this.authService.signOut().subscribe({\r\n * next: (response) => {\r\n * console.log('User signed out successfully');\r\n * // Clear client-side authentication data\r\n * localStorage.removeItem('accessToken');\r\n * localStorage.removeItem('refreshToken');\r\n * // Redirect to login page\r\n * this.router.navigate(['/login']);\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign out failed:', error);\r\n * // Even if server sign-out fails, clear local data\r\n * localStorage.clear();\r\n * this.router.navigate(['/login']);\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign out with state management\r\n * async signOut() {\r\n * try {\r\n * await this.authService.signOut().toPromise();\r\n * // Clear authentication state\r\n * this.authState.clearUser();\r\n * this.notificationService.showSuccess('Signed out successfully');\r\n * } catch (error) {\r\n * console.error('Sign out error:', error);\r\n * } finally {\r\n * // Always redirect to login\r\n * this.router.navigate(['/login']);\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link SuccessResponse} Interface for success response\r\n * @see {@link AuthEndpoint.SIGN_OUT} Backend endpoint for user sign-out\r\n * @see {@link signIn} Method to authenticate user after sign-out\r\n */\r\n signOut(skipNotify?: boolean): Observable<SuccessResponse | null> {\r\n // this.app.startSpinner();\r\n return this.http\r\n .post<SuccessResponse>(`${Endpoint.AUTH}/${AuthEndpoint.SIGN_OUT}`, {}, skipNotifyContext(skipNotify))\r\n .pipe(take(1));\r\n }\r\n}\r\n","/* eslint-disable */\r\n// noinspection JSUnusedGlobalSymbols\r\n\r\nimport { computed, inject, Signal } from \"@angular/core\";\r\nimport {\r\n patchState,\r\n signalStore,\r\n withComputed,\r\n withMethods,\r\n withState\r\n} from \"@ngrx/signals\";\r\nimport { withStorageSync } from \"@angular-architects/ngrx-toolkit\";\r\nimport { catchError, EMPTY, firstValueFrom, Observable, tap } from \"rxjs\";\r\nimport {\r\n AccessToken,\r\n AuthResponse, isRoleObject,\r\n RefreshToken,\r\n SignInBody,\r\n TokenResponse,\r\n User\r\n} from \"@hichchi/nest-connector/auth\";\r\nimport { SuccessResponse } from \"@hichchi/nest-connector\";\r\nimport { AuthService } from \"../services\";\r\nimport { Router } from \"@angular/router\";\r\n\r\n/**\r\n * Interface defining the authentication state model\r\n *\r\n * This interface represents the complete authentication state structure used\r\n * throughout the Angular application. It contains user information, authentication\r\n * tokens, and session data that persists across browser sessions.\r\n *\r\n * The state is automatically synchronized with browser storage to maintain\r\n * authentication across page refreshes and browser restarts.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Accessing state in a component\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get isSignedIn() {\r\n * return this.authState.signedIn();\r\n * }\r\n *\r\n * get currentUser() {\r\n * return this.authState.user();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthState} The signal store that manages this state\r\n * @see {@link User} Interface for user data\r\n * @see {@link AccessToken} Type for access tokens\r\n * @see {@link RefreshToken} Type for refresh tokens\r\n */\r\nexport interface AuthStateModel<Data extends object= object> {\r\n /** Whether the user is currently signed in */\r\n signedIn: boolean;\r\n /** Unique identifier for the current session */\r\n sessionId: string | null;\r\n /** Current authenticated user information */\r\n user: User | null;\r\n /** JWT access token for API authentication */\r\n accessToken: AccessToken | null;\r\n /** JWT refresh token for obtaining new access tokens */\r\n refreshToken: RefreshToken | null;\r\n /** Expiration date of the access token */\r\n accessTokenExpiresOn: Date | null;\r\n /** Expiration date of the refresh token */\r\n refreshTokenExpiresOn: Date | null;\r\n\r\n data: Data\r\n}\r\n\r\nconst initialState: AuthStateModel = {\r\n signedIn: false,\r\n sessionId: null,\r\n user: null,\r\n accessToken: null,\r\n refreshToken: null,\r\n accessTokenExpiresOn: null,\r\n refreshTokenExpiresOn: null,\r\n data: {}\r\n};\r\n\r\n/**\r\n * Authentication state management store using NgRx Signals\r\n *\r\n * This signal store provides centralized state management for authentication in Angular applications.\r\n * It manages user authentication state, tokens, and provides methods for authentication operations.\r\n * The store automatically persists state to browser storage and provides reactive computed values.\r\n *\r\n * Key features:\r\n * - Automatic state persistence with browser storage sync\r\n * - Reactive computed properties for common authentication checks\r\n * - Built-in methods for sign-in, sign-out, and token management\r\n * - Integration with Angular Router for navigation after authentication\r\n * - Type-safe state management with TypeScript\r\n *\r\n * The store is provided at the root level and can be injected into any component or service.\r\n * It uses NgRx Signals for reactive state management and provides a modern alternative\r\n * to traditional NgRx store patterns.\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class AppComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * // Access reactive state\r\n * isSignedIn = this.authState.signedIn;\r\n * currentUser = this.authState.user;\r\n * hasAccessToken = this.authState.hasAccessToken;\r\n *\r\n * // Sign in user\r\n * async signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard').subscribe({\r\n * next: (response) => console.log('Signed in:', response.user),\r\n * error: (error) => console.error('Sign in failed:', error)\r\n * });\r\n * }\r\n *\r\n * // Sign out user\r\n * signOut() {\r\n * this.authState.signOut('/login').subscribe();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a guard\r\n * export class AuthGuard {\r\n * private authState = inject(AuthState)\r\n *\r\n * canActivate(): boolean {\r\n * return this.authState.signedIn() && this.authState.hasAccessToken();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Using computed properties\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * // Reactive computed values\r\n * userRole = this.authState.role;\r\n * isEmailVerified = this.authState.emailVerified;\r\n * hasValidToken = this.authState.hasAccessToken;\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthStateModel} Interface defining the state structure\r\n * @see {@link AuthService} Service used for authentication operations\r\n * @see {@link signalStore} NgRx Signals store factory function\r\n * @see {@link withStorageSync} Storage synchronization feature\r\n */\r\nexport const AuthState = signalStore(\r\n { providedIn: \"root\" },\r\n withState<AuthStateModel>(initialState),\r\n withStorageSync({ key: \"auth\" }),\r\n withComputed(({ accessToken, user }) => ({\r\n /**\r\n * Computed signal that indicates whether a valid access token is available\r\n *\r\n * This computed property returns true if an access token exists in the state,\r\n * false otherwise. It's useful for checking authentication status and\r\n * protecting routes or UI elements.\r\n *\r\n * @returns Boolean indicating if access token exists\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get showUserMenu() {\r\n * return this.authState.hasAccessToken();\r\n * }\r\n * }\r\n * ```\r\n */\r\n hasAccessToken: computed(() => Boolean(accessToken())),\r\n\r\n /**\r\n * Computed signal that returns the current user's role object\r\n *\r\n * This computed property extracts the role from the current user object.\r\n * The role can be either a string or an object depending on the backend\r\n * implementation. Use roleName() for a consistent string representation.\r\n *\r\n * @returns The user's role object or string, or undefined if no user\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class AdminComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get userRole() {\r\n * return this.authState.role();\r\n * }\r\n * }\r\n * ```\r\n */\r\n role: computed(() => user()?.role),\r\n\r\n permissions: computed(() => {\r\n const role = user()?.role;\r\n return role && isRoleObject(role) ? role.permissions || [] : []\r\n }),\r\n\r\n /**\r\n * Computed signal that returns the current user's role name as a string\r\n *\r\n * This computed property extracts the role name from the current user,\r\n * handling both string roles and object roles with a 'name' property.\r\n * It provides a consistent string representation of the user's role.\r\n *\r\n * @returns The user's role name as a string, or undefined if no user/role\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a guard\r\n * export class AdminGuard {\r\n * private authState = inject(AuthState)\r\n *\r\n * canActivate(): boolean {\r\n * return this.authState.roleName() === 'admin';\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class UserProfileComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get displayRole() {\r\n * const roleName = this.authState.roleName();\r\n * return roleName ? roleName.charAt(0).toUpperCase() + roleName.slice(1) : 'Guest';\r\n * }\r\n * }\r\n * ```\r\n */\r\n roleName: computed(() => {\r\n const role = user()?.role\r\n return role && typeof role === \"object\" ? role.name : role\r\n }),\r\n\r\n /**\r\n * Computed signal that indicates whether the current user's email is verified\r\n *\r\n * This computed property returns true if the current user has verified their\r\n * email address, false otherwise. It's useful for conditional UI rendering\r\n * and access control based on email verification status.\r\n *\r\n * @returns Boolean indicating if user's email is verified\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class DashboardComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get showVerificationBanner() {\r\n * return this.authState.signedIn() && !this.authState.emailVerified();\r\n * }\r\n * }\r\n * ```\r\n */\r\n emailVerified: computed((): boolean => Boolean(user()?.emailVerified)),\r\n })),\r\n withMethods((state, router = inject(Router), authService = inject(AuthService)) => ({\r\n /**\r\n * Resets the authentication state to its initial values\r\n *\r\n * This method clears all authentication data including user information,\r\n * tokens, and session data. It effectively signs out the user and resets\r\n * the state to the same condition as when the application first loads.\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class SettingsComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * clearAllData() {\r\n * this.authState.reset();\r\n * console.log('Authentication state cleared');\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In an error handler\r\n * export class ErrorHandler {\r\n * private authState = inject(AuthState)\r\n *\r\n * handleCriticalError() {\r\n * // Clear auth state on critical errors\r\n * this.authState.reset();\r\n * this.router.navigate(['/login']);\r\n * }\r\n * }\r\n * ```\r\n */\r\n reset(): void {\r\n patchState(state, initialState);\r\n },\r\n\r\n /**\r\n * Updates the authentication state with new token information\r\n *\r\n * This method updates the current authentication state with new access and\r\n * refresh tokens along with their expiration dates. It's typically used\r\n * after token refresh operations or when receiving new tokens from the server.\r\n *\r\n * @param tokenResponse - The token response containing new token information\r\n *\r\n * @example\r\n * ```typescript\r\n * // After token refresh\r\n * export class TokenService {\r\n * private authState = inject(AuthState)\r\n *\r\n * async refreshTokens() {\r\n * const tokenResponse = await this.authService.refreshToken(currentRefreshToken);\r\n * this.authState.setTokens(tokenResponse);\r\n * console.log('Tokens updated successfully');\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In an interceptor\r\n * export class AuthInterceptor {\r\n * private authState = inject(AuthState)\r\n *\r\n * handleTokenRefresh(tokenResponse: TokenResponse) {\r\n * this.authState.setTokens(tokenResponse);\r\n * // Continue with the original request\r\n * }\r\n * }\r\n * ```\r\n */\r\n setTokens(tokenResponse: TokenResponse): void {\r\n const {\r\n accessToken,\r\n refreshToken,\r\n accessTokenExpiresOn,\r\n refreshTokenExpiresOn\r\n } = tokenResponse;\r\n patchState(state, data => ({\r\n ...data,\r\n accessToken,\r\n refreshToken,\r\n accessTokenExpiresOn,\r\n refreshTokenExpiresOn,\r\n }));\r\n },\r\n\r\n /**\r\n * Authenticates a user with email/username and password\r\n *\r\n * This method handles user sign-in by calling the AuthService and updating\r\n * the authentication state with the response. It supports both Observable\r\n * and Promise return types based on the asPromise parameter, and can\r\n * automatically redirect users after successful authentication.\r\n *\r\n * The method integrates with the error notification system and can\r\n * optionally suppress error notifications for custom error handling.\r\n *\r\n * @param signInBody - The sign-in credentials containing email/username and password\r\n * @param redirect - Optional redirect path or function that returns a path after successful sign-in\r\n * @param asPromise - Optional flag to return a Promise instead of an Observable (defaults to false)\n * @param showError - Optional flag to control error notification display (defaults to true for Promise mode, false for Observable mode)\r\n * @returns Promise<AuthResponse> if asPromise is true, otherwise Observable<AuthResponse>\n *\r\n * @example\r\n * ```typescript\r\n * // Basic sign-in with Promise (default behavior)\r\n * export class LoginComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async signIn() {\r\n * try {\r\n * await this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard');\r\n * console.log('Sign-in successful');\r\n * } catch (error) {\r\n * console.error('Sign-in failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-in with Observable for reactive handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard', true).subscribe({\r\n * next: (response) => {\r\n * console.log('User signed in:', response.user);\r\n * this.handleSuccessfulSignIn(response);\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign-in failed:', error);\r\n * this.handleSignInError(error);\r\n * }\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Dynamic redirect based on user role\r\n * export class LoginComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, (response) => {\r\n * return response.user.role === 'admin' ? '/admin' : '/dashboard';\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-in with custom error handling\r\n * export class LoginComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard', true, false).subscribe({\r\n * next: (response) => console.log('Success:', response),\r\n * error: (error) => this.showCustomError(error)\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthService.signIn} The underlying service method for authentication\r\n * @see {@link SignInBody} Interface for sign-in request data\r\n * @see {@link AuthResponse} Interface for authentication response\r\n */\r\n signIn: <AsPromise extends boolean = false>(\r\n signInBody: SignInBody,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ): AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse> => {\r\n const sub = authService.signIn(signInBody, !(showError || asPromise && showError === undefined)).pipe(\r\n tap((res: AuthResponse): void => {\r\n patchState(state, { ...res, signedIn: true });\r\n if (redirect) {\r\n void router.navigateByUrl(typeof redirect === \"string\" ? redirect : redirect(res));\r\n }\r\n }),\r\n );\r\n\r\n if (asPromise) {\r\n return firstValueFrom(sub) as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>\r\n }\r\n\r\n return sub as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n },\r\n\r\n /**\r\n * Authenticates a user using an existing access token\r\n *\r\n * This method exchanges an access token for a complete authentication response\r\n * and updates the authentication state. It's typically used after OAuth flows\r\n * (like Google sign-in) or when resuming sessions with stored tokens. The method\r\n * supports both Observable and Promise return types and can automatically redirect\r\n * users after successful authentication.\r\n *\r\n * The method integrates with the error notification system and includes error\r\n * handling that gracefully handles token validation failures.\r\n *\r\n * @param accessToken - The access token to authenticate with\r\n * @param redirect - Optional redirect path or function that returns a path after successful authentication\r\n * @param asPromise - Optional flag to return a Promise instead of an Observable (defaults to false)\n * @param showError - Optional flag to control error notification display (defaults to true for Promise mode, false for Observable mode)\r\n * @returns Promise<AuthResponse> if asPromise is true, otherwise Observable<AuthResponse>\n *\r\n * @example\r\n * ```typescript\r\n * // Basic token authentication with Promise (default behavior)\r\n * export class OAuthCallbackComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async handleCallback(token: string) {\r\n * try {\r\n * await this.authState.authenticateWithToken(token, '/dashboard');\r\n * console.log('Token authentication successful');\r\n * } catch (error) {\r\n * console.error('Token authentication failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Token authentication with Observable for reactive handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * authenticateWithToken(token: AccessToken) {\r\n * this.authState.authenticateWithToken(token, '/dashboard', true).subscribe({\r\n * next: (response) => {\r\n * console.log('User authenticated:', response.user);\r\n * this.handleSuccessfulAuth(response);\r\n * },\r\n * error: (error) => {\r\n * console.error('Token authentication failed:', error);\r\n * this.handleAuthError(error);\r\n * }\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Google OAuth integration\r\n * export class GoogleAuthComponent {\r\n * private authState = inject(AuthState)\r\n * private authService = inject(AuthService)\r\n *\r\n * async signInWithGoogle() {\r\n * try {\r\n * const accessToken = await this.authService.googleSignIn();\r\n * await this.authState.authenticateWithToken(accessToken, (response) => {\r\n * return response.user.role === 'admin' ? '/admin' : '/dashboard';\r\n * });\r\n * } catch (error) {\r\n * console.error('Google sign-in failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Token authentication with custom error handling\r\n * export class TokenAuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * authenticateWithStoredToken(token: AccessToken) {\r\n * this.authState.authenticateWithToken(token, '/dashboard', true, false).subscribe({\r\n * next: (response) => console.log('Success:', response),\r\n * error: (error) => this.handleCustomTokenError(error)\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthService.getAuthResponse} The underlying service method for token authentication\r\n * @see {@link AccessToken} Type representing access tokens\r\n * @see {@link AuthResponse} Interface for authentication response\r\n */\r\n authenticateWithToken: <AsPromise extends boolean = false>(\r\n accessToken: AccessToken,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ): AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse> => {\r\n const sub = authService.getAuthResponse(accessToken, !(showError || asPromise && showError === undefined)).pipe(\r\n tap((res: AuthResponse): void => {\r\n patchState(state, {\r\n ...res,\r\n signedIn: Boolean(res.user.role)\r\n });\r\n if (redirect) {\r\n void router.navigateByUrl(typeof redirect === \"string\" ? redirect : redirect(res));\r\n }\r\n }),\r\n catchError(() => EMPTY),\r\n );\r\n\r\n if (asPromise) {\r\n return firstValueFrom(sub) as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>\r\n }\r\n\r\n return sub as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n },\r\n\r\n /**\r\n * Signs out the current user and clears authentication state\r\n *\r\n * This method handles user sign-out by calling the AuthService to invalidate\r\n * the session on the server and then clearing all authentication data from\r\n * the local state. It supports both Observable and Promise return types and\r\n * can automatically redirect users after successful sign-out.\r\n *\r\n * The method integrates with the error notification system and includes error\r\n * handling that ensures local state is cleared even if server sign-out fails.\r\n *\r\n * @param redirect - Optional redirect path after successful sign-out\r\n * @param asPromise - Optional flag to return a Promise instead of an Observable (defaults to false)\n * @param showError - Optional flag to control error notification display (defaults to true for Promise mode, false for Observable mode)\r\n * @returns Promise<SuccessResponse | null> if asPromise is true, otherwise Observable<SuccessResponse | null>\n *\r\n * @example\r\n * ```typescript\r\n * // Basic sign-out with Promise (default behavior)\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async signOut() {\r\n * try {\r\n * await this.authState.signOut('/login');\r\n * console.log('Sign-out successful');\r\n * } catch (error) {\r\n * console.error('Sign-out failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-out with Observable for reactive handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signOut() {\r\n * this.authState.signOut('/login', true).subscribe({\r\n * next: (response) => {\r\n * console.log('Sign-out successful:', response);\r\n * this.handleSuccessfulSignOut();\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign-out failed:', error);\r\n * this.handleSignOutError(error);\r\n * }\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-out without redirect\r\n * export class SettingsComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async signOut() {\r\n * await this.authState.signOut(); // No redirect\r\n * this.showSignOutMessage();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-out with custom error handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signOut() {\r\n * this.authState.signOut('/login', true, false).subscribe({\r\n * next: (response) => console.log('Success:', response),\r\n * error: (error) => this.handleCustomSignOutError(error)\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Emergency sign-out (clear local state immediately)\r\n * export class SecurityComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * emergencySignOut() {\r\n * // Clear local state first\r\n * this.authState.reset();\r\n * // Then attempt server sign-out\r\n * this.authState.signOut('/login').catch(() => {\r\n * // Ignore server errors in emergency situations\r\n * console.log('Local state cleared, server sign-out may have failed');\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthService.signOut} The underlying service method for server sign-out\r\n * @see {@link SuccessResponse} Interface for success response\r\n * @see {@link reset} Method to manually clear authentication state\r\n */\r\n signOut: <AsPromise extends boolean = false>(\r\n redirect?: string,\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ): AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null> => {\r\n const sub = authService.signOut(!(showError || asPromise && showError === undefined)).pipe(\r\n tap({\r\n next: (): void => {\r\n patchState(state, initialState);\r\n if (redirect) {\r\n void router.navigateByUrl(redirect);\r\n }\r\n },\r\n }),\r\n catchError(() => EMPTY),\r\n );\r\n\r\n if (asPromise) {\r\n return firstValueFrom(sub) as AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null>;\r\n }\r\n\r\n return sub as AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null>;\r\n },\r\n\r\n setData(stateData: object): void {\r\n patchState(state, data => ({\r\n ...data,\r\n data: { ...data.data, ...stateData },\r\n }));\r\n }\r\n })),\r\n);\n\n/**\n * Public typed shape of the `AuthState` signal store.\n */\nexport type AuthState<D = unknown, R extends string = string, P extends string = string, U extends User<R, P> = User<R, P>, > = {\n signedIn: Signal<boolean>;\r\n sessionId: Signal<string | null>;\r\n user: Signal<U | null>;\r\n accessToken: Signal<AccessToken | null>;\r\n refreshToken: Signal<RefreshToken | null>;\r\n accessTokenExpiresOn: Signal<Date | null>;\r\n refreshTokenExpiresOn: Signal<Date | null>;\r\n data: Signal<D>;\r\n\r\n hasAccessToken: Signal<boolean>;\r\n role: Signal<U[\"role\"] | null | undefined>;\r\n roleName: Signal<R | null | undefined>;\r\n permissions: Signal<P[]>;\r\n emailVerified: Signal<boolean>;\r\n\r\n reset: () => void;\r\n setTokens: (tokenResponse: TokenResponse) => void;\r\n signIn: <AsPromise extends boolean = false>(\r\n signInBody: SignInBody,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ) => AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n authenticateWithToken: <AsPromise extends boolean = false>(\r\n accessToken: AccessToken,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ) => AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n signOut: <AsPromise extends boolean = false>(\r\n redirect?: string,\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ) => AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null>;\r\n setData: (stateData: { [K in keyof D]?: D[K] }) => void\r\n}\r\n","/* eslint-disable @angular-eslint/no-output-on-prefix */\r\nimport {\r\n Component,\r\n effect,\r\n inject,\r\n input,\r\n InputSignal,\r\n output,\r\n OutputEmitterRef,\r\n signal,\r\n WritableSignal,\r\n} from \"@angular/core\";\r\nimport { FormBuilder, Validators } from \"@angular/forms\";\r\nimport { AuthField, AuthResponse, SignInBody, SignUpBody, User } from \"@hichchi/nest-connector/auth\";\r\nimport { AuthFormData } from \"../../interfaces\";\r\nimport { AuthService } from \"../../services\";\r\nimport { AUTH_CONFIG } from \"../../tokens\";\r\nimport { toFirstCase } from \"@hichchi/utils\";\r\nimport { DataFormGroup, HttpError, validatedFormData } from \"@hichchi/ngx-utils\";\r\nimport { AuthState } from \"../../state\";\r\n\r\n@Component({\r\n selector: \"hc-auth-card\",\r\n standalone: false,\r\n templateUrl: \"./auth-form.component.html\",\r\n styleUrl: \"./auth-form.component.scss\",\r\n})\r\n/**\r\n * Angular component for handling authentication forms with multiple provider support\r\n *\r\n * This component provides a comprehensive authentication interface that supports both\r\n * local authentication (sign-in/sign-up) and third-party authentication providers\r\n * (Google, Facebook). It manages form state, validation, and user interactions while\r\n * integrating with the authentication services and state management.\r\n *\r\n * The component dynamically adapts its form fields based on the authentication mode\r\n * (sign-in vs sign-up) and the configured authentication field type (email vs username).\r\n * It provides reactive form validation, loading states, error handling, and emits\r\n * events for successful authentication or errors.\r\n *\r\n * Key features:\r\n * - Local authentication with sign-in and sign-up modes\r\n * - Google OAuth integration\r\n * - Facebook authentication support (configurable)\r\n * - Dynamic form field management based on authentication mode\r\n * - Reactive form validation with Angular FormBuilder\r\n * - Loading states and error handling\r\n * - Configurable authentication field (email or username)\r\n * - Event emission for authentication success and errors\r\n * - Integration with AuthState and AuthService\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage with all providers enabled -->\r\n * <hc-auth-card\r\n * [local]=\"true\"\r\n * [google]=\"true\"\r\n * [facebook]=\"true\"\r\n * (onSignIn)=\"handleSignIn($event)\"\r\n * (onSignUp)=\"handleSignUp($event)\"\r\n * (onError)=\"handleError($event)\">\r\n * </hc-auth-card>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Local authentication only -->\r\n * <hc-auth-card\r\n * [local]=\"true\"\r\n * [google]=\"false\"\r\n * [facebook]=\"false\"\r\n * (onSignIn)=\"handleSignIn($event)\"\r\n * (onError)=\"handleError($event)\">\r\n * </hc-auth-card>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Google authentication only -->\r\n * <hc-auth-card\r\n * [local]=\"false\"\r\n * [google]=\"true\"\r\n * [facebook]=\"false\"\r\n * (onSignIn)=\"handleSignIn($event)\"\r\n * (onError)=\"handleError($event)\">\r\n * </hc-auth-card>\r\n * ```\r\n *\r\n * @see {@link AuthService} Service for handling authentication operations\r\n * @see {@link AuthState} Service for managing authentication state\r\n * @see {@link AuthConfig} Configuration interface for authentication settings\r\n * @see {@link AuthFormData} Interface defining the form data structure\r\n * @see {@link AuthResponse} Interface for authentication response data\r\n * @see {@link User} Interface for user data structure\r\n * @see {@link HttpError} Interface for HTTP error handling\r\n */\r\nexport class AuthFormComponent {\r\n private readonly config = inject(AUTH_CONFIG);\r\n\r\n private readonly fb = inject(FormBuilder);\r\n\r\n private readonly authService = inject(AuthService);\r\n\r\n /** Input signal to control whether local authentication (username/email + password) is enabled */\r\n local: InputSignal<boolean> = input(true);\r\n\r\n /** Input signal to control whether Google OAuth authentication is enabled */\r\n google: InputSignal<boolean> = input(true);\r\n\r\n /** Input signal to control whether Facebook authentication is enabled */\r\n facebook: InputSignal<boolean> = input(true);\r\n\r\n /** Output emitter that fires when an authentication error occurs */\r\n onError: OutputEmitterRef<HttpError> = output<HttpError>();\r\n\r\n /** Output emitter that fires when a user successfully signs in */\r\n onSignIn: OutputEmitterRef<AuthResponse> = output<AuthResponse>();\r\n\r\n /** Output emitter that fires when a user successfully signs up */\r\n onSignUp: OutputEmitterRef<User> = output<User>();\r\n\r\n /** Writable signal indicating whether an authentication operation is in progress */\r\n isLoading: WritableSignal<boolean> = signal(false);\r\n\r\n /** Writable signal indicating whether the form is in sign-up mode (true) or sign-in mode (false) */\r\n isSignUp: WritableSignal<boolean> = signal(false);\r\n\r\n /** Writable signal indicating whether an error state is currently active */\r\n isError: WritableSignal<boolean> = signal(false);\r\n\r\n /** Writable signal containing the current authentication field type (EMAIL or USERNAME) */\r\n authField: WritableSignal<AuthField> = signal(AuthField.EMAIL);\r\n\r\n /** Writable signal containing the display label for the authentication field */\r\n authFieldLabel: WritableSignal<string> = signal(toFirstCase(AuthField.EMAIL));\r\n\r\n /** Writable signal containing the current error object, if any */\r\n error: WritableSignal<HttpError | null> = signal<HttpError | null>(null);\r\n\r\n /** Injected AuthState service for managing authentication state */\r\n authState = inject(AuthState);\r\n\r\n /** Reactive form group for handling authentication form data */\r\n authForm: DataFormGroup<AuthFormData>;\r\n\r\n constructor() {\r\n this.authField.set(this.config.authField === AuthField.USERNAME ? AuthField.USERNAME : AuthField.EMAIL);\r\n this.authFieldLabel.set(toFirstCase(this.authField()));\r\n\r\n this.authForm = this.fb.group({\r\n firstName: [\"\", Validators.required],\r\n lastName: [\"\", Validators.required],\r\n authFieldValue: [\"\", [Validators.required]],\r\n password: [\"\", Validators.required],\r\n });\r\n\r\n effect((): void => {\r\n if (this.isSignUp()) {\r\n this.authForm.controls?.firstName?.enable();\r\n this.authForm.controls?.lastName?.enable();\r\n } else {\r\n this.authForm.controls?.firstName?.disable();\r\n this.authForm.controls?.lastName?.disable();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Handles Google OAuth sign-in authentication\r\n *\r\n * This method initiates the Google OAuth flow, retrieves an access token,\r\n * and authenticates the user with the backend service. It manages loading\r\n * states and emits appropriate events based on the authentication result.\r\n *\r\n * @returns Promise that resolves when the Google sign-in process completes\r\n *\r\n * @example\r\n * ```typescript\r\n * // Called automatically when user clicks Google sign-in button\r\n * await this.handleGoogleSignIn();\r\n * ```\r\n */\r\n async handleGoogleSignIn(): Promise<void> {\r\n const accessToken = await this.authService.googleSignIn();\r\n // noinspection ES6MissingAwait\r\n this.authState.authenticateWithToken(accessToken, undefined, false).subscribe({\r\n next: authResponse => {\r\n this.isLoading.set(false);\r\n this.onSignIn.emit(authResponse);\r\n },\r\n error: this.handleError.bind(this),\r\n });\r\n }\r\n\r\n /**\r\n * Handles local authentication sign-in process\r\n *\r\n * This method processes local authentication using username/email and password.\r\n * It sets loading and error states, then calls the AuthState service to perform\r\n * the sign-in operation.\r\n *\r\n * @param signInBody - The sign-in data containing authentication credentials\r\n *\r\n * @example\r\n * ```typescript\r\n * const signInData = {\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * };\r\n * this.handleLocalAuth(signInData);\r\n * ```\r\n */\r\n handleLocalAuth(signInBody: SignInBody): void {\r\n this.isLoading.set(true);\r\n this.isError.set(false);\r\n\r\n this.authState.signIn(signInBody, \"/\", false).subscribe({\r\n next: () => {\r\n this.isLoading.set(false);\r\n },\r\n error: () => {\r\n this.isLoading.set(false);\r\n this.isError.set(true);\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Handles user registration (sign-up) process\r\n *\r\n * This method processes user registration with the provided sign-up data.\r\n * It sets loading and error states, calls the AuthService to create a new user,\r\n * and emits the onSignUp event upon successful registration.\r\n *\r\n * @param signUpBody - The sign-up data containing user registration information\r\n *\r\n * @example\r\n * ```typescript\r\n * const signUpData = {\r\n * firstName: 'John',\r\n * lastName: 'Doe',\r\n * email: 'john.doe@example.com',\r\n * password: 'password123'\r\n * };\r\n * this.handleSignUp(signUpData);\r\n * ```\r\n */\r\n handleSignUp(signUpBody: SignUpBody): void {\r\n this.isLoading.set(true);\r\n this.isError.set(false);\r\n\r\n this.authService.signUp(signUpBody).subscribe({\r\n next: user => {\r\n this.isLoading.set(false);\r\n this.onSignUp.emit(user);\r\n },\r\n error: this.handleError.bind(this),\r\n });\r\n }\r\n\r\n /**\r\n * Handles form submission for both sign-in and sign-up modes\r\n *\r\n * This method processes form submission by preventing the default browser behavior,\r\n * validating the form data, and routing to the appropriate authentication method\r\n * based on the current mode (sign-in or sign-up). It extracts form data and\r\n * calls either handleSignUp() or handleLocalAuth() accordingly.\r\n *\r\n * @param e - The form submit event to prevent default behavior\r\n *\r\n * @example\r\n * ```typescript\r\n * // Called automatically when form is submitted\r\n * // In template: <form (submit)=\"handleSubmit($event)\">\r\n * handleSubmit(event);\r\n * ```\r\n */\r\n handleSubmit(e: SubmitEvent): void {\r\n e.preventDefault();\r\n if (this.isSignUp()) {\r\n const formData = validatedFormData<AuthFormData>(this.authForm);\r\n if (formData) {\r\n this.handleSignUp({\r\n firstName: formData.firstName,\r\n lastName: formData.lastName,\r\n [this.authField()]: formData.authFieldValue,\r\n password: formData.password,\r\n });\r\n }\r\n } else {\r\n const formData = validatedFormData<AuthFormData>(this.authForm);\r\n if (formData) {\r\n this.handleLocalAuth({\r\n [this.authField()]: formData.authFieldValue,\r\n password: formData.password,\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handles authentication errors and updates component state\r\n *\r\n * This method is called when any authentication operation fails. It updates\r\n * the component's loading and error states, stores the error for display,\r\n * and emits the onError event to notify parent components of the failure.\r\n *\r\n * @param error - The HTTP error object containing error details\r\n *\r\n * @example\r\n * ```typescript\r\n * // Called automatically by authentication methods on error\r\n * // Can also be called manually to handle custom errors\r\n * const customError = new HttpError('Custom error message');\r\n * this.handleError(customError);\r\n * ```\r\n */\r\n handleError(error: HttpError): void {\r\n this.isLoading.set(false);\r\n this.isError.set(true);\r\n this.error.set(error);\r\n this.onError.emit(error);\r\n }\r\n}\r\n","<hc-card>\r\n <section class=\"auth-shell\">\r\n <header class=\"auth-header\">\r\n <div class=\"auth-badge\">{{ isSignUp() ? \"Create Account\" : \"Welcome Back\" }}</div>\r\n <h2 class=\"auth-title\">{{ isSignUp() ? \"Create your account\" : \"Sign in to your account\" }}</h2>\r\n <p class=\"auth-subtitle\">\r\n {{ isSignUp() ? \"Set up your account to get started.\" : \"Use your credentials to continue.\" }}\r\n </p>\r\n </header>\r\n\r\n <form class=\"auth-form\" [formGroup]=\"authForm\" (ngSubmit)=\"handleSubmit($event)\">\r\n @if (isSignUp()) {\r\n <div class=\"auth-grid\">\r\n <div class=\"auth-field\">\r\n <label for=\"firstName\" class=\"auth-label\">First Name</label>\r\n <input\r\n id=\"firstName\"\r\n type=\"text\"\r\n class=\"auth-input\"\r\n formControlName=\"firstName\"\r\n placeholder=\"Enter your first name\"\r\n />\r\n </div>\r\n <div class=\"auth-field\">\r\n <label for=\"lastName\" class=\"auth-label\">Last Name</label>\r\n <input\r\n id=\"lastName\"\r\n type=\"text\"\r\n class=\"auth-input\"\r\n formControlName=\"lastName\"\r\n placeholder=\"Enter your last name\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-field\">\r\n <label for=\"authField\" class=\"auth-label\">{{ authFieldLabel() }}</label>\r\n <input\r\n id=\"authField\"\r\n type=\"text\"\r\n class=\"auth-input\"\r\n formControlName=\"authFieldValue\"\r\n [placeholder]=\"'Enter your ' + authFieldLabel().toLowerCase()\"\r\n />\r\n </div>\r\n\r\n <div class=\"auth-field\">\r\n <label for=\"password\" class=\"auth-label\">Password</label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n class=\"auth-input\"\r\n formControlName=\"password\"\r\n placeholder=\"Enter your password\"\r\n />\r\n </div>\r\n\r\n <button type=\"submit\" class=\"auth-btn auth-btn-primary\">\r\n {{ isSignUp() ? (isLoading() ? \"Signing Up...\" : \"Sign Up\") : isLoading() ? \"Signing In...\" : \"Sign In\" }}\r\n </button>\r\n\r\n <button type=\"button\" class=\"auth-btn auth-btn-link\" (click)=\"isSignUp.set(!isSignUp())\">\r\n {{ isSignUp() ? \"Already have an account? Sign In\" : \"Don't have an account? Sign Up\" }}\r\n </button>\r\n\r\n @if (!isSignUp()) {\r\n @if (local() && (google() || facebook())) {\r\n <hc-separator label=\"or\"></hc-separator>\r\n }\r\n\r\n @if (google()) {\r\n <button type=\"button\" class=\"auth-btn social-btn google-btn\" (click)=\"handleGoogleSignIn()\">\r\n <div class=\"icon\"></div>\r\n Continue with Google\r\n </button>\r\n }\r\n\r\n @if (facebook()) {\r\n <button type=\"button\" class=\"auth-btn social-btn facebook-btn\">\r\n <div class=\"icon\"></div>\r\n Continue with Facebook\r\n </button>\r\n }\r\n\r\n @if (isError()) {\r\n <p class=\"error-message\">\r\n {{ error()?.error?.message || \"Something went wrong!\" }}\r\n </p>\r\n }\r\n }\r\n </form>\r\n </section>\r\n</hc-card>\r\n","import { Directive, effect, inject, input, InputSignal, TemplateRef, ViewContainerRef } from \"@angular/core\";\r\nimport { isRoleObject, Role, User } from \"@hichchi/nest-connector/auth\";\r\nimport { AuthState } from \"../state\";\r\n\r\n/**\r\n * Angular structural directive for permission-based conditional rendering\r\n *\r\n * This directive conditionally displays or hides DOM elements based on the current user's permissions.\r\n * It integrates with the authentication state to check if the authenticated user has the required\r\n * permission to view the content. The directive uses Angular's structural directive pattern and\r\n * automatically updates when the user's authentication state or permissions change.\r\n *\r\n * The directive works by checking the user's role permissions against the required permission string.\r\n * If the user has the required permission, the template content is rendered; otherwise, it's removed\r\n * from the DOM.\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage - show content only if user has 'users.read' permission -->\r\n * <div *hcPermission=\"'users.read'\">\r\n * <p>This content is only visible to users with read permission</p>\r\n * </div>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Using with component properties -->\r\n * <button *hcPermission=\"'users.delete'\" (click)=\"deleteUser()\">\r\n * Delete User\r\n * </button>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Using with multiple permissions (user needs at least one) -->\r\n * <div *hcPermission=\"['users.read', 'users.write']\">\r\n * <p>This content is visible to users with either read OR write permission</p>\r\n * </div>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Using with dynamic permissions -->\r\n * <ng-container *hcPermission=\"requiredPermission\">\r\n * <app-admin-panel></app-admin-panel>\r\n * </ng-container>\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Component usage with dynamic permission\r\n * export class UserListComponent {\r\n * requiredPermission = 'users.manage';\r\n * // Or with multiple permissions\r\n * requiredPermissions = ['users.read', 'users.write'];\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthState} Authentication state service that provides user information\r\n * @see {@link User} User interface that contains role and permission information\r\n * @see {@link isRoleObject} Utility function to check if role is an object with permissions\r\n * @see {@link NgxHichchiAuthModule} Module that provides this directive\r\n */\r\n@Directive({\r\n selector: \"[hcPermission]\",\r\n})\r\nexport class PermissionDirective {\r\n /**\r\n * Template reference for the content to be conditionally rendered\r\n * @private\r\n */\r\n private templateRef = inject(TemplateRef);\r\n\r\n /**\r\n * View container reference for managing the template rendering\r\n * @private\r\n */\r\n private viewContainerRef = inject(ViewContainerRef);\r\n\r\n /**\r\n * Authentication state service for accessing current user information\r\n * @private\r\n */\r\n private authState = inject(AuthState);\r\n\r\n /**\r\n * Required permission string or array of strings input signal\r\n *\r\n * This input defines the permission(s) that the current user must have\r\n * for the template content to be displayed. The permission string(s)\r\n * should match the permissions defined in the user's role.\r\n *\r\n * When an array is provided, the user needs to have at least one of\r\n * the specified permissions (OR logic).\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Single permission -->\r\n * <div *hcPermission=\"'users.read'\">Content</div>\r\n *\r\n * <!-- Multiple permissions (user needs at least one) -->\r\n * <div *hcPermission=\"['users.read', 'users.write']\">Content</div>\r\n * ```\r\n */\r\n hcPermission: InputSignal<string | string[]> = input.required<string | string[]>();\r\n\r\n /**\r\n * Constructor that sets up the permission checking effect\r\n *\r\n * Initializes an Angular effect that automatically re-evaluates permission\r\n * whenever the authentication state or required permission changes. This\r\n * ensures the UI stays in sync with the user's current permissions.\r\n */\r\n constructor() {\r\n effect(() => {\r\n if (this.hasPermission(this.authState.user(), this.hcPermission())) {\r\n if (this.viewContainerRef.length === 0) {\r\n this.viewContainerRef.createEmbeddedView(this.templateRef);\r\n }\r\n } else {\r\n this.viewContainerRef.clear();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Checks if the user has the required permission(s)\r\n *\r\n * This method evaluates whether the provided user has the specified permission(s)\r\n * by checking their role and associated permissions. It handles cases where\r\n * the user is null, has no role, or the role doesn't contain permissions.\r\n *\r\n * When an array of permissions is provided, the method returns true if the user\r\n * has at least one of the specified permissions (OR logic).\r\n *\r\n * @param user - The user object to check permissions for, can be null\r\n * @param requiredPermission - The permission string or array of strings that must be present in the user's role\r\n * @returns True if the user has the required permission(s), false otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * // Single permission\r\n * const hasPermission = this.hasPermission(currentUser, 'users.delete');\r\n *\r\n * // Multiple permissions (user needs at least one)\r\n * const hasAnyPermission = this.hasPermission(currentUser, ['users.read', 'users.write']);\r\n * ```\r\n *\r\n * @private\r\n */\r\n private hasPermission(user: User | null, requiredPermission: string | string[]): boolean {\r\n if (!user || !user.role) {\r\n return false;\r\n }\r\n\r\n return isRoleObject(user.role) && user.role.permissions?.length\r\n ? Array.isArray(requiredPermission)\r\n ? requiredPermission.some(permission => (user.role as Role)!.permissions?.includes(permission))\r\n : user.role.permissions.includes(requiredPermission)\r\n : false;\r\n }\r\n}\r\n","/**\n * Enumeration of authentication guard conditions\n *\n * This enum defines the different conditions that authentication guards can check\n * to determine whether a user should be allowed to access a route. Each condition\n * represents a different aspect of the user's authentication state.\n *\n * These conditions are used in conjunction with AuthGuardOption to create\n * flexible route protection rules that can handle various authentication scenarios.\n *\n * @example\n * ```typescript\n * // Check if user is signed in\n * const guardOption: AuthGuardOption = {\n * condition: AuthGuardCondition.SIGNED_IN,\n * state: true,\n * redirect: '/login'\n * };\n * ```\n *\n * @example\n * ```typescript\n * // Check if user has a valid token\n * const tokenGuardOption: AuthGuardOption = {\n * condition: AuthGuardCondition.HAS_TOKEN,\n * state: true,\n * redirect: '/unauthorized'\n * };\n * ```\n *\n * @see {@link AuthGuardOption} Interface that uses these conditions\n */\nexport enum AuthGuardCondition {\n /** Check if the user is signed in to the application */\n SIGNED_IN = \"signed-in\",\n /** Check if the user has a valid access token */\n HAS_TOKEN = \"has-token\",\n}\n","import { ActivatedRouteSnapshot } from \"@angular/router\";\r\nimport { AuthGuardOption } from \"../interfaces\";\r\nimport { AUTH_GUARD_OPTIONS_KEY } from \"../constants\";\r\n\r\n/**\r\n * Retrieves all authentication guard options from a route and its parent routes\r\n *\r\n * This utility function extracts authentication guard options from the current route\r\n * and recursively collects options from parent routes in the route hierarchy. It handles\r\n * the inheritance and merging of guard options, ensuring that parent route guards are\r\n * applied alongside child route guards.\r\n *\r\n * The function implements a hierarchical guard system where:\r\n * - Child route options take precedence over parent options for the same condition\r\n * - Parent options are inherited when no conflicting child option exists\r\n * - Options are collected recursively up the route tree\r\n * - The final array contains all applicable guard options for the route\r\n *\r\n * This enables complex authentication scenarios where different route levels can\r\n * specify different authentication requirements, with child routes able to override\r\n * or supplement parent route authentication rules.\r\n *\r\n * @param currentRoute - The activated route snapshot to extract guard options from\r\n * @returns Array of authentication guard options applicable to the route\r\n *\r\n * @example\r\n * ```typescript\r\n * // Route configuration with nested guards\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminLayoutComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, true, '/login')],\r\n * children: [\r\n * {\r\n * path: 'users',\r\n * component: UsersComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.HAS_TOKEN, true, '/unauthorized')]\r\n * }\r\n * ]\r\n * }\r\n * ];\r\n *\r\n * // In the guard, get all applicable options\r\n * const allOptions = getAllAuthGuardOptions(route);\r\n * // Result: [\r\n * // { condition: 'signed-in', state: true, redirect: '/login' },\r\n * // { condition: 'has-token', state: true, redirect: '/unauthorized' }\r\n * // ]\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Using in a custom guard implementation\r\n * export const customAuthGuard: CanActivateFn = (route, state) => {\r\n * const authState = inject(AuthState);\r\n * const router = inject(Router);\r\n *\r\n * const guardOptions = getAllAuthGuardOptions(route);\r\n *\r\n * for (const option of guardOptions) {\r\n * const conditionMet = checkAuthCondition(option.condition, authState);\r\n * if (option.state !== conditionMet) {\r\n * router.navigateByUrl(option.redirect);\r\n * return false;\r\n * }\r\n * }\r\n *\r\n * return true;\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Route hierarchy with inherited guards\r\n * const routes: Routes = [\r\n * {\r\n * path: 'app',\r\n * data: { [AUTH_GUARD_OPTIONS_KEY]: [\r\n * { condition: AuthGuardCondition.SIGNED_IN, state: true, redirect: '/login' }\r\n * ]},\r\n * children: [\r\n * {\r\n * path: 'profile',\r\n * component: ProfileComponent,\r\n * data: { [AUTH_GUARD_OPTIONS_KEY]: [\r\n * { condition: AuthGuardCondition.HAS_TOKEN, state: true, redirect: '/expired' }\r\n * ]}\r\n * }\r\n * ]\r\n * }\r\n * ];\r\n *\r\n * // When accessing /app/profile, both parent and child guards apply\r\n * ```\r\n *\r\n * @see {@link AuthGuardOption} Interface defining the structure of guard options\r\n * @see {@link AUTH_GUARD_OPTIONS_KEY} Constant for the route data key\r\n * @see {@link authGuard} Function that uses this utility to process guard options\r\n * @see {@link ActivatedRouteSnapshot} Angular router interface for route snapshots\r\n */\r\nexport const getAllAuthGuardOptions = (currentRoute: ActivatedRouteSnapshot): AuthGuardOption[] => {\r\n const options: AuthGuardOption[] = currentRoute.data?.[AUTH_GUARD_OPTIONS_KEY] || [];\r\n\r\n if (!currentRoute.parent?.data?.[AUTH_GUARD_OPTIONS_KEY]) {\r\n return options;\r\n }\r\n\r\n const parentOptions = getAllAuthGuardOptions(currentRoute.parent);\r\n for (const parentOption of parentOptions) {\r\n const currentConditionIndex = options.findIndex(option => option.condition === parentOption.condition);\r\n if (currentConditionIndex !== -1) {\r\n // skip\r\n } else {\r\n options.unshift(parentOption);\r\n }\r\n }\r\n return options;\r\n};\r\n","import { inject } from \"@angular/core\";\r\nimport { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from \"@angular/router\";\r\nimport { AuthState } from \"../state\";\r\nimport { AuthGuardOption } from \"../interfaces\";\r\nimport { AuthGuardCondition } from \"../enums\";\r\nimport { getAllAuthGuardOptions } from \"../utils\";\r\nimport { AUTH_GUARD_OPTIONS_KEY } from \"../constants\";\r\n\r\n/**\r\n * Creates an authentication guard function with multiple configuration options\r\n *\r\n * This overload accepts an array of AuthGuardOption objects, allowing for complex\r\n * authentication rules with multiple conditions. Each option can specify different\r\n * conditions, states, and redirect paths.\r\n *\r\n * @param options - Array of authentication guard options to evaluate\r\n * @returns A CanActivateFn that can be used in Angular route guards\r\n *\r\n * @example\r\n * ```typescript\r\n * // Multiple conditions guard\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [authGuard([\r\n * { condition: AuthGuardCondition.SIGNED_IN, state: true, redirect: '/login' },\r\n * { condition: AuthGuardCondition.HAS_TOKEN, state: true, redirect: '/unauthorized' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthGuardOption} Interface defining guard configuration options\r\n * @see {@link AuthGuardCondition} Enum of available authentication conditions\r\n */\r\nexport function authGuard(options: AuthGuardOption[]): CanActivateFn;\r\n\r\n/**\r\n * Creates an authentication guard function with a single condition\r\n *\r\n * This overload provides a simplified way to create guards with a single authentication\r\n * condition. It's more convenient when you only need to check one condition.\r\n *\r\n * @param condition - The authentication condition to check\r\n * @param state - The required state of the condition (true/false)\r\n * @param fallbackRedirect - The path to redirect to if the condition is not met\r\n * @returns A CanActivateFn that can be used in Angular route guards\r\n *\r\n * @example\r\n * ```typescript\r\n * // Simple signed-in guard\r\n * const routes: Routes = [\r\n * {\r\n * path: 'profile',\r\n * component: ProfileComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, true, '/login')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Redirect signed-in users away from login page\r\n * const routes: Routes = [\r\n * {\r\n * path: 'login',\r\n * component: LoginComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, false, '/dashboard')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthGuardCondition} Enum of available authentication conditions\r\n * @see {@link AuthGuardOption} Interface for more complex guard configurations\r\n */\r\nexport function authGuard(condition: AuthGuardCondition, state: boolean, fallbackRedirect: string): CanActivateFn;\r\n\r\n/**\r\n * Authentication guard factory function for Angular route protection\r\n *\r\n * This function creates a route guard that protects routes based on authentication state.\r\n * It supports both simple single-condition guards and complex multi-condition guards.\r\n * The guard evaluates authentication conditions and redirects users when conditions are not met.\r\n *\r\n * The guard integrates with the AuthState service to check the current authentication status\r\n * and uses the Angular Router for navigation when redirects are needed. It supports checking\r\n * whether users are signed in, have valid tokens, and other authentication-related conditions.\r\n *\r\n * Key features:\r\n * - Multiple authentication condition support\r\n * - Automatic redirection on failed conditions\r\n * - Integration with AuthState for reactive authentication checks\r\n * - Support for both simple and complex guard configurations\r\n * - Type-safe condition checking\r\n *\r\n * @param param - Either a single AuthGuardCondition or an array of AuthGuardOption objects\r\n * @param state - Required state for single condition (ignored when using options array)\r\n * @param fallbackRedirect - Redirect path for single condition (ignored when using options array)\r\n * @returns A CanActivateFn that evaluates authentication conditions and handles navigation\r\n *\r\n * @example\r\n * ```typescript\r\n * // Protecting a route that requires authentication\r\n * const routes: Routes = [\r\n * {\r\n * path: 'dashboard',\r\n * component: DashboardComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, true, '/login')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Complex guard with multiple conditions\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [authGuard([\r\n * { condition: AuthGuardCondition.SIGNED_IN, state: true, redirect: '/login' },\r\n * { condition: AuthGuardCondition.HAS_TOKEN, state: true, redirect: '/unauthorized' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Preventing authenticated users from accessing login page\r\n * const routes: Routes = [\r\n * {\r\n * path: 'login',\r\n * component: LoginComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, false, '/dashboard')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthState} Service that provides authentication state information\r\n * @see {@link AuthGuardOption} Interface for configuring guard options\r\n * @see {@link AuthGuardCondition} Enum defining available authentication conditions\r\n * @see {@link getAllAuthGuardOptions} Utility function for extracting guard options from routes\r\n * @see {@link AUTH_GUARD_OPTIONS_KEY} Constant for storing guard options in route data\r\n */\r\nexport function authGuard(\r\n param: AuthGuardCondition | AuthGuardOption[],\r\n state?: boolean,\r\n fallbackRedirect?: string,\r\n): CanActivateFn {\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n return async (route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Promise<boolean> => {\r\n const router = inject(Router);\r\n const authState = inject(AuthState);\r\n\r\n route.data = {\r\n ...route.data,\r\n [AUTH_GUARD_OPTIONS_KEY]: Array.isArray(param)\r\n ? param\r\n : [{ condition: param, state: state!, redirect: fallbackRedirect! }],\r\n };\r\n\r\n const conditionCheckers = {\r\n [AuthGuardCondition.SIGNED_IN]: authState.signedIn,\r\n [AuthGuardCondition.HAS_TOKEN]: authState.hasAccessToken,\r\n };\r\n\r\n const authGuardOptions = getAllAuthGuardOptions(route);\r\n\r\n if (!authGuardOptions.length) {\r\n return true;\r\n }\r\n\r\n const conditionsMet = authGuardOptions.every(option => {\r\n return option.state === conditionCheckers[option.condition]();\r\n });\r\n\r\n if (!conditionsMet) {\r\n const option = authGuardOptions.pop()!;\r\n const redirectPath = option.redirect.startsWith(\"/\") ? option.redirect : `/${option.redirect}`;\r\n await router.navigateByUrl(redirectPath);\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n}\r\n","// noinspection JSUnusedGlobalSymbols\r\n\r\nimport { inject } from \"@angular/core\";\r\nimport { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from \"@angular/router\";\r\nimport { AuthState } from \"../state\";\r\nimport { RoleGuardOption } from \"../interfaces\";\r\n\r\n/**\r\n * Creates a role-based authorization guard function for Angular route protection\r\n *\r\n * This function creates a route guard that protects routes based on user roles.\r\n * It checks if the current user's role matches the required role, and if not,\r\n * it evaluates the provided options to determine the appropriate action (redirect\r\n * or sign out).\r\n *\r\n * The guard integrates with the AuthState service to check the current user's role\r\n * and uses the Angular Router for navigation when redirects are needed. If no\r\n * matching role or redirect option is found, the user is automatically signed out.\r\n *\r\n * Key features:\r\n * - Role-based route protection\r\n * - Configurable redirect options based on user roles\r\n * - Automatic sign-out for unauthorized access\r\n * - Integration with AuthState for reactive role checking\r\n * - Support for multiple role-based redirect scenarios\r\n *\r\n * @param role - The required role name that the user must have to access the route\r\n * @param options - Array of role guard options that define redirect behavior for different user roles\r\n * @returns A CanActivateFn that evaluates role-based authorization and handles navigation\r\n *\r\n * @example\r\n * ```typescript\r\n * // Protecting an admin route\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [roleGuard('admin', [\r\n * { state: 'user', redirect: '/dashboard' },\r\n * { state: 'moderator', redirect: '/moderator-panel' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Protecting a moderator route with fallback redirects\r\n * const routes: Routes = [\r\n * {\r\n * path: 'moderate',\r\n * component: ModeratorComponent,\r\n * canActivate: [roleGuard('moderator', [\r\n * { state: 'user', redirect: '/unauthorized' },\r\n * { state: 'guest', redirect: '/login' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Simple role guard without specific redirects (will sign out unauthorized users)\r\n * const routes: Routes = [\r\n * {\r\n * path: 'super-admin',\r\n * component: SuperAdminComponent,\r\n * canActivate: [roleGuard('super-admin', [])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthState} Service that provides authentication and role state information\r\n * @see {@link RoleGuardOption} Interface for configuring role-based redirect options\r\n */\r\nexport function roleGuard(role: string, options: RoleGuardOption[]): CanActivateFn {\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n return async (_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Promise<boolean> => {\r\n const router = inject(Router);\r\n const authState = inject(AuthState);\r\n\r\n if (!options.length) {\r\n return true;\r\n }\r\n\r\n for await (const option of options) {\r\n if (role === authState.roleName()) {\r\n return true;\r\n } else if (option.state === authState.roleName()) {\r\n const redirectPath = option.redirect.startsWith(\"/\") ? option.redirect : `/${option.redirect}`;\r\n await router.navigateByUrl(redirectPath);\r\n return false;\r\n }\r\n }\r\n\r\n await authState.signOut(\"/auth\", true);\r\n\r\n return false;\r\n };\r\n}\r\n","import { HttpEvent, HttpHandlerFn, HttpInterceptorFn, HttpRequest } from \"@angular/common/http\";\r\nimport { catchError, filter, Observable, ReplaySubject, switchMap, take, throwError } from \"rxjs\";\r\nimport { AccessToken, AuthEndpoint, AuthErrorResponseCode, TokenResponse } from \"@hichchi/nest-connector/auth\";\r\nimport { Endpoint, ErrorResponseCode, HttpClientErrorStatus } from \"@hichchi/nest-connector\";\r\nimport { inject } from \"@angular/core\";\r\nimport { Router } from \"@angular/router\";\r\nimport { HttpError } from \"@hichchi/ngx-utils\";\r\nimport { AuthState } from \"../state\";\r\nimport { AuthService } from \"../services\";\r\n\r\n/**\r\n * Array of authentication error codes that should trigger token refresh instead of immediate redirect\r\n *\r\n * These error codes indicate authentication issues that can potentially be resolved\r\n * by refreshing the access token. When these errors are encountered, the interceptor\r\n * will attempt to refresh the token before redirecting the user to the login page.\r\n *\r\n * @example\r\n * ```typescript\r\n * // The interceptor checks if the error code is in this array\r\n * if (SKIPPED_ERRORS.includes(error.error?.code)) {\r\n * // Attempt token refresh instead of immediate redirect\r\n * return refreshToken(req, next);\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthErrorResponseCode} Enum containing all authentication error codes\r\n * @see {@link authInterceptor} Function that uses this array for error handling\r\n */\r\nexport const SKIPPED_ERRORS: ErrorResponseCode[] = [\r\n AuthErrorResponseCode.AUTH_401_EXPIRED_TOKEN,\r\n AuthErrorResponseCode.AUTH_401_INVALID_TOKEN,\r\n AuthErrorResponseCode.AUTH_401_NOT_LOGGED_IN,\r\n];\r\n\r\n/**\r\n * Flag to prevent multiple simultaneous token refresh operations\r\n *\r\n * This global flag ensures that only one token refresh operation can be in progress\r\n * at any given time. This prevents race conditions and duplicate refresh requests\r\n * when multiple HTTP requests fail simultaneously due to expired tokens.\r\n *\r\n * @private\r\n */\r\nlet refreshingInProgress = false;\r\n\r\n/**\r\n * Checks if an HTTP request is a token refresh request\r\n *\r\n * This utility function determines whether the given HTTP request is attempting\r\n * to refresh authentication tokens. This is important to avoid intercepting\r\n * and modifying token refresh requests themselves, which could cause infinite loops.\r\n *\r\n * @param req - The HTTP request to check\r\n * @returns True if the request is a token refresh request, false otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used in the interceptor to avoid processing refresh token requests\r\n * if (!isRefreshTokenReq(req)) {\r\n * // Apply authentication logic\r\n * }\r\n * ```\r\n *\r\n * @private\r\n * @see {@link AuthEndpoint.REFRESH_TOKEN} Endpoint constant for token refresh\r\n * @see {@link Endpoint.AUTH} Base authentication endpoint\r\n */\r\nconst isRefreshTokenReq = (req: HttpRequest<unknown>): boolean =>\r\n req.url.includes(`${Endpoint.AUTH}/${AuthEndpoint.REFRESH_TOKEN}`);\r\n\r\n/**\r\n * Subject for coordinating token refresh operations across multiple HTTP requests\r\n *\r\n * This ReplaySubject is used to coordinate token refresh operations when multiple\r\n * HTTP requests fail simultaneously due to expired tokens. It ensures that all\r\n * waiting requests receive the new token once the refresh operation completes.\r\n *\r\n * The subject emits the new access token when refresh succeeds, or an error when\r\n * refresh fails. It uses ReplaySubject to ensure late subscribers still receive\r\n * the last emitted value.\r\n *\r\n * @private\r\n * @see {@link ReplaySubject} RxJS subject type used for token coordination\r\n * @see {@link AccessToken} Type representing access tokens\r\n */\r\nlet tokenSubject: ReplaySubject<AccessToken | null> = new ReplaySubject<AccessToken | null>(1);\r\n\r\n/**\r\n * Creates an HTTP interceptor for handling authentication tokens and automatic token refresh\r\n *\r\n * This interceptor automatically adds authentication tokens to outgoing HTTP requests\r\n * and handles token refresh when requests fail due to expired tokens. It provides\r\n * seamless authentication management for Angular applications using JWT tokens.\r\n *\r\n * Key features:\r\n * - Automatic token attachment to HTTP requests\r\n * - Automatic token refresh on authentication errors\r\n * - Prevention of multiple simultaneous refresh operations\r\n * - Coordinated handling of multiple failed requests during token refresh\r\n * - Automatic redirect to login page when refresh fails\r\n * - Configurable redirect behavior with optional callback\r\n *\r\n * The interceptor works by:\r\n * 1. Adding the current access token to outgoing requests\r\n * 2. Monitoring responses for authentication errors\r\n * 3. Attempting token refresh when authentication errors occur\r\n * 4. Retrying failed requests with the new token\r\n * 5. Redirecting to login when refresh fails or no refresh token is available\r\n *\r\n * @param redirect - The path to redirect to when authentication fails completely\r\n * @param onRedirect - Optional callback function to execute before redirecting\r\n * @returns An HttpInterceptorFn that can be used in Angular HTTP interceptor configuration\r\n *\r\n * @example\r\n * ```typescript\r\n * // Basic usage in app configuration\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(\r\n * withInterceptors([\r\n * authInterceptor('/login')\r\n * ])\r\n * )\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // With custom redirect callback\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(\r\n * withInterceptors([\r\n * authInterceptor('/login', () => {\r\n * console.log('Redirecting to login due to authentication failure');\r\n * // Clear any cached data\r\n * localStorage.clear();\r\n * })\r\n * ])\r\n * )\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a module-based application\r\n * @NgModule({\r\n * providers: [\r\n * {\r\n * provide: HTTP_INTERCEPTORS,\r\n * useValue: authInterceptor('/auth/login'),\r\n * multi: true\r\n * }\r\n * ]\r\n * })\r\n * export class AppModule {}\r\n * ```\r\n *\r\n * @see {@link AuthState} Service that provides authentication state and tokens\r\n * @see {@link AuthService} Service that handles token refresh operations\r\n * @see {@link HttpInterceptorFn} Angular HTTP interceptor function type\r\n * @see {@link SKIPPED_ERRORS} Array of error codes that trigger token refresh\r\n */\r\nexport function authInterceptor(redirect: string, onRedirect?: () => void): HttpInterceptorFn {\r\n return (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {\r\n const authState = inject(AuthState);\r\n const authService = inject(AuthService);\r\n const router = inject(Router);\r\n\r\n const setAccessToken = (req: HttpRequest<unknown>, accessToken: AccessToken): HttpRequest<unknown> => {\r\n return req.clone({\r\n headers: req.headers.set(\"Authorization\", `Bearer ${accessToken}`),\r\n });\r\n };\r\n\r\n const gotoSignIn = (): void => {\r\n onRedirect?.();\r\n authState.reset();\r\n // eslint-disable-next-line no-void\r\n void router.navigateByUrl(redirect);\r\n };\r\n\r\n const refreshToken = (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {\r\n if (!refreshingInProgress) {\r\n refreshingInProgress = true;\r\n tokenSubject.next(null);\r\n\r\n const refreshToken = authState.refreshToken();\r\n\r\n if (!refreshToken) {\r\n refreshingInProgress = false;\r\n gotoSignIn();\r\n return throwError(() => new Error(\"Refresh token not found.\"));\r\n }\r\n\r\n return authService.refreshToken(refreshToken).pipe(\r\n switchMap((tokenResponse: TokenResponse) => {\r\n authState.setTokens(tokenResponse);\r\n tokenSubject.next(tokenResponse.accessToken);\r\n tokenSubject.complete();\r\n tokenSubject = new ReplaySubject<AccessToken | null>(1);\r\n refreshingInProgress = false;\r\n return next(setAccessToken(req, tokenResponse.accessToken));\r\n }),\r\n catchError((error: HttpError) => {\r\n refreshingInProgress = false;\r\n tokenSubject.error(error);\r\n tokenSubject.complete();\r\n tokenSubject = new ReplaySubject<AccessToken | null>(1);\r\n gotoSignIn();\r\n return throwError(() => error);\r\n }),\r\n );\r\n }\r\n\r\n return tokenSubject.pipe(\r\n filter(result => result !== null),\r\n take(1),\r\n switchMap(token => {\r\n return next(setAccessToken(req, token));\r\n }),\r\n );\r\n };\r\n\r\n const handleRequest = (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {\r\n return next(req).pipe(\r\n catchError((error: HttpError) => {\r\n if (\r\n error.status === HttpClientErrorStatus.UNAUTHORIZED &&\r\n error.error?.code &&\r\n SKIPPED_ERRORS.includes(error.error?.code) &&\r\n !isRefreshTokenReq(req)\r\n ) {\r\n if (authState.signedIn()) {\r\n return refreshToken(req, next);\r\n }\r\n }\r\n return throwError(() => error);\r\n }),\r\n );\r\n };\r\n\r\n if (authState.accessToken()) {\r\n const tokenizedRequest = req.clone({\r\n headers: req.headers.set(\"Authorization\", `Bearer ${authState.accessToken()}`),\r\n });\r\n return handleRequest(tokenizedRequest, next);\r\n }\r\n return handleRequest(req, next);\r\n };\r\n}\r\n","import { ModuleWithProviders, NgModule } from \"@angular/core\";\r\nimport { CommonModule } from \"@angular/common\";\r\nimport { FormsModule, ReactiveFormsModule } from \"@angular/forms\";\r\nimport { AuthFormComponent } from \"./components\";\r\nimport { PermissionDirective } from \"./directives\";\r\nimport { AuthService } from \"./services\";\r\nimport { AuthConfig } from \"./interfaces\";\r\nimport { AUTH_CONFIG } from \"./tokens\";\r\nimport { ButtonComponent, HcCardComponent, HcSeparatorComponent } from \"@hichchi/ngx-ui\";\r\n\r\n/**\r\n * Angular module for authentication functionality\r\n *\r\n * This module provides comprehensive authentication features for Angular applications,\r\n * including authentication forms, permission-based directives, and authentication services.\r\n * It integrates with the Hichchi authentication system and provides both components\r\n * and directives for building secure Angular applications.\r\n *\r\n * The module exports:\r\n * - AuthFormComponent: A ready-to-use authentication form component\r\n * - PermissionDirective: A structural directive for permission-based conditional rendering\r\n *\r\n * The module must be configured using the forRoot() method to provide the necessary\r\n * authentication configuration.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Basic module configuration\r\n * @NgModule({\r\n * imports: [\r\n * NgxHichchiAuthModule.forRoot({\r\n * apiBaseURL: 'https://api.example.com'\r\n * })\r\n * ]\r\n * })\r\n * export class AppModule { }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Advanced configuration with custom authentication field\r\n * @NgModule({\r\n * imports: [\r\n * NgxHichchiAuthModule.forRoot({\r\n * apiBaseURL: 'https://api.example.com',\r\n * authField: AuthField.EMAIL\r\n * })\r\n * ]\r\n * })\r\n * export class AppModule { }\r\n * ```\r\n *\r\n * @see {@link AuthConfig} Configuration interface for the authentication module\r\n * @see {@link AuthFormComponent} Authentication form component\r\n * @see {@link PermissionDirective} Permission-based conditional rendering directive\r\n * @see {@link AuthService} Authentication service for managing user sessions\r\n */\r\n@NgModule({\n declarations: [AuthFormComponent],\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n ReactiveFormsModule,\r\n ButtonComponent,\r\n HcCardComponent,\r\n HcSeparatorComponent,\r\n PermissionDirective,\r\n ],\r\n exports: [AuthFormComponent, PermissionDirective],\r\n})\n/**\n * Root module for reusable authentication UI, directives, and providers.\n */\nexport class NgxHichchiAuthModule {\n /**\r\n * Configures the NgxHichchiAuthModule with the provided authentication configuration\r\n *\r\n * This static method sets up the module with the necessary providers and configuration\r\n * for authentication functionality. It provides the AuthService, HTTP client, and\r\n * authentication configuration token that are required for the module to function properly.\r\n *\r\n * @param config - The authentication configuration object containing API endpoints and settings\r\n * @returns A ModuleWithProviders object configured with authentication providers\r\n *\r\n * @example\r\n * ```typescript\r\n * // Basic configuration\r\n * NgxHichchiAuthModule.forRoot({\r\n * apiBaseURL: 'https://api.example.com'\r\n * })\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Configuration with environment variables and authentication field\r\n * NgxHichchiAuthModule.forRoot({\r\n * apiBaseURL: environment.apiUrl,\r\n * authField: AuthField.USERNAME\r\n * })\r\n * ```\r\n *\r\n * @see {@link AuthConfig} Interface defining the configuration structure\r\n * @see {@link AUTH_CONFIG} Injection token for the authentication configuration\r\n * @see {@link AuthService} Service that uses the provided configuration\r\n */\r\n static forRoot(config: AuthConfig): ModuleWithProviders<NgxHichchiAuthModule> {\r\n return {\r\n ngModule: NgxHichchiAuthModule,\r\n providers: [{ provide: AUTH_CONFIG, useValue: config }, AuthService],\r\n };\r\n }\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hichchi-ngx-auth.mjs","sources":["../../../../libs/ngx-auth/src/lib/tokens.ts","../../../../libs/ngx-auth/src/lib/constants.ts","../../../../libs/ngx-auth/src/lib/services/auth.service.ts","../../../../libs/ngx-auth/src/lib/state/auth.state.ts","../../../../libs/ngx-auth/src/lib/components/auth-form/auth-form.component.ts","../../../../libs/ngx-auth/src/lib/components/auth-form/auth-form.component.html","../../../../libs/ngx-auth/src/lib/directives/permission.directive.ts","../../../../libs/ngx-auth/src/lib/enums/auth-guard-condition.enum.ts","../../../../libs/ngx-auth/src/lib/utils/route.utils.ts","../../../../libs/ngx-auth/src/lib/guards/auth.guard.ts","../../../../libs/ngx-auth/src/lib/guards/role.guard.ts","../../../../libs/ngx-auth/src/lib/interceptors/auth.interceptor.ts","../../../../libs/ngx-auth/src/lib/auth.module.ts","../../../../libs/ngx-auth/src/hichchi-ngx-auth.ts"],"sourcesContent":["import { InjectionToken } from \"@angular/core\";\r\nimport { AuthConfig } from \"./interfaces\";\r\n\r\n/**\r\n * Injection token for the ngx-auth runtime configuration.\r\n *\r\n * This token is bound in `NgxHichchiAuthModule.forRoot(config)` as:\r\n * `{ provide: AUTH_CONFIG, useValue: config }`.\r\n * Consumers can inject it to access the same `AuthConfig` object\r\n * (for example `apiBaseURL` and optional `authField`).\r\n *\r\n * @example\r\n * ```typescript\r\n * NgxHichchiAuthModule.forRoot({\r\n * apiBaseURL: \"https://api.example.com\",\r\n * });\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * @Injectable()\r\n * export class ExampleService {\r\n * constructor(@Inject(AUTH_CONFIG) private readonly config: AuthConfig) {\r\n * console.log(this.config.apiBaseURL);\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthConfig} Configuration contract provided through this token\r\n */\r\nexport const AUTH_CONFIG = new InjectionToken<AuthConfig>(\"AUTH_CONFIG\");\r\n","/**\r\n * Width of the Google OAuth authentication popup window in pixels\r\n *\r\n * This constant defines the width of the popup window that opens during Google OAuth\r\n * authentication. The width is optimized to provide a good user experience while\r\n * ensuring the Google sign-in interface is fully visible and usable.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used internally in AuthService.googleSignIn()\r\n * const popup = window.open(\r\n * googleAuthUrl,\r\n * 'google-login-popup',\r\n * `width=${GOOGLE_AUTH_POPUP_WIDTH}, height=${GOOGLE_AUTH_POPUP_HEIGHT}`\r\n * );\r\n * ```\r\n *\r\n * @see {@link AuthService.googleSignIn} Method that uses this constant\r\n * @see {@link GOOGLE_AUTH_POPUP_HEIGHT} Related constant for popup height\r\n */\r\nexport const GOOGLE_AUTH_POPUP_WIDTH = 500;\r\n\r\n/**\r\n * Height of the Google OAuth authentication popup window in pixels\r\n *\r\n * This constant defines the height of the popup window that opens during Google OAuth\r\n * authentication. The height is optimized to accommodate the Google sign-in interface\r\n * and provide sufficient space for user interaction.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used internally in AuthService.googleSignIn()\r\n * const popup = window.open(\r\n * googleAuthUrl,\r\n * 'google-login-popup',\r\n * `width=${GOOGLE_AUTH_POPUP_WIDTH}, height=${GOOGLE_AUTH_POPUP_HEIGHT}`\r\n * );\r\n * ```\r\n *\r\n * @see {@link AuthService.googleSignIn} Method that uses this constant\r\n * @see {@link GOOGLE_AUTH_POPUP_WIDTH} Related constant for popup width\r\n */\r\nexport const GOOGLE_AUTH_POPUP_HEIGHT = 600;\r\n\r\n/**\r\n * Polling interval for checking Google OAuth popup status in milliseconds\r\n *\r\n * This constant defines how frequently (in milliseconds) the AuthService checks\r\n * the status of the Google OAuth popup window. The polling is used to detect\r\n * when the authentication process is complete or if the user has closed the popup.\r\n *\r\n * A shorter interval provides more responsive detection but uses more CPU resources.\r\n * The current value of 100ms provides a good balance between responsiveness and\r\n * performance.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used internally in AuthService.googleSignIn()\r\n * const interval = setInterval(() => {\r\n * // Check popup status\r\n * if (popup?.closed) {\r\n * clearInterval(interval);\r\n * }\r\n * // Check for authentication completion\r\n * }, POPUP_POLLING_INTERVAL_MS);\r\n * ```\r\n *\r\n * @see {@link AuthService.googleSignIn} Method that uses this constant for popup polling\r\n */\r\nexport const POPUP_POLLING_INTERVAL_MS = 100;\r\n\r\n/**\r\n * Key used to store authentication guard options in route data\r\n *\r\n * This constant defines the property name used to store authentication guard\r\n * configuration in Angular route data. It allows routes to specify custom\r\n * authentication requirements and behaviors.\r\n *\r\n * @example\r\n * ```typescript\r\n * // In route configuration\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [AuthGuard],\r\n * data: {\r\n * [AUTH_GUARD_OPTIONS_KEY]: {\r\n * requiredPermissions: ['admin.read'],\r\n * redirectTo: '/unauthorized'\r\n * }\r\n * }\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthGuardOption} Interface defining the structure of guard options\r\n */\r\nexport const AUTH_GUARD_OPTIONS_KEY = \"authGuardOptions\";\r\n","// noinspection JSUnusedGlobalSymbols\r\n\r\nimport { Inject, Injectable } from \"@angular/core\";\r\nimport { map, Observable, take } from \"rxjs\";\r\nimport {\r\n AccessToken,\r\n AuthEndpoint,\r\n AuthResponse,\r\n RefreshToken,\r\n SignInBody,\r\n SignUpBody,\r\n TokenResponse,\r\n User,\r\n} from \"@hichchi/nest-connector/auth\";\r\nimport { Endpoint, SuccessResponse } from \"@hichchi/nest-connector\";\r\nimport { AUTH_CONFIG } from \"../tokens\";\r\nimport { AuthConfig } from \"../interfaces\";\r\nimport { GOOGLE_AUTH_POPUP_HEIGHT, GOOGLE_AUTH_POPUP_WIDTH, POPUP_POLLING_INTERVAL_MS } from \"../constants\";\r\nimport { CrudHttpService, skipNotifyContext } from \"@hichchi/ngx-utils\";\r\n\r\n/**\r\n * Angular authentication service for client-side authentication operations\r\n *\r\n * This service provides methods for handling authentication operations in Angular applications,\r\n * including user sign-in, sign-up, Google OAuth authentication, token management, and sign-out.\r\n * It communicates with the backend authentication API and handles the client-side aspects\r\n * of the authentication flow.\r\n *\r\n * The service is configured through the AuthConfig interface and automatically handles\r\n * token expiration date parsing and HTTP request management. It integrates seamlessly\r\n * with the @hichchi/nest-auth backend module.\r\n *\r\n * Key features:\r\n * - Local authentication (email/username and password)\r\n * - Google OAuth authentication with popup flow\r\n * - Token refresh functionality\r\n * - User registration\r\n * - Automatic token expiration handling\r\n * - RESTful API communication\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class LoginComponent {\r\n * constructor(private authService: AuthService) {}\r\n *\r\n * async signIn() {\r\n * try {\r\n * const response = await this.authService.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }).toPromise();\r\n * console.log('Signed in:', response.user);\r\n * } catch (error) {\r\n * console.error('Sign in failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthConfig} Configuration interface for the authentication service\r\n * @see {@link NgxHichchiAuthModule} Module that provides this service\r\n * @see {@link AuthState} State management service for authentication\r\n * @see {@link AuthResponse} Response interface for authentication operations\r\n */\r\n@Injectable({\r\n providedIn: \"root\",\r\n})\r\n/**\r\n * HTTP client wrapper for authentication and token lifecycle endpoints.\r\n */\r\nexport class AuthService extends CrudHttpService {\r\n /**\r\n * Creates an instance of AuthService\r\n *\r\n * @param config - The authentication configuration injected from AUTH_CONFIG token\r\n *\r\n * @see {@link AUTH_CONFIG} Injection token for authentication configuration\r\n * @see {@link AuthConfig} Interface defining the configuration structure\r\n */\r\n // eslint-disable-next-line @angular-eslint/prefer-inject\r\n constructor(@Inject(AUTH_CONFIG) private readonly config: AuthConfig) {\r\n super();\r\n }\r\n\r\n /**\r\n * Authenticates a user with email/username and password\r\n *\r\n * This method sends a sign-in request to the backend authentication API with the provided\r\n * credentials. It automatically converts the token expiration timestamps from the response\r\n * into JavaScript Date objects for easier handling in the client application.\r\n *\r\n * @param dto - The sign-in data containing user credentials\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the authentication response with user data and tokens\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign in with email and password\r\n * this.authService.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }).subscribe({\r\n * next: (response) => {\r\n * console.log('User signed in:', response.user);\r\n * console.log('Access token expires:', response.accessTokenExpiresOn);\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign in failed:', error);\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @see {@link SignInBody} Interface for sign-in request data\r\n * @see {@link AuthResponse} Interface for authentication response\r\n * @see {@link AuthEndpoint.SIGN_IN} Backend endpoint for user authentication\r\n */\r\n signIn(dto: SignInBody, skipNotify?: boolean): Observable<AuthResponse> {\r\n return this.post<AuthResponse>(`${Endpoint.AUTH}/${AuthEndpoint.SIGN_IN}`, dto, { skipNotify }).pipe(\r\n take(1),\r\n map(res => ({\r\n ...res,\r\n accessTokenExpiresOn: new Date(res.accessTokenExpiresOn),\r\n refreshTokenExpiresOn: new Date(res.refreshTokenExpiresOn),\r\n })),\r\n );\r\n }\r\n\r\n /**\r\n * Initiates Google OAuth authentication using a popup window\r\n *\r\n * This method opens a popup window that navigates to the Google OAuth authentication\r\n * endpoint. It handles the OAuth flow by monitoring the popup window and extracting\r\n * the access token from the callback URL when authentication is successful.\r\n *\r\n * The popup is automatically positioned in the center of the screen and has predefined\r\n * dimensions for optimal user experience. The method polls the popup window to detect\r\n * when authentication is complete or if the user closes the popup.\r\n *\r\n * @returns Promise that resolves with the access token when authentication succeeds\r\n *\r\n * @throws {Error} If authentication fails or the popup is blocked\r\n *\r\n * @example\r\n * ```typescript\r\n * // Initiate Google sign-in\r\n * try {\r\n * const accessToken = await this.authService.googleSignIn();\r\n * console.log('Google authentication successful:', accessToken);\r\n *\r\n * // Use the token to get full auth response\r\n * const authResponse = await this.authService.getAuthResponse(accessToken).toPromise();\r\n * console.log('User data:', authResponse.user);\r\n * } catch (error) {\r\n * console.error('Google authentication failed:', error);\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component with error handling\r\n * async signInWithGoogle() {\r\n * try {\r\n * const token = await this.authService.googleSignIn();\r\n * // Handle successful authentication\r\n * this.router.navigate(['/dashboard']);\r\n * } catch (error) {\r\n * if (error.message.includes('popup')) {\r\n * this.showError('Please allow popups for Google sign-in');\r\n * } else {\r\n * this.showError('Google sign-in failed. Please try again.');\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link getAuthResponse} Method to get full authentication response using the access token\r\n * @see {@link AuthEndpoint.GOOGLE_SIGN_IN} Backend endpoint for Google OAuth initiation\r\n * @see {@link GOOGLE_AUTH_POPUP_WIDTH} Constant defining popup window width\r\n * @see {@link GOOGLE_AUTH_POPUP_HEIGHT} Constant defining popup window height\r\n * @see {@link POPUP_POLLING_INTERVAL_MS} Constant defining popup polling interval\r\n */\r\n googleSignIn(): Promise<AccessToken> {\r\n return new Promise((resolve: (token: AccessToken) => void, reject: (error: unknown) => void): void => {\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n const left = (window.screen.width - GOOGLE_AUTH_POPUP_WIDTH) / 2;\r\n // eslint-disable-next-line @typescript-eslint/no-magic-numbers\r\n const top = (window.screen.height - GOOGLE_AUTH_POPUP_HEIGHT) / 2;\r\n\r\n const popup = window.open(\r\n `${this.config.apiBaseURL}/${Endpoint.AUTH}/${AuthEndpoint.GOOGLE_SIGN_IN}?redirectUrl=${window.location.origin}`,\r\n \"google-login-popup\",\r\n // eslint-disable-next-line prefer-template\r\n \"resizable=no, location=no, toolbar=false, width=\" +\r\n GOOGLE_AUTH_POPUP_WIDTH +\r\n \", height=\" +\r\n GOOGLE_AUTH_POPUP_HEIGHT +\r\n \", top=\" +\r\n top +\r\n \", left=\" +\r\n left,\r\n );\r\n\r\n const interval = setInterval(() => {\r\n if (popup?.closed) {\r\n clearInterval(interval);\r\n }\r\n\r\n try {\r\n if (popup?.location.href !== \"about:blank\" && popup?.location?.search?.includes(\"?token=e\")) {\r\n const token = popup.location.search.split(\"=\")[1] as AccessToken;\r\n clearInterval(interval);\r\n popup.close();\r\n resolve(token);\r\n }\r\n } catch (error) {\r\n if (!String(error).includes(\"SecurityError\")) {\r\n clearInterval(interval);\r\n reject(error);\r\n }\r\n }\r\n }, POPUP_POLLING_INTERVAL_MS);\r\n });\r\n }\r\n\r\n /**\r\n * Retrieves the complete authentication response using an access token\r\n *\r\n * This method exchanges an access token for a complete authentication response\r\n * containing user information and token details. It's typically used after\r\n * Google OAuth authentication to get the full user profile and session data.\r\n *\r\n * The method automatically converts token expiration timestamps to JavaScript\r\n * Date objects for easier handling in the client application.\r\n *\r\n * @param accessToken - The access token to exchange for authentication response\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the complete authentication response\r\n *\r\n * @example\r\n * ```typescript\r\n * // Get auth response after Google sign-in\r\n * const accessToken = await this.authService.googleSignIn();\r\n * this.authService.getAuthResponse(accessToken).subscribe({\r\n * next: (response) => {\r\n * console.log('User:', response.user);\r\n * console.log('Tokens:', {\r\n * access: response.accessToken,\r\n * refresh: response.refreshToken\r\n * });\r\n * },\r\n * error: (error) => {\r\n * console.error('Failed to get auth response:', error);\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @see {@link AccessToken} Type representing access tokens\r\n * @see {@link AuthResponse} Interface for complete authentication response\r\n * @see {@link AuthEndpoint.GET_AUTH_RESPONSE} Backend endpoint for token exchange\r\n * @see {@link googleSignIn} Method that provides access tokens for this operation\r\n */\r\n getAuthResponse(accessToken: AccessToken, skipNotify?: boolean): Observable<AuthResponse> {\r\n return this.http\r\n .post<AuthResponse>(\r\n `${Endpoint.AUTH}/${AuthEndpoint.GET_AUTH_RESPONSE}`,\r\n {\r\n accessToken,\r\n },\r\n skipNotifyContext(skipNotify),\r\n )\r\n .pipe(\r\n take(1),\r\n map(res => ({\r\n ...res,\r\n accessTokenExpiresOn: new Date(res.accessTokenExpiresOn),\r\n refreshTokenExpiresOn: new Date(res.refreshTokenExpiresOn),\r\n })),\r\n );\r\n }\r\n\r\n /**\r\n * Registers a new user account\r\n *\r\n * This method sends a registration request to the backend API with the provided\r\n * user information. It creates a new user account and returns the user data\r\n * upon successful registration.\r\n *\r\n * Note that this method only creates the user account and does not automatically\r\n * sign the user in. After successful registration, you may need to call signIn\r\n * or handle email verification depending on your application's configuration.\r\n *\r\n * @param dto - The sign-up data containing user registration information\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the newly created user data\r\n *\r\n * @example\r\n * ```typescript\r\n * // Register a new user\r\n * this.authService.signUp({\r\n * email: 'newuser@example.com',\r\n * password: 'securePassword123',\r\n * firstName: 'John',\r\n * lastName: 'Doe'\r\n * }).subscribe({\r\n * next: (user) => {\r\n * console.log('User registered successfully:', user);\r\n * // Optionally redirect to sign-in or email verification page\r\n * this.router.navigate(['/verify-email']);\r\n * },\r\n * error: (error) => {\r\n * console.error('Registration failed:', error);\r\n * // Handle registration errors (email already exists, etc.)\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @see {@link SignUpBody} Interface for user registration data\r\n * @see {@link User} Interface for user data returned after registration\r\n * @see {@link AuthEndpoint.SIGN_UP} Backend endpoint for user registration\r\n * @see {@link signIn} Method to authenticate user after registration\r\n */\r\n signUp(dto: SignUpBody, skipNotify?: boolean): Observable<User> {\r\n return this.http\r\n .post<User>(`${Endpoint.AUTH}/${AuthEndpoint.SIGN_UP}`, dto, skipNotifyContext(skipNotify))\r\n .pipe(take(1));\r\n }\r\n\r\n /**\r\n * Refreshes an expired access token using a refresh token\r\n *\r\n * This method exchanges a valid refresh token for a new set of access and refresh tokens.\r\n * It's typically used when the current access token has expired but the refresh token\r\n * is still valid, allowing the user to maintain their session without re-authenticating.\r\n *\r\n * The refresh token mechanism provides a secure way to maintain long-lived sessions\r\n * while keeping access tokens short-lived for better security.\r\n *\r\n * @param refreshToken - The refresh token to exchange for new tokens\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits the new token response\r\n *\r\n * @example\r\n * ```typescript\r\n * // Refresh tokens when access token expires\r\n * const storedRefreshToken = localStorage.getItem('refreshToken');\r\n * if (storedRefreshToken) {\r\n * this.authService.refreshToken(storedRefreshToken).subscribe({\r\n * next: (tokenResponse) => {\r\n * console.log('Tokens refreshed successfully');\r\n * // Store new tokens\r\n * localStorage.setItem('accessToken', tokenResponse.accessToken);\r\n * localStorage.setItem('refreshToken', tokenResponse.refreshToken);\r\n * },\r\n * error: (error) => {\r\n * console.error('Token refresh failed:', error);\r\n * // Redirect to login page\r\n * this.router.navigate(['/login']);\r\n * }\r\n * });\r\n * }\r\n * ```\r\n *\r\n * @see {@link RefreshToken} Type representing refresh tokens\r\n * @see {@link TokenResponse} Interface for token refresh response\r\n * @see {@link AuthEndpoint.REFRESH_TOKEN} Backend endpoint for token refresh\r\n * @see {@link signIn} Method to get initial tokens through authentication\r\n */\r\n refreshToken(refreshToken: RefreshToken, skipNotify?: boolean): Observable<TokenResponse> {\r\n return this.http\r\n .post<AuthResponse>(\r\n `${Endpoint.AUTH}/${AuthEndpoint.REFRESH_TOKEN}`,\r\n {\r\n refreshToken,\r\n },\r\n skipNotifyContext(skipNotify),\r\n )\r\n .pipe(take(1));\r\n }\r\n\r\n /**\r\n * Signs out the current user and invalidates their session\r\n *\r\n * This method sends a sign-out request to the backend API to invalidate the user's\r\n * current session and tokens. It effectively logs the user out of the application\r\n * and clears their authentication state on the server.\r\n *\r\n * After calling this method, you should also clear any client-side authentication\r\n * data such as tokens stored in localStorage, sessionStorage, or application state.\r\n *\r\n * @param skipNotify - Optional flag to skip error notifications for this request\r\n * @returns Observable that emits a success response when sign-out is complete\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign out the current user\r\n * this.authService.signOut().subscribe({\r\n * next: (response) => {\r\n * console.log('User signed out successfully');\r\n * // Clear client-side authentication data\r\n * localStorage.removeItem('accessToken');\r\n * localStorage.removeItem('refreshToken');\r\n * // Redirect to login page\r\n * this.router.navigate(['/login']);\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign out failed:', error);\r\n * // Even if server sign-out fails, clear local data\r\n * localStorage.clear();\r\n * this.router.navigate(['/login']);\r\n * }\r\n * });\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign out with state management\r\n * async signOut() {\r\n * try {\r\n * await this.authService.signOut().toPromise();\r\n * // Clear authentication state\r\n * this.authState.clearUser();\r\n * this.notificationService.showSuccess('Signed out successfully');\r\n * } catch (error) {\r\n * console.error('Sign out error:', error);\r\n * } finally {\r\n * // Always redirect to login\r\n * this.router.navigate(['/login']);\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link SuccessResponse} Interface for success response\r\n * @see {@link AuthEndpoint.SIGN_OUT} Backend endpoint for user sign-out\r\n * @see {@link signIn} Method to authenticate user after sign-out\r\n */\r\n signOut(skipNotify?: boolean): Observable<SuccessResponse | null> {\r\n // this.app.startSpinner();\r\n return this.http\r\n .post<SuccessResponse>(`${Endpoint.AUTH}/${AuthEndpoint.SIGN_OUT}`, {}, skipNotifyContext(skipNotify))\r\n .pipe(take(1));\r\n }\r\n}\r\n","/* eslint-disable */\r\n// noinspection JSUnusedGlobalSymbols\r\n\r\nimport { computed, inject, Signal } from \"@angular/core\";\r\nimport {\r\n patchState,\r\n signalStore,\r\n withComputed,\r\n withMethods,\r\n withState\r\n} from \"@ngrx/signals\";\r\nimport { withStorageSync } from \"@angular-architects/ngrx-toolkit\";\r\nimport { catchError, EMPTY, firstValueFrom, Observable, tap } from \"rxjs\";\r\nimport {\r\n AccessToken,\r\n AuthResponse, isRoleObject,\r\n RefreshToken,\r\n SignInBody,\r\n TokenResponse,\r\n User\r\n} from \"@hichchi/nest-connector/auth\";\r\nimport { SuccessResponse } from \"@hichchi/nest-connector\";\r\nimport { AuthService } from \"../services\";\r\nimport { Router } from \"@angular/router\";\r\n\r\n/**\r\n * Interface defining the authentication state model\r\n *\r\n * This interface represents the complete authentication state structure used\r\n * throughout the Angular application. It contains user information, authentication\r\n * tokens, and session data that persists across browser sessions.\r\n *\r\n * The state is automatically synchronized with browser storage to maintain\r\n * authentication across page refreshes and browser restarts.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Accessing state in a component\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get isSignedIn() {\r\n * return this.authState.signedIn();\r\n * }\r\n *\r\n * get currentUser() {\r\n * return this.authState.user();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthState} The signal store that manages this state\r\n * @see {@link User} Interface for user data\r\n * @see {@link AccessToken} Type for access tokens\r\n * @see {@link RefreshToken} Type for refresh tokens\r\n */\r\nexport interface AuthStateModel<Data extends object= object> {\r\n /** Whether the user is currently signed in */\r\n signedIn: boolean;\r\n /** Unique identifier for the current session */\r\n sessionId: string | null;\r\n /** Current authenticated user information */\r\n user: User | null;\r\n /** JWT access token for API authentication */\r\n accessToken: AccessToken | null;\r\n /** JWT refresh token for obtaining new access tokens */\r\n refreshToken: RefreshToken | null;\r\n /** Expiration date of the access token */\r\n accessTokenExpiresOn: Date | null;\r\n /** Expiration date of the refresh token */\r\n refreshTokenExpiresOn: Date | null;\r\n\r\n data: Data\r\n}\r\n\r\nconst initialState: AuthStateModel = {\r\n signedIn: false,\r\n sessionId: null,\r\n user: null,\r\n accessToken: null,\r\n refreshToken: null,\r\n accessTokenExpiresOn: null,\r\n refreshTokenExpiresOn: null,\r\n data: {}\r\n};\r\n\r\n/**\r\n * Authentication state management store using NgRx Signals\r\n *\r\n * This signal store provides centralized state management for authentication in Angular applications.\r\n * It manages user authentication state, tokens, and provides methods for authentication operations.\r\n * The store automatically persists state to browser storage and provides reactive computed values.\r\n *\r\n * Key features:\r\n * - Automatic state persistence with browser storage sync\r\n * - Reactive computed properties for common authentication checks\r\n * - Built-in methods for sign-in, sign-out, and token management\r\n * - Integration with Angular Router for navigation after authentication\r\n * - Type-safe state management with TypeScript\r\n *\r\n * The store is provided at the root level and can be injected into any component or service.\r\n * It uses NgRx Signals for reactive state management and provides a modern alternative\r\n * to traditional NgRx store patterns.\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class AppComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * // Access reactive state\r\n * isSignedIn = this.authState.signedIn;\r\n * currentUser = this.authState.user;\r\n * hasAccessToken = this.authState.hasAccessToken;\r\n *\r\n * // Sign in user\r\n * async signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard').subscribe({\r\n * next: (response) => console.log('Signed in:', response.user),\r\n * error: (error) => console.error('Sign in failed:', error)\r\n * });\r\n * }\r\n *\r\n * // Sign out user\r\n * signOut() {\r\n * this.authState.signOut('/login').subscribe();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a guard\r\n * export class AuthGuard {\r\n * private authState = inject(AuthState)\r\n *\r\n * canActivate(): boolean {\r\n * return this.authState.signedIn() && this.authState.hasAccessToken();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Using computed properties\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * // Reactive computed values\r\n * userRole = this.authState.role;\r\n * isEmailVerified = this.authState.emailVerified;\r\n * hasValidToken = this.authState.hasAccessToken;\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthStateModel} Interface defining the state structure\r\n * @see {@link AuthService} Service used for authentication operations\r\n * @see {@link signalStore} NgRx Signals store factory function\r\n * @see {@link withStorageSync} Storage synchronization feature\r\n */\r\nexport const AuthState = signalStore(\r\n { providedIn: \"root\" },\r\n withState<AuthStateModel>(initialState),\r\n withStorageSync({ key: \"auth\" }),\r\n withComputed(({ accessToken, user }) => ({\r\n /**\r\n * Computed signal that indicates whether a valid access token is available\r\n *\r\n * This computed property returns true if an access token exists in the state,\r\n * false otherwise. It's useful for checking authentication status and\r\n * protecting routes or UI elements.\r\n *\r\n * @returns Boolean indicating if access token exists\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get showUserMenu() {\r\n * return this.authState.hasAccessToken();\r\n * }\r\n * }\r\n * ```\r\n */\r\n hasAccessToken: computed(() => Boolean(accessToken())),\r\n\r\n /**\r\n * Computed signal that returns the current user's role object\r\n *\r\n * This computed property extracts the role from the current user object.\r\n * The role can be either a string or an object depending on the backend\r\n * implementation. Use roleName() for a consistent string representation.\r\n *\r\n * @returns The user's role object or string, or undefined if no user\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class AdminComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get userRole() {\r\n * return this.authState.role();\r\n * }\r\n * }\r\n * ```\r\n */\r\n role: computed(() => user()?.role),\r\n\r\n permissions: computed(() => {\r\n const role = user()?.role;\r\n return role && isRoleObject(role) ? role.permissions || [] : []\r\n }),\r\n\r\n /**\r\n * Computed signal that returns the current user's role name as a string\r\n *\r\n * This computed property extracts the role name from the current user,\r\n * handling both string roles and object roles with a 'name' property.\r\n * It provides a consistent string representation of the user's role.\r\n *\r\n * @returns The user's role name as a string, or undefined if no user/role\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a guard\r\n * export class AdminGuard {\r\n * private authState = inject(AuthState)\r\n *\r\n * canActivate(): boolean {\r\n * return this.authState.roleName() === 'admin';\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class UserProfileComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get displayRole() {\r\n * const roleName = this.authState.roleName();\r\n * return roleName ? roleName.charAt(0).toUpperCase() + roleName.slice(1) : 'Guest';\r\n * }\r\n * }\r\n * ```\r\n */\r\n roleName: computed(() => {\r\n const role = user()?.role\r\n return role && typeof role === \"object\" ? role.name : role\r\n }),\r\n\r\n /**\r\n * Computed signal that indicates whether the current user's email is verified\r\n *\r\n * This computed property returns true if the current user has verified their\r\n * email address, false otherwise. It's useful for conditional UI rendering\r\n * and access control based on email verification status.\r\n *\r\n * @returns Boolean indicating if user's email is verified\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class DashboardComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * get showVerificationBanner() {\r\n * return this.authState.signedIn() && !this.authState.emailVerified();\r\n * }\r\n * }\r\n * ```\r\n */\r\n emailVerified: computed((): boolean => Boolean(user()?.emailVerified)),\r\n })),\r\n withMethods((state, router = inject(Router), authService = inject(AuthService)) => ({\r\n /**\r\n * Resets the authentication state to its initial values\r\n *\r\n * This method clears all authentication data including user information,\r\n * tokens, and session data. It effectively signs out the user and resets\r\n * the state to the same condition as when the application first loads.\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a component\r\n * export class SettingsComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * clearAllData() {\r\n * this.authState.reset();\r\n * console.log('Authentication state cleared');\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In an error handler\r\n * export class ErrorHandler {\r\n * private authState = inject(AuthState)\r\n *\r\n * handleCriticalError() {\r\n * // Clear auth state on critical errors\r\n * this.authState.reset();\r\n * this.router.navigate(['/login']);\r\n * }\r\n * }\r\n * ```\r\n */\r\n reset(): void {\r\n patchState(state, initialState);\r\n },\r\n\r\n /**\r\n * Updates the authentication state with new token information\r\n *\r\n * This method updates the current authentication state with new access and\r\n * refresh tokens along with their expiration dates. It's typically used\r\n * after token refresh operations or when receiving new tokens from the server.\r\n *\r\n * @param tokenResponse - The token response containing new token information\r\n *\r\n * @example\r\n * ```typescript\r\n * // After token refresh\r\n * export class TokenService {\r\n * private authState = inject(AuthState)\r\n *\r\n * async refreshTokens() {\r\n * const tokenResponse = await this.authService.refreshToken(currentRefreshToken);\r\n * this.authState.setTokens(tokenResponse);\r\n * console.log('Tokens updated successfully');\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In an interceptor\r\n * export class AuthInterceptor {\r\n * private authState = inject(AuthState)\r\n *\r\n * handleTokenRefresh(tokenResponse: TokenResponse) {\r\n * this.authState.setTokens(tokenResponse);\r\n * // Continue with the original request\r\n * }\r\n * }\r\n * ```\r\n */\r\n setTokens(tokenResponse: TokenResponse): void {\r\n const {\r\n accessToken,\r\n refreshToken,\r\n accessTokenExpiresOn,\r\n refreshTokenExpiresOn\r\n } = tokenResponse;\r\n patchState(state, data => ({\r\n ...data,\r\n accessToken,\r\n refreshToken,\r\n accessTokenExpiresOn,\r\n refreshTokenExpiresOn,\r\n }));\r\n },\r\n\r\n /**\r\n * Authenticates a user with email/username and password\r\n *\r\n * This method handles user sign-in by calling the AuthService and updating\r\n * the authentication state with the response. It supports both Observable\r\n * and Promise return types based on the asPromise parameter, and can\r\n * automatically redirect users after successful authentication.\r\n *\r\n * The method integrates with the error notification system and can\r\n * optionally suppress error notifications for custom error handling.\r\n *\r\n * @param signInBody - The sign-in credentials containing email/username and password\r\n * @param redirect - Optional redirect path or function that returns a path after successful sign-in\r\n * @param asPromise - Optional flag to return a Promise instead of an Observable (defaults to false)\n * @param showError - Optional flag to control error notification display (defaults to true for Promise mode, false for Observable mode)\r\n * @returns Promise<AuthResponse> if asPromise is true, otherwise Observable<AuthResponse>\n *\r\n * @example\r\n * ```typescript\r\n * // Basic sign-in with Promise (default behavior)\r\n * export class LoginComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async signIn() {\r\n * try {\r\n * await this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard');\r\n * console.log('Sign-in successful');\r\n * } catch (error) {\r\n * console.error('Sign-in failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-in with Observable for reactive handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard', true).subscribe({\r\n * next: (response) => {\r\n * console.log('User signed in:', response.user);\r\n * this.handleSuccessfulSignIn(response);\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign-in failed:', error);\r\n * this.handleSignInError(error);\r\n * }\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Dynamic redirect based on user role\r\n * export class LoginComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, (response) => {\r\n * return response.user.role === 'admin' ? '/admin' : '/dashboard';\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-in with custom error handling\r\n * export class LoginComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signIn() {\r\n * this.authState.signIn({\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * }, '/dashboard', true, false).subscribe({\r\n * next: (response) => console.log('Success:', response),\r\n * error: (error) => this.showCustomError(error)\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthService.signIn} The underlying service method for authentication\r\n * @see {@link SignInBody} Interface for sign-in request data\r\n * @see {@link AuthResponse} Interface for authentication response\r\n */\r\n signIn: <AsPromise extends boolean = false>(\r\n signInBody: SignInBody,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ): AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse> => {\r\n const sub = authService.signIn(signInBody, !(showError || asPromise && showError === undefined)).pipe(\r\n tap((res: AuthResponse): void => {\r\n patchState(state, { ...res, signedIn: true });\r\n if (redirect) {\r\n void router.navigateByUrl(typeof redirect === \"string\" ? redirect : redirect(res));\r\n }\r\n }),\r\n );\r\n\r\n if (asPromise) {\r\n return firstValueFrom(sub) as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>\r\n }\r\n\r\n return sub as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n },\r\n\r\n /**\r\n * Authenticates a user using an existing access token\r\n *\r\n * This method exchanges an access token for a complete authentication response\r\n * and updates the authentication state. It's typically used after OAuth flows\r\n * (like Google sign-in) or when resuming sessions with stored tokens. The method\r\n * supports both Observable and Promise return types and can automatically redirect\r\n * users after successful authentication.\r\n *\r\n * The method integrates with the error notification system and includes error\r\n * handling that gracefully handles token validation failures.\r\n *\r\n * @param accessToken - The access token to authenticate with\r\n * @param redirect - Optional redirect path or function that returns a path after successful authentication\r\n * @param asPromise - Optional flag to return a Promise instead of an Observable (defaults to false)\n * @param showError - Optional flag to control error notification display (defaults to true for Promise mode, false for Observable mode)\r\n * @returns Promise<AuthResponse> if asPromise is true, otherwise Observable<AuthResponse>\n *\r\n * @example\r\n * ```typescript\r\n * // Basic token authentication with Promise (default behavior)\r\n * export class OAuthCallbackComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async handleCallback(token: string) {\r\n * try {\r\n * await this.authState.authenticateWithToken(token, '/dashboard');\r\n * console.log('Token authentication successful');\r\n * } catch (error) {\r\n * console.error('Token authentication failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Token authentication with Observable for reactive handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * authenticateWithToken(token: AccessToken) {\r\n * this.authState.authenticateWithToken(token, '/dashboard', true).subscribe({\r\n * next: (response) => {\r\n * console.log('User authenticated:', response.user);\r\n * this.handleSuccessfulAuth(response);\r\n * },\r\n * error: (error) => {\r\n * console.error('Token authentication failed:', error);\r\n * this.handleAuthError(error);\r\n * }\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Google OAuth integration\r\n * export class GoogleAuthComponent {\r\n * private authState = inject(AuthState)\r\n * private authService = inject(AuthService)\r\n *\r\n * async signInWithGoogle() {\r\n * try {\r\n * const accessToken = await this.authService.googleSignIn();\r\n * await this.authState.authenticateWithToken(accessToken, (response) => {\r\n * return response.user.role === 'admin' ? '/admin' : '/dashboard';\r\n * });\r\n * } catch (error) {\r\n * console.error('Google sign-in failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Token authentication with custom error handling\r\n * export class TokenAuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * authenticateWithStoredToken(token: AccessToken) {\r\n * this.authState.authenticateWithToken(token, '/dashboard', true, false).subscribe({\r\n * next: (response) => console.log('Success:', response),\r\n * error: (error) => this.handleCustomTokenError(error)\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthService.getAuthResponse} The underlying service method for token authentication\r\n * @see {@link AccessToken} Type representing access tokens\r\n * @see {@link AuthResponse} Interface for authentication response\r\n */\r\n authenticateWithToken: <AsPromise extends boolean = false>(\r\n accessToken: AccessToken,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ): AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse> => {\r\n const sub = authService.getAuthResponse(accessToken, !(showError || asPromise && showError === undefined)).pipe(\r\n tap((res: AuthResponse): void => {\r\n patchState(state, {\r\n ...res,\r\n signedIn: Boolean(res.user.role)\r\n });\r\n if (redirect) {\r\n void router.navigateByUrl(typeof redirect === \"string\" ? redirect : redirect(res));\r\n }\r\n }),\r\n catchError(() => EMPTY),\r\n );\r\n\r\n if (asPromise) {\r\n return firstValueFrom(sub) as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>\r\n }\r\n\r\n return sub as AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n },\r\n\r\n /**\r\n * Signs out the current user and clears authentication state\r\n *\r\n * This method handles user sign-out by calling the AuthService to invalidate\r\n * the session on the server and then clearing all authentication data from\r\n * the local state. It supports both Observable and Promise return types and\r\n * can automatically redirect users after successful sign-out.\r\n *\r\n * The method integrates with the error notification system and includes error\r\n * handling that ensures local state is cleared even if server sign-out fails.\r\n *\r\n * @param redirect - Optional redirect path after successful sign-out\r\n * @param asPromise - Optional flag to return a Promise instead of an Observable (defaults to false)\n * @param showError - Optional flag to control error notification display (defaults to true for Promise mode, false for Observable mode)\r\n * @returns Promise<SuccessResponse | null> if asPromise is true, otherwise Observable<SuccessResponse | null>\n *\r\n * @example\r\n * ```typescript\r\n * // Basic sign-out with Promise (default behavior)\r\n * export class HeaderComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async signOut() {\r\n * try {\r\n * await this.authState.signOut('/login');\r\n * console.log('Sign-out successful');\r\n * } catch (error) {\r\n * console.error('Sign-out failed:', error);\r\n * }\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-out with Observable for reactive handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signOut() {\r\n * this.authState.signOut('/login', true).subscribe({\r\n * next: (response) => {\r\n * console.log('Sign-out successful:', response);\r\n * this.handleSuccessfulSignOut();\r\n * },\r\n * error: (error) => {\r\n * console.error('Sign-out failed:', error);\r\n * this.handleSignOutError(error);\r\n * }\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-out without redirect\r\n * export class SettingsComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * async signOut() {\r\n * await this.authState.signOut(); // No redirect\r\n * this.showSignOutMessage();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Sign-out with custom error handling\r\n * export class AuthComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * signOut() {\r\n * this.authState.signOut('/login', true, false).subscribe({\r\n * next: (response) => console.log('Success:', response),\r\n * error: (error) => this.handleCustomSignOutError(error)\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Emergency sign-out (clear local state immediately)\r\n * export class SecurityComponent {\r\n * private authState = inject(AuthState)\r\n *\r\n * emergencySignOut() {\r\n * // Clear local state first\r\n * this.authState.reset();\r\n * // Then attempt server sign-out\r\n * this.authState.signOut('/login').catch(() => {\r\n * // Ignore server errors in emergency situations\r\n * console.log('Local state cleared, server sign-out may have failed');\r\n * });\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthService.signOut} The underlying service method for server sign-out\r\n * @see {@link SuccessResponse} Interface for success response\r\n * @see {@link reset} Method to manually clear authentication state\r\n */\r\n signOut: <AsPromise extends boolean = false>(\r\n redirect?: string,\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ): AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null> => {\r\n const sub = authService.signOut(!(showError || asPromise && showError === undefined)).pipe(\r\n tap({\r\n next: (): void => {\r\n patchState(state, initialState);\r\n if (redirect) {\r\n void router.navigateByUrl(redirect);\r\n }\r\n },\r\n }),\r\n catchError(() => EMPTY),\r\n );\r\n\r\n if (asPromise) {\r\n return firstValueFrom(sub) as AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null>;\r\n }\r\n\r\n return sub as AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null>;\r\n },\r\n\r\n setData(stateData: object): void {\r\n patchState(state, data => ({\r\n ...data,\r\n data: { ...data.data, ...stateData },\r\n }));\r\n }\r\n })),\r\n);\n\n/**\n * Public typed shape of the `AuthState` signal store.\n */\nexport type AuthState<D = unknown, R extends string = string, P extends string = string, U extends User<R, P> = User<R, P>, > = {\n signedIn: Signal<boolean>;\r\n sessionId: Signal<string | null>;\r\n user: Signal<U | null>;\r\n accessToken: Signal<AccessToken | null>;\r\n refreshToken: Signal<RefreshToken | null>;\r\n accessTokenExpiresOn: Signal<Date | null>;\r\n refreshTokenExpiresOn: Signal<Date | null>;\r\n data: Signal<D>;\r\n\r\n hasAccessToken: Signal<boolean>;\r\n role: Signal<U[\"role\"] | null | undefined>;\r\n roleName: Signal<R | null | undefined>;\r\n permissions: Signal<P[]>;\r\n emailVerified: Signal<boolean>;\r\n\r\n reset: () => void;\r\n setTokens: (tokenResponse: TokenResponse) => void;\r\n signIn: <AsPromise extends boolean = false>(\r\n signInBody: SignInBody,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ) => AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n authenticateWithToken: <AsPromise extends boolean = false>(\r\n accessToken: AccessToken,\r\n redirect?: string | ((res: AuthResponse) => string),\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ) => AsPromise extends true ? Promise<AuthResponse> : Observable<AuthResponse>;\r\n signOut: <AsPromise extends boolean = false>(\r\n redirect?: string,\r\n asPromise?: AsPromise,\r\n showError?: boolean\r\n ) => AsPromise extends true ? Promise<SuccessResponse | null> : Observable<SuccessResponse | null>;\r\n setData: (stateData: { [K in keyof D]?: D[K] }) => void\r\n}\r\n","/* eslint-disable @angular-eslint/no-output-on-prefix */\r\nimport {\r\n Component,\r\n effect,\r\n inject,\r\n input,\r\n InputSignal,\r\n output,\r\n OutputEmitterRef,\r\n signal,\r\n WritableSignal,\r\n} from \"@angular/core\";\r\nimport { FormBuilder, Validators } from \"@angular/forms\";\r\nimport { AuthField, AuthResponse, SignInBody, SignUpBody, User } from \"@hichchi/nest-connector/auth\";\r\nimport { AuthFormData } from \"../../interfaces\";\r\nimport { AuthService } from \"../../services\";\r\nimport { AUTH_CONFIG } from \"../../tokens\";\r\nimport { toFirstCase } from \"@hichchi/utils\";\r\nimport { DataFormGroup, HttpError, validatedFormData } from \"@hichchi/ngx-utils\";\r\nimport { AuthState } from \"../../state\";\r\n\r\n@Component({\r\n selector: \"hc-auth-card\",\r\n standalone: false,\r\n templateUrl: \"./auth-form.component.html\",\r\n styleUrl: \"./auth-form.component.scss\",\r\n})\r\n/**\r\n * Angular component for handling authentication forms with multiple provider support\r\n *\r\n * This component provides a comprehensive authentication interface that supports both\r\n * local authentication (sign-in/sign-up) and third-party authentication providers\r\n * (Google, Facebook). It manages form state, validation, and user interactions while\r\n * integrating with the authentication services and state management.\r\n *\r\n * The component dynamically adapts its form fields based on the authentication mode\r\n * (sign-in vs sign-up) and the configured authentication field type (email vs username).\r\n * It provides reactive form validation, loading states, error handling, and emits\r\n * events for successful authentication or errors.\r\n *\r\n * Key features:\r\n * - Local authentication with sign-in and sign-up modes\r\n * - Google OAuth integration\r\n * - Facebook authentication support (configurable)\r\n * - Dynamic form field management based on authentication mode\r\n * - Reactive form validation with Angular FormBuilder\r\n * - Loading states and error handling\r\n * - Configurable authentication field (email or username)\r\n * - Event emission for authentication success and errors\r\n * - Integration with AuthState and AuthService\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage with all providers enabled -->\r\n * <hc-auth-card\r\n * [local]=\"true\"\r\n * [google]=\"true\"\r\n * [facebook]=\"true\"\r\n * (onSignIn)=\"handleSignIn($event)\"\r\n * (onSignUp)=\"handleSignUp($event)\"\r\n * (onError)=\"handleError($event)\">\r\n * </hc-auth-card>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Local authentication only -->\r\n * <hc-auth-card\r\n * [local]=\"true\"\r\n * [google]=\"false\"\r\n * [facebook]=\"false\"\r\n * (onSignIn)=\"handleSignIn($event)\"\r\n * (onError)=\"handleError($event)\">\r\n * </hc-auth-card>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Google authentication only -->\r\n * <hc-auth-card\r\n * [local]=\"false\"\r\n * [google]=\"true\"\r\n * [facebook]=\"false\"\r\n * (onSignIn)=\"handleSignIn($event)\"\r\n * (onError)=\"handleError($event)\">\r\n * </hc-auth-card>\r\n * ```\r\n *\r\n * @see {@link AuthService} Service for handling authentication operations\r\n * @see {@link AuthState} Service for managing authentication state\r\n * @see {@link AuthConfig} Configuration interface for authentication settings\r\n * @see {@link AuthFormData} Interface defining the form data structure\r\n * @see {@link AuthResponse} Interface for authentication response data\r\n * @see {@link User} Interface for user data structure\r\n * @see {@link HttpError} Interface for HTTP error handling\r\n */\r\nexport class AuthFormComponent {\r\n private readonly config = inject(AUTH_CONFIG);\r\n\r\n private readonly fb = inject(FormBuilder);\r\n\r\n private readonly authService = inject(AuthService);\r\n\r\n /** Input signal to control whether local authentication (username/email + password) is enabled */\r\n local: InputSignal<boolean> = input(true);\r\n\r\n /** Input signal to control whether Google OAuth authentication is enabled */\r\n google: InputSignal<boolean> = input(true);\r\n\r\n /** Input signal to control whether Facebook authentication is enabled */\r\n facebook: InputSignal<boolean> = input(true);\r\n\r\n /** Output emitter that fires when an authentication error occurs */\r\n onError: OutputEmitterRef<HttpError> = output<HttpError>();\r\n\r\n /** Output emitter that fires when a user successfully signs in */\r\n onSignIn: OutputEmitterRef<AuthResponse> = output<AuthResponse>();\r\n\r\n /** Output emitter that fires when a user successfully signs up */\r\n onSignUp: OutputEmitterRef<User> = output<User>();\r\n\r\n /** Writable signal indicating whether an authentication operation is in progress */\r\n isLoading: WritableSignal<boolean> = signal(false);\r\n\r\n /** Writable signal indicating whether the form is in sign-up mode (true) or sign-in mode (false) */\r\n isSignUp: WritableSignal<boolean> = signal(false);\r\n\r\n /** Writable signal indicating whether an error state is currently active */\r\n isError: WritableSignal<boolean> = signal(false);\r\n\r\n /** Writable signal containing the current authentication field type (EMAIL or USERNAME) */\r\n authField: WritableSignal<AuthField> = signal(AuthField.EMAIL);\r\n\r\n /** Writable signal containing the display label for the authentication field */\r\n authFieldLabel: WritableSignal<string> = signal(toFirstCase(AuthField.EMAIL));\r\n\r\n /** Writable signal containing the current error object, if any */\r\n error: WritableSignal<HttpError | null> = signal<HttpError | null>(null);\r\n\r\n /** Injected AuthState service for managing authentication state */\r\n authState = inject(AuthState);\r\n\r\n /** Reactive form group for handling authentication form data */\r\n authForm: DataFormGroup<AuthFormData>;\r\n\r\n constructor() {\r\n this.authField.set(this.config.authField === AuthField.USERNAME ? AuthField.USERNAME : AuthField.EMAIL);\r\n this.authFieldLabel.set(toFirstCase(this.authField()));\r\n\r\n this.authForm = this.fb.group({\r\n firstName: [\"\", Validators.required],\r\n lastName: [\"\", Validators.required],\r\n authFieldValue: [\"\", [Validators.required]],\r\n password: [\"\", Validators.required],\r\n });\r\n\r\n effect((): void => {\r\n if (this.isSignUp()) {\r\n this.authForm.controls?.firstName?.enable();\r\n this.authForm.controls?.lastName?.enable();\r\n } else {\r\n this.authForm.controls?.firstName?.disable();\r\n this.authForm.controls?.lastName?.disable();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Handles Google OAuth sign-in authentication\r\n *\r\n * This method initiates the Google OAuth flow, retrieves an access token,\r\n * and authenticates the user with the backend service. It manages loading\r\n * states and emits appropriate events based on the authentication result.\r\n *\r\n * @returns Promise that resolves when the Google sign-in process completes\r\n *\r\n * @example\r\n * ```typescript\r\n * // Called automatically when user clicks Google sign-in button\r\n * await this.handleGoogleSignIn();\r\n * ```\r\n */\r\n async handleGoogleSignIn(): Promise<void> {\r\n const accessToken = await this.authService.googleSignIn();\r\n // noinspection ES6MissingAwait\r\n this.authState.authenticateWithToken(accessToken, undefined, false).subscribe({\r\n next: authResponse => {\r\n this.isLoading.set(false);\r\n this.onSignIn.emit(authResponse);\r\n },\r\n error: this.handleError.bind(this),\r\n });\r\n }\r\n\r\n /**\r\n * Handles local authentication sign-in process\r\n *\r\n * This method processes local authentication using username/email and password.\r\n * It sets loading and error states, then calls the AuthState service to perform\r\n * the sign-in operation.\r\n *\r\n * @param signInBody - The sign-in data containing authentication credentials\r\n *\r\n * @example\r\n * ```typescript\r\n * const signInData = {\r\n * email: 'user@example.com',\r\n * password: 'password123'\r\n * };\r\n * this.handleLocalAuth(signInData);\r\n * ```\r\n */\r\n handleLocalAuth(signInBody: SignInBody): void {\r\n this.isLoading.set(true);\r\n this.isError.set(false);\r\n\r\n this.authState.signIn(signInBody, \"/\", false).subscribe({\r\n next: () => {\r\n this.isLoading.set(false);\r\n },\r\n error: () => {\r\n this.isLoading.set(false);\r\n this.isError.set(true);\r\n },\r\n });\r\n }\r\n\r\n /**\r\n * Handles user registration (sign-up) process\r\n *\r\n * This method processes user registration with the provided sign-up data.\r\n * It sets loading and error states, calls the AuthService to create a new user,\r\n * and emits the onSignUp event upon successful registration.\r\n *\r\n * @param signUpBody - The sign-up data containing user registration information\r\n *\r\n * @example\r\n * ```typescript\r\n * const signUpData = {\r\n * firstName: 'John',\r\n * lastName: 'Doe',\r\n * email: 'john.doe@example.com',\r\n * password: 'password123'\r\n * };\r\n * this.handleSignUp(signUpData);\r\n * ```\r\n */\r\n handleSignUp(signUpBody: SignUpBody): void {\r\n this.isLoading.set(true);\r\n this.isError.set(false);\r\n\r\n this.authService.signUp(signUpBody).subscribe({\r\n next: user => {\r\n this.isLoading.set(false);\r\n this.onSignUp.emit(user);\r\n },\r\n error: this.handleError.bind(this),\r\n });\r\n }\r\n\r\n /**\r\n * Handles form submission for both sign-in and sign-up modes\r\n *\r\n * This method processes form submission by preventing the default browser behavior,\r\n * validating the form data, and routing to the appropriate authentication method\r\n * based on the current mode (sign-in or sign-up). It extracts form data and\r\n * calls either handleSignUp() or handleLocalAuth() accordingly.\r\n *\r\n * @param e - The form submit event to prevent default behavior\r\n *\r\n * @example\r\n * ```typescript\r\n * // Called automatically when form is submitted\r\n * // In template: <form (submit)=\"handleSubmit($event)\">\r\n * handleSubmit(event);\r\n * ```\r\n */\r\n handleSubmit(e: SubmitEvent): void {\r\n e.preventDefault();\r\n if (this.isSignUp()) {\r\n const formData = validatedFormData<AuthFormData>(this.authForm);\r\n if (formData) {\r\n this.handleSignUp({\r\n firstName: formData.firstName,\r\n lastName: formData.lastName,\r\n [this.authField()]: formData.authFieldValue,\r\n password: formData.password,\r\n });\r\n }\r\n } else {\r\n const formData = validatedFormData<AuthFormData>(this.authForm);\r\n if (formData) {\r\n this.handleLocalAuth({\r\n [this.authField()]: formData.authFieldValue,\r\n password: formData.password,\r\n });\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handles authentication errors and updates component state\r\n *\r\n * This method is called when any authentication operation fails. It updates\r\n * the component's loading and error states, stores the error for display,\r\n * and emits the onError event to notify parent components of the failure.\r\n *\r\n * @param error - The HTTP error object containing error details\r\n *\r\n * @example\r\n * ```typescript\r\n * // Called automatically by authentication methods on error\r\n * // Can also be called manually to handle custom errors\r\n * const customError = new HttpError('Custom error message');\r\n * this.handleError(customError);\r\n * ```\r\n */\r\n handleError(error: HttpError): void {\r\n this.isLoading.set(false);\r\n this.isError.set(true);\r\n this.error.set(error);\r\n this.onError.emit(error);\r\n }\r\n}\r\n","<hc-card>\r\n <section class=\"auth-shell\">\r\n <header class=\"auth-header\">\r\n <div class=\"auth-badge\">{{ isSignUp() ? \"Create Account\" : \"Welcome Back\" }}</div>\r\n <h2 class=\"auth-title\">{{ isSignUp() ? \"Create your account\" : \"Sign in to your account\" }}</h2>\r\n <p class=\"auth-subtitle\">\r\n {{ isSignUp() ? \"Set up your account to get started.\" : \"Use your credentials to continue.\" }}\r\n </p>\r\n </header>\r\n\r\n <form class=\"auth-form\" [formGroup]=\"authForm\" (ngSubmit)=\"handleSubmit($event)\">\r\n @if (isSignUp()) {\r\n <div class=\"auth-grid\">\r\n <div class=\"auth-field\">\r\n <label for=\"firstName\" class=\"auth-label\">First Name</label>\r\n <input\r\n id=\"firstName\"\r\n type=\"text\"\r\n class=\"auth-input\"\r\n formControlName=\"firstName\"\r\n placeholder=\"Enter your first name\"\r\n />\r\n </div>\r\n <div class=\"auth-field\">\r\n <label for=\"lastName\" class=\"auth-label\">Last Name</label>\r\n <input\r\n id=\"lastName\"\r\n type=\"text\"\r\n class=\"auth-input\"\r\n formControlName=\"lastName\"\r\n placeholder=\"Enter your last name\"\r\n />\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"auth-field\">\r\n <label for=\"authField\" class=\"auth-label\">{{ authFieldLabel() }}</label>\r\n <input\r\n id=\"authField\"\r\n type=\"text\"\r\n class=\"auth-input\"\r\n formControlName=\"authFieldValue\"\r\n [placeholder]=\"'Enter your ' + authFieldLabel().toLowerCase()\"\r\n />\r\n </div>\r\n\r\n <div class=\"auth-field\">\r\n <label for=\"password\" class=\"auth-label\">Password</label>\r\n <input\r\n id=\"password\"\r\n type=\"password\"\r\n class=\"auth-input\"\r\n formControlName=\"password\"\r\n placeholder=\"Enter your password\"\r\n />\r\n </div>\r\n\r\n <button type=\"submit\" class=\"auth-btn auth-btn-primary\">\r\n {{ isSignUp() ? (isLoading() ? \"Signing Up...\" : \"Sign Up\") : isLoading() ? \"Signing In...\" : \"Sign In\" }}\r\n </button>\r\n\r\n <button type=\"button\" class=\"auth-btn auth-btn-link\" (click)=\"isSignUp.set(!isSignUp())\">\r\n {{ isSignUp() ? \"Already have an account? Sign In\" : \"Don't have an account? Sign Up\" }}\r\n </button>\r\n\r\n @if (local() && (google() || facebook())) {\r\n <hc-separator label=\"or\"></hc-separator>\r\n }\r\n\r\n @if (google()) {\r\n <button type=\"button\" class=\"auth-btn social-btn google-btn\" (click)=\"handleGoogleSignIn()\">\r\n <div class=\"icon\"></div>\r\n Continue with Google\r\n </button>\r\n }\r\n\r\n @if (facebook()) {\r\n <button type=\"button\" class=\"auth-btn social-btn facebook-btn\">\r\n <div class=\"icon\"></div>\r\n Continue with Facebook\r\n </button>\r\n }\r\n\r\n @if (isError()) {\r\n <p class=\"error-message\">\r\n {{ error()?.error?.message || \"Something went wrong!\" }}\r\n </p>\r\n }\r\n </form>\r\n </section>\r\n</hc-card>\r\n","import { Directive, effect, inject, input, InputSignal, TemplateRef, ViewContainerRef } from \"@angular/core\";\r\nimport { isRoleObject, Role, User } from \"@hichchi/nest-connector/auth\";\r\nimport { AuthState } from \"../state\";\r\n\r\n/**\r\n * Angular structural directive for permission-based conditional rendering\r\n *\r\n * This directive conditionally displays or hides DOM elements based on the current user's permissions.\r\n * It integrates with the authentication state to check if the authenticated user has the required\r\n * permission to view the content. The directive uses Angular's structural directive pattern and\r\n * automatically updates when the user's authentication state or permissions change.\r\n *\r\n * The directive works by checking the user's role permissions against the required permission string.\r\n * If the user has the required permission, the template content is rendered; otherwise, it's removed\r\n * from the DOM.\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Basic usage - show content only if user has 'users.read' permission -->\r\n * <div *hcPermission=\"'users.read'\">\r\n * <p>This content is only visible to users with read permission</p>\r\n * </div>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Using with component properties -->\r\n * <button *hcPermission=\"'users.delete'\" (click)=\"deleteUser()\">\r\n * Delete User\r\n * </button>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Using with multiple permissions (user needs at least one) -->\r\n * <div *hcPermission=\"['users.read', 'users.write']\">\r\n * <p>This content is visible to users with either read OR write permission</p>\r\n * </div>\r\n * ```\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Using with dynamic permissions -->\r\n * <ng-container *hcPermission=\"requiredPermission\">\r\n * <app-admin-panel></app-admin-panel>\r\n * </ng-container>\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Component usage with dynamic permission\r\n * export class UserListComponent {\r\n * requiredPermission = 'users.manage';\r\n * // Or with multiple permissions\r\n * requiredPermissions = ['users.read', 'users.write'];\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthState} Authentication state service that provides user information\r\n * @see {@link User} User interface that contains role and permission information\r\n * @see {@link isRoleObject} Utility function to check if role is an object with permissions\r\n * @see {@link NgxHichchiAuthModule} Module that provides this directive\r\n */\r\n@Directive({\r\n selector: \"[hcPermission]\",\r\n})\r\nexport class PermissionDirective {\r\n /**\r\n * Template reference for the content to be conditionally rendered\r\n * @private\r\n */\r\n private templateRef = inject(TemplateRef);\r\n\r\n /**\r\n * View container reference for managing the template rendering\r\n * @private\r\n */\r\n private viewContainerRef = inject(ViewContainerRef);\r\n\r\n /**\r\n * Authentication state service for accessing current user information\r\n * @private\r\n */\r\n private authState = inject(AuthState);\r\n\r\n /**\r\n * Required permission string or array of strings input signal\r\n *\r\n * This input defines the permission(s) that the current user must have\r\n * for the template content to be displayed. The permission string(s)\r\n * should match the permissions defined in the user's role.\r\n *\r\n * When an array is provided, the user needs to have at least one of\r\n * the specified permissions (OR logic).\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Single permission -->\r\n * <div *hcPermission=\"'users.read'\">Content</div>\r\n *\r\n * <!-- Multiple permissions (user needs at least one) -->\r\n * <div *hcPermission=\"['users.read', 'users.write']\">Content</div>\r\n * ```\r\n */\r\n hcPermission: InputSignal<string | string[]> = input.required<string | string[]>();\r\n\r\n /**\r\n * Constructor that sets up the permission checking effect\r\n *\r\n * Initializes an Angular effect that automatically re-evaluates permission\r\n * whenever the authentication state or required permission changes. This\r\n * ensures the UI stays in sync with the user's current permissions.\r\n */\r\n constructor() {\r\n effect(() => {\r\n if (this.hasPermission(this.authState.user(), this.hcPermission())) {\r\n if (this.viewContainerRef.length === 0) {\r\n this.viewContainerRef.createEmbeddedView(this.templateRef);\r\n }\r\n } else {\r\n this.viewContainerRef.clear();\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Checks if the user has the required permission(s)\r\n *\r\n * This method evaluates whether the provided user has the specified permission(s)\r\n * by checking their role and associated permissions. It handles cases where\r\n * the user is null, has no role, or the role doesn't contain permissions.\r\n *\r\n * When an array of permissions is provided, the method returns true if the user\r\n * has at least one of the specified permissions (OR logic).\r\n *\r\n * @param user - The user object to check permissions for, can be null\r\n * @param requiredPermission - The permission string or array of strings that must be present in the user's role\r\n * @returns True if the user has the required permission(s), false otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * // Single permission\r\n * const hasPermission = this.hasPermission(currentUser, 'users.delete');\r\n *\r\n * // Multiple permissions (user needs at least one)\r\n * const hasAnyPermission = this.hasPermission(currentUser, ['users.read', 'users.write']);\r\n * ```\r\n *\r\n * @private\r\n */\r\n private hasPermission(user: User | null, requiredPermission: string | string[]): boolean {\r\n if (!user || !user.role) {\r\n return false;\r\n }\r\n\r\n return isRoleObject(user.role) && user.role.permissions?.length\r\n ? Array.isArray(requiredPermission)\r\n ? requiredPermission.some(permission => (user.role as Role)!.permissions?.includes(permission))\r\n : user.role.permissions.includes(requiredPermission)\r\n : false;\r\n }\r\n}\r\n","/**\n * Enumeration of authentication guard conditions\n *\n * This enum defines the different conditions that authentication guards can check\n * to determine whether a user should be allowed to access a route. Each condition\n * represents a different aspect of the user's authentication state.\n *\n * These conditions are used in conjunction with AuthGuardOption to create\n * flexible route protection rules that can handle various authentication scenarios.\n *\n * @example\n * ```typescript\n * // Check if user is signed in\n * const guardOption: AuthGuardOption = {\n * condition: AuthGuardCondition.SIGNED_IN,\n * state: true,\n * redirect: '/login'\n * };\n * ```\n *\n * @example\n * ```typescript\n * // Check if user has a valid token\n * const tokenGuardOption: AuthGuardOption = {\n * condition: AuthGuardCondition.HAS_TOKEN,\n * state: true,\n * redirect: '/unauthorized'\n * };\n * ```\n *\n * @see {@link AuthGuardOption} Interface that uses these conditions\n */\nexport enum AuthGuardCondition {\n /** Check if the user is signed in to the application */\n SIGNED_IN = \"signed-in\",\n /** Check if the user has a valid access token */\n HAS_TOKEN = \"has-token\",\n}\n","import { ActivatedRouteSnapshot } from \"@angular/router\";\r\nimport { AuthGuardOption } from \"../interfaces\";\r\nimport { AUTH_GUARD_OPTIONS_KEY } from \"../constants\";\r\n\r\n/**\r\n * Retrieves all authentication guard options from a route and its parent routes\r\n *\r\n * This utility function extracts authentication guard options from the current route\r\n * and recursively collects options from parent routes in the route hierarchy. It handles\r\n * the inheritance and merging of guard options, ensuring that parent route guards are\r\n * applied alongside child route guards.\r\n *\r\n * The function implements a hierarchical guard system where:\r\n * - Child route options take precedence over parent options for the same condition\r\n * - Parent options are inherited when no conflicting child option exists\r\n * - Options are collected recursively up the route tree\r\n * - The final array contains all applicable guard options for the route\r\n *\r\n * This enables complex authentication scenarios where different route levels can\r\n * specify different authentication requirements, with child routes able to override\r\n * or supplement parent route authentication rules.\r\n *\r\n * @param currentRoute - The activated route snapshot to extract guard options from\r\n * @returns Array of authentication guard options applicable to the route\r\n *\r\n * @example\r\n * ```typescript\r\n * // Route configuration with nested guards\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminLayoutComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, true, '/login')],\r\n * children: [\r\n * {\r\n * path: 'users',\r\n * component: UsersComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.HAS_TOKEN, true, '/unauthorized')]\r\n * }\r\n * ]\r\n * }\r\n * ];\r\n *\r\n * // In the guard, get all applicable options\r\n * const allOptions = getAllAuthGuardOptions(route);\r\n * // Result: [\r\n * // { condition: 'signed-in', state: true, redirect: '/login' },\r\n * // { condition: 'has-token', state: true, redirect: '/unauthorized' }\r\n * // ]\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Using in a custom guard implementation\r\n * export const customAuthGuard: CanActivateFn = (route, state) => {\r\n * const authState = inject(AuthState);\r\n * const router = inject(Router);\r\n *\r\n * const guardOptions = getAllAuthGuardOptions(route);\r\n *\r\n * for (const option of guardOptions) {\r\n * const conditionMet = checkAuthCondition(option.condition, authState);\r\n * if (option.state !== conditionMet) {\r\n * router.navigateByUrl(option.redirect);\r\n * return false;\r\n * }\r\n * }\r\n *\r\n * return true;\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Route hierarchy with inherited guards\r\n * const routes: Routes = [\r\n * {\r\n * path: 'app',\r\n * data: { [AUTH_GUARD_OPTIONS_KEY]: [\r\n * { condition: AuthGuardCondition.SIGNED_IN, state: true, redirect: '/login' }\r\n * ]},\r\n * children: [\r\n * {\r\n * path: 'profile',\r\n * component: ProfileComponent,\r\n * data: { [AUTH_GUARD_OPTIONS_KEY]: [\r\n * { condition: AuthGuardCondition.HAS_TOKEN, state: true, redirect: '/expired' }\r\n * ]}\r\n * }\r\n * ]\r\n * }\r\n * ];\r\n *\r\n * // When accessing /app/profile, both parent and child guards apply\r\n * ```\r\n *\r\n * @see {@link AuthGuardOption} Interface defining the structure of guard options\r\n * @see {@link AUTH_GUARD_OPTIONS_KEY} Constant for the route data key\r\n * @see {@link authGuard} Function that uses this utility to process guard options\r\n * @see {@link ActivatedRouteSnapshot} Angular router interface for route snapshots\r\n */\r\nexport const getAllAuthGuardOptions = (currentRoute: ActivatedRouteSnapshot): AuthGuardOption[] => {\r\n const options: AuthGuardOption[] = currentRoute.data?.[AUTH_GUARD_OPTIONS_KEY] || [];\r\n\r\n if (!currentRoute.parent?.data?.[AUTH_GUARD_OPTIONS_KEY]) {\r\n return options;\r\n }\r\n\r\n const parentOptions = getAllAuthGuardOptions(currentRoute.parent);\r\n for (const parentOption of parentOptions) {\r\n const currentConditionIndex = options.findIndex(option => option.condition === parentOption.condition);\r\n if (currentConditionIndex !== -1) {\r\n // skip\r\n } else {\r\n options.unshift(parentOption);\r\n }\r\n }\r\n return options;\r\n};\r\n","import { inject } from \"@angular/core\";\r\nimport { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from \"@angular/router\";\r\nimport { AuthState } from \"../state\";\r\nimport { AuthGuardOption } from \"../interfaces\";\r\nimport { AuthGuardCondition } from \"../enums\";\r\nimport { getAllAuthGuardOptions } from \"../utils\";\r\nimport { AUTH_GUARD_OPTIONS_KEY } from \"../constants\";\r\n\r\n/**\r\n * Creates an authentication guard function with multiple configuration options\r\n *\r\n * This overload accepts an array of AuthGuardOption objects, allowing for complex\r\n * authentication rules with multiple conditions. Each option can specify different\r\n * conditions, states, and redirect paths.\r\n *\r\n * @param options - Array of authentication guard options to evaluate\r\n * @returns A CanActivateFn that can be used in Angular route guards\r\n *\r\n * @example\r\n * ```typescript\r\n * // Multiple conditions guard\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [authGuard([\r\n * { condition: AuthGuardCondition.SIGNED_IN, state: true, redirect: '/login' },\r\n * { condition: AuthGuardCondition.HAS_TOKEN, state: true, redirect: '/unauthorized' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthGuardOption} Interface defining guard configuration options\r\n * @see {@link AuthGuardCondition} Enum of available authentication conditions\r\n */\r\nexport function authGuard(options: AuthGuardOption[]): CanActivateFn;\r\n\r\n/**\r\n * Creates an authentication guard function with a single condition\r\n *\r\n * This overload provides a simplified way to create guards with a single authentication\r\n * condition. It's more convenient when you only need to check one condition.\r\n *\r\n * @param condition - The authentication condition to check\r\n * @param state - The required state of the condition (true/false)\r\n * @param fallbackRedirect - The path to redirect to if the condition is not met\r\n * @returns A CanActivateFn that can be used in Angular route guards\r\n *\r\n * @example\r\n * ```typescript\r\n * // Simple signed-in guard\r\n * const routes: Routes = [\r\n * {\r\n * path: 'profile',\r\n * component: ProfileComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, true, '/login')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Redirect signed-in users away from login page\r\n * const routes: Routes = [\r\n * {\r\n * path: 'login',\r\n * component: LoginComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, false, '/dashboard')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthGuardCondition} Enum of available authentication conditions\r\n * @see {@link AuthGuardOption} Interface for more complex guard configurations\r\n */\r\nexport function authGuard(condition: AuthGuardCondition, state: boolean, fallbackRedirect: string): CanActivateFn;\r\n\r\n/**\r\n * Authentication guard factory function for Angular route protection\r\n *\r\n * This function creates a route guard that protects routes based on authentication state.\r\n * It supports both simple single-condition guards and complex multi-condition guards.\r\n * The guard evaluates authentication conditions and redirects users when conditions are not met.\r\n *\r\n * The guard integrates with the AuthState service to check the current authentication status\r\n * and uses the Angular Router for navigation when redirects are needed. It supports checking\r\n * whether users are signed in, have valid tokens, and other authentication-related conditions.\r\n *\r\n * Key features:\r\n * - Multiple authentication condition support\r\n * - Automatic redirection on failed conditions\r\n * - Integration with AuthState for reactive authentication checks\r\n * - Support for both simple and complex guard configurations\r\n * - Type-safe condition checking\r\n *\r\n * @param param - Either a single AuthGuardCondition or an array of AuthGuardOption objects\r\n * @param state - Required state for single condition (ignored when using options array)\r\n * @param fallbackRedirect - Redirect path for single condition (ignored when using options array)\r\n * @returns A CanActivateFn that evaluates authentication conditions and handles navigation\r\n *\r\n * @example\r\n * ```typescript\r\n * // Protecting a route that requires authentication\r\n * const routes: Routes = [\r\n * {\r\n * path: 'dashboard',\r\n * component: DashboardComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, true, '/login')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Complex guard with multiple conditions\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [authGuard([\r\n * { condition: AuthGuardCondition.SIGNED_IN, state: true, redirect: '/login' },\r\n * { condition: AuthGuardCondition.HAS_TOKEN, state: true, redirect: '/unauthorized' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Preventing authenticated users from accessing login page\r\n * const routes: Routes = [\r\n * {\r\n * path: 'login',\r\n * component: LoginComponent,\r\n * canActivate: [authGuard(AuthGuardCondition.SIGNED_IN, false, '/dashboard')]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthState} Service that provides authentication state information\r\n * @see {@link AuthGuardOption} Interface for configuring guard options\r\n * @see {@link AuthGuardCondition} Enum defining available authentication conditions\r\n * @see {@link getAllAuthGuardOptions} Utility function for extracting guard options from routes\r\n * @see {@link AUTH_GUARD_OPTIONS_KEY} Constant for storing guard options in route data\r\n */\r\nexport function authGuard(\r\n param: AuthGuardCondition | AuthGuardOption[],\r\n state?: boolean,\r\n fallbackRedirect?: string,\r\n): CanActivateFn {\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n return async (route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Promise<boolean> => {\r\n const router = inject(Router);\r\n const authState = inject(AuthState);\r\n\r\n route.data = {\r\n ...route.data,\r\n [AUTH_GUARD_OPTIONS_KEY]: Array.isArray(param)\r\n ? param\r\n : [{ condition: param, state: state!, redirect: fallbackRedirect! }],\r\n };\r\n\r\n const conditionCheckers = {\r\n [AuthGuardCondition.SIGNED_IN]: authState.signedIn,\r\n [AuthGuardCondition.HAS_TOKEN]: authState.hasAccessToken,\r\n };\r\n\r\n const authGuardOptions = getAllAuthGuardOptions(route);\r\n\r\n if (!authGuardOptions.length) {\r\n return true;\r\n }\r\n\r\n const conditionsMet = authGuardOptions.every(option => {\r\n return option.state === conditionCheckers[option.condition]();\r\n });\r\n\r\n if (!conditionsMet) {\r\n const option = authGuardOptions.pop()!;\r\n const redirectPath = option.redirect.startsWith(\"/\") ? option.redirect : `/${option.redirect}`;\r\n await router.navigateByUrl(redirectPath);\r\n return false;\r\n }\r\n\r\n return true;\r\n };\r\n}\r\n","// noinspection JSUnusedGlobalSymbols\r\n\r\nimport { inject } from \"@angular/core\";\r\nimport { ActivatedRouteSnapshot, CanActivateFn, Router, RouterStateSnapshot } from \"@angular/router\";\r\nimport { AuthState } from \"../state\";\r\nimport { RoleGuardOption } from \"../interfaces\";\r\n\r\n/**\r\n * Creates a role-based authorization guard function for Angular route protection\r\n *\r\n * This function creates a route guard that protects routes based on user roles.\r\n * It checks if the current user's role matches the required role, and if not,\r\n * it evaluates the provided options to determine the appropriate action (redirect\r\n * or sign out).\r\n *\r\n * The guard integrates with the AuthState service to check the current user's role\r\n * and uses the Angular Router for navigation when redirects are needed. If no\r\n * matching role or redirect option is found, the user is automatically signed out.\r\n *\r\n * Key features:\r\n * - Role-based route protection\r\n * - Configurable redirect options based on user roles\r\n * - Automatic sign-out for unauthorized access\r\n * - Integration with AuthState for reactive role checking\r\n * - Support for multiple role-based redirect scenarios\r\n *\r\n * @param role - The required role name that the user must have to access the route\r\n * @param options - Array of role guard options that define redirect behavior for different user roles\r\n * @returns A CanActivateFn that evaluates role-based authorization and handles navigation\r\n *\r\n * @example\r\n * ```typescript\r\n * // Protecting an admin route\r\n * const routes: Routes = [\r\n * {\r\n * path: 'admin',\r\n * component: AdminComponent,\r\n * canActivate: [roleGuard('admin', [\r\n * { state: 'user', redirect: '/dashboard' },\r\n * { state: 'moderator', redirect: '/moderator-panel' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Protecting a moderator route with fallback redirects\r\n * const routes: Routes = [\r\n * {\r\n * path: 'moderate',\r\n * component: ModeratorComponent,\r\n * canActivate: [roleGuard('moderator', [\r\n * { state: 'user', redirect: '/unauthorized' },\r\n * { state: 'guest', redirect: '/login' }\r\n * ])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // Simple role guard without specific redirects (will sign out unauthorized users)\r\n * const routes: Routes = [\r\n * {\r\n * path: 'super-admin',\r\n * component: SuperAdminComponent,\r\n * canActivate: [roleGuard('super-admin', [])]\r\n * }\r\n * ];\r\n * ```\r\n *\r\n * @see {@link AuthState} Service that provides authentication and role state information\r\n * @see {@link RoleGuardOption} Interface for configuring role-based redirect options\r\n */\r\nexport function roleGuard(role: string, options: RoleGuardOption[]): CanActivateFn {\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n return async (_route: ActivatedRouteSnapshot, _state: RouterStateSnapshot): Promise<boolean> => {\r\n const router = inject(Router);\r\n const authState = inject(AuthState);\r\n\r\n if (!options.length) {\r\n return true;\r\n }\r\n\r\n for await (const option of options) {\r\n if (role === authState.roleName()) {\r\n return true;\r\n } else if (option.state === authState.roleName()) {\r\n const redirectPath = option.redirect.startsWith(\"/\") ? option.redirect : `/${option.redirect}`;\r\n await router.navigateByUrl(redirectPath);\r\n return false;\r\n }\r\n }\r\n\r\n await authState.signOut(\"/auth\", true);\r\n\r\n return false;\r\n };\r\n}\r\n","import { HttpEvent, HttpHandlerFn, HttpInterceptorFn, HttpRequest } from \"@angular/common/http\";\r\nimport { catchError, filter, Observable, ReplaySubject, switchMap, take, throwError } from \"rxjs\";\r\nimport { AccessToken, AuthEndpoint, AuthErrorResponseCode, TokenResponse } from \"@hichchi/nest-connector/auth\";\r\nimport { Endpoint, ErrorResponseCode, HttpClientErrorStatus } from \"@hichchi/nest-connector\";\r\nimport { inject } from \"@angular/core\";\r\nimport { Router } from \"@angular/router\";\r\nimport { HttpError } from \"@hichchi/ngx-utils\";\r\nimport { AuthState } from \"../state\";\r\nimport { AuthService } from \"../services\";\r\n\r\n/**\r\n * Array of authentication error codes that should trigger token refresh instead of immediate redirect\r\n *\r\n * These error codes indicate authentication issues that can potentially be resolved\r\n * by refreshing the access token. When these errors are encountered, the interceptor\r\n * will attempt to refresh the token before redirecting the user to the login page.\r\n *\r\n * @example\r\n * ```typescript\r\n * // The interceptor checks if the error code is in this array\r\n * if (SKIPPED_ERRORS.includes(error.error?.code)) {\r\n * // Attempt token refresh instead of immediate redirect\r\n * return refreshToken(req, next);\r\n * }\r\n * ```\r\n *\r\n * @see {@link AuthErrorResponseCode} Enum containing all authentication error codes\r\n * @see {@link authInterceptor} Function that uses this array for error handling\r\n */\r\nexport const SKIPPED_ERRORS: ErrorResponseCode[] = [\r\n AuthErrorResponseCode.AUTH_401_EXPIRED_TOKEN,\r\n AuthErrorResponseCode.AUTH_401_INVALID_TOKEN,\r\n AuthErrorResponseCode.AUTH_401_NOT_LOGGED_IN,\r\n];\r\n\r\n/**\r\n * Flag to prevent multiple simultaneous token refresh operations\r\n *\r\n * This global flag ensures that only one token refresh operation can be in progress\r\n * at any given time. This prevents race conditions and duplicate refresh requests\r\n * when multiple HTTP requests fail simultaneously due to expired tokens.\r\n *\r\n * @private\r\n */\r\nlet refreshingInProgress = false;\r\n\r\n/**\r\n * Checks if an HTTP request is a token refresh request\r\n *\r\n * This utility function determines whether the given HTTP request is attempting\r\n * to refresh authentication tokens. This is important to avoid intercepting\r\n * and modifying token refresh requests themselves, which could cause infinite loops.\r\n *\r\n * @param req - The HTTP request to check\r\n * @returns True if the request is a token refresh request, false otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * // Used in the interceptor to avoid processing refresh token requests\r\n * if (!isRefreshTokenReq(req)) {\r\n * // Apply authentication logic\r\n * }\r\n * ```\r\n *\r\n * @private\r\n * @see {@link AuthEndpoint.REFRESH_TOKEN} Endpoint constant for token refresh\r\n * @see {@link Endpoint.AUTH} Base authentication endpoint\r\n */\r\nconst isRefreshTokenReq = (req: HttpRequest<unknown>): boolean =>\r\n req.url.includes(`${Endpoint.AUTH}/${AuthEndpoint.REFRESH_TOKEN}`);\r\n\r\n/**\r\n * Subject for coordinating token refresh operations across multiple HTTP requests\r\n *\r\n * This ReplaySubject is used to coordinate token refresh operations when multiple\r\n * HTTP requests fail simultaneously due to expired tokens. It ensures that all\r\n * waiting requests receive the new token once the refresh operation completes.\r\n *\r\n * The subject emits the new access token when refresh succeeds, or an error when\r\n * refresh fails. It uses ReplaySubject to ensure late subscribers still receive\r\n * the last emitted value.\r\n *\r\n * @private\r\n * @see {@link ReplaySubject} RxJS subject type used for token coordination\r\n * @see {@link AccessToken} Type representing access tokens\r\n */\r\nlet tokenSubject: ReplaySubject<AccessToken | null> = new ReplaySubject<AccessToken | null>(1);\r\n\r\n/**\r\n * Creates an HTTP interceptor for handling authentication tokens and automatic token refresh\r\n *\r\n * This interceptor automatically adds authentication tokens to outgoing HTTP requests\r\n * and handles token refresh when requests fail due to expired tokens. It provides\r\n * seamless authentication management for Angular applications using JWT tokens.\r\n *\r\n * Key features:\r\n * - Automatic token attachment to HTTP requests\r\n * - Automatic token refresh on authentication errors\r\n * - Prevention of multiple simultaneous refresh operations\r\n * - Coordinated handling of multiple failed requests during token refresh\r\n * - Automatic redirect to login page when refresh fails\r\n * - Configurable redirect behavior with optional callback\r\n *\r\n * The interceptor works by:\r\n * 1. Adding the current access token to outgoing requests\r\n * 2. Monitoring responses for authentication errors\r\n * 3. Attempting token refresh when authentication errors occur\r\n * 4. Retrying failed requests with the new token\r\n * 5. Redirecting to login when refresh fails or no refresh token is available\r\n *\r\n * @param redirect - The path to redirect to when authentication fails completely\r\n * @param onRedirect - Optional callback function to execute before redirecting\r\n * @returns An HttpInterceptorFn that can be used in Angular HTTP interceptor configuration\r\n *\r\n * @example\r\n * ```typescript\r\n * // Basic usage in app configuration\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(\r\n * withInterceptors([\r\n * authInterceptor('/login')\r\n * ])\r\n * )\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // With custom redirect callback\r\n * export const appConfig: ApplicationConfig = {\r\n * providers: [\r\n * provideHttpClient(\r\n * withInterceptors([\r\n * authInterceptor('/login', () => {\r\n * console.log('Redirecting to login due to authentication failure');\r\n * // Clear any cached data\r\n * localStorage.clear();\r\n * })\r\n * ])\r\n * )\r\n * ]\r\n * };\r\n * ```\r\n *\r\n * @example\r\n * ```typescript\r\n * // In a module-based application\r\n * @NgModule({\r\n * providers: [\r\n * {\r\n * provide: HTTP_INTERCEPTORS,\r\n * useValue: authInterceptor('/auth/login'),\r\n * multi: true\r\n * }\r\n * ]\r\n * })\r\n * export class AppModule {}\r\n * ```\r\n *\r\n * @see {@link AuthState} Service that provides authentication state and tokens\r\n * @see {@link AuthService} Service that handles token refresh operations\r\n * @see {@link HttpInterceptorFn} Angular HTTP interceptor function type\r\n * @see {@link SKIPPED_ERRORS} Array of error codes that trigger token refresh\r\n */\r\nexport function authInterceptor(redirect: string, onRedirect?: () => void): HttpInterceptorFn {\r\n return (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {\r\n const authState = inject(AuthState);\r\n const authService = inject(AuthService);\r\n const router = inject(Router);\r\n\r\n const setAccessToken = (req: HttpRequest<unknown>, accessToken: AccessToken): HttpRequest<unknown> => {\r\n return req.clone({\r\n headers: req.headers.set(\"Authorization\", `Bearer ${accessToken}`),\r\n });\r\n };\r\n\r\n const gotoSignIn = (): void => {\r\n onRedirect?.();\r\n authState.reset();\r\n // eslint-disable-next-line no-void\r\n void router.navigateByUrl(redirect);\r\n };\r\n\r\n const refreshToken = (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {\r\n if (!refreshingInProgress) {\r\n refreshingInProgress = true;\r\n tokenSubject.next(null);\r\n\r\n const refreshToken = authState.refreshToken();\r\n\r\n if (!refreshToken) {\r\n refreshingInProgress = false;\r\n gotoSignIn();\r\n return throwError(() => new Error(\"Refresh token not found.\"));\r\n }\r\n\r\n return authService.refreshToken(refreshToken).pipe(\r\n switchMap((tokenResponse: TokenResponse) => {\r\n authState.setTokens(tokenResponse);\r\n tokenSubject.next(tokenResponse.accessToken);\r\n tokenSubject.complete();\r\n tokenSubject = new ReplaySubject<AccessToken | null>(1);\r\n refreshingInProgress = false;\r\n return next(setAccessToken(req, tokenResponse.accessToken));\r\n }),\r\n catchError((error: HttpError) => {\r\n refreshingInProgress = false;\r\n tokenSubject.error(error);\r\n tokenSubject.complete();\r\n tokenSubject = new ReplaySubject<AccessToken | null>(1);\r\n gotoSignIn();\r\n return throwError(() => error);\r\n }),\r\n );\r\n }\r\n\r\n return tokenSubject.pipe(\r\n filter(result => result !== null),\r\n take(1),\r\n switchMap(token => {\r\n return next(setAccessToken(req, token));\r\n }),\r\n );\r\n };\r\n\r\n const handleRequest = (req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> => {\r\n return next(req).pipe(\r\n catchError((error: HttpError) => {\r\n if (\r\n error.status === HttpClientErrorStatus.UNAUTHORIZED &&\r\n error.error?.code &&\r\n SKIPPED_ERRORS.includes(error.error?.code) &&\r\n !isRefreshTokenReq(req)\r\n ) {\r\n if (authState.signedIn()) {\r\n return refreshToken(req, next);\r\n }\r\n }\r\n return throwError(() => error);\r\n }),\r\n );\r\n };\r\n\r\n if (authState.accessToken()) {\r\n const tokenizedRequest = req.clone({\r\n headers: req.headers.set(\"Authorization\", `Bearer ${authState.accessToken()}`),\r\n });\r\n return handleRequest(tokenizedRequest, next);\r\n }\r\n return handleRequest(req, next);\r\n };\r\n}\r\n","import { ModuleWithProviders, NgModule } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport { FormsModule, ReactiveFormsModule } from \"@angular/forms\";\nimport { AuthFormComponent } from \"./components\";\nimport { PermissionDirective } from \"./directives\";\nimport { AuthService } from \"./services\";\nimport { AuthConfig } from \"./interfaces\";\nimport { AUTH_CONFIG } from \"./tokens\";\nimport { ButtonComponent, HcCardComponent, HcSeparatorComponent } from \"@hichchi/ngx-ui\";\nimport { prependSubdomainToUrlBrowser } from \"@hichchi/ngx-utils\";\n\n/**\n * Angular module for authentication functionality\n *\n * This module provides comprehensive authentication features for Angular applications,\n * including authentication forms, permission-based directives, and authentication services.\n * It integrates with the Hichchi authentication system and provides both components\n * and directives for building secure Angular applications.\n *\n * The module exports:\n * - AuthFormComponent: A ready-to-use authentication form component\n * - PermissionDirective: A structural directive for permission-based conditional rendering\n *\n * The module must be configured using the forRoot() method to provide the necessary\n * authentication configuration.\n *\n * API base URL handling:\n * - `apiBaseURL` defines the base API host for auth requests.\n * - Optional `prependSubdomain` lets you prepend a subdomain to `apiBaseURL`.\n * - `string`: uses the provided subdomain\n * - `true`: resolves subdomain dynamically from the current host context\n * - `false` / `undefined`: keeps `apiBaseURL` unchanged\n *\n * @example\n * ```typescript\n * // Basic module configuration\n * @NgModule({\n * imports: [\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: 'https://api.example.com'\n * })\n * ]\n * })\n * export class AppModule { }\n * ```\n *\n * @example\n * ```typescript\n * // Advanced configuration with custom authentication field\n * @NgModule({\n * imports: [\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: 'https://api.example.com',\n * authField: AuthField.EMAIL\n * })\n * ]\n * })\n * export class AppModule { }\n * ```\n *\n * @example\n * ```typescript\n * // Configuration with a static subdomain\n * @NgModule({\n * imports: [\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: 'https://api.example.com',\n * prependSubdomain: 'tenant-a'\n * })\n * ]\n * })\n * export class AppModule { }\n * ```\n *\n * @example\n * ```typescript\n * // Configuration with dynamic subdomain resolution\n * @NgModule({\n * imports: [\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: 'https://api.example.com',\n * prependSubdomain: true\n * })\n * ]\n * })\n * export class AppModule { }\n * ```\n *\n * @see {@link AuthConfig} Configuration interface for the authentication module\n * @see {@link AuthFormComponent} Authentication form component\n * @see {@link PermissionDirective} Permission-based conditional rendering directive\n * @see {@link AuthService} Authentication service for managing user sessions\n */\n@NgModule({\n declarations: [AuthFormComponent],\n imports: [\n CommonModule,\n FormsModule,\n ReactiveFormsModule,\n ButtonComponent,\n HcCardComponent,\n HcSeparatorComponent,\n PermissionDirective,\n ],\n exports: [AuthFormComponent, PermissionDirective],\n})\n/**\n * Root module for reusable authentication UI, directives, and providers.\n */\nexport class NgxHichchiAuthModule {\n /**\n * Configures the NgxHichchiAuthModule with the provided authentication configuration\n *\n * This static method sets up the module with the necessary providers and configuration\n * for authentication functionality. Before providers are created, `apiBaseURL` is normalized\n * through `prependSubdomainToApi(config.apiBaseURL, config.prependSubdomain)`.\n * It then provides the AuthService and authentication configuration token required\n * for the module to function properly.\n *\n * `prependSubdomain` behavior:\n * - `string`: prepend that subdomain to the API host\n * - `true`: derive subdomain dynamically from the current host context\n * - `false` / `undefined`: do not prepend a subdomain\n *\n * @param config - The authentication configuration object containing API endpoints and settings\n * @returns A ModuleWithProviders object configured with authentication providers\n *\n * @example\n * ```typescript\n * // Basic configuration\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: 'https://api.example.com'\n * })\n * ```\n *\n * @example\n * ```typescript\n * // Configuration with environment variables and authentication field\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: environment.apiUrl,\n * authField: AuthField.USERNAME\n * })\n * ```\n *\n * @example\n * ```typescript\n * // Static subdomain\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: 'https://api.example.com',\n * prependSubdomain: 'tenant-a'\n * })\n * ```\n *\n * @example\n * ```typescript\n * // Dynamic subdomain\n * NgxHichchiAuthModule.forRoot({\n * apiBaseURL: 'https://api.example.com',\n * prependSubdomain: true\n * })\n * ```\n *\n * @see {@link AuthConfig} Interface defining the configuration structure\n * @see {@link AUTH_CONFIG} Injection token for the authentication configuration\n * @see {@link AuthService} Service that uses the provided configuration\n * @see {@link prependSubdomainToUrlBrowser} Utility used to transform `apiBaseURL`\n */\n static forRoot(config: AuthConfig): ModuleWithProviders<NgxHichchiAuthModule> {\n config.apiBaseURL = prependSubdomainToUrlBrowser(config.apiBaseURL, config.splitDomain, config.devSubdomain);\n\n return {\n ngModule: NgxHichchiAuthModule,\n providers: [{ provide: AUTH_CONFIG, useValue: config }, AuthService],\n };\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"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"}
|