145 lines
4.2 KiB
TypeScript
145 lines
4.2 KiB
TypeScript
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
|
||
);
|
||
}
|
||
}
|
||
} |