-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Create manager role and limit default role #351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create manager role and limit default role #351
Conversation
|
Still WIP, fixing single user mode |
frontend/src/components/Modals/MangeWorkspace/index.jsxIt's a good practice to implement role-based access control (RBAC) in your application. This ensures that users can only perform actions that they are authorized to do, enhancing the security of your application. if (user?.role === "admin" || user?.role === "manager") {
setShowing(true);
}frontend/src/pages/Admin/Users/NewUserModal/index.jsxAdding a new role 'Manager' to the application can help in better segregation of duties. This ensures that only certain users can perform certain actions, enhancing the security of your application. <option value="manager">Manager</option>frontend/src/components/Sidebar/ActiveWorkspaces/index.jsxRestricting access to certain features based on user role is a good practice. This ensures that only authorized users can access certain features, enhancing the security of your application. hidden={!isActive || user?.role === "default"}frontend/src/components/PrivateRoute/index.jsxAdding a new route for 'Manager' role can help in better segregation of duties. This ensures that only certain users can access certain routes, enhancing the security of your application. export function ManagerRoute({ Component }) {
const { isAuthd, shouldRedirectToOnboarding, multiUserMode } =
useIsAuthenticated();
if (isAuthd === null) return <FullScreenLoader />;
if (shouldRedirectToOnboarding) {
return <Navigate to={paths.onboarding()} />;
}
const user = userFromStorage();
return isAuthd &&
(user?.role === "manager" || user?.role === "admin" || !multiUserMode) ? (
<UserMenu>
<Component />
</UserMenu>
) : (
<Navigate to={paths.home()} />
);
}frontend/src/components/Sidebar/index.jsxThere is a repetition of the same code block for checking the user role in multiple places. This can be refactored into a separate function to improve readability and maintainability. const isAdminOrManager = (user) => user?.role === "admin" || user?.role === "manager";The useEffect hook in the SidebarMobileHeader component is triggered every time the showSidebar state changes. However, the setTimeout function inside it is not cleared when the component unmounts, which could lead to memory leaks and unnecessary re-renders. To fix this, you can return a cleanup function from the useEffect hook that clears the timeout. useEffect(() => {
let timeoutId;
if (showSidebar) {
timeoutId = setTimeout(() => {
setShowBgOverlay(true);
}, 300);
} else {
setShowBgOverlay(false);
}
return () => clearTimeout(timeoutId);
}, [showSidebar]);The variable name 'showBgOverlay' is not very descriptive. Consider renaming it to 'showBackgroundOverlay' to make it more clear what it represents. const [showBackgroundOverlay, setShowBackgroundOverlay] = useState(false);The variable name 'showNewWsModal' is not very descriptive. Consider renaming it to 'showNewWorkspaceModal' to make it more clear what it represents. const {
showing: showingNewWorkspaceModal,
showModal: showNewWorkspaceModal,
hideModal: hideNewWorkspaceModal,
} = useNewWorkspaceModal();server/endpoints/admin.jsInstead of checking the user role in each endpoint, you can create a middleware function that checks if the user has the required role (admin or manager). This will make the code DRY (Don't Repeat Yourself) and easier to maintain. function requireRole(...roles) {
return async (request, response, next) => {
const user = await userFromSession(request, response);
if (!user || !roles.includes(user?.role)) {
response.sendStatus(401).end();
return;
}
next();
};
}
app.get("/admin/users", [validatedRequest, requireRole('admin', 'manager')], async (request, response) => {
// ...
});Instead of repeating the error handling code in each endpoint, you can create an error handling middleware. This will make the code DRY (Don't Repeat Yourself) and easier to maintain. function errorHandler(err, req, res, next) {
console.error(err);
res.sendStatus(500).end();
}
app.get("/admin/users", [validatedRequest, requireRole('admin', 'manager')], async (request, response) => {
// ...
}, errorHandler);Console.log statements are generally used for debugging and should not be present in production code. They can clutter the console output and make it harder to read the important messages. If you need to log certain events or errors, consider using a logging library that provides different levels of logging and can be configured to log only the important messages in production. // Remove the console.log statementsserver/endpoints/system.jsThere are multiple instances where the same code is repeated to check if the user is an admin or a manager. This can be refactored into a separate function to improve code readability and maintainability. function isAdminOrManager(user) {
return user?.role === "admin" || user?.role === "manager";
}Currently, the error messages are being logged to the console and a generic 500 status code is being sent in the response. It would be better to send a more descriptive error message in the response to help with debugging. However, be careful not to expose any sensitive information in the error messages. } catch (e) {
console.log(e.message, e);
response.status(500).json({ error: e.message }).end();
}There are several string values that are repeated multiple times throughout the code (e.g., "admin", "manager"). It would be better to define these as constants at the top of the file to avoid potential typos and make it easier to change the value in the future. const ADMIN = "admin";
const MANAGER = "manager";There are some places in the code where promises are being used instead of async/await. For consistency and readability, it would be better to use async/await throughout the code. const user = await userFromSession(request, response); |
* added manager role to options * block default role from editing workspace settings on workspace and text input box * block default user from accessing settings at all * create manager route * let pass through if in single user mode * fix permissions for manager and admin roles in settings * fix settings button for single user and remove unneeded console.logs * rename routes and paths for clarity * admin, manager, default roles complete * remove unneeded comments * consistency changes * manage permissions for mum modes * update sidebar for single-user mode * update comment on middleware Modify permission setting for admins * update render conditional * Add role usage hint to each role --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
Created a "Manager" role that has all access that the "Admin" role has except for changing
"Default" role