Files
OCR/frontend/src/app/interceptors/auth.interceptor.ts
2026-05-21 21:33:37 +05:30

145 lines
4.2 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { SessionService } from './../services/commons/session.service';
import {
HttpInterceptorFn,
HttpRequest,
HttpHandlerFn,
HttpEvent,
HttpResponse,
HttpErrorResponse,
HttpHeaders
} from '@angular/common/http';
import { Observable, tap, catchError, throwError, from, switchMap } from 'rxjs';
import { EncryptionService } from '../services/utilities/encryption.service';
import { inject } from '@angular/core';
import { ResponseDto } from '../models/response.dto';
export const AuthInterceptor: HttpInterceptorFn = (
req: HttpRequest<any>,
next: HttpHandlerFn
): Observable<HttpEvent<any>> => {
const encryptionService = inject(EncryptionService);
const sessionService = inject(SessionService);
/* -----------------------------------------
* 1⃣ Always attach Authorization header
* ----------------------------------------- */
// OCR uses sessionStorage for token now (migrated previously)
const token = sessionStorage.getItem('token');
let reqHeaders = req.headers;
// Only set application/json if it's not FormData
// FormData requests need the browser to set Content-Type with boundary
if (!(req.body instanceof FormData)) {
reqHeaders = reqHeaders.set('Content-Type', 'application/json');
}
if (token) {
reqHeaders = reqHeaders.set(
'Authorization',
`Bearer ${token}`
);
}
/* -----------------------------------------
* 2⃣ Handle encrypted (compressed) requests
* ----------------------------------------- */
if (
req.body &&
typeof req.body === 'object' &&
req.body.compressed
) {
return from(encryptionService.encrypt(req.body.data)).pipe(
switchMap(encryptedBody => {
const payload = {
scopes: req.body.scopes ?? [],
data: encryptedBody,
target: req.body.target ?? null,
compressed: true
};
const modifiedReq = req.clone({
body: payload,
headers: reqHeaders
});
// Use 'any' type for event to avoid strict type mismatch if ResponseDto structure varies
return next(modifiedReq).pipe(
tap((event: any) => handleResponse(event, sessionService, encryptionService)),
catchError((error: HttpErrorResponse) =>
throwError(() => error)
)
);
})
);
}
/* -----------------------------------------
* 3⃣ Non-encrypted requests (GET included)
* ----------------------------------------- */
const modifiedReq = req.clone({
headers: reqHeaders
});
return next(modifiedReq).pipe(
tap((event: any) => handleResponse(event, sessionService, encryptionService)),
catchError((error: HttpErrorResponse) =>
throwError(() => error)
)
);
};
function handleResponse(
event: HttpEvent<any>,
sessionService: SessionService,
encryptionService: EncryptionService
): void {
if (!(event instanceof HttpResponse) || !event.ok) {
return;
}
// Handle Authenticate Response
if (event.url?.endsWith('/authenticate')) {
const response = event.body as ResponseDto;
if (response?.data?.token) {
sessionStorage.setItem('token', response.data.token);
}
if (response?.data?.companies) {
sessionService.setItem('companies', response.data.companies);
}
}
// Handle Authorize Response
if (event.url?.endsWith('/authorize')) {
const response = event.body as ResponseDto;
// Clearing session might be too aggressive if we just logged in, but following source logic
// sessionService.clear();
if (response?.data?.token) {
sessionStorage.setItem('token', response.data.token);
}
if (response?.data?.refreshToken) {
sessionService.setItem('refreshToken', response.data.refreshToken);
}
if (response?.data?.userDetails) {
sessionService.setItem('userDetails', response.data.userDetails);
}
if (response?.data?.data) {
encryptionService.encrypt(response.data.data)
.then(encryptedNav => {
sessionService.setItem('nav', encryptedNav);
});
}
if (response?.data?.companies) {
sessionService.setItem(
'companies',
response.data.companies
);
}
}
}