UNPKG

@cauca-911/core

Version:

Run `npm install @cauca-911/core` to add this library to your project

1,159 lines (1,135 loc) 82.2 kB
import * as i0 from '@angular/core'; import { inject, Injectable, Component, InjectionToken, EventEmitter, provideAppInitializer, LOCALE_ID, importProvidersFrom, Injector, NgModule } from '@angular/core'; import * as i1 from '@ngx-translate/core'; import { TranslateService as TranslateService$1, TranslateStore, TranslateLoader, TranslateCompiler, TranslateParser, MissingTranslationHandler, TranslateModule } from '@ngx-translate/core'; export { TranslatePipe } from '@ngx-translate/core'; import { HttpBackend, HttpClient, HttpErrorResponse, HTTP_INTERCEPTORS, provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'; import { LOCATION_INITIALIZED } from '@angular/common'; import { throwError, Subject, of, BehaviorSubject, take, switchMap, filter, map as map$1, finalize, timer, forkJoin, Observable } from 'rxjs'; import { catchError, retry, map, switchMap as switchMap$1 } from 'rxjs/operators'; import { __decorate } from 'tslib'; import { debounce } from 'lodash'; import { Router } from '@angular/router'; import { toSignal } from '@angular/core/rxjs-interop'; import { provideHttpClientTesting } from '@angular/common/http/testing'; var LogLevel; (function (LogLevel) { LogLevel[LogLevel["trace"] = 0] = "trace"; LogLevel[LogLevel["debug"] = 1] = "debug"; LogLevel[LogLevel["information"] = 2] = "information"; LogLevel[LogLevel["warning"] = 3] = "warning"; LogLevel[LogLevel["error"] = 4] = "error"; LogLevel[LogLevel["critical"] = 5] = "critical"; LogLevel[LogLevel["disconnection"] = 6] = "disconnection"; })(LogLevel || (LogLevel = {})); class CoreModuleOptions { constructor() { this.logLevel = LogLevel.error; this.apiUrl = ''; this.languages = ['fr', 'en']; this.autoLoadMaterialLocales = true; this.refreshLoginURL = ''; this.allowRefreshToken = false; this.libraries = []; this.i18nPaths = []; this.locale = ''; this.jsonConfigFile = ''; this.nbRetryOnNetworkError = 2; this.contentSecurityPolicyActivated = false; this.loginURL = ''; this.keepReturnUrlWhenRedirectingToLogin = false; this.useLogoutService = false; // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars this.logError = (level, message, data = null) => { }; // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars this.updateToken = (newToken) => { }; // eslint-disable-next-line @typescript-eslint/no-empty-function, @typescript-eslint/no-unused-vars this.onHttpError = (error) => { }; } } class Configuration { constructor(options) { this.jsonConfigFile = ''; this.libraries = []; this.i18nPaths = []; this.useLogoutService = false; this.allowRefreshToken = false; this.autoLoadMaterialLocales = true; this.logLevel = LogLevel.debug; this.apiUrl = ''; this.nbRetryOnNetworkError = 2; this.contentSecurityPolicyActivated = false; this.keepReturnUrlWhenRedirectingToLogin = false; this.useCharset = 'UTF-8'; this.useAuthorizationType = 'Bearer'; this.useAccessToken = ''; this.useRefreshToken = ''; this.useCSRFToken = ''; this.useLocale = options.locale || ''; this.useLanguages = options.languages || ['fr']; this.autoLoadMaterialLocales = options.autoLoadMaterialLocales ?? true; this.libraries = options.libraries || []; this.i18nPaths = options.i18nPaths || []; this.apiUrl = options.apiUrl || '/api/'; this.logLevel = options.logLevel || LogLevel.debug; this.allowRefreshToken = options.allowRefreshToken || false; this.nbRetryOnNetworkError = options.nbRetryOnNetworkError || 2; this.contentSecurityPolicyActivated = options.contentSecurityPolicyActivated || false; this.keepReturnUrlWhenRedirectingToLogin = options.keepReturnUrlWhenRedirectingToLogin || false; this.logError = options.logError || this.defaultLogError; this.updateToken = options.updateToken; this.onHttpError = options.onHttpError; this.useLogoutService = options.useLogoutService || false; this.setRefreshUrl(options); this.setLoginUrl(options); this.setDefaultLocale(); } get locale() { return this.useLocale; } set locale(value) { this.useLocale = value; } get languages() { return this.useLanguages; } set languages(value) { this.useLanguages = value; this.setDefaultLocale(); } get charset() { return this.useCharset; } set charset(value) { this.useCharset = value; } get authorizationType() { return this.useAuthorizationType; } set authorizationType(value) { this.useAuthorizationType = value; } get refreshToken() { if (this.contentSecurityPolicyActivated && !this.useRefreshToken) { this.useRefreshToken = localStorage.getItem('refreshToken'); } else if (!this.useRefreshToken) { this.useRefreshToken = sessionStorage.getItem('refreshToken'); } return this.useRefreshToken; } set refreshToken(value) { this.setStorageValue('refreshToken', value); this.useRefreshToken = value; } get accessToken() { if (this.contentSecurityPolicyActivated && !this.useAccessToken) { this.useAccessToken = localStorage.getItem('accessToken'); } else if (!this.useAccessToken) { this.useAccessToken = sessionStorage.getItem('accessToken'); } return this.useAccessToken; } set accessToken(value) { this.setStorageValue('accessToken', value); this.useAccessToken = value; } // eslint-disable-next-line @typescript-eslint/naming-convention get CSRFToken() { if (this.contentSecurityPolicyActivated && !this.useAccessToken) { this.useCSRFToken = localStorage.getItem('CSRFToken'); } else if (!this.useCSRFToken) { this.useCSRFToken = sessionStorage.getItem('CSRFToken'); } return this.useCSRFToken; } // eslint-disable-next-line @typescript-eslint/naming-convention set CSRFToken(value) { this.setStorageValue('CSRFToken', value); this.useCSRFToken = value; } // eslint-disable-next-line @typescript-eslint/naming-convention get CSRFCookie() { return sessionStorage.getItem('CSRFCookie'); } // eslint-disable-next-line @typescript-eslint/naming-convention set CSRFCookie(value) { sessionStorage.setItem('CSRFCookie', value); } setDefaultLocale() { if (this.useLocale) { return; } if (navigator && navigator.language.indexOf('-') > -1) { if (this.languages.indexOf(navigator.language) > -1) { this.locale = navigator.language; return; } // eslint-disable-next-line @typescript-eslint/no-unused-vars const [langue, country] = navigator.language.split('-'); if (this.languages.indexOf(langue) > -1) { this.locale = langue; return; } } else if (navigator && navigator.languages.length > 0) { for (const i in navigator.languages) { if (this.languages.indexOf(navigator.languages[i]) > -1) { this.locale = navigator.languages[i]; return; } } } } setLoginUrl(options) { if (typeof (options.loginURL) === 'function') { this.loginURL = options.loginURL; } else { const url = options.loginURL?.toString() || '/login'; this.loginURL = () => url; } } setRefreshUrl(options) { if (typeof (options.refreshLoginURL) === 'function') { this.refreshLoginURL = options.refreshLoginURL; } else { const url = options.refreshLoginURL?.toString() || ''; this.refreshLoginURL = () => url; } } defaultLogError(level, message, data) { if (level >= this.logLevel) { console.log(`LogLevel: ${level} >= ${this.logLevel}`); console.log(`Message: ${message}`); if (data) { console.log(data); } } } setStorageValue(key, value) { if (this.contentSecurityPolicyActivated) { if (!value) { localStorage.removeItem(key); } else { localStorage.setItem(key, value); } } else { if (!value) { sessionStorage.removeItem(key); } else { sessionStorage.setItem(key, value); } } } } class CaucaCoreService { constructor() { this.httpBackend = inject(HttpBackend); this.translateService = inject(TranslateService$1); this.config = new Configuration(new CoreModuleOptions()); this.jsonIsLoaded = false; } async appInitializer(coreOptions) { this.config = new Configuration(coreOptions); this.setupLocale(); this.config.languages = this.config.languages || ['fr', 'en']; this.translateService.addLangs(this.config.languages); this.translateService.setDefaultLang(this.config.locale); this.translateService.use(this.config.locale); if (coreOptions.jsonConfigFile && !this.jsonIsLoaded) { const httpClient = new HttpClient(this.httpBackend); const jsonConfig = await httpClient.get(coreOptions.jsonConfigFile).toPromise(); this.jsonIsLoaded = true; this.config = Object.assign(this.config, jsonConfig); } } getConfig() { return this.config; } toggleLanguage() { if (this.config.languages.length < 2) { throw new Error('You need to configure at least two languages.'); } else if (this.config.languages.length > 2) { throw new Error('Since you had more then two languages, use "setLanguage(language)".'); } localStorage.setItem('locale', this.config.locale === 'fr' ? 'en' : 'fr'); } setLanguage(language) { if (this.config.languages.length < 2) { throw new Error('You need to configure at least two languages.'); } else if (!this.config.languages.includes(language)) { throw new Error('This language is not available.'); } localStorage.setItem('locale', language); } setupLocale() { const storedLocale = localStorage.getItem('locale'); if (storedLocale && this.config.languages.includes(storedLocale)) { this.config.locale = storedLocale; } else { this.config.locale = this.config.locale || 'fr'; } } static { this.ɵfac = function CaucaCoreService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CaucaCoreService)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: CaucaCoreService, factory: CaucaCoreService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CaucaCoreService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], null, null); })(); class CaucaCoreComponent { static { this.ɵfac = function CaucaCoreComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CaucaCoreComponent)(); }; } static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CaucaCoreComponent, selectors: [["cauca-core"]], standalone: false, decls: 3, vars: 3, template: function CaucaCoreComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div"); i0.ɵɵtext(1); i0.ɵɵpipe(2, "translate"); i0.ɵɵelementEnd(); } if (rf & 2) { i0.ɵɵadvance(); i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(2, 1, "core.noGenericComponentOnThisLibrary")); } }, dependencies: [i1.TranslatePipe], encapsulation: 2 }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CaucaCoreComponent, [{ type: Component, args: [{ selector: 'cauca-core', standalone: false, template: "<div>{{'core.noGenericComponentOnThisLibrary' | translate}}</div>" }] }], null, null); })(); (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CaucaCoreComponent, { className: "CaucaCoreComponent", filePath: "lib/cauca-core.component.ts", lineNumber: 9 }); })(); const CAUCA_CORE_MODULE_OPTIONS_FACTORY = () => new CoreModuleOptions(); const CAUCA_CORE_MODULE_OPTIONS = new InjectionToken('cauca-core-module-options', { providedIn: 'root', factory: CAUCA_CORE_MODULE_OPTIONS_FACTORY, }); class CaucaPageNotFoundComponent { static { this.ɵfac = function CaucaPageNotFoundComponent_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CaucaPageNotFoundComponent)(); }; } static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: CaucaPageNotFoundComponent, selectors: [["cauca-page-not-found"]], standalone: false, decls: 3, vars: 0, consts: [[1, "middle"]], template: function CaucaPageNotFoundComponent_Template(rf, ctx) { if (rf & 1) { i0.ɵɵelementStart(0, "div", 0)(1, "h1"); i0.ɵɵtext(2, "Ooops... page not found"); i0.ɵɵelementEnd()(); } }, styles: [".middle[_ngcontent-%COMP%]{max-width:600px;margin:0 auto}.middle[_ngcontent-%COMP%] h1[_ngcontent-%COMP%]{text-align:center}"] }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CaucaPageNotFoundComponent, [{ type: Component, args: [{ selector: 'cauca-page-not-found', standalone: false, template: "<div class=\"middle\">\n <h1>Ooops... page not found</h1>\n</div>", styles: [".middle{max-width:600px;margin:0 auto}.middle h1{text-align:center}\n"] }] }], null, null); })(); (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(CaucaPageNotFoundComponent, { className: "CaucaPageNotFoundComponent", filePath: "lib/cauca-page-not-found/cauca-page-not-found.component.ts", lineNumber: 9 }); })(); class InterceptorErrorService { constructor() { this.error = new EventEmitter(); } append(statusCode, message) { this.error.emit({ statusCode, message }); } static { this.ɵfac = function InterceptorErrorService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || InterceptorErrorService)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: InterceptorErrorService, factory: InterceptorErrorService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(InterceptorErrorService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], null, null); })(); class HttpOfflineInterceptor { constructor() { this.interceptorErrorService = inject(InterceptorErrorService); } intercept(request, next) { request = request.clone(); if (!navigator.onLine) { return this.onOffline(new HttpErrorResponse({ headers: request.headers, status: 408, statusText: 'Offline', url: request.url, })); } else { return next.handle(request).pipe(catchError((error) => { if (error.status === 0) { return this.onOffline(error); } return throwError(() => error); })); } } onOffline(error) { this.interceptorErrorService.append(error.status, error.statusText); return throwError(() => error); } static { this.ɵfac = function HttpOfflineInterceptor_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HttpOfflineInterceptor)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: HttpOfflineInterceptor, factory: HttpOfflineInterceptor.ɵfac }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HttpOfflineInterceptor, [{ type: Injectable }], null, null); })(); class HttpError { constructor(error) { this.url = error.url || ''; this.status = error.status; this.statusText = error.statusText; if (error.error instanceof ErrorEvent) { this.body = error.error.message; } else if (error.error) { this.body = error.error.title || JSON.stringify(error.error); } } setData(data) { this.data = JSON.stringify(data); } } // eslint-disable-next-line @typescript-eslint/naming-convention const Debounce = (ms) => ((target, key, descriptor) => { const oldFunc = descriptor.value; const newFunc = debounce(oldFunc, ms); descriptor.value = function () { // eslint-disable-next-line prefer-rest-params return newFunc.apply(this, arguments); }; }); class LogService { constructor() { this.coreService = inject(CaucaCoreService); this.errors = []; this.activeSending = new Subject(); const coreService = this.coreService; const handler = inject(HttpBackend); this.config = coreService.getConfig(); this.httpClient = new HttpClient(handler); this.activeSending.subscribe(() => { this.sendErrors(); }); } get errorCount() { return this.errors.length; } get waitToSendAgain() { return this.timer ? true : false; } information(message, data = null) { const config = this.coreService.getConfig(); config.logError(LogLevel.information, message, data); } warning(message, data = null) { const config = this.coreService.getConfig(); config.logError(LogLevel.warning, message, data); } error(message, data = null) { const config = this.coreService.getConfig(); config.logError(LogLevel.error, message, data); } disconnection(message, data = null) { const config = this.coreService.getConfig(); config.logError(LogLevel.disconnection, message, data); } publishInformation(error, data = null) { if (error instanceof HttpErrorResponse) { const httpError = new HttpError(error); httpError.setData(data); this.httpClient.post(`${this.config.apiUrl}Error/LogInformation`, httpError).subscribe(); } } publishWarning(error, data = null) { if (error instanceof HttpErrorResponse) { const httpError = new HttpError(error); httpError.setData(data); this.httpClient.post(`${this.config.apiUrl}Error/LogWarning`, httpError).subscribe(); } } publishError(error, data = null) { if (error instanceof HttpErrorResponse) { const httpError = new HttpError(error); httpError.setData(data); this.errors.push(httpError); this.activeSending.next(); } } sendErrors() { if (!navigator.onLine) { return; } this.stopTimer(); this.httpClient.post(`${this.config.apiUrl}Error/LogErrors`, this.errors).subscribe({ next: () => { this.errors = []; }, error: () => { this.httpClient.post(`${this.config.apiUrl}logErrors`, this.errors).subscribe({ next: () => { this.errors = []; }, error: () => { const minuteToWait = 5 * 60 * 1000; this.timer = setTimeout(() => this.sendErrors(), minuteToWait); } }); } }); } stopTimer() { if (this.timer) { clearTimeout(this.timer); this.timer = null; } } static { this.ɵfac = function LogService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || LogService)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: LogService, factory: LogService.ɵfac, providedIn: 'root' }); } } __decorate([ Debounce(1000) ], LogService.prototype, "sendErrors", null); (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(LogService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [], { sendErrors: [] }); })(); const LOGOUT_HANDLER_TOKEN = new InjectionToken('CoreLogoutHandlerService'); const REFRESH_URL_SERVICE_TOKEN = new InjectionToken('CoreRefreshUrlService'); class RefreshTokenService { constructor() { this.coreService = inject(CaucaCoreService); this.logService = inject(LogService); this.router = inject(Router); this.logoutHandler = inject(LOGOUT_HANDLER_TOKEN, { optional: true }) ?? null; this.refreshUrlService = inject(REFRESH_URL_SERVICE_TOKEN, { optional: true }) ?? null; this.errorPrefix = 'Interceptor - HttpTokenWriter - '; const handler = inject(HttpBackend); this.http = new HttpClient(handler); } refreshToken() { const config = this.coreService.getConfig(); return this.postRefreshToken().pipe(retry(3), map((data) => { this.logService.information(`${this.errorPrefix}Response from refreshing token.`, data); config.accessToken = data.accessToken || ''; if (config.updateToken) { config.updateToken(data); } return data.accessToken ? true : false; }), catchError((error) => { this.logService.information(`${this.errorPrefix}Error when refreshing token.`, error); if (error.status === 0 || error.status === 408) { return of(true); } config.accessToken = ''; if (config.updateToken) { config.updateToken(null); } return of(false); })); } refreshTokenWithRedirect() { const config = this.coreService.getConfig(); const loginUrl = config.loginURL(); return this.refreshToken().pipe(map((response) => { if (!response && location.pathname !== loginUrl) { this.logout(); } this.logService.information(`${this.errorPrefix}Refresh accessToken work.`); return response; })); } logout() { const currentUrl = this.router.routerState.snapshot.url; const config = this.coreService.getConfig(); this.logService.disconnection(`${this.errorPrefix}Could not refresh access token, redirect to login page.`); if (config.useLogoutService) { this.logoutHandler?.logoutWithMessage(currentUrl); } else { const params = config.keepReturnUrlWhenRedirectingToLogin ? { returnUrl: currentUrl } : {}; this.router.navigate([config.loginURL()], { queryParams: params }); } } postRefreshToken() { const config = this.coreService.getConfig(); const host = config.refreshLoginURL(); const token = { accessToken: config.accessToken, refreshToken: config.refreshToken, }; let refreshUrl = this.refreshUrlService?.getRefreshUrl() || host; if (!refreshUrl) { refreshUrl = `/api/Authentication/Refresh`; } return this.http.post(refreshUrl, token); } static { this.ɵfac = function RefreshTokenService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || RefreshTokenService)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: RefreshTokenService, factory: RefreshTokenService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(RefreshTokenService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [], null); })(); class HttpTokenProvider { constructor() { this.isRefreshingToken = new BehaviorSubject(false); this.core = inject(CaucaCoreService); this.tokenRefresher = inject(RefreshTokenService); this.isRefreshing = toSignal(this.isRefreshingToken); } getNewToken() { return this.isRefreshingToken.pipe(take(1), switchMap((refreshing) => refreshing ? this.getToken() : this.refreshToken().pipe(switchMap(() => this.getToken())))); } getToken() { return this.isRefreshingToken .pipe(filter(refreshing => !refreshing), take(1), map$1(() => this.core.getConfig().accessToken)); } refreshToken() { this.isRefreshingToken.next(true); return this.tokenRefresher.refreshToken() .pipe(finalize(() => this.isRefreshingToken.next(false))); } static { this.ɵfac = function HttpTokenProvider_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HttpTokenProvider)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: HttpTokenProvider, factory: HttpTokenProvider.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HttpTokenProvider, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [], null); })(); class HttpTokenWriterInterceptor { constructor() { this.logoutHandler = inject(LOGOUT_HANDLER_TOKEN, { optional: true }) ?? null; this.errorPrefix = 'Interceptor - HttpTokenWriter - '; this.tokenProvider = inject(HttpTokenProvider); this.coreService = inject(CaucaCoreService); this.logService = inject(LogService); this.router = inject(Router); } intercept(request, next) { return this.getRequestWithToken(request) .pipe(switchMap$1((requestWithToken) => this.executeRequest(requestWithToken, next, request))); } executeRequest(request, next, originalRequest) { return next.handle(request).pipe(catchError((error) => { this.logService.information(`${this.errorPrefix}An error has been catch.`); return this.checkIfWeCanManageError(error, originalRequest).pipe(switchMap$1((handledRequest) => this.handleRetry(handledRequest, next)), catchError((unHandleError) => this.handleExecutionError(unHandleError))); })); } handleRetry(request, next) { this.logService.information(`${this.errorPrefix}Occur error can be managed, we resend the original request.`); return this.getRequestWithToken(request).pipe(switchMap$1((clonedRequest) => next.handle(clonedRequest))); } handleExecutionError(unhandledError) { this.logService.warning(`${this.errorPrefix}Occur error can't be managed.`, unhandledError); return throwError(() => unhandledError); } getRequestWithToken(request) { return this.generateHeaders(request) .pipe(map((headers) => request = request.clone({ headers, }))); } generateHeaders(request) { const config = this.coreService.getConfig(); if (config.accessToken) { return this.tokenProvider.getToken() .pipe(map((token) => this.setupHeaders(request, token))); } else { return of(this.setupHeaders(request, null)); } } setupHeaders(request, token) { let headers = request.headers; const config = this.coreService.getConfig(); const isFormData = request.body instanceof FormData; this.logService.information(`${this.errorPrefix}The request has a header authorization.`, config); if (!headers.has('Authorization') && token) { headers = headers.set('Authorization', `${config.authorizationType} ${token}`); } if (!headers.has('X-CSRF-Token') && config.CSRFToken) { headers = headers.set('X-CSRF-Token', `${config.CSRFToken}`); if (config.CSRFCookie) { headers = headers.set('X-CSRF-Cookie', `${config.CSRFCookie}`); } } if (!headers.has('Content-Type') && !isFormData) { headers = headers.set('Content-Type', `application/json; charset=${config.charset}`); } if (!headers.has('Language-Code')) { headers = headers.set('Language-Code', config.locale); } return headers; } checkIfWeCanManageError(error, originalRequest) { const config = this.coreService.getConfig(); const loginUrl = config.loginURL(); this.logService.information(`${this.errorPrefix}Check if we can refresh the accessToken.`, error); if (error.status === 401 && config.accessToken && config.allowRefreshToken) { this.logService.information(`${this.errorPrefix}Try to refresh the user access token.`); return this.retryWithNewToken(originalRequest, loginUrl); } else if (error.status === 401 && config.accessToken && location.pathname !== loginUrl) { this.logout(); } else if (error.status === 200) { if (error.message && error.message.indexOf('Http failure during parsing for') === 0) { this.logService.information(`${this.errorPrefix}Does not receive a JSON, so the call is send with "text/html".`); return of(this.resendAsHTML(originalRequest)); } } this.logService.information(`${this.errorPrefix}Error receive can't be manage.`); return throwError(() => error); } retryWithNewToken(request, loginUrl) { return this.tokenProvider.getNewToken().pipe(map((token) => this.handleRefreshResponse(request, token, loginUrl))); } handleRefreshResponse(request, token, loginUrl) { if (!token && location.pathname !== loginUrl) { this.logout(); } this.logService.information(`${this.errorPrefix}Refresh accessToken work.`); return request; } logout() { const currentUrl = this.router.routerState.snapshot.url; const config = this.coreService.getConfig(); this.logService.disconnection(`${this.errorPrefix}Could not refresh access token, redirect to login page.`); if (config.useLogoutService) { this.logoutHandler?.logoutWithMessage(currentUrl); } else { const params = config.keepReturnUrlWhenRedirectingToLogin ? { returnUrl: currentUrl } : {}; this.router.navigate([config.loginURL()], { queryParams: params }); } } resendAsHTML(originalRequest) { const config = this.coreService.getConfig(); let headers = originalRequest.headers; headers = headers.set('Content-Type', `text/html; charset=${config.charset}`); return originalRequest.clone({ responseType: 'text', headers, }); } static { this.ɵfac = function HttpTokenWriterInterceptor_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HttpTokenWriterInterceptor)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: HttpTokenWriterInterceptor, factory: HttpTokenWriterInterceptor.ɵfac }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HttpTokenWriterInterceptor, [{ type: Injectable }], null, null); })(); class HttpTokenReaderInterceptor { constructor() { this.coreService = inject(CaucaCoreService); } intercept(request, next) { return next.handle(request).pipe(map((response) => { if (response.headers && response.headers.get('x-csrf-token')) { this.coreService.getConfig().CSRFToken = response.headers.get('x-csrf-token'); } if (response.headers && response.headers.get('x-csrf-cookie')) { this.coreService.getConfig().CSRFCookie = response.headers.get('x-csrf-cookie'); } return response; })); } static { this.ɵfac = function HttpTokenReaderInterceptor_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HttpTokenReaderInterceptor)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: HttpTokenReaderInterceptor, factory: HttpTokenReaderInterceptor.ɵfac }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HttpTokenReaderInterceptor, [{ type: Injectable }], null, null); })(); class HttpErrorInterceptor { constructor() { this.logService = inject(LogService); this.interceptorErrorService = inject(InterceptorErrorService); const coreService = inject(CaucaCoreService); this.config = coreService.getConfig(); } intercept(request, next) { return next.handle(request).pipe(retry({ count: this.config.nbRetryOnNetworkError, delay: (error) => this.handleRetry(error) }), catchError((error) => this.handleError(error, request))); } handleRetry(error) { const isNetworkError = [0, 408, 502, 503, 504].includes(error.status); this.logService.information(`Interceptor - HttpErrorInterceptor - Status code "${error.status}"`); if (isNetworkError) { return timer(100); } throw error; } handleError(error, request) { if (error instanceof HttpErrorResponse) { if (error.status === 0) { this.interceptorErrorService.append(0, 'La demande ne peut être complétée.'); } else if (error.status === 400) { if (error.error && error.error.message) { this.interceptorErrorService.append(400, error.error.message); } else if (error.error && error.error.title) { this.interceptorErrorService.append(400, error.error.title); } else if (error.error) { if (typeof error.error === 'string') { this.interceptorErrorService.append(400, error.error); } } else if (error.statusText) { this.interceptorErrorService.append(400, error.statusText); } else { this.interceptorErrorService.append(400, 'La demande ne peut pas être complétée.'); } } else if (error.status === 404) { this.interceptorErrorService.append(404, 'Le URL demandé n\'existe pas.'); } else if (error.status === 500) { this.interceptorErrorService.append(500, 'Erreur de communication.'); } else if (error.status !== 200 && error.status !== 401) { this.interceptorErrorService.append(error.status, error.statusText); } } if (this.config.onHttpError != null) { this.config.onHttpError(error, request.method, request.urlWithParams); } return throwError(() => error); } static { this.ɵfac = function HttpErrorInterceptor_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || HttpErrorInterceptor)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: HttpErrorInterceptor, factory: HttpErrorInterceptor.ɵfac }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(HttpErrorInterceptor, [{ type: Injectable }], () => [], null); })(); class CustomMissingTranslationHandler { handle(params) { return `i18n "${params.key}" is missing`; } } class CustomMultiTranslateHttpLoader { constructor(httpBackend, options) { this.resources = [{ prefix: '/assets/i18n/', suffix: '.json', }, { prefix: '/assets/i18n/cauca/', suffix: '-core.json', }]; this.http = new HttpClient(httpBackend); if (options && options.libraries) { options.libraries.forEach((library) => { this.resources.push({ prefix: '/assets/i18n/cauca/', suffix: `-${library}.json`, }); }); } if (options && options.i18nPaths) { options.i18nPaths.forEach((path) => { this.resources.push({ prefix: `/assets/i18n/${path}/`, suffix: `.json`, }); }); } } getTranslation(lang) { return forkJoin(this.resources.map((config) => this.getOneResourceTranslation(lang, config))).pipe(map((response) => response.reduce((a, b) => Object.assign(a, b)))); } getOneResourceTranslation(lang, config) { return this.http.get(`${config.prefix}${lang}${config.suffix}`).pipe(catchError(() => of({}))); } } /** * @deprecated Use TranslateService from @ngx-translate/core instead. You need to use provideCaucaCore to make it work. */ class TranslateService extends TranslateService$1 { constructor() { const store = inject(TranslateStore); const currentLoader = inject(TranslateLoader); const compiler = inject(TranslateCompiler); const parser = inject(TranslateParser); const missingTranslationHandler = inject(MissingTranslationHandler); const httpBackend = inject(HttpBackend); super(store, currentLoader, compiler, parser, missingTranslationHandler, false, false, false, 'fr'); this.coreService = inject(CaucaCoreService); this.multiLangDictionary = {}; this.http = new HttpClient(httpBackend); } async appInitializer() { const config = this.coreService.getConfig(); this.addLangs(config.languages); this.setDefaultLang(config.locale); return new Promise((resolve) => { this.use(config.locale) .subscribe({ complete: () => resolve() }); }); } getMultilingualTranslations(languages, wordsToTranslate) { if (!this.multiLangDictionary[languages[0]]) { return forkJoin(this.coreService.getConfig().languages.map((lang) => this.loadOneLanguage(lang))).pipe(map(() => this.getTranslationForSpecificLanguages(languages, wordsToTranslate))); } return new Observable((observer) => { observer.next(this.getTranslationForSpecificLanguages(languages, wordsToTranslate)); observer.complete(); }); } loadOneLanguage(lang) { return this.getTranslation(lang).pipe(catchError(() => of({})), map((result) => { this.multiLangDictionary[lang] = result; })); } getTranslationForSpecificLanguages(languages, wordsToTranslate) { const objectToReturn = {}; languages.forEach((lang) => { objectToReturn[lang] = {}; wordsToTranslate.forEach((word) => { const levels = word.split('.'); let translation = this.multiLangDictionary[lang]; levels.forEach((level) => { translation = translation[level]; }); objectToReturn[lang][word] = translation; }); }); return objectToReturn; } static { this.ɵfac = function TranslateService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || TranslateService)(); }; } static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: TranslateService, factory: TranslateService.ɵfac, providedIn: 'root' }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(TranslateService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], () => [], null); })(); const configFactory = (coreService) => (coreService.getConfig().locale); const translateFactory = (translateService, coreOptions, coreService, logService, injector) => { const promise = async () => { await coreService.appInitializer(coreOptions); await injector.get(LOCATION_INITIALIZED, Promise.resolve(null)); logService.information(`CaucaCoreModule - Use config.`, coreService.getConfig()); return translateService.appInitializer(); }; return promise; }; const TRANSLATE_CONFIGURATION$1 = { loader: { provide: TranslateLoader, useClass: CustomMultiTranslateHttpLoader, deps: [HttpBackend, CAUCA_CORE_MODULE_OPTIONS] }, missingTranslationHandler: { provide: MissingTranslationHandler, useClass: CustomMissingTranslationHandler, }, useDefaultLang: false }; function provideCaucaCore(options) { const providers = [ CaucaCoreService, RefreshTokenService, { provide: CAUCA_CORE_MODULE_OPTIONS, useValue: options }, { provide: HTTP_INTERCEPTORS, useClass: HttpOfflineInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpTokenWriterInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpTokenReaderInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true }, { provide: options.locale, useFactory: configFactory, deps: [CaucaCoreService] }, provideAppInitializer(() => { const initializerFn = (translateFactory)(inject(TranslateService), inject(CAUCA_CORE_MODULE_OPTIONS), inject(CaucaCoreService), inject(LogService), inject(Injector)); return initializerFn(); }), { provide: LOCALE_ID, useFactory: configFactory, deps: [CaucaCoreService] }, importProvidersFrom(TranslateModule.forRoot(TRANSLATE_CONFIGURATION$1)), ]; if (options.logoutService) { providers.push({ provide: LOGOUT_HANDLER_TOKEN, useClass: options.logoutService }); } if (options.refreshUrlService) { providers.push({ provide: REFRESH_URL_SERVICE_TOKEN, useClass: options.refreshUrlService }); } return providers; } /** * @deprecated Use provideCaucaCore() instead */ class CaucaCoreModule { static { this.ɵfac = function CaucaCoreModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CaucaCoreModule)(); }; } static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: CaucaCoreModule }); } static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ providers: [ CaucaCoreService, RefreshTokenService, { provide: HTTP_INTERCEPTORS, useClass: HttpOfflineInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpTokenWriterInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpTokenReaderInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true }, { provide: LOCALE_ID, useFactory: configFactory, deps: [CaucaCoreService] }, provideAppInitializer(() => { const initializerFn = (translateFactory)(inject(TranslateService), inject(CAUCA_CORE_MODULE_OPTIONS), inject(CaucaCoreService), inject(LogService), inject(Injector)); return initializerFn(); }), provideHttpClient(withInterceptorsFromDi()) ], imports: [TranslateModule.forRoot(TRANSLATE_CONFIGURATION$1), TranslateModule] }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CaucaCoreModule, [{ type: NgModule, args: [{ declarations: [ CaucaCoreComponent, CaucaPageNotFoundComponent, ], exports: [ CaucaCoreComponent, CaucaPageNotFoundComponent, TranslateModule, ], imports: [TranslateModule.forRoot(TRANSLATE_CONFIGURATION$1)], providers: [ CaucaCoreService, RefreshTokenService, { provide: HTTP_INTERCEPTORS, useClass: HttpOfflineInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpTokenWriterInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpTokenReaderInterceptor, multi: true }, { provide: HTTP_INTERCEPTORS, useClass: HttpErrorInterceptor, multi: true }, { provide: LOCALE_ID, useFactory: configFactory, deps: [CaucaCoreService] }, provideAppInitializer(() => { const initializerFn = (translateFactory)(inject(TranslateService), inject(CAUCA_CORE_MODULE_OPTIONS), inject(CaucaCoreService), inject(LogService), inject(Injector)); return initializerFn(); }), provideHttpClient(withInterceptorsFromDi()) ] }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(CaucaCoreModule, { declarations: [CaucaCoreComponent, CaucaPageNotFoundComponent], imports: [i1.TranslateModule], exports: [CaucaCoreComponent, CaucaPageNotFoundComponent, TranslateModule] }); })(); const configFactoryForLazyLoading = (coreService) => (coreService.getConfig().locale); const TRANSLATE_CONFIGURATION = { loader: { provide: TranslateLoader, useClass: CustomMultiTranslateHttpLoader, deps: [HttpBackend, CAUCA_CORE_MODULE_OPTIONS] }, missingTranslationHandler: { provide: MissingTranslationHandler, useClass: CustomMissingTranslationHandler, }, useDefaultLang: false }; class CaucaCoreForChildModule { static { this.ɵfac = function CaucaCoreForChildModule_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || CaucaCoreForChildModule)(); }; } static { this.ɵmod = /*@__PURE__*/ i0.ɵɵdefineNgModule({ type: CaucaCoreForChildModule }); } static { this.ɵinj = /*@__PURE__*/ i0.ɵɵdefineInjector({ imports: [TranslateModule.forChild(TRANSLATE_CONFIGURATION), TranslateModule] }); } } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(CaucaCoreForChildModule, [{ type: NgModule, args: [{ declarations: [], exports: [ TranslateModule, ], imports: [ TranslateModule.forChild(TRANSLATE_CONFIGURATION), ], providers: [], }] }], null, null); })(); (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0.ɵɵsetNgModuleScope(CaucaCoreForChildModule, { imports: [i1.TranslateModule], exports: [TranslateModule] }); })(); class ApiLookupService { constructor() { this.http = inject(HttpClient); const http = this.http; this.http = http; } getIpInformation() { return new Observable((observer) => { this.lookupIpWithIpApi().subscribe((result) => { observer.next(result); observer.complete(); }, () => { this.lookupIpWithGeoIpDb().subscribe((result) => { observer.next(result); observer.complete(); }, () => { observer.error('Can\'t lookup the IP address'); }); }); }); } lookupIpWithGeoIpDb() { return new Observable((observer) => { this.http.get('http://geoip-db.com/json').subscribe((response) => { observer.next({ country: response['country_code'], countryName: response['country_name'], stateName: response['state'], cityName: response['city'], longitude: response['longitude'], latitude: response['latitude'], ipAddress: response['IPv4'], }); observer.complete(); }, (error) => { observer.error(error); }); }); } lookupIpWithIpApi() { return new Observable((observer) => { this.http.get('http://ip-api.com/json').subscribe((response) => { observer.next({ country: response['countryCode'], countryName: response['country'], state: response['region'], stateName: response['regionName'], cityName: response['city'], isp: response['isp