commit
This commit is contained in:
145
frontend/src/app/interceptors/auth.interceptor.ts
Normal file
145
frontend/src/app/interceptors/auth.interceptor.ts
Normal 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
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user