This commit is contained in:
2026-05-21 21:33:37 +05:30
parent f50dd4692d
commit 26478608b1
28 changed files with 4948 additions and 259 deletions

View File

@@ -0,0 +1,145 @@
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
);
}
}
}