mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 18:28:12 +00:00
misc: added support for removing instance admin access of users
This commit is contained in:
@@ -435,6 +435,42 @@ export const registerAdminRouter = async (server: FastifyZodProvider) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
server.route({
|
||||||
|
method: "DELETE",
|
||||||
|
url: "/user-management/users/:userId/admin-access",
|
||||||
|
config: {
|
||||||
|
rateLimit: writeLimit
|
||||||
|
},
|
||||||
|
schema: {
|
||||||
|
params: z.object({
|
||||||
|
userId: z.string()
|
||||||
|
}),
|
||||||
|
response: {
|
||||||
|
200: z.object({
|
||||||
|
user: UsersSchema.pick({
|
||||||
|
username: true,
|
||||||
|
firstName: true,
|
||||||
|
lastName: true,
|
||||||
|
email: true,
|
||||||
|
id: true
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onRequest: (req, res, done) => {
|
||||||
|
verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN])(req, res, () => {
|
||||||
|
verifySuperAdmin(req, res, done);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
handler: async (req) => {
|
||||||
|
const user = await server.services.superAdmin.deleteUserSuperAdminAccess(req.params.userId);
|
||||||
|
|
||||||
|
return {
|
||||||
|
user
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "/bootstrap",
|
url: "/bootstrap",
|
||||||
|
|||||||
@@ -453,6 +453,17 @@ export const superAdminServiceFactory = ({
|
|||||||
return identity;
|
return identity;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const deleteUserSuperAdminAccess = async (userId: string) => {
|
||||||
|
const user = await userDAL.findById(userId);
|
||||||
|
if (!user) {
|
||||||
|
throw new NotFoundError({ name: "User", message: "User not found" });
|
||||||
|
}
|
||||||
|
|
||||||
|
const updatedUser = userDAL.updateById(userId, { superAdmin: false });
|
||||||
|
|
||||||
|
return updatedUser;
|
||||||
|
};
|
||||||
|
|
||||||
const getIdentities = async ({ offset, limit, searchTerm }: TAdminGetIdentitiesDTO) => {
|
const getIdentities = async ({ offset, limit, searchTerm }: TAdminGetIdentitiesDTO) => {
|
||||||
const identities = await identityDAL.getIdentitiesByFilter({
|
const identities = await identityDAL.getIdentitiesByFilter({
|
||||||
limit,
|
limit,
|
||||||
@@ -571,6 +582,7 @@ export const superAdminServiceFactory = ({
|
|||||||
updateRootEncryptionStrategy,
|
updateRootEncryptionStrategy,
|
||||||
getConfiguredEncryptionStrategies,
|
getConfiguredEncryptionStrategies,
|
||||||
grantServerAdminAccessToUser,
|
grantServerAdminAccessToUser,
|
||||||
deleteIdentitySuperAdminAccess
|
deleteIdentitySuperAdminAccess,
|
||||||
|
deleteUserSuperAdminAccess
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ export {
|
|||||||
useAdminGrantServerAdminAccess,
|
useAdminGrantServerAdminAccess,
|
||||||
useAdminRemoveIdentitySuperAdminAccess,
|
useAdminRemoveIdentitySuperAdminAccess,
|
||||||
useCreateAdminUser,
|
useCreateAdminUser,
|
||||||
|
useRemoveUserServerAdminAccess,
|
||||||
useUpdateAdminSlackConfig,
|
useUpdateAdminSlackConfig,
|
||||||
useUpdateServerConfig,
|
useUpdateServerConfig,
|
||||||
useUpdateServerEncryptionStrategy
|
useUpdateServerEncryptionStrategy
|
||||||
|
|||||||
@@ -88,6 +88,22 @@ export const useAdminRemoveIdentitySuperAdminAccess = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const useRemoveUserServerAdminAccess = () => {
|
||||||
|
const queryClient = useQueryClient();
|
||||||
|
return useMutation({
|
||||||
|
mutationFn: async (userId: string) => {
|
||||||
|
await apiRequest.delete(`/api/v1/admin/user-management/users/${userId}/admin-access`);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
onSuccess: () => {
|
||||||
|
queryClient.invalidateQueries({
|
||||||
|
queryKey: [adminStandaloneKeys.getUsers]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const useAdminGrantServerAdminAccess = () => {
|
export const useAdminGrantServerAdminAccess = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation({
|
return useMutation({
|
||||||
|
|||||||
@@ -33,22 +33,26 @@ import {
|
|||||||
THead,
|
THead,
|
||||||
Tr
|
Tr
|
||||||
} from "@app/components/v2";
|
} from "@app/components/v2";
|
||||||
import { useSubscription, useUser } from "@app/context";
|
import { useSubscription } from "@app/context";
|
||||||
import { useDebounce, usePopUp } from "@app/hooks";
|
import { useDebounce, usePopUp } from "@app/hooks";
|
||||||
import {
|
import {
|
||||||
useAdminDeleteUser,
|
useAdminDeleteUser,
|
||||||
useAdminGetUsers,
|
useAdminGetUsers,
|
||||||
useAdminGrantServerAdminAccess
|
useAdminGrantServerAdminAccess,
|
||||||
|
useRemoveUserServerAdminAccess
|
||||||
} from "@app/hooks/api";
|
} from "@app/hooks/api";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
|
|
||||||
const addServerAdminUpgradePlanMessage = "Granting another user Server Admin permissions";
|
const addServerAdminUpgradePlanMessage = "Granting another user Server Admin permissions";
|
||||||
|
const removeServerAdminUpgradePlanMessage = "Removing Server Admin permissions from user";
|
||||||
|
|
||||||
const UserPanelTable = ({
|
const UserPanelTable = ({
|
||||||
handlePopUpOpen
|
handlePopUpOpen
|
||||||
}: {
|
}: {
|
||||||
handlePopUpOpen: (
|
handlePopUpOpen: (
|
||||||
popUpName: keyof UsePopUpState<["removeUser", "upgradePlan", "upgradeToServerAdmin"]>,
|
popUpName: keyof UsePopUpState<
|
||||||
|
["removeUser", "upgradePlan", "upgradeToServerAdmin", "removeServerAdmin"]
|
||||||
|
>,
|
||||||
data?: {
|
data?: {
|
||||||
username: string;
|
username: string;
|
||||||
id: string;
|
id: string;
|
||||||
@@ -58,8 +62,6 @@ const UserPanelTable = ({
|
|||||||
}) => {
|
}) => {
|
||||||
const [searchUserFilter, setSearchUserFilter] = useState("");
|
const [searchUserFilter, setSearchUserFilter] = useState("");
|
||||||
const [adminsOnly, setAdminsOnly] = useState(false);
|
const [adminsOnly, setAdminsOnly] = useState(false);
|
||||||
const { user } = useUser();
|
|
||||||
const userId = user?.id || "";
|
|
||||||
const [debouncedSearchTerm] = useDebounce(searchUserFilter, 500);
|
const [debouncedSearchTerm] = useDebounce(searchUserFilter, 500);
|
||||||
const { subscription } = useSubscription();
|
const { subscription } = useSubscription();
|
||||||
|
|
||||||
@@ -143,45 +145,61 @@ const UserPanelTable = ({
|
|||||||
</Td>
|
</Td>
|
||||||
<Td className="w-5/12">{email}</Td>
|
<Td className="w-5/12">{email}</Td>
|
||||||
<Td>
|
<Td>
|
||||||
{userId !== id && (
|
<div className="flex justify-end">
|
||||||
<div className="flex justify-end">
|
<DropdownMenu>
|
||||||
<DropdownMenu>
|
<DropdownMenuTrigger asChild className="rounded-lg">
|
||||||
<DropdownMenuTrigger asChild className="rounded-lg">
|
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
|
||||||
<div className="hover:text-primary-400 data-[state=open]:text-primary-400">
|
<FontAwesomeIcon size="sm" icon={faEllipsis} />
|
||||||
<FontAwesomeIcon size="sm" icon={faEllipsis} />
|
</div>
|
||||||
</div>
|
</DropdownMenuTrigger>
|
||||||
</DropdownMenuTrigger>
|
<DropdownMenuContent align="start" className="p-1">
|
||||||
<DropdownMenuContent align="start" className="p-1">
|
<DropdownMenuItem
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
handlePopUpOpen("removeUser", { username, id });
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Remove User
|
||||||
|
</DropdownMenuItem>
|
||||||
|
{!superAdmin && (
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handlePopUpOpen("removeUser", { username, id });
|
if (!subscription?.instanceUserManagement) {
|
||||||
|
handlePopUpOpen("upgradePlan", {
|
||||||
|
username,
|
||||||
|
id,
|
||||||
|
message: addServerAdminUpgradePlanMessage
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
handlePopUpOpen("upgradeToServerAdmin", { username, id });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
Remove User
|
Make User Server Admin
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
{!superAdmin && (
|
)}
|
||||||
<DropdownMenuItem
|
{superAdmin && (
|
||||||
onClick={(e) => {
|
<DropdownMenuItem
|
||||||
e.stopPropagation();
|
onClick={(e) => {
|
||||||
if (!subscription?.instanceUserManagement) {
|
e.stopPropagation();
|
||||||
handlePopUpOpen("upgradePlan", {
|
if (!subscription?.instanceUserManagement) {
|
||||||
username,
|
handlePopUpOpen("upgradePlan", {
|
||||||
id,
|
username,
|
||||||
message: addServerAdminUpgradePlanMessage
|
id,
|
||||||
});
|
message: removeServerAdminUpgradePlanMessage
|
||||||
return;
|
});
|
||||||
}
|
return;
|
||||||
handlePopUpOpen("upgradeToServerAdmin", { username, id });
|
}
|
||||||
}}
|
handlePopUpOpen("removeServerAdmin", { username, id });
|
||||||
>
|
}}
|
||||||
Make User Server Admin
|
>
|
||||||
</DropdownMenuItem>
|
Remove Server Admin
|
||||||
)}
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
)}
|
||||||
</DropdownMenu>
|
</DropdownMenuContent>
|
||||||
</div>
|
</DropdownMenu>
|
||||||
)}
|
</div>
|
||||||
</Td>
|
</Td>
|
||||||
</Tr>
|
</Tr>
|
||||||
);
|
);
|
||||||
@@ -212,11 +230,13 @@ export const UserPanel = () => {
|
|||||||
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
|
const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
|
||||||
"removeUser",
|
"removeUser",
|
||||||
"upgradePlan",
|
"upgradePlan",
|
||||||
"upgradeToServerAdmin"
|
"upgradeToServerAdmin",
|
||||||
|
"removeServerAdmin"
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
const { mutateAsync: deleteUser } = useAdminDeleteUser();
|
const { mutateAsync: deleteUser } = useAdminDeleteUser();
|
||||||
const { mutateAsync: grantAdminAccess } = useAdminGrantServerAdminAccess();
|
const { mutateAsync: grantAdminAccess } = useAdminGrantServerAdminAccess();
|
||||||
|
const { mutateAsync: removeAdminAccess } = useRemoveUserServerAdminAccess();
|
||||||
|
|
||||||
const handleRemoveUser = async () => {
|
const handleRemoveUser = async () => {
|
||||||
const { id } = popUp?.removeUser?.data as { id: string; username: string };
|
const { id } = popUp?.removeUser?.data as { id: string; username: string };
|
||||||
@@ -256,6 +276,25 @@ export const UserPanel = () => {
|
|||||||
handlePopUpClose("upgradeToServerAdmin");
|
handlePopUpClose("upgradeToServerAdmin");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRemoveServerAdminAccess = async () => {
|
||||||
|
const { id } = popUp?.removeServerAdmin?.data as { id: string; username: string };
|
||||||
|
|
||||||
|
try {
|
||||||
|
await removeAdminAccess(id);
|
||||||
|
createNotification({
|
||||||
|
type: "success",
|
||||||
|
text: "Successfully removed server admin access from user"
|
||||||
|
});
|
||||||
|
} catch {
|
||||||
|
createNotification({
|
||||||
|
type: "error",
|
||||||
|
text: "Error removing server admin access from user"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handlePopUpClose("removeServerAdmin");
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||||
<div className="mb-4">
|
<div className="mb-4">
|
||||||
@@ -282,6 +321,17 @@ export const UserPanel = () => {
|
|||||||
onDeleteApproved={handleGrantServerAdminAccess}
|
onDeleteApproved={handleGrantServerAdminAccess}
|
||||||
buttonText="Grant Access"
|
buttonText="Grant Access"
|
||||||
/>
|
/>
|
||||||
|
<DeleteActionModal
|
||||||
|
isOpen={popUp.removeServerAdmin.isOpen}
|
||||||
|
title={`Are you sure want to remove Server Admin permissions from ${
|
||||||
|
(popUp?.removeServerAdmin?.data as { id: string; username: string })?.username || ""
|
||||||
|
}?`}
|
||||||
|
subTitle=""
|
||||||
|
onChange={(isOpen) => handlePopUpToggle("removeServerAdmin", isOpen)}
|
||||||
|
deleteKey="confirm"
|
||||||
|
onDeleteApproved={handleRemoveServerAdminAccess}
|
||||||
|
buttonText="Remove Access"
|
||||||
|
/>
|
||||||
<UpgradePlanModal
|
<UpgradePlanModal
|
||||||
isOpen={popUp.upgradePlan.isOpen}
|
isOpen={popUp.upgradePlan.isOpen}
|
||||||
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
|
||||||
|
|||||||
Reference in New Issue
Block a user