Files
cbsnexora/src/app/zitadel/token.interceptor.ts
T

73 lines
2.6 KiB
TypeScript

/**
* Copyright since 2025 Mifos Initiative
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { Injectable, inject } from '@angular/core';
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpErrorResponse } from '@angular/common/http';
import { Observable, throwError, from } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { AuthService } from './auth.service';
import { environment } from '../../environments/environment';
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
private authService = inject(AuthService);
public environment = environment;
FINERACT_PLATFORM_TENANT_IDENTIFIER = environment.fineractPlatformTenantId;
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
const token = this.authService.getAccessToken();
let headersConfig: { [key: string]: string } = {
'Fineract-Platform-TenantId': this.FINERACT_PLATFORM_TENANT_IDENTIFIER,
'Content-Type': req.headers.get('Content-Type') || 'application/json'
};
const publicEndpoints = [
'/auth/test',
'/health'
];
const isPublicEndpoint = publicEndpoints.some((url) => req.url.includes(url));
if (token && !isPublicEndpoint) {
headersConfig['Authorization'] = `Bearer ${token}`;
}
const authReq = req.clone({ setHeaders: headersConfig });
return next.handle(authReq).pipe(
catchError((err) => {
if (err instanceof HttpErrorResponse && err.status === 401 && !isPublicEndpoint) {
return from(this.handle401Error(authReq, next));
}
return throwError(() => err);
})
);
}
private async handle401Error(request: HttpRequest<any>, next: HttpHandler): Promise<HttpEvent<any>> {
try {
await this.authService.refreshToken();
const newToken = this.authService.getAccessToken();
if (newToken) {
const retriedReq = request.clone({
setHeaders: {
Authorization: `Bearer ${newToken}`,
'Fineract-Platform-TenantId': this.FINERACT_PLATFORM_TENANT_IDENTIFIER,
'Content-Type': request.headers.get('Content-Type') || 'application/json'
}
});
return next.handle(retriedReq).toPromise() as Promise<HttpEvent<any>>;
} else {
throw new Error('No new access token obtained after refresh');
}
} catch (e) {
console.error('Error in handle401Error, forcing logout');
throw e;
}
}
}