@cauca-911/core
Version:
Run `npm install @cauca-911/core` to add this library to your project
1 lines • 150 kB
Source Map (JSON)
{"version":3,"file":"cauca-911-core.mjs","sources":["../../../projects/cauca-core/src/lib/shared/models/log-level.enum.ts","../../../projects/cauca-core/src/lib/shared/models/core-module-options.ts","../../../projects/cauca-core/src/lib/shared/classes/configuration.ts","../../../projects/cauca-core/src/lib/cauca-core.service.ts","../../../projects/cauca-core/src/lib/cauca-core.component.ts","../../../projects/cauca-core/src/lib/cauca-core.component.html","../../../projects/cauca-core/src/lib/shared/constants/cauca-core-module-options.ts","../../../projects/cauca-core/src/lib/cauca-page-not-found/cauca-page-not-found.component.ts","../../../projects/cauca-core/src/lib/cauca-page-not-found/cauca-page-not-found.component.html","../../../projects/cauca-core/src/lib/shared/interceptors/interceptor-error.service.ts","../../../projects/cauca-core/src/lib/shared/interceptors/http-offline-interceptor.ts","../../../projects/cauca-core/src/lib/shared/models/http-error.ts","../../../projects/cauca-core/src/lib/shared/decorators/debounce.ts","../../../projects/cauca-core/src/lib/shared/services/log.service.ts","../../../projects/cauca-core/src/lib/shared/services/refresh-token.service.ts","../../../projects/cauca-core/src/lib/shared/services/http-token-provider.ts","../../../projects/cauca-core/src/lib/shared/interceptors/http-token-writer-interceptor.ts","../../../projects/cauca-core/src/lib/shared/interceptors/http-token-reader-interceptor.ts","../../../projects/cauca-core/src/lib/shared/interceptors/http-error-interceptor.ts","../../../projects/cauca-core/src/lib/shared/ngx-translate/custom-missing-translation-handler.ts","../../../projects/cauca-core/src/lib/shared/ngx-translate/custom-multi-translate-http-loader.ts","../../../projects/cauca-core/src/lib/shared/services/translate.service.ts","../../../projects/cauca-core/src/lib/cauca-core.module.ts","../../../projects/cauca-core/src/lib/cauca-core-for-child.module.ts","../../../projects/cauca-core/src/lib/shared/services/api-lookup.service.ts","../../../projects/cauca-core/src/lib/shared/classes/network-estimates.ts","../../../projects/cauca-core/src/lib/shared/services/network-information.service.ts","../../../projects/cauca-core/src/lib/cauca-core-testing.module.ts","../../../projects/cauca-core/src/lib/shared/classes/browser.ts","../../../projects/cauca-core/src/lib/shared/classes/operating-system.ts","../../../projects/cauca-core/src/lib/shared/services/client-information.service.ts","../../../projects/cauca-core/src/lib/shared/services/fullscreen.service.ts","../../../projects/cauca-core/src/lib/shared/services/image.service.ts","../../../projects/cauca-core/src/lib/shared/models/version.ts","../../../projects/cauca-core/src/lib/shared/services/version-check.service.ts","../../../projects/cauca-core/src/lib/shared/services/refresh-url.service.ts","../../../projects/cauca-core/src/lib/shared/interceptors/interceptor-delay.service.ts","../../../projects/cauca-core/src/lib/shared/interceptors/http-delay.interceptor.ts","../../../projects/cauca-core/src/lib/shared/classes/color.ts","../../../projects/cauca-core/src/lib/functions/to-lower-case-and-without-diacritics.ts","../../../projects/cauca-core/src/public-api.ts","../../../projects/cauca-core/src/cauca-911-core.ts"],"sourcesContent":["export enum LogLevel {\n trace = 0,\n debug = 1,\n information = 2,\n warning = 3,\n error = 4,\n critical = 5,\n disconnection = 6,\n}\n","import { LogLevel } from './log-level.enum';\nimport { RefreshToken } from './refresh-token';\n\nexport type LoginUrlFunction = () => string;\nexport type RefreshUrlFunction = () => string;\nexport type LogErrorFunction = (level: LogLevel, message: string, data: any) => void;\nexport type UpdateTokenFunction = (newToken: RefreshToken) => void;\nexport type HttpErrorFunction = (error: any, method: string, url: string) => void;\n\nexport class CoreModuleOptions {\n public logLevel: LogLevel = LogLevel.error;\n public apiUrl: string = '';\n public languages: string[] = ['fr', 'en'];\n public autoLoadMaterialLocales: boolean = true;\n public refreshLoginURL: string | RefreshUrlFunction = '';\n public allowRefreshToken: boolean = false;\n public libraries: string[] = [];\n public i18nPaths: string[] = [];\n public locale: string = '';\n public jsonConfigFile: string = '';\n public nbRetryOnNetworkError: number = 2;\n public contentSecurityPolicyActivated: boolean = false;\n public loginURL: string | LoginUrlFunction = '';\n public keepReturnUrlWhenRedirectingToLogin: boolean = false;\n public useLogoutService: boolean = false;\n // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n public logError: LogErrorFunction = (level: LogLevel, message: string, data: any = null) => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n public updateToken: UpdateTokenFunction = (newToken: RefreshToken) => {};\n // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars\n public onHttpError: HttpErrorFunction = (error: any) => {};\n}\n","import { CoreModuleOptions, HttpErrorFunction, LogErrorFunction, LoginUrlFunction, RefreshUrlFunction, UpdateTokenFunction } from '../models/core-module-options';\nimport { LogLevel } from '../models/log-level.enum';\n\nexport class Configuration {\n public jsonConfigFile: string = '';\n public libraries: string[] = [];\n public i18nPaths: string[] = [];\n public loginURL: LoginUrlFunction;\n public logError: LogErrorFunction;\n public updateToken: UpdateTokenFunction;\n public onHttpError: HttpErrorFunction;\n public refreshLoginURL: RefreshUrlFunction;\n public useLogoutService: boolean = false;\n public allowRefreshToken: boolean = false;\n public autoLoadMaterialLocales: boolean = true;\n public logLevel: LogLevel = LogLevel.debug;\n public apiUrl: string = '';\n public nbRetryOnNetworkError: number = 2;\n public contentSecurityPolicyActivated: boolean = false;\n public keepReturnUrlWhenRedirectingToLogin: boolean = false;\n\n private useCharset;\n private useAuthorizationType;\n private useAccessToken;\n private useRefreshToken;\n private useCSRFToken;\n private useLocale: string;\n private useLanguages: string[];\n\n public constructor(options: CoreModuleOptions) {\n this.useCharset = 'UTF-8';\n this.useAuthorizationType = 'Bearer';\n this.useAccessToken = '';\n this.useRefreshToken = '';\n this.useCSRFToken = '';\n this.useLocale = options.locale || '';\n this.useLanguages = options.languages || ['fr'];\n this.autoLoadMaterialLocales = options.autoLoadMaterialLocales ?? true;\n this.libraries = options.libraries || [];\n this.i18nPaths = options.i18nPaths || [];\n this.apiUrl = options.apiUrl || '/api/';\n this.logLevel = options.logLevel || LogLevel.debug;\n this.allowRefreshToken = options.allowRefreshToken || false;\n this.nbRetryOnNetworkError = options.nbRetryOnNetworkError || 2;\n this.contentSecurityPolicyActivated = options.contentSecurityPolicyActivated || false;\n this.keepReturnUrlWhenRedirectingToLogin = options.keepReturnUrlWhenRedirectingToLogin || false;\n this.logError = options.logError || this.defaultLogError;\n this.updateToken = options.updateToken;\n this.onHttpError = options.onHttpError;\n this.useLogoutService = options.useLogoutService || false;\n this.setRefreshUrl(options);\n this.setLoginUrl(options);\n this.setDefaultLocale();\n }\n\n public get locale(): string {\n return this.useLocale;\n }\n public set locale(value: string) {\n this.useLocale = value;\n }\n\n public get languages(): string[] {\n return this.useLanguages;\n }\n public set languages(value: string[]) {\n this.useLanguages = value;\n this.setDefaultLocale();\n }\n\n public get charset(): string {\n return this.useCharset;\n }\n public set charset(value: string) {\n this.useCharset = value;\n }\n\n public get authorizationType(): string {\n return this.useAuthorizationType;\n }\n public set authorizationType(value: string) {\n this.useAuthorizationType = value;\n }\n\n public get refreshToken(): string {\n if (this.contentSecurityPolicyActivated && !this.useRefreshToken) {\n this.useRefreshToken = localStorage.getItem('refreshToken');\n } else if (!this.useRefreshToken) {\n this.useRefreshToken = sessionStorage.getItem('refreshToken');\n }\n\n return this.useRefreshToken;\n }\n public set refreshToken(value: string) {\n if (this.contentSecurityPolicyActivated) {\n localStorage.setItem('refreshToken', value);\n } else {\n sessionStorage.setItem('refreshToken', value);\n }\n this.useRefreshToken = value;\n }\n\n public get accessToken(): string {\n if (this.contentSecurityPolicyActivated && !this.useAccessToken) {\n this.useAccessToken = localStorage.getItem('accessToken');\n } else if (!this.useAccessToken) {\n this.useAccessToken = sessionStorage.getItem('accessToken');\n }\n return this.useAccessToken;\n }\n public set accessToken(value: string) {\n if (this.contentSecurityPolicyActivated) {\n localStorage.setItem('accessToken', value);\n } else {\n sessionStorage.setItem('accessToken', value);\n }\n\n this.useAccessToken = value;\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public get CSRFToken(): string {\n if (this.contentSecurityPolicyActivated && !this.useAccessToken) {\n this.useCSRFToken = localStorage.getItem('CSRFToken');\n } else if (!this.useCSRFToken) {\n this.useCSRFToken = sessionStorage.getItem('CSRFToken');\n }\n\n return this.useCSRFToken;\n }\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public set CSRFToken(value: string) {\n if (this.contentSecurityPolicyActivated) {\n localStorage.setItem('CSRFToken', value);\n } else {\n sessionStorage.setItem('CSRFToken', value);\n }\n\n this.useCSRFToken = value;\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public get CSRFCookie(): string {\n return sessionStorage.getItem('CSRFCookie');\n }\n // eslint-disable-next-line @typescript-eslint/naming-convention\n public set CSRFCookie(value: string) {\n sessionStorage.setItem('CSRFCookie', value);\n }\n\n private setDefaultLocale(): void {\n if (this.useLocale) {\n return;\n }\n\n if (navigator && navigator.language.indexOf('-') > -1) {\n if (this.languages.indexOf(navigator.language) > -1) {\n this.locale = navigator.language;\n return;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const [langue, country] = navigator.language.split('-');\n\n if (this.languages.indexOf(langue) > -1) {\n this.locale = langue;\n return;\n }\n } else if (navigator && navigator.languages.length > 0) {\n for (const i in navigator.languages) {\n if (this.languages.indexOf(navigator.languages[i]) > -1) {\n this.locale = navigator.languages[i];\n return;\n }\n }\n }\n }\n\n private setLoginUrl(options: CoreModuleOptions): void {\n if (typeof(options.loginURL) === 'function') {\n this.loginURL = options.loginURL;\n } else {\n const url = options.loginURL?.toString() || '/login';\n this.loginURL = () => url;\n }\n }\n\n private setRefreshUrl(options: CoreModuleOptions): void {\n if (typeof(options.refreshLoginURL) === 'function') {\n this.refreshLoginURL = options.refreshLoginURL;\n } else {\n const url = options.refreshLoginURL?.toString() || '';\n this.refreshLoginURL = () => url;\n }\n }\n\n private defaultLogError(level: LogLevel, message: string, data: any): void {\n if (level >= this.logLevel) {\n console.log(`LogLevel: ${level} >= ${this.logLevel}`);\n console.log(`Message: ${message}`);\n\n if (data) {\n console.log(data);\n }\n }\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { TranslateService } from '@ngx-translate/core';\nimport { CoreModuleOptions } from './shared/models/core-module-options';\nimport { Configuration } from './shared/classes/configuration';\nimport { HttpBackend, HttpClient } from '@angular/common/http';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class CaucaCoreService {\n private httpBackend = inject(HttpBackend);\n private translateService = inject(TranslateService);\n\n private config = new Configuration(new CoreModuleOptions());\n private jsonIsLoaded: boolean = false;\n\n public async appInitializer(coreOptions: CoreModuleOptions): Promise<void> {\n this.config = new Configuration(coreOptions);\n this.setupLocale();\n this.config.languages = this.config.languages || ['fr', 'en'];\n this.translateService.addLangs(this.config.languages);\n this.translateService.setDefaultLang(this.config.locale);\n this.translateService.use(this.config.locale);\n\n if (coreOptions.jsonConfigFile && !this.jsonIsLoaded) {\n const httpClient = new HttpClient(this.httpBackend);\n const jsonConfig = await httpClient.get(coreOptions.jsonConfigFile).toPromise();\n\n this.jsonIsLoaded = true;\n this.config = Object.assign(this.config, jsonConfig);\n }\n }\n\n public getConfig(): Configuration {\n return this.config;\n }\n\n public toggleLanguage(): void {\n if (this.config.languages.length < 2) {\n throw new Error('You need to configure at least two languages.');\n } else if (this.config.languages.length > 2) {\n throw new Error('Since you had more then two languages, use \"setLanguage(language)\".');\n }\n localStorage.setItem('locale', this.config.locale === 'fr' ? 'en' : 'fr');\n }\n\n public setLanguage(language: string): void {\n if (this.config.languages.length < 2) {\n throw new Error('You need to configure at least two languages.');\n } else if (!this.config.languages.includes(language)) {\n throw new Error('This language is not available.');\n }\n\n localStorage.setItem('locale', language);\n }\n\n private setupLocale(): void {\n const storedLocale = localStorage.getItem('locale');\n if (storedLocale && this.config.languages.includes(storedLocale)) {\n this.config.locale = storedLocale;\n } else {\n this.config.locale = this.config.locale || 'fr';\n }\n }\n}\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'cauca-core',\n templateUrl: './cauca-core.component.html',\n styleUrls: ['./cauca-core.component.scss'],\n standalone: false\n})\nexport class CaucaCoreComponent {\n\n}\n","<div>{{'core.noGenericComponentOnThisLibrary' | translate}}</div>","import { InjectionToken } from '@angular/core';\nimport { CoreModuleOptions } from '../models/core-module-options';\n\nexport const CAUCA_CORE_MODULE_OPTIONS_FACTORY = (): CoreModuleOptions => new CoreModuleOptions();\n\nexport const CAUCA_CORE_MODULE_OPTIONS = new InjectionToken<CoreModuleOptions>('cauca-core-module-options', {\n providedIn: 'root',\n factory: CAUCA_CORE_MODULE_OPTIONS_FACTORY,\n});\n\n","import { Component } from '@angular/core';\n\n@Component({\n selector: 'cauca-page-not-found',\n templateUrl: './cauca-page-not-found.component.html',\n styleUrls: ['./cauca-page-not-found.component.scss'],\n standalone: false\n})\nexport class CaucaPageNotFoundComponent {\n\n}\n","<div class=\"middle\">\n <h1>Ooops... page not found</h1>\n</div>","import { EventEmitter, Injectable } from '@angular/core';\nimport { InterceptorError } from '../interfaces/interceptor-error';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class InterceptorErrorService {\n public error = new EventEmitter<InterceptorError>();\n\n public append(statusCode: number, message: string): void {\n this.error.emit({\n statusCode,\n message\n });\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { HttpErrorResponse, HttpEvent, HttpHandler, HttpRequest } from '@angular/common/http';\nimport { Observable, throwError } from 'rxjs';\nimport { catchError } from 'rxjs/operators';\nimport { InterceptorErrorService } from './interceptor-error.service';\n\n@Injectable()\nexport class HttpOfflineInterceptor {\n private interceptorErrorService = inject(InterceptorErrorService);\n\n\n public intercept(\n request: HttpRequest<any>,\n next: HttpHandler\n ): Observable<HttpEvent<any>> {\n request = request.clone();\n\n if (!navigator.onLine) {\n return this.onOffline(new HttpErrorResponse({\n headers: request.headers,\n status: 408,\n statusText: 'Offline',\n url: request.url,\n }));\n } else {\n return next.handle(request).pipe(\n catchError((error: any) => {\n if (error.status === 0) {\n return this.onOffline(error);\n }\n return throwError(() => error);\n })\n );\n }\n }\n\n private onOffline(error: HttpErrorResponse): Observable<any> {\n this.interceptorErrorService.append(error.status, error.statusText);\n return throwError(() => error);\n }\n}\n","import { HttpErrorResponse } from '@angular/common/http';\n\nexport class HttpError {\n public status: number;\n public statusText: string;\n public url: string;\n public data: string;\n public body: string;\n\n public constructor(error: HttpErrorResponse) {\n this.url = error.url || '';\n this.status = error.status;\n this.statusText = error.statusText;\n\n if (error.error instanceof ErrorEvent) {\n this.body = error.error.message;\n } else if (error.error) {\n this.body = error.error.title || JSON.stringify(error.error);\n }\n }\n\n public setData(data: any): void {\n this.data = JSON.stringify(data);\n }\n}\n","import { debounce } from 'lodash';\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const Debounce = (ms: number): any => ((target: any, key: string, descriptor: PropertyDescriptor) => {\n const oldFunc = descriptor.value;\n const newFunc = debounce(oldFunc, ms);\n\n descriptor.value = function(): any {\n // eslint-disable-next-line prefer-rest-params\n return newFunc.apply(this, arguments);\n };\n});\n","import { Injectable, inject } from '@angular/core';\nimport { HttpClient, HttpErrorResponse, HttpBackend } from '@angular/common/http';\nimport { Subject } from 'rxjs';\nimport { CaucaCoreService } from '../../cauca-core.service';\nimport { Configuration } from '../classes/configuration';\nimport { HttpError } from '../models/http-error';\nimport { Debounce } from '../decorators/debounce';\nimport { LogLevel } from '../models/log-level.enum';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class LogService {\n private coreService = inject(CaucaCoreService);\n\n private config: Configuration;\n private httpClient: HttpClient;\n private errors: HttpError[] = [];\n private activeSending = new Subject<void>();\n private timer: any;\n\n public constructor() {\n const coreService = this.coreService;\n const handler = inject(HttpBackend);\n\n this.config = coreService.getConfig();\n this.httpClient = new HttpClient(handler);\n this.activeSending.subscribe(() => {\n this.sendErrors();\n });\n }\n\n public get errorCount(): number {\n return this.errors.length;\n }\n\n public get waitToSendAgain(): boolean {\n return this.timer ? true : false;\n }\n\n public information(message: string, data: any = null): void {\n const config = this.coreService.getConfig();\n config.logError(LogLevel.information, message, data);\n }\n\n public warning(message: string, data: any = null): void {\n const config = this.coreService.getConfig();\n config.logError(LogLevel.warning, message, data);\n }\n\n public error(message: string, data: any = null): void {\n const config = this.coreService.getConfig();\n config.logError(LogLevel.error, message, data);\n }\n\n public disconnection(message: string, data: any = null): void {\n const config = this.coreService.getConfig();\n config.logError(LogLevel.disconnection, message, data);\n }\n\n public publishInformation(error: any, data: any = null): void {\n if (error instanceof HttpErrorResponse) {\n const httpError = new HttpError(error);\n httpError.setData(data);\n\n this.httpClient.post(`${this.config.apiUrl}Error/LogInformation`, httpError).subscribe();\n }\n }\n\n public publishWarning(error: any, data: any = null): void {\n if (error instanceof HttpErrorResponse) {\n const httpError = new HttpError(error);\n httpError.setData(data);\n\n this.httpClient.post(`${this.config.apiUrl}Error/LogWarning`, httpError).subscribe();\n }\n }\n\n public publishError(error: any, data: any = null): void {\n if (error instanceof HttpErrorResponse) {\n const httpError = new HttpError(error);\n httpError.setData(data);\n\n this.errors.push(httpError);\n this.activeSending.next();\n }\n }\n\n @Debounce(1000)\n private sendErrors(): void {\n if (!navigator.onLine) {\n return;\n }\n\n this.stopTimer();\n this.httpClient.post(`${this.config.apiUrl}Error/LogErrors`, this.errors).subscribe({\n next: () => {\n this.errors = [];\n },\n error: () => {\n this.httpClient.post(`${this.config.apiUrl}logErrors`, this.errors).subscribe({\n next: () => {\n this.errors = [];\n },\n error: () => {\n const minuteToWait = 5 * 60 * 1000;\n this.timer = setTimeout(() => this.sendErrors(), minuteToWait);\n }\n });\n }\n });\n }\n\n private stopTimer(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n}\n","import { HttpBackend, HttpClient } from '@angular/common/http';\nimport { Injectable, inject } from '@angular/core';\nimport { Observable, of } from 'rxjs';\nimport { catchError, map, retry } from 'rxjs/operators';\nimport { CaucaCoreService } from '../../cauca-core.service';\nimport { RefreshToken } from '../models/refresh-token';\nimport { LogService } from './log.service';\nimport { RefreshUrlService } from './refresh-url.service';\nimport { BaseLogoutHandler } from './logout-handler';\nimport { Router } from '@angular/router';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class RefreshTokenService {\n private coreService = inject(CaucaCoreService);\n private logService = inject(LogService);\n private router = inject(Router);\n private logoutHandler = inject<BaseLogoutHandler>('LogoutHandler' as any, { optional: true }) ?? null;\n private refreshUrlService = inject<RefreshUrlService>('RefreshUrlService' as any, { optional: true }) ?? null;\n\n private http: HttpClient;\n private errorPrefix: string = 'Interceptor - HttpTokenWriter - ';\n\n public constructor() {\n const handler = inject(HttpBackend);\n\n this.http = new HttpClient(handler);\n }\n\n public refreshToken(): Observable<boolean> {\n const config = this.coreService.getConfig();\n\n return this.postRefreshToken().pipe(\n retry(3),\n map((data: RefreshToken) => {\n this.logService.information(`${this.errorPrefix}Response from refreshing token.`, data);\n\n config.accessToken = data.accessToken || '';\n if (config.updateToken) {\n config.updateToken(data);\n }\n return data.accessToken ? true : false;\n }),\n catchError((error: any) => {\n this.logService.information(`${this.errorPrefix}Error when refreshing token.`, error);\n\n if (error.status === 0 || error.status === 408) {\n return of(true);\n }\n config.accessToken = '';\n if (config.updateToken) {\n config.updateToken(null);\n }\n return of(false);\n })\n );\n }\n\n public refreshTokenWithRedirect(): Observable<boolean> {\n const config = this.coreService.getConfig();\n const loginUrl = config.loginURL();\n return this.refreshToken().pipe(\n map((response: any) => {\n if (!response && location.pathname !== loginUrl) {\n this.logout();\n }\n this.logService.information(`${this.errorPrefix}Refresh accessToken work.`);\n return response;\n })\n );\n }\n\n private logout(): void {\n const currentUrl = this.router.routerState.snapshot.url;\n const config = this.coreService.getConfig();\n this.logService.disconnection(`${this.errorPrefix}Could not refresh access token, redirect to login page.`);\n if (config.useLogoutService) {\n this.logoutHandler?.logoutWithMessage(currentUrl);\n } else {\n const params = config.keepReturnUrlWhenRedirectingToLogin ? { returnUrl: currentUrl } : {};\n this.router.navigate([config.loginURL()], { queryParams: params });\n }\n }\n\n private postRefreshToken(): Observable<RefreshToken> {\n const config = this.coreService.getConfig();\n const host = config.refreshLoginURL();\n const token = {\n accessToken: config.accessToken,\n refreshToken: config.refreshToken,\n } as RefreshToken;\n\n let refreshUrl = this.refreshUrlService?.getRefreshUrl() || host;\n if (!refreshUrl) {\n refreshUrl = `/api/Authentication/Refresh`;\n }\n\n return this.http.post<RefreshToken>(refreshUrl, token);\n }\n}\n","import { Injectable, Signal, inject } from \"@angular/core\";\r\nimport { toSignal } from \"@angular/core/rxjs-interop\";\r\n\r\nimport { BehaviorSubject, Observable, take, switchMap, finalize, filter, map } from \"rxjs\";\r\nimport { CaucaCoreService } from \"../../cauca-core.service\";\r\nimport { RefreshTokenService } from \"./refresh-token.service\";\r\n\r\n@Injectable({providedIn: 'root'})\r\nexport class HttpTokenProvider {\r\n public isRefreshing: Signal<boolean>;\r\n\r\n private isRefreshingToken: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);\r\n private readonly core = inject(CaucaCoreService);\r\n private readonly tokenRefresher = inject(RefreshTokenService);\r\n\r\n public constructor() {\r\n this.isRefreshing = toSignal(this.isRefreshingToken);\r\n }\r\n\r\n public getNewToken(): Observable<string> {\r\n return this.isRefreshingToken.pipe(\r\n take(1),\r\n switchMap((refreshing) => refreshing ? this.getToken() : this.refreshToken().pipe(switchMap(() => this.getToken())))\r\n );\r\n }\r\n\r\n public getToken(): Observable<string> {\r\n return this.isRefreshingToken\r\n .pipe(\r\n filter(refreshing => !refreshing),\r\n take(1),\r\n map(() => this.core.getConfig().accessToken)\r\n );\r\n }\r\n\r\n private refreshToken(): Observable<boolean> {\r\n this.isRefreshingToken.next(true);\r\n return this.tokenRefresher.refreshToken()\r\n .pipe(finalize(() => this.isRefreshingToken.next(false)));\r\n }\r\n}","import { inject, Injectable } from '@angular/core';\nimport { HttpEvent, HttpHandler, HttpRequest, HttpHeaders, HttpInterceptor } from '@angular/common/http';\nimport { Observable, of, throwError } from 'rxjs';\nimport { catchError, map, switchMap } from 'rxjs/operators';\nimport { CaucaCoreService } from '../../cauca-core.service';\nimport { LogService } from '../services/log.service';\nimport { BaseLogoutHandler } from '../services/logout-handler';\nimport { Router } from '@angular/router';\nimport { HttpTokenProvider } from '../services/http-token-provider';\n\n@Injectable()\nexport class HttpTokenWriterInterceptor implements HttpInterceptor {\n private logoutHandler = inject<BaseLogoutHandler>('LogoutHandler' as any, { optional: true }) ?? null;\n\n\n private errorPrefix: string = 'Interceptor - HttpTokenWriter - ';\n\n private readonly tokenProvider = inject(HttpTokenProvider);\n private readonly coreService = inject(CaucaCoreService);\n private readonly logService = inject(LogService);\n private readonly router = inject(Router);\n\n public intercept(request: HttpRequest<any>, next: HttpHandler,): Observable<HttpEvent<any>> {\n return this.getRequestWithToken(request)\n .pipe(switchMap((requestWithToken: HttpRequest<any>)=> this.executeRequest(requestWithToken, next, request)));\n }\n\n private executeRequest(request: HttpRequest<any>, next: HttpHandler, originalRequest: HttpRequest<any>): Observable<HttpEvent<any>> {\n return next.handle(request).pipe(\n catchError((error: any) => {\n this.logService.information(`${this.errorPrefix}An error has been catch.`);\n return this.checkIfWeCanManageError(error, originalRequest).pipe(\n switchMap((handledRequest: HttpRequest<any>) => this.handleRetry(handledRequest, next)),\n catchError((unHandleError: any) => this.handleExecutionError(unHandleError))\n );\n })\n );\n }\n\n private handleRetry(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n this.logService.information(`${this.errorPrefix}Occur error can be managed, we resend the original request.`);\n return this.getRequestWithToken(request).pipe(switchMap((clonedRequest) => next.handle(clonedRequest)));\n }\n\n private handleExecutionError(unhandledError: any): Observable<never> {\n this.logService.warning(`${this.errorPrefix}Occur error can't be managed.`, unhandledError);\n return throwError(() => unhandledError);\n }\n\n private getRequestWithToken(request: HttpRequest<any>): Observable<HttpRequest<any>> {\n return this.generateHeaders(request)\n .pipe(map((headers: HttpHeaders) => request = request.clone({ headers, })));\n }\n\n private generateHeaders(request: HttpRequest<any>): Observable<HttpHeaders> {\n const config = this.coreService.getConfig();\n if (config.accessToken) {\n return this.tokenProvider.getToken()\n .pipe(map((token: string) => this.setupHeaders(request, token)));\n } else {\n return of(this.setupHeaders(request, null));\n }\n }\n\n private setupHeaders(request: HttpRequest<any>, token: string): HttpHeaders {\n let headers = request.headers;\n const config = this.coreService.getConfig();\n const isFormData = request.body instanceof FormData;\n\n this.logService.information(`${this.errorPrefix}The request has a header authorization.`, config);\n\n if (!headers.has('Authorization') && token) {\n headers = headers.set('Authorization', `${config.authorizationType} ${token}`);\n }\n if (!headers.has('X-CSRF-Token') && config.CSRFToken) {\n headers = headers.set('X-CSRF-Token', `${config.CSRFToken}`);\n\n if (config.CSRFCookie) {\n headers = headers.set('X-CSRF-Cookie', `${config.CSRFCookie}`);\n }\n }\n if (!headers.has('Content-Type') && !isFormData) {\n headers = headers.set('Content-Type', `application/json; charset=${config.charset}`);\n }\n if (!headers.has('Language-Code')) {\n headers = headers.set('Language-Code', config.locale);\n }\n return headers;\n }\n\n private checkIfWeCanManageError(error: any, originalRequest: HttpRequest<any>): Observable<HttpRequest<any>> {\n const config = this.coreService.getConfig();\n const loginUrl = config.loginURL();\n this.logService.information(`${this.errorPrefix}Check if we can refresh the accessToken.`, error);\n if (error.status === 401 && config.accessToken && config.allowRefreshToken) {\n this.logService.information(`${this.errorPrefix}Try to refresh the user access token.`);\n return this.retryWithNewToken(originalRequest, loginUrl);\n } else if (error.status === 401 && config.accessToken && location.pathname !== loginUrl) {\n this.logout();\n } else if (error.status === 200) {\n if (error.message && error.message.indexOf('Http failure during parsing for') === 0) {\n this.logService.information(`${this.errorPrefix}Does not receive a JSON, so the call is send with \"text/html\".`);\n return of(this.resendAsHTML(originalRequest));\n }\n }\n\n this.logService.information(`${this.errorPrefix}Error receive can't be manage.`);\n return throwError(() => error);\n }\n\n private retryWithNewToken(request: HttpRequest<any>, loginUrl: string): Observable<HttpRequest<any>> {\n return this.tokenProvider.getNewToken().pipe(map((token: string) => this.handleRefreshResponse(request, token, loginUrl)));\n }\n\n private handleRefreshResponse(request: HttpRequest<any>, token: any, loginUrl: string): HttpRequest<any> {\n if (!token && location.pathname !== loginUrl) {\n this.logout();\n }\n this.logService.information(`${this.errorPrefix}Refresh accessToken work.`);\n return request;\n }\n\n private logout(): void {\n const currentUrl = this.router.routerState.snapshot.url;\n const config = this.coreService.getConfig();\n this.logService.disconnection(`${this.errorPrefix}Could not refresh access token, redirect to login page.`);\n if (config.useLogoutService) {\n this.logoutHandler?.logoutWithMessage(currentUrl);\n } else {\n const params = config.keepReturnUrlWhenRedirectingToLogin ? { returnUrl: currentUrl } : {};\n this.router.navigate([config.loginURL()], { queryParams: params });\n }\n }\n\n private resendAsHTML(originalRequest: HttpRequest<any>): HttpRequest<any> {\n const config = this.coreService.getConfig();\n let headers = originalRequest.headers;\n headers = headers.set('Content-Type', `text/html; charset=${config.charset}`);\n return originalRequest.clone({ responseType: 'text', headers, });\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '@angular/common/http';\nimport {Observable} from 'rxjs';\nimport {map} from 'rxjs/operators';\nimport {CaucaCoreService} from '../../cauca-core.service';\n\n@Injectable()\nexport class HttpTokenReaderInterceptor implements HttpInterceptor {\n private coreService = inject(CaucaCoreService);\n\n\n public intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {\n return next.handle(request).pipe(\n map((response: HttpResponse<any>) => {\n if (response.headers && response.headers.get('x-csrf-token')) {\n this.coreService.getConfig().CSRFToken = response.headers.get('x-csrf-token');\n }\n if (response.headers && response.headers.get('x-csrf-cookie')) {\n this.coreService.getConfig().CSRFCookie = response.headers.get('x-csrf-cookie');\n }\n\n return response;\n })\n );\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { HttpInterceptor, HttpErrorResponse, HttpEvent, HttpHandler, HttpRequest } from '@angular/common/http';\nimport { Observable, throwError, timer } from 'rxjs';\nimport { catchError, retry } from 'rxjs/operators';\nimport { Configuration } from '../classes/configuration';\nimport { CaucaCoreService } from '../../cauca-core.service';\nimport { InterceptorErrorService } from './interceptor-error.service';\nimport { LogService } from '../services/log.service';\n\n@Injectable()\nexport class HttpErrorInterceptor implements HttpInterceptor {\n private logService = inject(LogService);\n private interceptorErrorService = inject(InterceptorErrorService);\n\n private config: Configuration;\n\n public constructor() {\n const coreService = inject(CaucaCoreService);\n\n this.config = coreService.getConfig();\n }\n\n public intercept(\n request: HttpRequest<any>,\n next: HttpHandler,\n ): Observable<HttpEvent<any>> {\n return next.handle(request).pipe(\n retry({\n count: this.config.nbRetryOnNetworkError,\n delay: (error: HttpErrorResponse) => this.handleRetry(error)\n }),\n catchError((error: any) => this.handleError(error, request))\n );\n }\n\n private handleRetry(error: HttpErrorResponse): Observable<any> {\n const isNetworkError = [0, 408, 502, 503, 504].includes(error.status);\n\n this.logService.information(`Interceptor - HttpErrorInterceptor - Status code \"${error.status}\"`);\n if (isNetworkError) {\n return timer(100);\n }\n\n throw error;\n }\n\n private handleError(error: any, request: HttpRequest<any>): Observable<never> {\n if (error instanceof HttpErrorResponse) {\n if (error.status === 0) {\n this.interceptorErrorService.append(0, 'La demande ne peut être complétée.');\n } else if (error.status === 400) {\n if (error.error && error.error.message) {\n this.interceptorErrorService.append(400, error.error.message);\n } else if (error.error && error.error.title) {\n this.interceptorErrorService.append(400, error.error.title);\n } else if (error.error) {\n if (typeof error.error === 'string') {\n this.interceptorErrorService.append(400, error.error);\n }\n } else if (error.statusText) {\n this.interceptorErrorService.append(400, error.statusText);\n } else {\n this.interceptorErrorService.append(400, 'La demande ne peut pas être complétée.');\n }\n } else if (error.status === 404) {\n this.interceptorErrorService.append(404, 'Le URL demandé n\\'existe pas.');\n } else if (error.status === 500) {\n this.interceptorErrorService.append(500, 'Erreur de communication.');\n } else if (error.status !== 200 && error.status !== 401) {\n this.interceptorErrorService.append(error.status, error.statusText);\n }\n }\n if (this.config.onHttpError != null) {\n this.config.onHttpError(error, request.method, request.urlWithParams);\n }\n return throwError(() => error);\n }\n}\n","\nexport class CustomMissingTranslationHandler {\n public handle(params: any): string {\n return `i18n \"${params.key}\" is missing`;\n }\n}\n","import { HttpClient, HttpBackend } from '@angular/common/http';\nimport {forkJoin, of, Observable} from 'rxjs';\nimport {catchError, map} from 'rxjs/operators';\nimport {CoreModuleOptions} from '../models/core-module-options';\nimport {ResourceOptions} from './resource-options';\nimport { TranslateLoader } from '@ngx-translate/core';\n\nexport class CustomMultiTranslateHttpLoader implements TranslateLoader {\n private http: HttpClient;\n private resources: ResourceOptions[] = [{\n prefix: '/assets/i18n/',\n suffix: '.json',\n }, {\n prefix: '/assets/i18n/cauca/',\n suffix: '-core.json',\n }];\n\n public constructor(\n httpBackend: HttpBackend,\n options: CoreModuleOptions\n ) {\n this.http = new HttpClient(httpBackend);\n\n if (options && options.libraries) {\n options.libraries.forEach((library: string) => {\n this.resources.push({\n prefix: '/assets/i18n/cauca/',\n suffix: `-${library}.json`,\n } as ResourceOptions);\n });\n }\n if (options && options.i18nPaths) {\n options.i18nPaths.forEach((path: string) => {\n this.resources.push({\n prefix: `/assets/i18n/${path}/`,\n suffix: `.json`,\n } as ResourceOptions);\n });\n }\n }\n\n public getTranslation(lang: string): Observable<any> {\n return forkJoin(\n this.resources.map((config: ResourceOptions) => this.getOneResourceTranslation(lang, config))\n ).pipe(\n map((response: any) => response.reduce((a: any, b: any) => Object.assign(a, b)))\n );\n }\n\n public getOneResourceTranslation(lang: string, config: ResourceOptions): Observable<any> {\n return this.http.get(`${config.prefix}${lang}${config.suffix}`).pipe(\n catchError(() => of({}))\n );\n }\n}\n","import { Injectable, inject } from '@angular/core';\nimport { HttpClient, HttpBackend } from '@angular/common/http';\nimport { forkJoin, Observable, Observer } from 'rxjs';\nimport { catchError, map } from 'rxjs/operators';\nimport { of } from 'rxjs';\nimport {\n TranslateService as NgxTranslateService,\n MissingTranslationHandler,\n TranslateCompiler,\n TranslateLoader,\n TranslateParser,\n TranslateStore\n} from '@ngx-translate/core';\nimport { CaucaCoreService } from '../../cauca-core.service';\n\n@Injectable({\n providedIn: 'root'\n})\nexport class TranslateService extends NgxTranslateService {\n private coreService = inject(CaucaCoreService);\n\n private http: HttpClient;\n private multiLangDictionary: any = {};\n\n public constructor() {\n const store = inject(TranslateStore);\n const currentLoader = inject(TranslateLoader);\n const compiler = inject(TranslateCompiler);\n const parser = inject(TranslateParser);\n const missingTranslationHandler = inject(MissingTranslationHandler);\n const httpBackend = inject(HttpBackend);\n\n super(store, currentLoader, compiler, parser, missingTranslationHandler, false, false, false, 'fr');\n this.http = new HttpClient(httpBackend);\n }\n\n public async appInitializer(): Promise<void> {\n const config = this.coreService.getConfig();\n this.addLangs(config.languages);\n this.setDefaultLang(config.locale);\n return new Promise((resolve: any) => {\n this.use(config.locale)\n .subscribe({ complete: () => resolve() });\n });\n }\n\n public getMultilingualTranslations(languages: string[], wordsToTranslate: string[]): Observable<any> {\n if (!this.multiLangDictionary[languages[0]]) {\n return forkJoin(\n this.coreService.getConfig().languages.map((lang: string) => this.loadOneLanguage(lang))\n ).pipe(\n map(() => this.getTranslationForSpecificLanguages(languages, wordsToTranslate))\n );\n }\n\n return new Observable((observer: Observer<any>) => {\n observer.next(this.getTranslationForSpecificLanguages(languages, wordsToTranslate));\n observer.complete();\n });\n }\n\n private loadOneLanguage(lang: string): Observable<void> {\n return this.getTranslation(lang).pipe(\n catchError(() => of({})),\n map((result: any) => {\n this.multiLangDictionary[lang] = result;\n })\n );\n }\n\n private getTranslationForSpecificLanguages(languages: string[], wordsToTranslate: string[]): any {\n const objectToReturn = {};\n\n languages.forEach((lang: string) => {\n objectToReturn[lang] = {};\n wordsToTranslate.forEach((word: string) => {\n const levels = word.split('.');\n let translation = this.multiLangDictionary[lang];\n levels.forEach((level: string) => {\n translation = translation[level];\n });\n objectToReturn[lang][word] = translation;\n });\n });\n\n return objectToReturn;\n }\n}\n","import { EnvironmentProviders, Injector, LOCALE_ID, NgModule, Provider, importProvidersFrom, inject, provideAppInitializer } from '@angular/core';\nimport { LOCATION_INITIALIZED } from '@angular/common';\nimport { HTTP_INTERCEPTORS, HttpBackend, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http';\nimport { MissingTranslationHandler, TranslateLoader, TranslateModule } from '@ngx-translate/core';\nimport { CaucaCoreComponent } from './cauca-core.component';\nimport { CaucaCoreService } from './cauca-core.service';\nimport { CAUCA_CORE_MODULE_OPTIONS } from './shared/constants/cauca-core-module-options';\nimport { CaucaPageNotFoundComponent } from './cauca-page-not-found/cauca-page-not-found.component';\nimport { HttpOfflineInterceptor } from './shared/interceptors/http-offline-interceptor';\nimport { HttpTokenWriterInterceptor } from './shared/interceptors/http-token-writer-interceptor';\nimport { HttpTokenReaderInterceptor } from './shared/interceptors/http-token-reader-interceptor';\nimport { HttpErrorInterceptor } from './shared/interceptors/http-error-interceptor';\nimport { CustomMissingTranslationHandler } from './shared/ngx-translate/custom-missing-translation-handler';\nimport { CustomMultiTranslateHttpLoader } from './shared/ngx-translate/custom-multi-translate-http-loader';\nimport { TranslateService } from './shared/services/translate.service';\nimport { CoreModuleOptions } from './shared/models/core-module-options';\nimport { LogService } from './shared/services/log.service';\nimport { RefreshTokenService } from './shared/services/refresh-token.service';\n\nexport const configFactory = (coreService: CaucaCoreService): string => (\n coreService.getConfig().locale\n);\n\nexport const translateFactory = (\n translateService: TranslateService,\n coreOptions: CoreModuleOptions,\n coreService: CaucaCoreService,\n logService: LogService,\n injector: Injector\n): any => {\n const promise = async () => {\n await coreService.appInitializer(coreOptions);\n await injector.get(LOCATION_INITIALIZED, Promise.resolve(null));\n\n logService.information(`CaucaCoreModule - Use config.`, coreService.getConfig());\n\n return translateService.appInitializer();\n };\n return promise;\n};\n\nconst TRANSLATE_CONFIGURATION = {\n loader: {\n provide: TranslateLoader,\n useClass: CustomMultiTranslateHttpLoader,\n deps: [HttpBackend, CAUCA_CORE_MODULE_OPTIONS]\n },\n missingTranslationHandler: {\n provide: MissingTranslationHandler,\n useClass: CustomMissingTranslationHandler,\n },\n useDefaultLang: false\n};\n\n@NgModule({ declarations: [\n CaucaCoreComponent,\n CaucaPageNotFoundComponent,\n ],\n exports: [\n CaucaCoreComponent,\n CaucaPageNotFoundComponent,\n TranslateModule,\n ], imports: [TranslateModule.forRoot(TRANSLATE_CONFIGURATION)], providers: [\n CaucaCoreService,\n RefreshTokenService,\n {\n provide: HTTP_INTERCEPTORS,\n useClass: HttpOfflineInterceptor,\n multi: true\n }, {\n provide: HTTP_INTERCEPTORS,\n useClass: HttpTokenWriterInterceptor,\n multi: true\n }, {\n provide: HTTP_INTERCEPTORS,\n useClass: HttpTokenReaderInterceptor,\n multi: true\n }, {\n provide: HTTP_INTERCEPTORS,\n useClass: HttpErrorInterceptor,\n multi: true\n }, {\n provide: LOCALE_ID,\n useFactory: configFactory,\n deps: [CaucaCoreService]\n }, provideAppInitializer(() => {\n const initializerFn = (translateFactory)(inject(TranslateService), inject(CAUCA_CORE_MODULE_OPTIONS), inject(CaucaCoreService), inject(LogService), inject(Injector));\n return initializerFn();\n }),\n provideHttpClient(withInterceptorsFromDi())\n ] })\nexport class CaucaCoreModule {\n}\n\nexport function importCaucaCoreTranslateProviders(): (Provider|EnvironmentProviders) {\n return importProvidersFrom(TranslateModule.forRoot(TRANSLATE_CONFIGURATION));\n}\n\nexport function provideCaucaCore(options: CoreModuleOptions): (Provider|EnvironmentProviders)[] {\n return [\n CaucaCoreService,\n RefreshTokenService,\n {\n provide: CAUCA_CORE_MODULE_OPTIONS,\n useValu