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