76 lines
2.6 KiB
TypeScript
76 lines
2.6 KiB
TypeScript
// Copyright (c) 2023 Tudor Stanciu
|
|
|
|
import { request } from "./utils/axios";
|
|
import { localStorage } from "@flare/utiliyo";
|
|
import { storageKeys } from "./constants";
|
|
import { getUrlTemplates } from "./config";
|
|
import { isValidURL } from "./utils/validations";
|
|
import type { UrlTemplates } from "./config";
|
|
import type { TuitioLoginResponse, TuitioLogoutResponse, TuitioUserInfo } from "./types";
|
|
|
|
const { setItem, getItem, removeItem } = localStorage;
|
|
|
|
const computeSafetyMargin = (expiresIn: number): number => {
|
|
let safetyMargin = 10; // 10 seconds of safety margin
|
|
const factor = expiresIn / safetyMargin;
|
|
if (factor <= 1) safetyMargin = 0;
|
|
else if (factor < 5) safetyMargin = 5;
|
|
return safetyMargin;
|
|
};
|
|
|
|
const computeValidUntil = (expiresIn: number): Date => {
|
|
const safetyMargin = computeSafetyMargin(expiresIn);
|
|
const _expiresIn = expiresIn - safetyMargin;
|
|
const currentDate = new Date();
|
|
const validUntil = new Date(currentDate.getTime() + _expiresIn * 1000); // adding "expiresIn" seconds in milliseconds
|
|
return validUntil;
|
|
};
|
|
|
|
class TuitioClient {
|
|
tuitioUrl: string;
|
|
urlTemplates: UrlTemplates;
|
|
|
|
constructor(tuitioUrl: string | null) {
|
|
if (tuitioUrl === null || tuitioUrl === "" || isValidURL(tuitioUrl) === false) {
|
|
throw new Error(`TuitioClient: ${tuitioUrl} is not a valid URL.`);
|
|
}
|
|
|
|
this.tuitioUrl = tuitioUrl;
|
|
this.urlTemplates = getUrlTemplates(this.tuitioUrl);
|
|
}
|
|
|
|
async login(userName: string, password: string): Promise<TuitioLoginResponse> {
|
|
const url = this.urlTemplates.login.replace("{username}", userName).replace("{password}", encodeURIComponent(password));
|
|
|
|
const response = await request(url, "post");
|
|
if (!response.error) {
|
|
const validUntil = computeValidUntil(response.result.expiresIn);
|
|
const authData = { token: response.result.token, validUntil, userName };
|
|
setItem(storageKeys.AUTH_DATA, authData);
|
|
response.result.validUntil = validUntil;
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
async logout(): Promise<TuitioLogoutResponse> {
|
|
const authData = getItem(storageKeys.AUTH_DATA);
|
|
if (!authData) return { result: null, error: "UNAUTHENTICATED" } as TuitioLogoutResponse;
|
|
const url = this.urlTemplates.logout.replace("{token}", authData.token);
|
|
const response = await request(url, "post");
|
|
if (!response.error) {
|
|
removeItem(storageKeys.AUTH_DATA);
|
|
}
|
|
return response;
|
|
}
|
|
|
|
async getUserInfo(): Promise<TuitioUserInfo> {
|
|
const url = this.urlTemplates.userInfo;
|
|
const response = await request(url, "get");
|
|
return response;
|
|
}
|
|
}
|
|
|
|
export { TuitioClient };
|
|
export default TuitioClient;
|