diff --git a/packages/user/src/components/UsersTable/UsersTable.tsx b/packages/user/src/components/UsersTable/UsersTable.tsx
index f05c4e14a..e932680cc 100644
--- a/packages/user/src/components/UsersTable/UsersTable.tsx
+++ b/packages/user/src/components/UsersTable/UsersTable.tsx
@@ -18,6 +18,7 @@ import type {
InvitationRoleOption,
InvitationExpiryDateField,
UserType,
+ Role,
} from "@/types";
type VisibleColumn =
@@ -112,16 +113,16 @@ export const UsersTable = ({
id: "roles",
header: t("table.defaultColumns.roles"),
cell: ({ getValue, row: { original } }) => {
- const roles = (original as unknown as { roles: string[] })?.roles;
+ const { roles } = original;
if (Array.isArray(roles)) {
return (
<>
- {roles?.map((role: string, index: number) => (
+ {roles?.map((role: Role) => (
))}
diff --git a/packages/user/src/components/__test__/DropdownUserMenu.snapshot.test.tsx b/packages/user/src/components/__test__/DropdownUserMenu.snapshot.test.tsx
index 2cde967ef..3f5d884a5 100644
--- a/packages/user/src/components/__test__/DropdownUserMenu.snapshot.test.tsx
+++ b/packages/user/src/components/__test__/DropdownUserMenu.snapshot.test.tsx
@@ -19,6 +19,14 @@ function toJson(component: ReactTestRenderer) {
return result as ReactTestRendererJSON;
}
+const roles = [
+ {
+ id: 2,
+ role: "USER",
+ default: true,
+ },
+];
+
test("Component matches snapshot", () => {
const values = {
setUser: vi.fn(),
@@ -31,7 +39,7 @@ test("Component matches snapshot", () => {
signedUpAt: 0,
surname: "name",
givenName: "test",
- roles: ["USER"],
+ roles,
},
loading: false,
};
diff --git a/packages/user/src/components/__test__/DropdownUserMenu.test.tsx b/packages/user/src/components/__test__/DropdownUserMenu.test.tsx
index 31e1576c5..9241b8852 100644
--- a/packages/user/src/components/__test__/DropdownUserMenu.test.tsx
+++ b/packages/user/src/components/__test__/DropdownUserMenu.test.tsx
@@ -8,6 +8,14 @@ import { userContext } from "../../context/UserProvider";
import DropdownUserMenu from "../DropdownUserMenu";
const setup = () => {
+ const roles = [
+ {
+ id: 2,
+ role: "USER",
+ default: true,
+ },
+ ];
+
const values = {
setUser: vi.fn(),
user: {
@@ -19,7 +27,7 @@ const setup = () => {
signedUpAt: 0,
surname: null,
givenName: null,
- roles: ["USER"],
+ roles,
},
loading: false,
};
diff --git a/packages/user/src/context/UserProvider.tsx b/packages/user/src/context/UserProvider.tsx
index a8b8b492e..b0d1ef3ea 100644
--- a/packages/user/src/context/UserProvider.tsx
+++ b/packages/user/src/context/UserProvider.tsx
@@ -7,7 +7,7 @@ import {
isUserVerified,
verifySessionRoles,
} from "../supertokens/helpers";
-import { UserContextType, UserType } from "../types";
+import { Role, UserContextType, UserType } from "../types";
interface Properties {
children: React.ReactNode;
@@ -49,7 +49,7 @@ const UserProvider = ({ children }: Properties) => {
const userData = {
...user,
- roles: roles,
+ roles,
};
if (appConfig.user.features?.signUp?.emailVerification) {
diff --git a/packages/user/src/index.ts b/packages/user/src/index.ts
index c3e75a2ce..a3cae4b57 100644
--- a/packages/user/src/index.ts
+++ b/packages/user/src/index.ts
@@ -37,6 +37,8 @@ import login from "./supertokens/login";
import logout from "./supertokens/logout";
import resetPassword from "./supertokens/reset-password";
import signup from "./supertokens/signup";
+import UserPermissionClaim from "./supertokens/UserPermissionClaim";
+import UserRoleClaim from "./supertokens/UserRoleClaim";
import verifyEmail from "./supertokens/verify-email";
import { AcceptInvitation } from "./views/AcceptInvitation";
import { ChangePassword } from "./views/ChangePassword";
@@ -112,6 +114,8 @@ export {
resetPassword,
setUserData,
signup,
+ UserPermissionClaim,
+ UserRoleClaim,
superTokens,
useEmailVerification,
useFirstUserSignup,
diff --git a/packages/user/src/supertokens/UserPermissionClaim.ts b/packages/user/src/supertokens/UserPermissionClaim.ts
new file mode 100644
index 000000000..7471324f0
--- /dev/null
+++ b/packages/user/src/supertokens/UserPermissionClaim.ts
@@ -0,0 +1,10 @@
+import { PrimitiveArrayClaim } from "supertokens-web-js/recipe/session";
+
+const UserPermissionClaim = new PrimitiveArrayClaim({
+ id: "permission",
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ refresh: async () => {},
+ defaultMaxAgeInSeconds: Number.MAX_SAFE_INTEGER,
+});
+
+export default UserPermissionClaim;
diff --git a/packages/user/src/supertokens/UserRoleClaim.ts b/packages/user/src/supertokens/UserRoleClaim.ts
new file mode 100644
index 000000000..ee074cc88
--- /dev/null
+++ b/packages/user/src/supertokens/UserRoleClaim.ts
@@ -0,0 +1,10 @@
+import { PrimitiveArrayClaim } from "supertokens-web-js/recipe/session";
+
+const UserRoleClaim = new PrimitiveArrayClaim({
+ id: "role",
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
+ refresh: async () => {},
+ defaultMaxAgeInSeconds: Number.MAX_SAFE_INTEGER,
+});
+
+export default UserRoleClaim;
diff --git a/packages/user/src/supertokens/helpers.ts b/packages/user/src/supertokens/helpers.ts
index e3aa9e1ff..fc707cac6 100644
--- a/packages/user/src/supertokens/helpers.ts
+++ b/packages/user/src/supertokens/helpers.ts
@@ -1,18 +1,20 @@
import EmailVerification from "supertokens-web-js/recipe/emailverification";
import Session from "supertokens-web-js/recipe/session";
-import { UserRoleClaim } from "supertokens-web-js/recipe/userroles";
import logout from "./logout";
+import UserRoleClaim from "./UserRoleClaim";
import { removeUserData } from "../helpers";
+// eslint-disable-next-line import/no-unresolved
+import { Role } from "../types";
/**
* Get User roles
*/
-async function getUserRoles(): Promise {
+async function getUserRoles(): Promise {
if (await Session.doesSessionExist()) {
const roles = await Session.getClaimValue({ claim: UserRoleClaim });
- return roles ? roles : [];
+ return (roles ? roles.map((role) => ({ role })) : []) as Role[];
}
return [];
@@ -59,7 +61,7 @@ async function verifySessionRoles(claims: string[]): Promise {
return true;
} else {
// all user roles claim check failed
- await removeUserData();
+ removeUserData();
await logout();
}
}
diff --git a/packages/user/src/types/index.ts b/packages/user/src/types/index.ts
index f1f4f20e2..b8d8c7227 100644
--- a/packages/user/src/types/index.ts
+++ b/packages/user/src/types/index.ts
@@ -16,6 +16,7 @@ import {
ErrorResponse,
ExtendedUser,
LoginCredentials,
+ Role,
SignInUpPromise,
UpdateProfileInputType,
UserContextType,
@@ -39,6 +40,7 @@ export type {
LoginCredentials,
ResendInvitationResponse,
RevokeInvitationResponse,
+ Role,
SignInUpPromise,
UpdateProfileInputType,
UserContextType,
diff --git a/packages/user/src/types/types.ts b/packages/user/src/types/types.ts
index f884d8a7d..f0e16deea 100644
--- a/packages/user/src/types/types.ts
+++ b/packages/user/src/types/types.ts
@@ -1,12 +1,19 @@
import { EmailPasswordUserType } from "supertokens-web-js/recipe/thirdpartyemailpassword";
+export interface Role {
+ id: number;
+ role: string;
+ default: boolean;
+ permissions?: string;
+}
+
export interface UserType extends EmailPasswordUserType {
disabled?: boolean;
givenName: string | null;
isEmailVerified?: boolean;
lastLoginAt: number;
middleNames: string | null;
- roles: string[];
+ roles: Role[];
signedUpAt: number;
surname: string | null;
}