Skip to content

Commit

Permalink
feat: userroles and permissions
Browse files Browse the repository at this point in the history
  • Loading branch information
Chakravarthy7102 committed Oct 18, 2023
1 parent bf2bd7e commit 4deec30
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 3 deletions.
5 changes: 3 additions & 2 deletions server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import Passwordless from "supertokens-node/recipe/passwordless";
import Session from "supertokens-node/recipe/session";
import ThirdParty from "supertokens-node/recipe/thirdparty";
import UserMetaData from "supertokens-node/recipe/usermetadata";
import UserRoles from "supertokens-node/recipe/userroles";

const websiteDomain = "http://localhost:3000";

Expand All @@ -35,7 +36,7 @@ app.use(morgan("[:date[iso]] :url :method :status :response-time ms - :res[conte
SuperTokens.init({
framework: "express",
supertokens: {
connectionURI: "try.supertokens.com",
connectionURI: "http://localhost:3567",
},
appInfo: {
appName: "Dashboard Dev Node",
Expand All @@ -45,7 +46,6 @@ SuperTokens.init({
},
recipeList: [
Dashboard.init({
apiKey: "test",
// Keep this so that the dev server uses api key based login
override: {
functions: (original) => {
Expand Down Expand Up @@ -88,6 +88,7 @@ SuperTokens.init({
}),
Session.init(),
AccountLinking.init(),
UserRoles.init(),
],
});

Expand Down
5 changes: 5 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { ToastNotificationContainer } from "./ui/components/toast/toastNotificat
import { AccessDeniedContextProvider } from "./ui/contexts/AccessDeniedContext";
import { PopupContentContextProvider } from "./ui/contexts/PopupContentContext";
import { TenantsListContextProvider } from "./ui/contexts/TenantsListContext";
import UserRolesList from "./ui/pages/userroles";

function App() {
return (
Expand All @@ -46,6 +47,10 @@ function App() {
path="/"
element={<UsersListPage />}
/>
<Route
path="/roles"
element={<UserRolesList />}
/>
<Route
path="*"
element={<UsersListPage />}
Expand Down
92 changes: 92 additions & 0 deletions src/api/userroles/roles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/* Copyright (c) 2022, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with the License. You may
* obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

import { getApiUrl, useFetchData } from "../../utils";

type Roles = Array<{ role: string; permissions: string[] }>;
type GetRolesResponse =
| {
status: "OK";
roles: Roles;
}
| {
status: "FEATURE_NOT_ENABLED_ERROR";
};

export const useRolesService = () => {
const fetchData = useFetchData();

const getRoles = async (): Promise<GetRolesResponse> => {
const response = await fetchData({
url: getApiUrl("/api/userroles/roles"),
method: "GET",
});

if (response.ok) {
const body = await response.json();

if (body.status === "FEATURE_NOT_ENABLED_ERROR") {
return {
status: "FEATURE_NOT_ENABLED_ERROR",
};
}

return body;
}

return {
status: "OK",
roles: [],
};
};

const createRole = async (): Promise<{
status: "OK" | "ROLE_ALREADY_EXITS";
}> => {
const response = await fetchData({
url: getApiUrl("/api/userroles/role"),
method: "POST",
});

if (response.ok) {
const body = await response.json();

if (body.status === "ROLE_ALREADY_EXITS") {
return {
status: "ROLE_ALREADY_EXITS",
};
}
}

return {
status: "OK",
};
};

const deleteRole = async (): Promise<void> => {
await fetchData({
url: getApiUrl("/api/userroles/role"),
method: "DELETE",
});
};

return {
getRoles,
createRole,
deleteRole,
};
};

export default useRolesService;
7 changes: 7 additions & 0 deletions src/ui/pages/userroles/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.userroles-container {
max-width: 830px;
height: 100vh;
padding: 72px 0px;
margin: auto;
width: 100vw;
}
28 changes: 28 additions & 0 deletions src/ui/pages/userroles/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useEffect } from "react";
import useRolesService from "../../../api/userroles/roles";
import { Footer } from "../../components/footer/footer";
import { AppEnvContextProvider } from "../../contexts/AppEnvContext";

import "./index.scss";

export default function UserRolesList() {
const { getRoles } = useRolesService();

useEffect(() => {
void getRoles();
}, []);
return (
<AppEnvContextProvider
connectionURI={
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(window as any).connectionURI
}>
<section className="userroles-container">Hello world!</section>
<Footer
colorMode="dark"
horizontalAlignment="center"
verticalAlignment="center"
/>
</AppEnvContextProvider>
);
}
8 changes: 7 additions & 1 deletion src/ui/pages/usersList/UsersList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ export const UsersList: React.FC<UserListProps> = ({
useTenantsListContext();
const selectedTenant = getSelectedTenant();

const navigate = useNavigate();

const insertUsersAtOffset = useCallback(
(paramUsers: User[], paramOffset?: number, isSearch?: boolean) => {
if (isSearch) {
Expand Down Expand Up @@ -260,6 +262,11 @@ export const UsersList: React.FC<UserListProps> = ({
/>
<h1 className="users-list-title">
User Management <span className="pill paid-feature-badge">Beta</span>
<button
onClick={() => navigate("/roles")}
className="pill paid-feature-badge">
Roles
</button>
</h1>
<p className="text-small users-list-subtitle">
One place to manage all your users, revoke access and edit information according to your needs.
Expand Down Expand Up @@ -327,7 +334,6 @@ export const UserListPage = () => {
const navigate = useNavigate();
const currentLocation = useLocation();
const [selectedUser, setSelectedUser] = useState<string>();
const [selectedRecipeId, setSelectedRecipeId] = useState<string>();
const [selectedUserEmailVerification, setSelectedUserEmailVerification] = useState<
EmailVerificationStatus | undefined
>();
Expand Down

0 comments on commit 4deec30

Please sign in to comment.