213 lines
6.0 KiB
TypeScript
213 lines
6.0 KiB
TypeScript
import { FrontendVariables } from "@Front/Config/VariablesFront";
|
|
import CookieService from "@Front/Services/CookieService/CookieService";
|
|
import jwt_decode from "jwt-decode";
|
|
import JwtService, { ICustomerJwtPayload, IUserJwtPayload } from "@Front/Services/JwtService/JwtService";
|
|
|
|
export enum ContentType {
|
|
JSON = "application/json",
|
|
PDF = "application/pdf",
|
|
FORM_DATA = "multipart/form-data;",
|
|
PNG = "image/png",
|
|
}
|
|
|
|
export type IRef = {
|
|
response?: Response;
|
|
};
|
|
export default abstract class BaseApiService {
|
|
private static baseUrl: string;
|
|
protected readonly variables = FrontendVariables.getInstance();
|
|
|
|
protected constructor() {
|
|
BaseApiService.baseUrl ??=
|
|
this.variables.BACK_API_PROTOCOL +
|
|
this.variables.BACK_API_HOST +
|
|
this.variables.BACK_API_ROOT_URL +
|
|
this.variables.BACK_API_VERSION;
|
|
}
|
|
|
|
protected getBaseUrl(): string {
|
|
return BaseApiService.baseUrl;
|
|
}
|
|
|
|
protected buildHeaders(contentType: ContentType) {
|
|
const token = CookieService.getInstance().getCookie("leCoffreAccessToken");
|
|
|
|
const headers = new Headers();
|
|
|
|
if (contentType === ContentType.JSON || contentType === ContentType.PDF) {
|
|
headers.set("Content-Type", contentType);
|
|
}
|
|
headers.set("Authorization", `Bearer ${token}`);
|
|
return headers;
|
|
}
|
|
|
|
protected buildBody(body: { [key: string]: unknown }): string {
|
|
return JSON.stringify(body);
|
|
}
|
|
|
|
protected async getRequest<T>(url: URL, token?: string, contentType?: ContentType, ref?: IRef, fileName?: string) {
|
|
await this.checkJwtToken();
|
|
const request = async () =>
|
|
await fetch(url, {
|
|
method: "GET",
|
|
headers: this.buildHeaders(contentType ?? ContentType.JSON),
|
|
});
|
|
return this.sendRequest<T>(request, ref, fileName);
|
|
}
|
|
|
|
protected async postRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
|
|
//await this.checkJwtToken();
|
|
return this.sendRequest<T>(
|
|
async () =>
|
|
await fetch(url, {
|
|
method: "POST",
|
|
headers: this.buildHeaders(ContentType.JSON),
|
|
body: this.buildBody(body),
|
|
}),
|
|
);
|
|
}
|
|
|
|
protected async postRequestFormData<T>(url: URL, body: FormData) {
|
|
await this.checkJwtToken();
|
|
return this.sendRequest<T>(
|
|
async () =>
|
|
await fetch(url, {
|
|
method: "POST",
|
|
headers: this.buildHeaders(ContentType.FORM_DATA),
|
|
body,
|
|
}),
|
|
);
|
|
}
|
|
|
|
protected async putRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
|
|
await this.checkJwtToken();
|
|
const request = async () =>
|
|
await fetch(url, {
|
|
method: "PUT",
|
|
headers: this.buildHeaders(ContentType.JSON),
|
|
body: this.buildBody(body),
|
|
});
|
|
|
|
return this.sendRequest<T>(request);
|
|
}
|
|
|
|
protected async patchRequest<T>(url: URL, body: { [key: string]: unknown } = {}) {
|
|
await this.checkJwtToken();
|
|
const request = async () =>
|
|
await fetch(url, {
|
|
method: "PATCH",
|
|
headers: this.buildHeaders(ContentType.JSON),
|
|
body: this.buildBody(body),
|
|
});
|
|
|
|
return this.sendRequest<T>(request);
|
|
}
|
|
|
|
protected async deleteRequest<T>(url: URL, body: { [key: string]: unknown } = {}, token?: string) {
|
|
await this.checkJwtToken();
|
|
const request = async () =>
|
|
await fetch(url, {
|
|
method: "DELETE",
|
|
headers: this.buildHeaders(ContentType.JSON),
|
|
body: this.buildBody(body),
|
|
});
|
|
|
|
return this.sendRequest<T>(request);
|
|
}
|
|
|
|
protected async putFormDataRequest<T>(url: URL, body: FormData, token?: string) {
|
|
await this.checkJwtToken();
|
|
const request = async () =>
|
|
await fetch(url, {
|
|
method: "PUT",
|
|
headers: this.buildHeaders(ContentType.FORM_DATA),
|
|
body,
|
|
});
|
|
|
|
return this.sendRequest<T>(request);
|
|
}
|
|
|
|
private async sendRequest<T>(request: () => Promise<Response>, ref?: IRef, fileName?: string): Promise<T> {
|
|
const response = await request();
|
|
|
|
return this.processResponse<T>(response, request, ref, fileName);
|
|
}
|
|
|
|
private async checkJwtToken() {
|
|
const accessToken = CookieService.getInstance().getCookie("leCoffreAccessToken");
|
|
if (!accessToken) return;
|
|
|
|
const userDecodedToken = jwt_decode(accessToken) as IUserJwtPayload;
|
|
const customerDecodedToken = jwt_decode(accessToken) as ICustomerJwtPayload;
|
|
|
|
if (!userDecodedToken && !customerDecodedToken) return;
|
|
|
|
const now = Math.floor(Date.now() / 1000);
|
|
if (userDecodedToken.userId && userDecodedToken.exp < now) {
|
|
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
|
|
if (!refreshToken) {
|
|
return;
|
|
}
|
|
const decodedRefreshToken = jwt_decode(refreshToken) as IUserJwtPayload | ICustomerJwtPayload;
|
|
if (decodedRefreshToken.exp < now) {
|
|
return;
|
|
}
|
|
await JwtService.getInstance().refreshToken(refreshToken);
|
|
}
|
|
if (customerDecodedToken.customerId && customerDecodedToken.exp < now) {
|
|
const refreshToken = CookieService.getInstance().getCookie("leCoffreRefreshToken");
|
|
if (!refreshToken) {
|
|
return;
|
|
}
|
|
const decodedRefreshToken = jwt_decode(refreshToken) as IUserJwtPayload | ICustomerJwtPayload;
|
|
if (decodedRefreshToken.exp < now) {
|
|
return;
|
|
}
|
|
await JwtService.getInstance().refreshToken(refreshToken);
|
|
}
|
|
return;
|
|
}
|
|
|
|
protected async processResponse<T>(response: Response, request: () => Promise<Response>, ref?: IRef, fileName?: string): Promise<T> {
|
|
let responseContent: T;
|
|
ref && (ref["response"] = response);
|
|
if (response.ok) {
|
|
// Check the Content-Type header to determine the response type
|
|
const contentType = response.headers.get("Content-Type");
|
|
if (contentType && !contentType.includes("application/json")) {
|
|
responseContent = (await response.blob()) as T;
|
|
} else {
|
|
// Handle JSON response
|
|
try {
|
|
responseContent = await response.json();
|
|
} catch (err) {
|
|
return Promise.reject(err);
|
|
}
|
|
}
|
|
} else {
|
|
// Handle error response
|
|
const responseCopy = response.clone();
|
|
try {
|
|
const responseJson = await response.json();
|
|
return Promise.reject(responseJson);
|
|
} catch (err) {
|
|
const responseText = await responseCopy.text();
|
|
return Promise.reject({
|
|
http_status: response.status,
|
|
message: responseText,
|
|
});
|
|
}
|
|
}
|
|
|
|
return responseContent;
|
|
}
|
|
|
|
protected onError(error: unknown) {
|
|
//console.error(error);
|
|
}
|
|
}
|
|
|
|
export interface IResponse {
|
|
http_status: number;
|
|
}
|