diff --git a/cypress/fixtures/userLogin.json b/cypress/fixtures/userLogin.json
index 7fa2907..bfdc6e0 100644
--- a/cypress/fixtures/userLogin.json
+++ b/cypress/fixtures/userLogin.json
@@ -1,5 +1,7 @@
{
- "token": "327a2d17-ce9b-45a7-b0ff-a556536d27fb",
+ "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyX3NpZCI6IjFjNTc4MWQyLTY5MGItNDIwYy1iZDUzLTVkN2Y1NjMwMDVjOCIsInNjb3BlIjoiYWRtaW4iLCJmb3JjZV9jaGFuZ2UiOnRydWUsInBlcm1pc3Npb25zIjpbIlBST1ZJU0lPTl9VU0VSUyIsIlBST1ZJU0lPTl9TRVJWSUNFUyIsIlZJRVdfT05MWSJdLCJpYXQiOjE2NjY3OTgzMTEsImV4cCI6MTY2NjgwMTkxMX0.ZV3KnRit8WGpipfiiMAZ2AVLQ25csWje1-K6hdqxktE",
+ "scope": "admin",
"user_sid": "78131ad5-f041-4d5d-821c-47b2d8c6d015",
- "force_change": false
+ "force_change": false,
+ "permissions": ["VIEW_ONLY", "PROVISION_SERVICES", "PROVISION_USERS"]
}
diff --git a/src/api/types.ts b/src/api/types.ts
index e32ae06..6658243 100644
--- a/src/api/types.ts
+++ b/src/api/types.ts
@@ -10,6 +10,22 @@ export type IpType = "ip" | "fqdn" | "fqdn-top-level" | "invalid";
export type LimitCategories = "api_rate" | "voice_call_session" | "device";
+/** User roles / permissions */
+
+export type UserScopes = "admin" | "service_provider" | "account";
+
+export type UserPermissions =
+ | "VIEW_ONLY"
+ | "PROVISION_SERVICES"
+ | "PROVISION_USERS";
+
+// We'll want something like this for actual permissions implementation...
+// export enum UserPermissions {
+// VIEW_ONLY = 0,
+// PROVISION_SERVICES = 1,
+// PROVISION_USERS = 2,
+// }
+
/** Status codes */
export enum StatusCodes {
@@ -90,12 +106,13 @@ export interface PasswordSettings {
/** API responses/payloads */
export interface User {
+ scope: UserScopes;
user_sid: string;
+ permissions: UserPermissions[];
}
-export interface UserLogin {
+export interface UserLogin extends User {
token: string;
- user_sid: string;
force_change: boolean;
}
diff --git a/src/containers/internal/navi/index.tsx b/src/containers/internal/navi/index.tsx
index 297032b..140ef4a 100644
--- a/src/containers/internal/navi/index.tsx
+++ b/src/containers/internal/navi/index.tsx
@@ -108,6 +108,7 @@ export const Navi = ({
/** Fetch service providers */
useEffect(() => {
+ dispatch({ type: "user" });
dispatch({ type: "serviceProviders" });
}, []);
@@ -166,12 +167,12 @@ export const Navi = ({
- {/* Until we have the APIs this initial UI is not accessible */}
- {user && (
+ {/* Intentionally hiding this as we will need to work this out as we go... */}
+ {/* ACL component will need to be updated for new user scope/permissions handling */}
+ {false && user && (
- {/* Seed should be user sid when we have the APIs for it... */}
{
localStorage.setItem(storageKey, token);
};
+/**
+ * Decode data from a JWT
+ * https://stackoverflow.com/questions/38552003/how-to-decode-jwt-token-in-javascript-without-using-a-library
+ */
+export const parseJwt = (token: string) => {
+ const base64Url = token.split(".")[1];
+ const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
+ const jsonPayload = decodeURIComponent(
+ window
+ .atob(base64)
+ .split("")
+ .map((c) => {
+ return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
+ })
+ .join("")
+ );
+
+ return JSON.parse(jsonPayload);
+};
+
/**
* Provider hook that creates auth object and handles state
*/
diff --git a/src/store/actions.ts b/src/store/actions.ts
index 6006358..5657f63 100644
--- a/src/store/actions.ts
+++ b/src/store/actions.ts
@@ -1,5 +1,6 @@
-import { getUser, getServiceProviders } from "src/api";
+import { getServiceProviders } from "src/api";
import { sortLocaleName } from "src/utils";
+import { getToken, parseJwt } from "src/router/auth";
import type { State, Action } from "./types";
import type { ServiceProvider, User } from "src/api/types";
@@ -61,8 +62,9 @@ export const currentServiceProviderAction = (
};
export const userAsyncAction = async (): Promise => {
- const response = await getUser("user_sid");
- return response.json;
+ const token = getToken();
+ const { user_sid, permissions, scope } = parseJwt(token);
+ return { user_sid, permissions, scope };
};
export const serviceProvidersAsyncAction = async (): Promise<
diff --git a/src/test/index.tsx b/src/test/index.tsx
index b17f66d..a904478 100644
--- a/src/test/index.tsx
+++ b/src/test/index.tsx
@@ -6,6 +6,7 @@ import { AuthContext } from "src/router/auth";
import { MSG_SOMETHING_WRONG } from "src/constants";
import type { AuthStateContext } from "src/router/auth";
+import type { UserLogin } from "src/api/types";
import userLogin from "../../cypress/fixtures/userLogin.json";
@@ -19,7 +20,7 @@ type LayoutProviderProps = TestProviderProps & {
};
export const signinError = () => Promise.reject(MSG_SOMETHING_WRONG);
-export const signinSuccess = () => Promise.resolve(userLogin);
+export const signinSuccess = () => Promise.resolve(userLogin as UserLogin);
export const signout = () => undefined;
export const authProps: AuthStateContext = {
token: "",