From 5c3c2acfdd3706f616379f8096a04f09e5fac521 Mon Sep 17 00:00:00 2001 From: Tudor Stanciu Date: Sun, 9 Apr 2023 13:31:44 +0300 Subject: [PATCH] [1.2.5] - The token "expires in" information measuring unit was changed from milliseconds to seconds. --- README.md | 13 +++++++------ package-lock.json | 4 ++-- package.json | 2 +- src/__tests__/TuitioLogin.test.ts | 29 ++++++++++++++++++++--------- src/client.ts | 20 +++++++++++++++++--- 5 files changed, 47 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index e6390b7..5e68ced 100644 --- a/README.md +++ b/README.md @@ -33,14 +33,15 @@ All tests in the package can be executed by running: `npm test`. ## Changelog -1.0.0 - Package initialization -1.0.1 - Export Tuitio types -1.0.2 - Validate that Tuitio's URL parameter is a valid URL -1.0.3 - Added LICENSE file -1.0.4 - TuitioState's token property can be null +1.0.0 - Package initialization. +1.0.1 - Export Tuitio types. +1.0.2 - Validate that Tuitio's URL parameter is a valid URL. +1.0.3 - Added LICENSE file. +1.0.4 - TuitioState's token property can be null. 1.1.0 - In this version, the account logout method and the latest changes published by Tuitio were implemented. 1.2.0 - Has been implemented the "user-info" method exposed by the Tuitio API. 1.2.1 - Added decodeToken function. The token is obtained directly by the function from local storage. If the token is missing, the function returns null. 1.2.2 - Upgraded @flare/js-utils package. 1.2.3 - Added user group and role types after enriching the "user-info" result. -1.2.4 - Password encoding at login. +1.2.4 - Password encoding at login. +1.2.5 - The token "expires in" information measuring unit was changed from milliseconds to seconds. diff --git a/package-lock.json b/package-lock.json index f3b9f9f..9a0a197 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@flare/tuitio-client", - "version": "1.2.4", + "version": "1.2.5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@flare/tuitio-client", - "version": "1.2.4", + "version": "1.2.5", "license": "MIT", "dependencies": { "@flare/js-utils": "^1.1.0", diff --git a/package.json b/package.json index af03fbf..2e552ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@flare/tuitio-client", - "version": "1.2.4", + "version": "1.2.5", "description": "Tuitio client is an npm package written in typescript that facilitates the integration of a javascript application with Tuitio.", "main": "./lib/index.js", "types": "./lib/index.d.ts", diff --git a/src/__tests__/TuitioLogin.test.ts b/src/__tests__/TuitioLogin.test.ts index 91b8e1b..3a6c64e 100644 --- a/src/__tests__/TuitioLogin.test.ts +++ b/src/__tests__/TuitioLogin.test.ts @@ -10,28 +10,39 @@ import { fetch } from "../state"; jest.mock("axios"); -test("Tuitio client: successfully account login", async () => { +const mockResult = (expiresIn: number = 240) => ({ + result: { + token: "token-mock", + expiresIn + }, + error: null +}); + +test.each([240, 100, 20, 10, 5])("Tuitio client: successfully account login", async (expiresIn: number) => { + const mock = mockResult(expiresIn); + (axios.request as jest.Mock).mockResolvedValue({ data: { - result: { - token: "token-mock", - expiresIn: 600000 - }, - error: null + ...mock } }); const client = new TuitioClient("https://test.com/api"); const loginResult = await client.login("user", "pass"); - expect(loginResult.result?.token).toBe("token-mock"); - expect(loginResult.result?.expiresIn).toBe(600000); + expect(loginResult.result?.token).toBe(mock.result.token); + expect(loginResult.result?.expiresIn).toBe(mock.result.expiresIn); expect(loginResult.result?.validUntil).toBeDefined(); + const validUntilTime = loginResult.result?.validUntil.getTime(); + if (validUntilTime) { + const now = new Date(); + expect(validUntilTime).toBeGreaterThan(now.getTime()); + } expect(loginResult.error).toBeNull(); const storage = fetch(); expect(storage).toBeDefined(); - expect(storage?.token).toBe("token-mock"); + expect(storage?.token).toBe(mock.result.token); expect(storage?.userName).toBe("user"); }); diff --git a/src/client.ts b/src/client.ts index db819e5..a597790 100644 --- a/src/client.ts +++ b/src/client.ts @@ -10,6 +10,22 @@ import type { TuitioLoginResponse, TuitioLogoutResponse, TuitioUserInfo } from " 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; @@ -28,9 +44,7 @@ class TuitioClient { const response = await request(url, "post"); if (!response.error) { - const currentDate = new Date(); - const expiresIn = response.result.expiresIn - 10000; // 10 seconds of safety margin - const validUntil = new Date(currentDate.getTime() + expiresIn); + const validUntil = computeValidUntil(response.result.expiresIn); const authData = { token: response.result.token, validUntil, userName }; setItem(storageKeys.AUTH_DATA, authData); response.result.validUntil = validUntil;