added tuitio react client blocks

master
Tudor Stanciu 2023-02-11 18:25:24 +02:00
parent de9a9b2470
commit b9910e2f61
7 changed files with 196 additions and 8 deletions

73
package-lock.json generated
View File

@ -9,10 +9,11 @@
"version": "1.0.0", "version": "1.0.0",
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"@flare/tuitio-client": "^1.0.0" "@flare/tuitio-client": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/jest": "^29.4.0", "@types/jest": "^29.4.0",
"@types/react": "^18.0.27",
"jest": "^29.4.1", "jest": "^29.4.1",
"jest-environment-jsdom": "^29.4.2", "jest-environment-jsdom": "^29.4.2",
"prettier": "^2.8.3", "prettier": "^2.8.3",
@ -616,9 +617,9 @@
"integrity": "sha512-VgXQHoQEVZ/71B6YQHQP8/Yd/w1smGD+kCCiNvJKZ1xMD3nkN9mjoHxIqbOJMZ2q5PZlV6gXYT7eVol8Wm+D0A==" "integrity": "sha512-VgXQHoQEVZ/71B6YQHQP8/Yd/w1smGD+kCCiNvJKZ1xMD3nkN9mjoHxIqbOJMZ2q5PZlV6gXYT7eVol8Wm+D0A=="
}, },
"node_modules/@flare/tuitio-client": { "node_modules/@flare/tuitio-client": {
"version": "1.0.0", "version": "1.0.2",
"resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.0.0.tgz", "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.0.2.tgz",
"integrity": "sha512-w3XBzH02qg+PsKOz1nbVk5BQdGoCssKzotYlMq59zttn2kHN6G7QDrg7VqKwSb4n0udyRAUGafzu9aUL8VEiFA==", "integrity": "sha512-USpnUfZ36RiTg2UTVRvW5+FT3c8UuXjTbIe02GLLKImjF4ZV27Rz9nn7UaVtkQLt9YyxNBYokGKekKl+WVRG0Q==",
"dependencies": { "dependencies": {
"@flare/js-utils": "^1.0.3", "@flare/js-utils": "^1.0.3",
"axios": "^1.3.2" "axios": "^1.3.2"
@ -1114,6 +1115,29 @@
"integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
"dev": true "dev": true
}, },
"node_modules/@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
},
"node_modules/@types/react": {
"version": "18.0.27",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"dev": true,
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
},
"node_modules/@types/stack-utils": { "node_modules/@types/stack-utils": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
@ -1644,6 +1668,12 @@
"integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==",
"dev": true "dev": true
}, },
"node_modules/csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
"dev": true
},
"node_modules/data-urls": { "node_modules/data-urls": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz",
@ -4996,9 +5026,9 @@
"integrity": "sha512-VgXQHoQEVZ/71B6YQHQP8/Yd/w1smGD+kCCiNvJKZ1xMD3nkN9mjoHxIqbOJMZ2q5PZlV6gXYT7eVol8Wm+D0A==" "integrity": "sha512-VgXQHoQEVZ/71B6YQHQP8/Yd/w1smGD+kCCiNvJKZ1xMD3nkN9mjoHxIqbOJMZ2q5PZlV6gXYT7eVol8Wm+D0A=="
}, },
"@flare/tuitio-client": { "@flare/tuitio-client": {
"version": "1.0.0", "version": "1.0.2",
"resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.0.0.tgz", "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.0.2.tgz",
"integrity": "sha512-w3XBzH02qg+PsKOz1nbVk5BQdGoCssKzotYlMq59zttn2kHN6G7QDrg7VqKwSb4n0udyRAUGafzu9aUL8VEiFA==", "integrity": "sha512-USpnUfZ36RiTg2UTVRvW5+FT3c8UuXjTbIe02GLLKImjF4ZV27Rz9nn7UaVtkQLt9YyxNBYokGKekKl+WVRG0Q==",
"requires": { "requires": {
"@flare/js-utils": "^1.0.3", "@flare/js-utils": "^1.0.3",
"axios": "^1.3.2" "axios": "^1.3.2"
@ -5418,6 +5448,29 @@
"integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==",
"dev": true "dev": true
}, },
"@types/prop-types": {
"version": "15.7.5",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz",
"integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==",
"dev": true
},
"@types/react": {
"version": "18.0.27",
"resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
"integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"dev": true,
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
"csstype": "^3.0.2"
}
},
"@types/scheduler": {
"version": "0.16.2",
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==",
"dev": true
},
"@types/stack-utils": { "@types/stack-utils": {
"version": "2.0.1", "version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
@ -5821,6 +5874,12 @@
} }
} }
}, },
"csstype": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.1.tgz",
"integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==",
"dev": true
},
"data-urls": { "data-urls": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz",

View File

@ -44,6 +44,7 @@
], ],
"devDependencies": { "devDependencies": {
"@types/jest": "^29.4.0", "@types/jest": "^29.4.0",
"@types/react": "^18.0.27",
"jest": "^29.4.1", "jest": "^29.4.1",
"jest-environment-jsdom": "^29.4.2", "jest-environment-jsdom": "^29.4.2",
"prettier": "^2.8.3", "prettier": "^2.8.3",
@ -53,7 +54,7 @@
"typescript": "^4.9.5" "typescript": "^4.9.5"
}, },
"dependencies": { "dependencies": {
"@flare/tuitio-client": "^1.0.0" "@flare/tuitio-client": "^1.0.2"
}, },
"peerDependencies": { "peerDependencies": {
"react": "^16.14.0" "react": "^16.14.0"

5
src/contexts.ts Normal file
View File

@ -0,0 +1,5 @@
import React from "react";
import { initialState, initialDispatchActions } from "./initialState";
export const TuitioContext = React.createContext(initialState);
export const TuitioDispatchContext = React.createContext(initialDispatchActions);

69
src/hooks.ts Normal file
View File

@ -0,0 +1,69 @@
import { useContext } from "react";
import { TuitioContext, TuitioDispatchContext } from "./contexts";
import { TuitioClient, invalidate } from "@flare/tuitio-client";
import type { TuitioAuthenticationResult } from "@flare/tuitio-client";
export type TuitioClientHookOptions = {
onLoginSuccess: (result: TuitioAuthenticationResult, userName: string) => void;
onLoginFailed: (result: TuitioAuthenticationResult, userName: string) => void;
onLoginError: (error: any) => void;
};
const useTuitioClient = (options: TuitioClientHookOptions) => {
const state = useContext(TuitioContext);
const dispatchActions = useContext(TuitioDispatchContext);
const { onLoginSuccess, onLoginFailed, onLoginError } = options;
const login = async (userName: string, password: string) => {
try {
const connector = new TuitioClient(state.configuration.tuitioUrl);
const response = await connector.authenticate(userName, password);
if (response.token) {
dispatchActions.onLoginSuccess(response.token, userName);
onLoginSuccess && onLoginSuccess(response, userName);
} else {
onLoginFailed && onLoginFailed(response, userName);
}
return response;
} catch (error) {
if (onLoginError) onLoginError(error);
else throw error;
}
};
const logout = (): void => {
invalidate();
dispatchActions.onLogout();
};
return { login, logout };
};
const useTuitioUser = () => {
const state = useContext(TuitioContext);
const userName = state.userName;
const lastLoginDate = state.token?.validFrom;
return { userName, lastLoginDate };
};
const useTuitioToken = () => {
const state = useContext(TuitioContext);
const token = state.token;
const validate = (): boolean => {
const token = state.token;
if (!token) {
return false;
}
const valid = new Date(token.validUntil) >= new Date();
return valid;
};
const valid: boolean = validate();
return { token, validate, valid };
};
export { useTuitioClient, useTuitioUser, useTuitioToken };

15
src/initialState.ts Normal file
View File

@ -0,0 +1,15 @@
import { fetch } from "@flare/tuitio-client";
import type { TuitioReactState, TuitioDispatchActions } from "./types";
const { userName, token } = fetch();
export const initialState: TuitioReactState = {
userName,
token,
configuration: { tuitioUrl: null }
};
export const initialDispatchActions: TuitioDispatchActions = {
onLoginSuccess: () => {},
onLogout: () => {}
};

31
src/reducer.ts Normal file
View File

@ -0,0 +1,31 @@
import { initialState } from "./initialState";
import type { TuitioReactState, TuitioDispatchActions } from "./types";
import type { TuitioToken } from "@flare/tuitio-client";
import { Dispatch } from "react";
export const reducer = (state: TuitioReactState = initialState, action: any) => {
switch (action.type) {
case "onLoginSuccess": {
return {
...state,
token: action.token,
userName: action.userName
};
}
case "onLogout": {
const { configuration } = state;
return {
...initialState,
configuration
};
}
default: {
return state;
}
}
};
export const dispatchActions = (dispatch: Dispatch<any>): TuitioDispatchActions => ({
onLoginSuccess: (token: TuitioToken, userName: string): void => dispatch({ type: "onLoginSuccess", token, userName }),
onLogout: (): void => dispatch({ type: "onLogout" })
});

8
src/types.ts Normal file
View File

@ -0,0 +1,8 @@
import type { TuitioToken } from "@flare/tuitio-client";
export type TuitioConfiguration = { tuitioUrl: string | null };
export type TuitioReactState = { userName: string; token: TuitioToken; configuration: TuitioConfiguration };
export type TuitioDispatchActions = {
onLoginSuccess: (token: TuitioToken, userName: string) => void;
onLogout: () => void;
};