@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
JavaScript
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