tuitio-client/src/client.ts

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;