@pvway/alpha-oas
Version:
Professional Angular 20+ OAuth2 authentication and authorization library. Provides robust session and refresh token management, secure HTTP interceptors, strongly-typed user and principal models, and full support for standalone components and signals. Des
1 lines • 59.6 kB
Source Map (JSON)
{"version":3,"file":"pvway-alpha-oas.mjs","sources":["../../../projects/alpha-oas/src/lib/alpha-oas-abstractions.ts","../../../projects/alpha-oas/src/lib/alpha-principal.ts","../../../projects/alpha-oas/src/lib/alpha-session-data.ts","../../../projects/alpha-oas/src/lib/alpha-refresh-data.ts","../../../projects/alpha-oas/src/lib/alpha-user.ts","../../../projects/alpha-oas/src/lib/alpha-auth-envelop.ts","../../../projects/alpha-oas/src/lib/alpha-oas.service.ts","../../../projects/alpha-oas/src/lib/alpha-oas-interceptor.ts","../../../projects/alpha-oas/src/public-api.ts","../../../projects/alpha-oas/src/pvway-alpha-oas.ts"],"sourcesContent":["/**\r\n * Represents the authentication status of the principal.\r\n * Used to track the current state in OAuth flows.\r\n */\r\nexport enum AlphaAuthStatusEnum {\r\n Undefined,\r\n Anonymous,\r\n Authenticating,\r\n Refreshing,\r\n Authenticated\r\n}\r\n\r\n/**\r\n * Represents a user in the authentication system.\r\n * Contains identity, language, and custom properties.\r\n */\r\nexport interface IAlphaUser {\r\n /** Unique identifier for the user. */\r\n userId: string;\r\n /** Username or display name. */\r\n username: string;\r\n /** Language code for localization. */\r\n languageCode: string;\r\n /** Custom user properties. */\r\n properties: Map<string, any>\r\n}\r\n\r\n/**\r\n * Envelope containing authentication tokens and user information.\r\n * Used for exchanging authentication data between client and backend.\r\n */\r\nexport interface IAlphaAuthEnvelop {\r\n /** Access token for API requests. */\r\n accessToken: string;\r\n /** Token expiry duration in seconds. */\r\n expiresIn: number;\r\n /** Refresh token for renewing access. */\r\n refreshToken: string;\r\n /** Authenticated user information. */\r\n user: IAlphaUser;\r\n}\r\n\r\n/**\r\n * Represents the principal (current authentication context).\r\n * Tracks status, user, language, and authentication flags.\r\n */\r\nexport interface IAlphaPrincipal {\r\n /** Current authentication status. */\r\n status: AlphaAuthStatusEnum;\r\n /** Authenticated user or null if anonymous. */\r\n user: IAlphaUser | null;\r\n /** Session language code. */\r\n languageCode: string;\r\n /** True if authenticated. */\r\n isAuthenticated: boolean;\r\n /** True if anonymous. */\r\n isAnonymous: boolean;\r\n /** True if currently authenticating. */\r\n isAuthenticating: boolean;\r\n /** Sets the session language code. */\r\n setSessionLanguageCode(lc: string): void;\r\n}\r\n","// noinspection JSUnresolvedReference\r\n\r\nimport {AlphaAuthStatusEnum, IAlphaPrincipal, IAlphaUser} from \"./alpha-oas-abstractions\";\r\n\r\n/**\r\n * Represents the authentication principal for the current session.\r\n * Tracks authentication status, user identity, and session language.\r\n *\r\n * Responsibilities:\r\n * - Maintains the current authentication status (anonymous, authenticating, authenticated, etc.).\r\n * - Stores and manages the authenticated user object.\r\n * - Persists and retrieves the session language code for localization and HTTP header enrichment.\r\n * - Provides flags for authentication state (isAuthenticated, isAnonymous, isAuthenticating).\r\n * - Supports clearing user identity and session language on sign-out.\r\n *\r\n * Usage:\r\n * - Used by authentication services to manage and expose principal state.\r\n * - Interacts with browser sessionStorage for language code persistence.\r\n */\r\nexport class AlphaPrincipal implements IAlphaPrincipal {\r\n /**\r\n * Current authentication status of the principal.\r\n */\r\n private mStatus: AlphaAuthStatusEnum;\r\n /**\r\n * Gets the current authentication status.\r\n */\r\n get status(): AlphaAuthStatusEnum {\r\n return this.mStatus;\r\n }\r\n /**\r\n * Sets the authentication status.\r\n * @param status - New authentication status.\r\n */\r\n setStatus(status: AlphaAuthStatusEnum): void {\r\n this.mStatus = status;\r\n }\r\n\r\n /**\r\n * Current authenticated user, or null if anonymous.\r\n */\r\n private mUser: IAlphaUser | null;\r\n /**\r\n * Gets the current user object, or null if not authenticated.\r\n */\r\n get user(): IAlphaUser | null {\r\n return this.mUser;\r\n }\r\n /**\r\n * Sets the current user and updates the session language code.\r\n * @param user - Authenticated user object.\r\n */\r\n setUser(user: IAlphaUser): void {\r\n this.mUser = user;\r\n this.setSessionLanguageCode(user.languageCode);\r\n }\r\n /**\r\n * Persists the session language code for localization and HTTP header enrichment.\r\n * @param lc - Language code to persist.\r\n */\r\n setSessionLanguageCode(lc: string): void {\r\n // interceptor will use this value for inserting\r\n // the language-code header on each outgoing request\r\n sessionStorage.setItem('alphaLanguageCode', lc);\r\n }\r\n /**\r\n * Clears the user identity and removes the session language code from storage.\r\n */\r\n clearUser(): void {\r\n this.mUser = null;\r\n sessionStorage.removeItem('alphaLanguageCode');\r\n }\r\n\r\n /**\r\n * Gets the current session language code.\r\n * Returns the user's language if authenticated, or falls back to sessionStorage or browser language.\r\n */\r\n get languageCode(): string {\r\n if (this.mUser) {\r\n return this.mUser.languageCode;\r\n }\r\n const lsLc = sessionStorage.getItem('alphaLanguageCode');\r\n if (lsLc) {\r\n return lsLc;\r\n }\r\n const nav = window.navigator as any;\r\n const userLang = (nav.language || nav.userLanguage) as string;\r\n return userLang\r\n ? userLang.substring(0, 2).toLowerCase()\r\n : 'en';\r\n }\r\n\r\n /**\r\n * True if the principal is authenticated.\r\n */\r\n get isAuthenticated(): boolean {\r\n return this.mStatus === AlphaAuthStatusEnum.Authenticated;\r\n }\r\n\r\n /**\r\n * True if the principal is anonymous (not authenticated).\r\n */\r\n get isAnonymous(): boolean {\r\n return this.mStatus === AlphaAuthStatusEnum.Undefined\r\n || this.mStatus === AlphaAuthStatusEnum.Anonymous;\r\n }\r\n\r\n /**\r\n * True if the principal is in the process of authenticating or refreshing.\r\n */\r\n get isAuthenticating(): boolean {\r\n return this.mStatus === AlphaAuthStatusEnum.Authenticating\r\n || this.mStatus === AlphaAuthStatusEnum.Refreshing;\r\n }\r\n\r\n /**\r\n * Constructs a new principal with undefined status and no user.\r\n */\r\n constructor() {\r\n this.mStatus = AlphaAuthStatusEnum.Undefined;\r\n this.mUser = null;\r\n }\r\n\r\n}\r\n","/**\r\n * Represents the session token data for OAuth authentication.\r\n *\r\n * Responsibilities:\r\n * - Stores, retrieves, and clears session token and metadata in browser storage.\r\n * - Tracks token reception and expiration timestamps for validity checks.\r\n * - Provides static methods for managing session token lifecycle.\r\n * - Used by authentication services to persist and access session tokens securely.\r\n *\r\n * Usage:\r\n * - Call `store()` to persist the session token and metadata in storage.\r\n * - Use `retrieve()` to get the session token and metadata from storage.\r\n * - Use `clear()` to remove the session token and metadata from storage on sign-out.\r\n * - Use `isExpiredOrExpiring` to check if the token is near expiration.\r\n * - Use `getTimestamps()` to calculate reception and expiration timestamps from expiry duration.\r\n */\r\nexport class AlphaSessionData {\r\n /**\r\n * Storage key for the rememberMe flag.\r\n */\r\n private static readonly rememberMeFieldName = 'alphaRememberMe';\r\n /**\r\n * Storage key for the access token.\r\n */\r\n private static readonly accessTokenFieldName = 'alphaAccessToken';\r\n /**\r\n * Storage key for the token reception timestamp.\r\n */\r\n private static readonly receptionTsFieldName = 'alphaReceptionTs';\r\n /**\r\n * Storage key for the token expiration timestamp.\r\n */\r\n private static readonly expirationTsFieldName = 'alphaExpirationTs';\r\n\r\n /**\r\n * Indicates if the user chose \"remember me\" during authentication.\r\n */\r\n rememberMe: boolean;\r\n /**\r\n * The access token string.\r\n */\r\n accessToken: string;\r\n /**\r\n * Timestamp of token reception in milliseconds.\r\n */\r\n receptionTs: number;\r\n /**\r\n * Timestamp of token expiration in milliseconds.\r\n */\r\n expirationTs: number;\r\n\r\n /**\r\n * Returns true if the token is expired or will expire within 60 seconds.\r\n */\r\n get isExpiredOrExpiring(): boolean {\r\n const nowTs = new Date().getTime();\r\n return this.expirationTs - nowTs < 60000;\r\n }\r\n\r\n /**\r\n * Constructs a new AlphaSessionData instance with the given properties.\r\n * @param rememberMe - Indicates if \"remember me\" was selected.\r\n * @param accessToken - The access token string.\r\n * @param receptionTs - Timestamp of token reception in ms.\r\n * @param expirationTs - Timestamp of token expiration in ms.\r\n */\r\n constructor(\r\n rememberMe: boolean,\r\n accessToken: string,\r\n receptionTs: number, // timestamp of token reception in ms\r\n expirationTs: number) {\r\n this.rememberMe = rememberMe;\r\n this.accessToken = accessToken;\r\n this.receptionTs = receptionTs;\r\n this.expirationTs = expirationTs;\r\n }\r\n\r\n /**\r\n * Calculates reception and expiration timestamps from expiry duration in seconds.\r\n * @param expiresIn - Expiry duration in seconds.\r\n * @returns Object containing receptionTs and expirationTs in ms.\r\n */\r\n static getTimestamps(expiresIn: number): {\r\n receptionTs: number,\r\n expirationTs: number\r\n } {\r\n const receptionTs = new Date().getTime();\r\n const expirationTs = receptionTs + expiresIn * 1000;\r\n return {\r\n receptionTs,\r\n expirationTs\r\n };\r\n }\r\n\r\n /**\r\n * Retrieves the session data from storage and returns an AlphaSessionData instance.\r\n * @param mStorage - Storage object to use (default: browser sessionStorage).\r\n * @returns AlphaSessionData instance if data exists, otherwise null.\r\n */\r\n static retrieve(mStorage: Storage = sessionStorage): AlphaSessionData | null {\r\n const rmString = mStorage\r\n .getItem(AlphaSessionData.rememberMeFieldName);\r\n if (rmString == null) return null;\r\n\r\n const rm = rmString === 'true';\r\n\r\n const at = mStorage\r\n .getItem(AlphaSessionData.accessTokenFieldName) ?? '';\r\n\r\n const rTsString = mStorage\r\n .getItem(AlphaSessionData.receptionTsFieldName) ?? '0';\r\n const rTs = parseInt(rTsString, 10);\r\n\r\n const xTsString = mStorage\r\n .getItem(AlphaSessionData.expirationTsFieldName) ?? '0';\r\n const xTs = parseInt(xTsString, 10);\r\n\r\n return new AlphaSessionData(rm, at, rTs, xTs);\r\n }\r\n\r\n /**\r\n * Removes the session data from storage.\r\n * @param mStorage - Storage object to use (default: browser sessionStorage).\r\n */\r\n static clear(mStorage: Storage = sessionStorage): void {\r\n mStorage.removeItem(AlphaSessionData.rememberMeFieldName);\r\n mStorage.removeItem(AlphaSessionData.accessTokenFieldName);\r\n mStorage.removeItem(AlphaSessionData.receptionTsFieldName);\r\n mStorage.removeItem(AlphaSessionData.expirationTsFieldName);\r\n }\r\n\r\n /**\r\n * Stores the session data in storage.\r\n * @param mStorage - Storage object to use (default: browser sessionStorage).\r\n */\r\n store(mStorage: Storage = sessionStorage): void {\r\n mStorage.setItem(\r\n AlphaSessionData.rememberMeFieldName, this.rememberMe.toString());\r\n mStorage.setItem(\r\n AlphaSessionData.accessTokenFieldName, this.accessToken);\r\n mStorage.setItem(\r\n AlphaSessionData.receptionTsFieldName, this.receptionTs.toString());\r\n mStorage.setItem(\r\n AlphaSessionData.expirationTsFieldName, this.expirationTs.toString());\r\n }\r\n\r\n}\r\n","/**\r\n * Represents the refresh token data for OAuth authentication.\r\n *\r\n * Responsibilities:\r\n * - Stores, retrieves, and clears the refresh token in browser storage.\r\n * - Provides static methods for managing refresh token lifecycle.\r\n * - Used by authentication services to persist and access refresh tokens securely.\r\n *\r\n * Usage:\r\n * - Call `store()` to persist the refresh token in storage.\r\n * - Use `retrieve()` to get the refresh token from storage.\r\n * - Use `clear()` to remove the refresh token from storage on sign-out.\r\n */\r\nexport class AlphaRefreshData {\r\n /**\r\n * The key used to store the refresh token in browser storage.\r\n */\r\n private static readonly refreshTokenFieldName = 'alphaRefreshToken';\r\n\r\n /**\r\n * The refresh token string.\r\n */\r\n refreshToken: string;\r\n\r\n /**\r\n * Constructs a new AlphaRefreshData instance with the given refresh token.\r\n * @param refreshToken - The refresh token string.\r\n */\r\n constructor(\r\n refreshToken: string) {\r\n this.refreshToken = refreshToken;\r\n }\r\n\r\n /**\r\n * Retrieves the refresh token from storage and returns an AlphaRefreshData instance.\r\n * @param mStorage - Storage object to use (default: browser localStorage).\r\n * @returns AlphaRefreshData instance if token exists, otherwise null.\r\n */\r\n static retrieve(mStorage: Storage = localStorage): AlphaRefreshData | null {\r\n const rt = mStorage\r\n .getItem(AlphaRefreshData.refreshTokenFieldName);\r\n if (rt == null) {\r\n return null;\r\n }\r\n return new AlphaRefreshData(rt);\r\n }\r\n\r\n /**\r\n * Removes the refresh token from storage.\r\n * @param mStorage - Storage object to use (default: browser localStorage).\r\n */\r\n static clear(mStorage: Storage = localStorage): void {\r\n mStorage.removeItem(AlphaRefreshData.refreshTokenFieldName);\r\n }\r\n\r\n /**\r\n * Stores the refresh token in storage.\r\n * @param mStorage - Storage object to use (default: browser localStorage).\r\n */\r\n store(mStorage: Storage = localStorage): void {\r\n mStorage.setItem(\r\n AlphaRefreshData.refreshTokenFieldName,\r\n this.refreshToken);\r\n }\r\n\r\n}\r\n","// noinspection JSUnresolvedReference\r\n\r\nimport {IAlphaUser} from \"./alpha-oas-abstractions\";\r\n\r\n/**\r\n * Factory for creating IAlphaUser instances from a raw data source object (DSO).\r\n * Converts backend user responses into strongly-typed user objects.\r\n *\r\n * Usage:\r\n * - Call `factorFromDso()` with a DSO to get an IAlphaUser instance.\r\n */\r\nexport class AlphaUserFactory {\r\n /**\r\n * Converts a raw DSO into an IAlphaUser instance.\r\n * @param dso - The raw user data source object, typically from an API response.\r\n * @returns A strongly-typed user object implementing IAlphaUser.\r\n */\r\n static factorFromDso(dso: any): IAlphaUser {\r\n const ds = new DsoSlicer(dso);\r\n return new AlphaUser(ds.SingleFragment);\r\n }\r\n}\r\n\r\n/**\r\n * Represents a single user fragment extracted from the DSO.\r\n * Contains userId, username, language code, and custom properties.\r\n */\r\ninterface SingleFragment {\r\n userId: string;\r\n username: string;\r\n languageCode: string;\r\n properties: Map<string, any>\r\n}\r\n\r\n/**\r\n * Utility class for extracting user fragments from a raw DSO.\r\n * Used internally by the factory to map backend fields to user properties.\r\n */\r\nclass DsoSlicer {\r\n private _dso: any;\r\n /**\r\n * Initializes the slicer with a raw data source object.\r\n * @param dso - The raw user data source object.\r\n */\r\n constructor(dso: any) {\r\n this._dso = dso;\r\n }\r\n\r\n /**\r\n * Extracts and maps user properties from the DSO to a SingleFragment.\r\n */\r\n get SingleFragment(): SingleFragment {\r\n const propertyArray =\r\n Object.entries(this._dso.userProperties);\r\n return {\r\n userId: this._dso.userId,\r\n username: this._dso.username,\r\n languageCode: this._dso.languageCode,\r\n properties: new Map(propertyArray)\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Concrete implementation of IAlphaUser.\r\n * Encapsulates user identity, language, and custom properties.\r\n */\r\nclass AlphaUser implements IAlphaUser {\r\n userId: string;\r\n username: string;\r\n languageCode: string;\r\n properties: Map<string, any>;\r\n\r\n /**\r\n * Constructs a user object from a SingleFragment.\r\n * @param f0 - The user fragment containing all required properties.\r\n */\r\n constructor(\r\n f0: SingleFragment) {\r\n this.userId = f0.userId;\r\n this.username = f0.username;\r\n this.languageCode = f0.languageCode;\r\n this.properties = f0.properties;\r\n }\r\n\r\n}\r\n","// noinspection JSUnresolvedReference\r\n\r\nimport { AlphaUserFactory } from './alpha-user';\r\nimport {IAlphaAuthEnvelop, IAlphaUser} from \"./alpha-oas-abstractions\";\r\n\r\n// FACTORY\r\n/**\r\n * Factory class for creating authentication envelope instances from a raw data source object (DSO).\r\n * Provides a static method to convert backend authentication responses into a strongly-typed envelope.\r\n */\r\nexport class AlphaAuthEnvelopFactory {\r\n /**\r\n * Converts a raw DSO into an IAlphaAuthEnvelop instance.\r\n * @param dso - The raw authentication data source object, typically from an API response.\r\n * @returns A strongly-typed authentication envelope implementing IAlphaAuthEnvelop.\r\n */\r\n static factorFromDso(dso: any): IAlphaAuthEnvelop {\r\n const ds = new DsoSlicer(dso);\r\n return new AuthEnvelop(ds.SingleFragment);\r\n }\r\n}\r\n\r\n// FRAGMENTS\r\n/**\r\n * Represents a single authentication fragment extracted from the DSO.\r\n * Contains access token, expiry, refresh token, and user information.\r\n */\r\ninterface SingleFragment {\r\n accessToken: string;\r\n expiresIn: number;\r\n refreshToken: string;\r\n user: IAlphaUser;\r\n}\r\n\r\n// DSO SLICER\r\n/**\r\n * Utility class for extracting authentication fragments from a raw DSO.\r\n * Used internally by the factory to map backend fields to envelope properties.\r\n */\r\nclass DsoSlicer {\r\n private _dso: any;\r\n /**\r\n * Initializes the slicer with a raw data source object.\r\n * @param dso - The raw authentication data source object.\r\n */\r\n constructor(dso: any) {\r\n this._dso = dso;\r\n }\r\n\r\n /**\r\n * Extracts and maps authentication properties from the DSO to a SingleFragment.\r\n */\r\n get SingleFragment(): SingleFragment {\r\n return {\r\n accessToken: this._dso.access_token,\r\n expiresIn: this._dso.expires_in,\r\n refreshToken: this._dso.refresh_token,\r\n user: AlphaUserFactory.factorFromDso(this._dso.user)\r\n };\r\n }\r\n\r\n}\r\n\r\n// CONCRETES\r\n/**\r\n * Concrete implementation of IAlphaAuthEnvelop.\r\n * Encapsulates authentication tokens and user information.\r\n */\r\nclass AuthEnvelop implements IAlphaAuthEnvelop {\r\n accessToken: string;\r\n expiresIn: number;\r\n refreshToken: string;\r\n user: IAlphaUser;\r\n\r\n /**\r\n * Constructs an authentication envelope from a SingleFragment.\r\n * @param f0 - The authentication fragment containing all required properties.\r\n */\r\n constructor(\r\n f0: SingleFragment) {\r\n this.accessToken = f0.accessToken;\r\n this.expiresIn = f0.expiresIn;\r\n this.refreshToken = f0.refreshToken;\r\n this.user = f0.user;\r\n }\r\n}\r\n","import {Injectable} from '@angular/core';\r\nimport {HttpClient, HttpErrorResponse, HttpHeaders} from \"@angular/common/http\";\r\nimport {AlphaPrincipal} from \"./alpha-principal\";\r\nimport {catchError, map, mergeMap, Observable, Subscriber, throwError} from \"rxjs\";\r\nimport {AlphaSessionData} from \"./alpha-session-data\";\r\nimport {AlphaRefreshData} from \"./alpha-refresh-data\";\r\nimport {AlphaAuthEnvelopFactory} from \"./alpha-auth-envelop\";\r\nimport {AlphaUserFactory} from \"./alpha-user\";\r\nimport {\r\n AlphaAuthStatusEnum, IAlphaAuthEnvelop,\r\n IAlphaPrincipal, IAlphaUser\r\n} from \"./alpha-oas-abstractions\";\r\n\r\n/**\r\n * AlphaOasService provides authentication and authorization logic for OAuth-based flows.\r\n * Handles sign-in, token refresh, user retrieval, and principal state management.\r\n *\r\n * Key Features:\r\n * - Supports custom implementations for sign-in, refresh, and authorize via injection methods.\r\n * - Manages session and refresh tokens using browser storage.\r\n * - Emits principal updates and error logs via callback functions.\r\n * - Designed for use as a singleton service (providedIn: 'root').\r\n *\r\n * Usage:\r\n * - Call `init()` to initialize the service with required URLs, HttpClient, and optional callbacks/storage.\r\n * - Use `signIn()`, `refresh()`, and `getMe()` for authentication flows.\r\n * - Use `authorize()` to wrap protected HTTP requests.\r\n * - Listen for principal updates via the `onPrincipalUpdated` callback.\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class AlphaOasService {\r\n /**\r\n * HttpClient instance for making HTTP requests. Set via init().\r\n */\r\n private mHttp: HttpClient | undefined;\r\n /**\r\n * Service context string for error logging.\r\n */\r\n private readonly mContext = 'OAuthService';\r\n /**\r\n * Principal representing the current authenticated user and status.\r\n */\r\n private readonly mPrincipal: AlphaPrincipal;\r\n /**\r\n * OAuth endpoint URLs. Set via init().\r\n */\r\n private mSignInUrl: string | undefined;\r\n private mRefreshUrl: string | undefined;\r\n private mGetMeUrl: string | undefined;\r\n /**\r\n * Storage objects for session and refresh tokens. Default to browser storage, can be injected.\r\n */\r\n private mSessionStorage: Storage = sessionStorage;\r\n private mLocalStorage: Storage = localStorage;\r\n /**\r\n * Callback for principal updates. Set via init().\r\n */\r\n private mOnPrincipalUpdated: (principal: AlphaPrincipal) => any = () => {};\r\n /**\r\n * Callback for error logging. Set via init().\r\n */\r\n private mPostErrorLog: (context: string, method: string, error: string) => any = () => {};\r\n\r\n /**\r\n * Returns the current principal (user and status).\r\n */\r\n get principal(): IAlphaPrincipal {\r\n return this.mPrincipal;\r\n }\r\n\r\n /**\r\n * Constructs the service and initializes the principal.\r\n */\r\n constructor() {\r\n this.mPrincipal = new AlphaPrincipal();\r\n }\r\n\r\n /**\r\n * Initializes the service with required dependencies and URLs.\r\n * Determines authentication state from session/refresh storage, or sets anonymous mode.\r\n *\r\n * @param httpClient - Angular HttpClient instance.\r\n * @param getMeUrl - URL for retrieving user info.\r\n * @param refreshUrl - URL for token refresh.\r\n * @param signInUrl - URL for sign-in.\r\n * @param postErrorLog - Optional error logging callback.\r\n * @param onPrincipalUpdated - Optional principal update callback.\r\n * @param sStorage - Optional session storage (default: browser sessionStorage).\r\n * @param lStorage - Optional local storage (default: browser localStorage).\r\n * @returns Observable emitting the result of initialization.\r\n */\r\n init(\r\n httpClient: HttpClient,\r\n getMeUrl?: string,\r\n refreshUrl?: string,\r\n signInUrl?: string,\r\n postErrorLog?: (context: string, method: string, error: string) => any,\r\n onPrincipalUpdated?: (principal: IAlphaPrincipal) => any,\r\n sStorage: Storage = sessionStorage,\r\n lStorage: Storage = localStorage\r\n ): Observable<string> {\r\n\r\n this.mHttp = httpClient;\r\n this.mSignInUrl = signInUrl;\r\n this.mRefreshUrl = refreshUrl;\r\n this.mGetMeUrl = getMeUrl;\r\n this.initStorage(sStorage, lStorage);\r\n\r\n if (postErrorLog) {\r\n this.mPostErrorLog = postErrorLog;\r\n }\r\n if (onPrincipalUpdated) {\r\n this.mOnPrincipalUpdated = onPrincipalUpdated;\r\n }\r\n\r\n // let's first see if there is still a session data\r\n const sd = AlphaSessionData.retrieve(sStorage);\r\n if (sd != null) {\r\n return this.initFromSd();\r\n }\r\n\r\n // then check if there is a refresh data available\r\n const rd = AlphaRefreshData.retrieve(lStorage);\r\n if (rd != null) {\r\n return this.initFromRd();\r\n }\r\n\r\n // no sd and no rd found let's start as anonymous\r\n return this.initAsAnonymous();\r\n }\r\n\r\n /**\r\n * Sets the session and local storage objects used for token management.\r\n * @param sStorage - Session storage.\r\n * @param lStorage - Local storage.\r\n */\r\n initStorage(sStorage: Storage, lStorage: Storage): void {\r\n this.mSessionStorage = sStorage;\r\n this.mLocalStorage = lStorage;\r\n }\r\n\r\n /**\r\n * Initializes authentication from session data (if present).\r\n * @returns Observable emitting result string.\r\n */\r\n private initFromSd(): Observable<string> {\r\n console.log('Sd found... calling getMe');\r\n return new Observable(\r\n (subscriber: Subscriber<string>) => {\r\n this.getMe().subscribe({\r\n next: () => subscriber.next('principal reloaded'),\r\n error: e => subscriber.error(e)\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Initializes authentication from refresh data (if present).\r\n * @returns Observable emitting result string.\r\n */\r\n private initFromRd(): Observable<string> {\r\n return new Observable(\r\n (subscriber: Subscriber<string>) => {\r\n console.log('rd active... calling refresh');\r\n this.mPrincipal.setStatus(AlphaAuthStatusEnum.Refreshing);\r\n this.refresh().subscribe({\r\n next: refreshed => {\r\n if (refreshed) {\r\n subscriber.next('identity refreshed');\r\n } else {\r\n this.mPrincipal.setStatus(AlphaAuthStatusEnum.Anonymous);\r\n subscriber.next('refresh failed');\r\n }\r\n },\r\n error: (e: any) => {\r\n subscriber.error(e);\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Initializes authentication in anonymous mode (no session/refresh data).\r\n * @returns Observable emitting result string.\r\n */\r\n private initAsAnonymous(): Observable<string> {\r\n return new Observable(\r\n (subscriber: Subscriber<string>) => {\r\n this.mPrincipal.setStatus(AlphaAuthStatusEnum.Anonymous);\r\n subscriber.next('anonymous');\r\n });\r\n }\r\n\r\n /**\r\n * Allows injection of a custom sign-in implementation.\r\n * @param signIn - Function implementing sign-in logic.\r\n */\r\n useSignIn(\r\n signIn: (\r\n userName: string,\r\n password: string,\r\n rememberMe: boolean\r\n ) => Observable<IAlphaAuthEnvelop>\r\n ): void {\r\n this.internalSignIn = signIn;\r\n }\r\n\r\n /**\r\n * Allows injection of a custom refresh implementation.\r\n * @param refresh - Function implementing refresh logic.\r\n */\r\n useRefresh(refresh: (refreshToken: string) => Observable<IAlphaAuthEnvelop>) {\r\n this.internalRefresh = refresh;\r\n }\r\n\r\n /**\r\n * Allows injection of a custom authorize implementation.\r\n * @param authorize - Function implementing authorization logic.\r\n */\r\n useAuthorize(authorize: (request: Observable<any>) => Observable<any>): void {\r\n this.internalAuthorize = authorize;\r\n }\r\n\r\n /**\r\n * Default sign-in implementation. Can be overridden via useSignIn().\r\n * @param username - User name.\r\n * @param password - User password.\r\n * @param rememberMe - Whether to persist refresh token.\r\n * @returns Observable emitting authentication envelope.\r\n */\r\n internalSignIn: (\r\n userName: string,\r\n password: string,\r\n rememberMe: boolean\r\n ) => Observable<IAlphaAuthEnvelop> =\r\n (username: string, password: string) => {\r\n\r\n if (this.mHttp === undefined) {\r\n throw new Error('service is not initialized');\r\n }\r\n\r\n const body = 'grant_type=password' +\r\n '&username=' + encodeURIComponent(username) +\r\n '&password=' + encodeURIComponent(password);\r\n\r\n const headers = new HttpHeaders()\r\n .set('content-type', 'application/x-www-form-urlencoded');\r\n\r\n const url = this.mSignInUrl!;\r\n return this.mHttp!\r\n .post<any>(url, body, {headers: headers})\r\n .pipe(\r\n map(dso =>\r\n AlphaAuthEnvelopFactory.factorFromDso(dso)),\r\n catchError(error => {\r\n this.mPostErrorLog(this.mContext,\r\n '_signIn', JSON.stringify(error));\r\n return throwError(() => error);\r\n }));\r\n }\r\n\r\n /**\r\n * On successful login call storeIdentity.\r\n * Remark: there is no need to call getMe from signIn as getMe\r\n * is actually returning the same data as signIn\r\n * @param username\r\n * @param password\r\n * @param rememberMe\r\n */\r\n signIn(\r\n username: string,\r\n password: string,\r\n rememberMe: boolean): Observable<boolean> {\r\n\r\n return new Observable<boolean>(\r\n (subscriber: Subscriber<boolean>) => {\r\n this.internalSignIn(username, password, rememberMe)\r\n .subscribe({\r\n next: (token: IAlphaAuthEnvelop) => {\r\n this.storeIdentity(token, rememberMe);\r\n subscriber.next(true);\r\n },\r\n error: (e: HttpErrorResponse) => {\r\n this.signOut();\r\n if (e.status === 400 || e.status === 401) {\r\n subscriber.next(false);\r\n } else {\r\n this.mPostErrorLog(\r\n this.mContext, 'login', JSON.stringify(e))\r\n subscriber.error(e);\r\n }\r\n }\r\n });\r\n return;\r\n });\r\n }\r\n\r\n /**\r\n * Default refresh implementation. Can be overridden via useRefresh().\r\n * @param refreshToken - Refresh token string.\r\n * @returns Observable emitting authentication envelope.\r\n */\r\n internalRefresh: (refreshToken: string) => Observable<IAlphaAuthEnvelop> =\r\n (refreshToken: string) => {\r\n\r\n if (this.mHttp === undefined) {\r\n throw new Error('service is not initialized');\r\n }\r\n\r\n const body = 'grant_type=refresh_token' +\r\n '&refresh_token=' + encodeURIComponent(refreshToken);\r\n\r\n const headers = new HttpHeaders()\r\n .set('content-type', 'application/x-www-form-urlencoded');\r\n\r\n const url = this.mRefreshUrl!;\r\n return this.mHttp!.post<any>(url, body, {headers: headers})\r\n .pipe(\r\n map(dso =>\r\n AlphaAuthEnvelopFactory.factorFromDso(dso)));\r\n }\r\n\r\n /**\r\n * Refreshes the access token using the refresh token from local storage.\r\n * Emits true on success, false on authentication error, or errors for other failures.\r\n * @returns Observable emitting boolean result.\r\n */\r\n refresh(): Observable<boolean> {\r\n\r\n const rd =\r\n AlphaRefreshData.retrieve(this.mLocalStorage);\r\n if (rd == null) {\r\n this.mPostErrorLog(this.mContext,\r\n 'refresh', 'rd should not be null');\r\n return throwError(\r\n () => 'rd should not be null');\r\n }\r\n\r\n return new Observable<boolean>(\r\n (subscriber: Subscriber<boolean>) => {\r\n this.internalRefresh(rd.refreshToken)\r\n .subscribe({\r\n next: (token: IAlphaAuthEnvelop) => {\r\n this.storeIdentity(token, true);\r\n subscriber.next(true);\r\n },\r\n error: (e: HttpErrorResponse) => {\r\n this.signOut();\r\n if (e.status == 401) {\r\n subscriber.next(false);\r\n } else {\r\n this.mPostErrorLog(this.mContext,\r\n 'refresh', JSON.stringify(e));\r\n subscriber.error(e);\r\n }\r\n }\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * called from the init() method when the session data is present\r\n */\r\n getMe(): Observable<IAlphaUser> {\r\n if (!this.mHttp) {\r\n throw new Error('service is not initialized');\r\n }\r\n const url = this.mGetMeUrl!;\r\n const call = this.mHttp.get<any>(url)\r\n .pipe(\r\n map(\r\n dso => {\r\n const user = AlphaUserFactory.factorFromDso(dso);\r\n this.populatePrincipal(user);\r\n return user;\r\n }),\r\n catchError((error: HttpErrorResponse) => {\r\n this.mPostErrorLog(this.mContext, url,\r\n JSON.stringify(error));\r\n return throwError(() => error);\r\n }));\r\n\r\n return this.authorize(call);\r\n }\r\n\r\n /**\r\n * Edits the principal's user info and emits principal update.\r\n * @param firstName - New first name.\r\n * @param lastName - New last name.\r\n * @param languageCode - New language code.\r\n */\r\n editUserInfo(\r\n firstName: string,\r\n lastName: string,\r\n languageCode: string): void {\r\n if (!this.mPrincipal.user) {\r\n return;\r\n }\r\n this.mPrincipal.user.username = firstName + \" \" + lastName;\r\n this.mPrincipal.user.languageCode = languageCode;\r\n\r\n this.mOnPrincipalUpdated(this.mPrincipal)\r\n }\r\n\r\n /**\r\n * Signs out the user, clears tokens and principal, and emits principal update.\r\n */\r\n signOut(): void {\r\n AlphaSessionData.clear(this.mSessionStorage);\r\n AlphaRefreshData.clear(this.mLocalStorage);\r\n this.mPrincipal.clearUser();\r\n this.mPrincipal.setStatus(AlphaAuthStatusEnum.Anonymous);\r\n this.mOnPrincipalUpdated(this.mPrincipal);\r\n }\r\n\r\n /**\r\n * Default authorization implementation. Can be overridden via useAuthorize().\r\n * Checks token validity and refreshes if needed before firing request.\r\n * @param httpRequest - Observable HTTP request to authorize.\r\n * @returns Observable emitting the result of the request.\r\n */\r\n internalAuthorize(\r\n httpRequest: Observable<any>): Observable<any> {\r\n const sd =\r\n AlphaSessionData.retrieve(this.mSessionStorage);\r\n if (sd == null || sd.isExpiredOrExpiring) {\r\n return this.refresh()\r\n .pipe(\r\n mergeMap(() => httpRequest),\r\n catchError(error => {\r\n this.mPostErrorLog(this.mContext,\r\n '_authorize', JSON.stringify(error));\r\n return throwError(() => error)\r\n }\r\n ));\r\n } else {\r\n return httpRequest;\r\n }\r\n }\r\n\r\n /**\r\n * Wraps a protected HTTP request with authorization logic.\r\n * @param httpRequest - Observable HTTP request to authorize.\r\n * @returns Observable emitting the result of the request.\r\n */\r\n authorize(\r\n httpRequest: Observable<any>): Observable<any> {\r\n return this.internalAuthorize(httpRequest);\r\n }\r\n\r\n /**\r\n * (1) stores the access token in the session storage\r\n * (2) stores the refresh token in the local storage\r\n * (3) populates the principal using the user info\r\n */\r\n storeIdentity(\r\n authEnvelop: IAlphaAuthEnvelop,\r\n rememberMe: boolean): void {\r\n\r\n const ts = AlphaSessionData\r\n .getTimestamps(authEnvelop.expiresIn);\r\n\r\n const sd = new AlphaSessionData(\r\n true, authEnvelop.accessToken,\r\n ts.receptionTs, ts.expirationTs);\r\n sd.store(this.mSessionStorage);\r\n console.log('sd populated');\r\n\r\n if (rememberMe) {\r\n const rd = new AlphaRefreshData(\r\n authEnvelop.refreshToken);\r\n rd.store(this.mLocalStorage);\r\n console.log('rd populated');\r\n }\r\n\r\n this.populatePrincipal(authEnvelop.user);\r\n }\r\n\r\n /**\r\n * Populates the principal with user info and emits principal update.\r\n * @param user - User object.\r\n */\r\n private populatePrincipal(user: IAlphaUser) {\r\n this.mPrincipal.setUser(user);\r\n console.log('principal user is set');\r\n this.mPrincipal.setStatus(AlphaAuthStatusEnum.Authenticated);\r\n this.mOnPrincipalUpdated(this.mPrincipal);\r\n }\r\n\r\n}\r\n","import {HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpHandlerFn} from '@angular/common/http';\r\nimport { Observable } from 'rxjs';\r\nimport { v4 as uuidV4 } from 'uuid';\r\nimport { AlphaSessionData } from \"./alpha-session-data\";\r\n\r\n/**\r\n * HTTP interceptor for OAuth authentication and client identification.\r\n *\r\n * Responsibilities:\r\n * - Adds language, client, and authorization headers to outgoing requests.\r\n * - Generates and persists a unique client ID per browser.\r\n * - Retrieves and attaches access tokens from session storage.\r\n * - Supports custom storage injection for testing or advanced scenarios.\r\n *\r\n * Usage:\r\n * - Use as a provider for HTTP_INTERCEPTORS in Angular.\r\n * - Call `initStorage()` to override default browser storage if needed.\r\n * - Use static `handlerFn()` for functional interceptors in Angular 16+.\r\n */\r\nexport class AlphaOasInterceptor implements HttpInterceptor {\r\n /**\r\n * Session storage for language and access token. Defaults to browser sessionStorage.\r\n */\r\n private mSessionStorage: Storage = sessionStorage;\r\n /**\r\n * Local storage for client ID. Defaults to browser localStorage.\r\n */\r\n private mLocalStorage: Storage = localStorage;\r\n\r\n /**\r\n * Allows injection of custom storage objects for session and local storage.\r\n * Useful for testing or non-browser environments.\r\n * @param sStorage - Session storage object (default: browser sessionStorage).\r\n * @param lStorage - Local storage object (default: browser localStorage).\r\n */\r\n initStorage(\r\n sStorage: Storage = sessionStorage,\r\n lStorage: Storage = localStorage): void {\r\n this.mSessionStorage = sStorage;\r\n this.mLocalStorage = lStorage;\r\n }\r\n\r\n /**\r\n * Intercepts outgoing HTTP requests and enriches them with authentication and client headers.\r\n * @param req - The outgoing HTTP request.\r\n * @param next - The next handler in the interceptor chain.\r\n * @returns Observable emitting the HTTP event stream.\r\n */\r\n intercept(req: HttpRequest<any>, next: HttpHandler):\r\n Observable<HttpEvent<any>> {\r\n const eReq =\r\n AlphaOasInterceptor.enrichReq(\r\n req, this.mSessionStorage, this.mLocalStorage);\r\n return next.handle(eReq);\r\n }\r\n\r\n /**\r\n * Functional interceptor handler for Angular 16+.\r\n * Allows direct injection of storage for advanced scenarios or testing.\r\n * @param req - The outgoing HTTP request.\r\n * @param next - The next handler function.\r\n * @param sStorage - Session storage object (default: browser sessionStorage).\r\n * @param lStorage - Local storage object (default: browser localStorage).\r\n * @returns Observable emitting the HTTP event stream.\r\n */\r\n static handlerFn(\r\n req: HttpRequest<any>,\r\n next: HttpHandlerFn,\r\n sStorage: Storage = sessionStorage,\r\n lStorage: Storage = localStorage): Observable<HttpEvent<any>> {\r\n const eReq = this.enrichReq(req, sStorage, lStorage);\r\n return next(eReq);\r\n }\r\n\r\n /**\r\n * Enriches an HTTP request with language, client, and authorization headers.\r\n * - Adds 'language-code' header based on session or browser language.\r\n * - Adds 'client-id' header, generating and persisting a UUID if needed.\r\n * - Adds 'authorization' header if an access token is present in session storage.\r\n * @param req - The original HTTP request.\r\n * @param sStorage - Session storage object.\r\n * @param lStorage - Local storage object.\r\n * @returns The enriched HTTP request.\r\n */\r\n private static enrichReq(\r\n req: HttpRequest<any>,\r\n sStorage: Storage,\r\n lStorage: Storage): HttpRequest<any> {\r\n\r\n let headers = req.headers;\r\n\r\n // getting languageCode\r\n // set by the principal when setting the user\r\n let languageCode = sStorage.getItem('alphaLanguageCode');\r\n if (!languageCode) {\r\n const nav = window.navigator as any;\r\n const userLang = (nav.language || nav.userLanguage) as string;\r\n languageCode = userLang\r\n ? userLang.substring(0, 2)?.toLowerCase()\r\n : 'en';\r\n sStorage.setItem('alphaLanguageCode', languageCode);\r\n }\r\n\r\n // always add the language-code header\r\n headers = headers.append('language-code', languageCode);\r\n\r\n /**\r\n * the ClientId (client-id header) identifies the client.\r\n * There will be one client-id for each browser.\r\n * With this in place it will be possible to\r\n * map a new user to his browsing history\r\n * ClientId is only generated once and stored in\r\n * the browser localstorage associated to the url\r\n */\r\n let clientId = lStorage.getItem('alphaClientId');\r\n if (clientId == null)\r\n {\r\n clientId = uuidV4();\r\n lStorage.setItem('alphaClientId', clientId!);\r\n }\r\n // always add the client-id header\r\n headers = headers.append('client-id', clientId!);\r\n\r\n /**\r\n * when an accessToken is present insert the authorization header\r\n * using the accessToken with the bearer scheme\r\n */\r\n const sd = AlphaSessionData.retrieve(sStorage);\r\n const token = sd?.accessToken;\r\n if (token) {\r\n headers = headers.append(\r\n 'authorization',\r\n `bearer ${token}`);\r\n }\r\n\r\n return req.clone({ headers });\r\n }\r\n\r\n}\r\n","/*\r\n * Public API Surface of alpha-oas\r\n */\r\n\r\nexport * from './lib/alpha-oas-abstractions';\r\nexport * from './lib/alpha-oas.service';\r\nexport * from './lib/alpha-user';\r\nexport * from './lib/alpha-auth-envelop';\r\nexport * from './lib/alpha-principal';\r\nexport * from './lib/alpha-oas-interceptor';\r\nexport * from './lib/alpha-session-data';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["DsoSlicer","uuidV4"],"mappings":"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