diff --git a/README.md b/README.md index 86d48f6..e8ef53e 100644 --- a/README.md +++ b/README.md @@ -16,13 +16,13 @@ The package installation can be done in two ways: ## How to use the package ```javascript! -const { TuitioProvider, useTuitioClient, useTuitioUser, useTuitioToken } = require("@flare/tuitio-client-react"); -const TuitioProvider = require("@flare/tuitio-client-react"); +const { TuitioProvider, useTuitioClient, useTuitioUser, useTuitioToken, useTuitioUserInfo } = require("@flare/tuitio-client-react"); +const TuitioProvider = require("@flare/tuitio-client-react"); ``` ```javascript! -import { TuitioProvider, useTuitioClient, useTuitioUser, useTuitioToken } from "@flare/tuitio-client-react"; +import { TuitioProvider, useTuitioClient, useTuitioUser, useTuitioToken, useTuitioUserInfo } from "@flare/tuitio-client-react"; import TuitioProvider from "@flare/tuitio-client-react"; ``` @@ -40,4 +40,5 @@ All tests in the package can be executed by running: `npm test`. 1.1.1 - Account logout bug fix 1.2.0 - Has been implemented the "user-info" method exposed by the Tuitio API and the latest changes published by "@flare/tuitio-client". 1.2.1 - Added decodedToken in useTuitioToken hook. The token is obtained directly from TuitioProvider's react context. -1.2.2 - Upgraded @flare/tuitio-client and @flare/js-utils packages. +1.2.2 - Upgraded @flare/tuitio-client and @flare/js-utils packages. +1.2.3 - User roles were handled in useTuitioUserInfo hook. diff --git a/package-lock.json b/package-lock.json index 9a18b7a..125be06 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,16 @@ { "name": "@flare/tuitio-client-react", - "version": "1.2.2", + "version": "1.2.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@flare/tuitio-client-react", - "version": "1.2.2", + "version": "1.2.3", "license": "MIT", "dependencies": { "@flare/js-utils": "^1.1.0", - "@flare/tuitio-client": "^1.2.2" + "@flare/tuitio-client": "^1.2.3" }, "devDependencies": { "@testing-library/react": "^12.1.5", @@ -724,9 +724,9 @@ "integrity": "sha512-6NBXdZgRrHbLXw4EMgyqCIzOVAlUgr1+8QGHjlA+n5Iw2Lp/+dP3FTgAfPW/cHR/PBI3cj7gUDVUf/zD/qTPOQ==" }, "node_modules/@flare/tuitio-client": { - "version": "1.2.2", - "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.2.2.tgz", - "integrity": "sha512-Rqz9seWFY5nUivMHrONphgYEeVriAq3yn8icAUQ+TFgf/ajoOqv0GlVfo2Nc//vqsLBJkZtHexmF92/5WHvvhQ==", + "version": "1.2.3", + "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.2.3.tgz", + "integrity": "sha512-m1cJZNTLNXwviD2hkeAvs6I/jlC17GHkUraExfaEaYOUrmDpovE64sg6Xheb01mXnDADCdA2MYxdJgxODNJAqw==", "dependencies": { "@flare/js-utils": "^1.1.0", "axios": "^1.3.2" @@ -7661,9 +7661,9 @@ "integrity": "sha512-6NBXdZgRrHbLXw4EMgyqCIzOVAlUgr1+8QGHjlA+n5Iw2Lp/+dP3FTgAfPW/cHR/PBI3cj7gUDVUf/zD/qTPOQ==" }, "@flare/tuitio-client": { - "version": "1.2.2", - "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.2.2.tgz", - "integrity": "sha512-Rqz9seWFY5nUivMHrONphgYEeVriAq3yn8icAUQ+TFgf/ajoOqv0GlVfo2Nc//vqsLBJkZtHexmF92/5WHvvhQ==", + "version": "1.2.3", + "resolved": "https://lab.code-rove.com/public-node-registry/@flare/tuitio-client/-/tuitio-client-1.2.3.tgz", + "integrity": "sha512-m1cJZNTLNXwviD2hkeAvs6I/jlC17GHkUraExfaEaYOUrmDpovE64sg6Xheb01mXnDADCdA2MYxdJgxODNJAqw==", "requires": { "@flare/js-utils": "^1.1.0", "axios": "^1.3.2" diff --git a/package.json b/package.json index 8508c69..82effcb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@flare/tuitio-client-react", - "version": "1.2.2", + "version": "1.2.3", "description": "Tuitio client react is an npm package written in typescript that facilitates the integration of a react application with Tuitio.", "main": "./dist/cjs/index.js", "module": "./dist/esm/index.js", @@ -49,7 +49,7 @@ ], "dependencies": { "@flare/js-utils": "^1.1.0", - "@flare/tuitio-client": "^1.2.2" + "@flare/tuitio-client": "^1.2.3" }, "peerDependencies": { "react": "^16.14.0" diff --git a/src/constants/userRoles.ts b/src/constants/userRoles.ts new file mode 100644 index 0000000..af5f49a --- /dev/null +++ b/src/constants/userRoles.ts @@ -0,0 +1,11 @@ +// Copyright (c) 2023 Tudor Stanciu + +export const userRoles = { + SYS_ADMIN: "SYSTEM_ADMINISTRATOR", + DEVELOPER: "FULLSTACK_DEVELOPER", + POWER_USER: "POWER_USER", + REGULAR_USER: "REGULAR_USER", + VIEWER: "READONLY_USER", + GUEST: "ANONYMOUS_USER", + DEMO: "DEMO_USER" +}; diff --git a/src/hooks/useTuitioUserInfo.ts b/src/hooks/useTuitioUserInfo.ts index 4e0091f..060194b 100644 --- a/src/hooks/useTuitioUserInfo.ts +++ b/src/hooks/useTuitioUserInfo.ts @@ -1,11 +1,47 @@ // Copyright (c) 2023 Tudor Stanciu -import { useContext, useCallback, useEffect } from "react"; +import { useContext, useCallback, useEffect, useMemo } from "react"; import { TuitioClient } from "@flare/tuitio-client"; -import type { TuitioUserInfo } from "@flare/tuitio-client"; +import type { TuitioUserInfo, UserRole } from "@flare/tuitio-client"; import { TuitioContext, TuitioDispatchContext } from "../contexts"; +import { userRoles } from "../constants/userRoles"; -const useTuitioUserInfo = () => { +type UserFlags = { + isSysAdmin: boolean; + isDeveloper: boolean; + isPowerUser: boolean; + isRegularUser: boolean; + isViewer: boolean; + isGuest: boolean; + isDemoGuest: boolean; +}; + +const defaultUserFlags: UserFlags = { + isSysAdmin: false, + isDeveloper: false, + isPowerUser: false, + isRegularUser: false, + isViewer: false, + isGuest: false, + isDemoGuest: false +}; + +export type TuitioUserInfoHookResult = UserFlags & { + userInfo?: TuitioUserInfo; +}; + +const getFlags = (roles: UserRole[]): UserFlags => { + const isSysAdmin = roles.some(role => role.code === userRoles.SYS_ADMIN); + const isDeveloper = roles.some(role => role.code === userRoles.DEVELOPER); + const isPowerUser = roles.some(role => role.code === userRoles.POWER_USER); + const isRegularUser = roles.some(role => role.code === userRoles.REGULAR_USER); + const isViewer = roles.some(role => role.code === userRoles.VIEWER); + const isGuest = roles.some(role => role.code === userRoles.GUEST); + const isDemoGuest = roles.some(role => role.code === userRoles.DEMO); + return { isSysAdmin, isDeveloper, isPowerUser, isRegularUser, isViewer, isGuest, isDemoGuest }; +}; + +const useTuitioUserInfo = (): TuitioUserInfoHookResult => { const state = useContext(TuitioContext); const dispatchActions = useContext(TuitioDispatchContext); @@ -22,8 +58,9 @@ const useTuitioUserInfo = () => { }, [getUserInfo, state.userInfo]); const userInfo = state.userInfo; + const flags = useMemo(() => (userInfo ? getFlags(userInfo.userRoles) : defaultUserFlags), [userInfo]); - return { userInfo }; + return { userInfo, ...flags }; }; export { useTuitioUserInfo }; diff --git a/tests/hooks/useTuitioUserInfo.test.tsx b/tests/hooks/useTuitioUserInfo.test.tsx index c5f666e..15d073d 100644 --- a/tests/hooks/useTuitioUserInfo.test.tsx +++ b/tests/hooks/useTuitioUserInfo.test.tsx @@ -20,10 +20,25 @@ const userInfoMock = { securityStamp: "mock", creationDate: "2023-03-08T11:46:31.453", failedLoginAttempts: 0, - lastLoginDate: "2023-03-27T16:09:26.283" + lastLoginDate: "2023-03-27T16:09:26.283", + userRoles: [ + { + id: 1, + code: "SYSTEM_ADMINISTRATOR", + name: "System administrator" + }, + { id: 2, code: "FULLSTACK_DEVELOPER", name: "Fullstack developer" } + ], + userGroups: [ + { + id: 1, + code: "ADMINISTRATORS", + name: "Administrators" + } + ] }; -describe("useTuitioClient: dispatchActions", () => { +describe("useTuitioUserInfo: dispatchActions", () => { const tuitioContextState = { auth: { userName: null, @@ -60,9 +75,14 @@ describe("useTuitioClient: dispatchActions", () => { expect(onUserInfoLoadedSpy).toHaveBeenCalled(); expect(onUserInfoLoadedSpy).toHaveBeenCalledWith(userInfoMock); - const { userInfo } = result.current; + const { userInfo, isSysAdmin, isDeveloper, isGuest } = result.current; expect(userInfo).toBeDefined(); expect(userInfo?.userId).toBe(1); expect(userInfo?.userName).toBe("tuitio.test"); + expect(userInfo?.userRoles).toHaveLength(2); + expect(userInfo?.userGroups).toHaveLength(1); + expect(isSysAdmin).toBe(true); + expect(isDeveloper).toBe(true); + expect(isGuest).toBe(false); }); });