1.2.0 - Has been implemented the "user-info" method exposed by the Tuitio API.
parent
5804ca084d
commit
13083aecf7
|
@ -38,4 +38,5 @@ All tests in the package can be executed by running: `npm test`.
|
||||||
1.0.2 - Validate that Tuitio's URL parameter is a valid URL
|
1.0.2 - Validate that Tuitio's URL parameter is a valid URL
|
||||||
1.0.3 - Added LICENSE file
|
1.0.3 - Added LICENSE file
|
||||||
1.0.4 - TuitioState's token property can be null
|
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.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,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@flare/tuitio-client",
|
"name": "@flare/tuitio-client",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@flare/tuitio-client",
|
"name": "@flare/tuitio-client",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@flare/js-utils": "^1.0.3",
|
"@flare/js-utils": "^1.0.3",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@flare/tuitio-client",
|
"name": "@flare/tuitio-client",
|
||||||
"version": "1.1.0",
|
"version": "1.2.0",
|
||||||
"description": "Tuitio client is an npm package written in typescript that facilitates the integration of a javascript application with Tuitio.",
|
"description": "Tuitio client is an npm package written in typescript that facilitates the integration of a javascript application with Tuitio.",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import { getUrlTemplates } from "../config";
|
import { getUrlTemplates } from "../config";
|
||||||
import { TuitioClient } from "../client";
|
import { TuitioClient } from "../client";
|
||||||
import type { TuitioLoginResponse } from "../client";
|
import type { TuitioLoginResponse } from "../types";
|
||||||
|
|
||||||
test("Get url templates", () => {
|
test("Get url templates", () => {
|
||||||
const result = getUrlTemplates("https://test.com/api");
|
const result = getUrlTemplates("https://test.com/api");
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
// Copyright (c) 2023 Tudor Stanciu
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { TuitioClient, fetch } from "../client";
|
import { TuitioClient } from "../client";
|
||||||
|
import { fetch } from "../state";
|
||||||
|
|
||||||
jest.mock("axios");
|
jest.mock("axios");
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
// Copyright (c) 2023 Tudor Stanciu
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { TuitioClient, fetch } from "../client";
|
import { TuitioClient } from "../client";
|
||||||
|
import { fetch } from "../state";
|
||||||
import { localStorage } from "@flare/js-utils";
|
import { localStorage } from "@flare/js-utils";
|
||||||
import { storageKeys } from "../constants";
|
import { storageKeys } from "../constants";
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
// Copyright (c) 2023 Tudor Stanciu
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
import { fetch } from "../client";
|
import { fetch } from "../state";
|
||||||
|
|
||||||
test("Tuitio empty storage", () => {
|
test("Tuitio empty storage", () => {
|
||||||
const result = fetch();
|
const result = fetch();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
// Copyright (c) 2023 Tudor Stanciu
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
import { combineUrls, isValidURL } from "../utils";
|
import { combineUrls, isValidURL } from "../../utils/validations";
|
||||||
|
|
||||||
test("Combine urls with trailing slash", () => {
|
test("Combine urls with trailing slash", () => {
|
||||||
const result = combineUrls("https://test.com/api/", "/test");
|
const result = combineUrls("https://test.com/api/", "/test");
|
|
@ -1,33 +1,15 @@
|
||||||
// Copyright (c) 2023 Tudor Stanciu
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
import axios from "axios";
|
import { request } from "./utils/axios";
|
||||||
import { localStorage } from "@flare/js-utils";
|
import { localStorage } from "@flare/js-utils";
|
||||||
import { storageKeys } from "./constants";
|
import { storageKeys } from "./constants";
|
||||||
import { getUrlTemplates } from "./config";
|
import { getUrlTemplates } from "./config";
|
||||||
import { isValidURL } from "./utils";
|
import { isValidURL } from "./utils/validations";
|
||||||
import type { UrlTemplates } from "./config";
|
import type { UrlTemplates } from "./config";
|
||||||
|
import type { TuitioLoginResponse, TuitioLogoutResponse, TuitioUserInfoResponse } from "./types";
|
||||||
|
|
||||||
const { setItem, getItem, removeItem } = localStorage;
|
const { setItem, getItem, removeItem } = localStorage;
|
||||||
|
|
||||||
async function request(url: string, method: string) {
|
|
||||||
try {
|
|
||||||
const res = await axios.request({ url, method });
|
|
||||||
return res.data;
|
|
||||||
} catch (error: any) {
|
|
||||||
if (error.response && error.response.data) {
|
|
||||||
const { detail, title } = error.response.data;
|
|
||||||
throw {
|
|
||||||
...error.response.data,
|
|
||||||
message: detail || title
|
|
||||||
};
|
|
||||||
}
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export type TuitioLoginResponse = { result: { token: string; expiresIn: number; validUntil: Date } | null; error: string | null };
|
|
||||||
export type TuitioLogoutResponse = { result: { userId: number; userName: string; logoutDate: Date } | null; error: string };
|
|
||||||
|
|
||||||
class TuitioClient {
|
class TuitioClient {
|
||||||
tuitioUrl: string;
|
tuitioUrl: string;
|
||||||
urlTemplates: UrlTemplates;
|
urlTemplates: UrlTemplates;
|
||||||
|
@ -67,22 +49,13 @@ class TuitioClient {
|
||||||
}
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUserInfo(): Promise<TuitioUserInfoResponse> {
|
||||||
|
const url = this.urlTemplates.userInfo;
|
||||||
|
const response = await request(url, "get");
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TuitioState = { token: string | null; validUntil: Date | null; userName: string | null };
|
export { TuitioClient };
|
||||||
const defaultTuitioState: TuitioState = { token: null, validUntil: null, userName: null };
|
|
||||||
|
|
||||||
const fetch = (): TuitioState => {
|
|
||||||
const authData = getItem(storageKeys.AUTH_DATA);
|
|
||||||
if (!authData) return defaultTuitioState;
|
|
||||||
const { token, validUntil, userName } = authData;
|
|
||||||
const data: TuitioState = {
|
|
||||||
token,
|
|
||||||
validUntil,
|
|
||||||
userName
|
|
||||||
};
|
|
||||||
return data;
|
|
||||||
};
|
|
||||||
|
|
||||||
export { TuitioClient, fetch };
|
|
||||||
export default TuitioClient;
|
export default TuitioClient;
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
// Copyright (c) 2023 Tudor Stanciu
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
import { combineUrls } from "./utils";
|
import { combineUrls } from "./utils/validations";
|
||||||
|
|
||||||
export type UrlTemplates = {
|
export type UrlTemplates = {
|
||||||
login: string;
|
login: string;
|
||||||
logout: string;
|
logout: string;
|
||||||
|
userInfo: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getUrlTemplates = (tuitioUrl: string): UrlTemplates => ({
|
const getUrlTemplates = (tuitioUrl: string): UrlTemplates => ({
|
||||||
login: combineUrls(tuitioUrl, "/account/login?UserName={username}&Password={password}"),
|
login: combineUrls(tuitioUrl, "/account/login?UserName={username}&Password={password}"),
|
||||||
logout: combineUrls(tuitioUrl, "/account/logout?Token={token}")
|
logout: combineUrls(tuitioUrl, "/account/logout?Token={token}"),
|
||||||
|
userInfo: combineUrls(tuitioUrl, "/connect/user-info")
|
||||||
});
|
});
|
||||||
|
|
||||||
export { getUrlTemplates };
|
export { getUrlTemplates };
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
// Copyright (c) 2023 Tudor Stanciu
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
import { TuitioClient, fetch } from "./client";
|
import { TuitioClient } from "./client";
|
||||||
import type { TuitioLoginResponse, TuitioLogoutResponse, TuitioState } from "./client";
|
import { fetch } from "./state";
|
||||||
|
|
||||||
|
export * from "./types";
|
||||||
|
|
||||||
export { TuitioClient, fetch };
|
export { TuitioClient, fetch };
|
||||||
export type { TuitioLoginResponse, TuitioLogoutResponse, TuitioState };
|
|
||||||
export default TuitioClient;
|
export default TuitioClient;
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
|
import { localStorage } from "@flare/js-utils";
|
||||||
|
import { storageKeys } from "./constants";
|
||||||
|
import type { TuitioState } from "./types";
|
||||||
|
|
||||||
|
const { getItem } = localStorage;
|
||||||
|
|
||||||
|
const defaultTuitioState: TuitioState = { token: null, validUntil: null, userName: null };
|
||||||
|
|
||||||
|
const fetch = (): TuitioState => {
|
||||||
|
const authData = getItem(storageKeys.AUTH_DATA);
|
||||||
|
if (!authData) return defaultTuitioState;
|
||||||
|
const { token, validUntil, userName } = authData;
|
||||||
|
const data: TuitioState = {
|
||||||
|
token,
|
||||||
|
validUntil,
|
||||||
|
userName
|
||||||
|
};
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { fetch };
|
|
@ -0,0 +1,25 @@
|
||||||
|
export type TuitioLoginResponse = { result: { token: string; expiresIn: number; validUntil: Date } | null; error: string | null };
|
||||||
|
export type TuitioLogoutResponse = { result: { userId: number; userName: string; logoutDate: Date } | null; error: string };
|
||||||
|
export type TuitioState = { token: string | null; validUntil: Date | null; userName: string | null };
|
||||||
|
|
||||||
|
export type TuitioUserContactOption = {
|
||||||
|
id: number;
|
||||||
|
contactTypeCode: string;
|
||||||
|
contactTypeName: string;
|
||||||
|
contactValue: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type TuitioUserInfoResponse = {
|
||||||
|
userId: number;
|
||||||
|
userName: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
email: string;
|
||||||
|
profilePictureUrl: string;
|
||||||
|
securityStamp: string;
|
||||||
|
creationDate: Date;
|
||||||
|
failedLoginAttempts: number;
|
||||||
|
lastLoginDate: Date;
|
||||||
|
claim?: object;
|
||||||
|
contactOptions?: [TuitioUserContactOption];
|
||||||
|
};
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright (c) 2023 Tudor Stanciu
|
||||||
|
|
||||||
|
import axios, { AxiosHeaders } from "axios";
|
||||||
|
import { fetch } from "../state";
|
||||||
|
|
||||||
|
function getHeaders(): AxiosHeaders {
|
||||||
|
const { token } = fetch();
|
||||||
|
const headers = new AxiosHeaders({
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
});
|
||||||
|
if (token) {
|
||||||
|
headers["Authorization"] = `Tuitio ${token}`;
|
||||||
|
}
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function request(url: string, method: string) {
|
||||||
|
const headers = getHeaders();
|
||||||
|
try {
|
||||||
|
const res = await axios.request({ url, method, headers });
|
||||||
|
return res.data;
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.response && error.response.data) {
|
||||||
|
const { detail, title } = error.response.data;
|
||||||
|
throw {
|
||||||
|
...error.response.data,
|
||||||
|
message: detail || title
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { request };
|
Loading…
Reference in New Issue