mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: changed blind index banner for everyone
This commit is contained in:
@@ -29,10 +29,7 @@ export const secretBlindIndexServiceFactory = ({
|
||||
projectId,
|
||||
actorId
|
||||
}: TGetProjectBlindIndexStatusDTO) => {
|
||||
const { membership } = await permissionService.getProjectPermission(actor, actorId, projectId);
|
||||
if (membership?.role !== ProjectMembershipRole.Admin) {
|
||||
throw new UnauthorizedError({ message: "User must be admin" });
|
||||
}
|
||||
await permissionService.getProjectPermission(actor, actorId, projectId);
|
||||
|
||||
const secretCount = await secretBlindIndexDAL.countOfSecretsWithNullSecretBlindIndex(projectId);
|
||||
return Number(secretCount);
|
||||
|
||||
@@ -25,7 +25,7 @@ export const ProjectPermissionCan: FunctionComponent<Props> = ({
|
||||
allowedLabel,
|
||||
...props
|
||||
}) => {
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
return (
|
||||
<Can {...props} passThrough={passThrough} ability={props?.ability || permission}>
|
||||
{(isAllowed, ability) => {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createContext, ReactNode, useContext } from "react";
|
||||
|
||||
import { useGetUserProjectPermissions } from "@app/hooks/api";
|
||||
import { TProjectMembership } from "@app/hooks/api/users/types";
|
||||
|
||||
import { useWorkspace } from "../WorkspaceContext";
|
||||
import { TProjectPermission } from "./types";
|
||||
@@ -9,7 +10,10 @@ type Props = {
|
||||
children: ReactNode;
|
||||
};
|
||||
|
||||
const ProjectPermissionContext = createContext<null | TProjectPermission>(null);
|
||||
const ProjectPermissionContext = createContext<null | {
|
||||
permission: TProjectPermission;
|
||||
membership: TProjectMembership;
|
||||
}>(null);
|
||||
|
||||
export const ProjectPermissionProvider = ({ children }: Props): JSX.Element => {
|
||||
const { currentWorkspace, isLoading: isWsLoading } = useWorkspace();
|
||||
|
||||
@@ -21,7 +21,7 @@ export const withProjectPermission = <T extends {}, J extends TProjectPermission
|
||||
{ action, subject, className, containerClassName }: Props<Generics<J>["abilities"]>
|
||||
) => {
|
||||
const HOC = (hocProps: T) => {
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
// akhilmhdh: Set as any due to casl/react ts type bug
|
||||
// REASON: casl due to its type checking can't seem to union even if union intersection is applied
|
||||
@@ -29,13 +29,13 @@ export const withProjectPermission = <T extends {}, J extends TProjectPermission
|
||||
return (
|
||||
<div
|
||||
className={twMerge(
|
||||
"container h-full mx-auto flex justify-center items-center",
|
||||
"container mx-auto flex h-full items-center justify-center",
|
||||
containerClassName
|
||||
)}
|
||||
>
|
||||
<div
|
||||
className={twMerge(
|
||||
"rounded-md bg-mineshaft-800 text-bunker-300 p-16 flex space-x-12 items-end",
|
||||
"flex items-end space-x-12 rounded-md bg-mineshaft-800 p-16 text-bunker-300",
|
||||
className
|
||||
)}
|
||||
>
|
||||
@@ -43,7 +43,7 @@ export const withProjectPermission = <T extends {}, J extends TProjectPermission
|
||||
<FontAwesomeIcon icon={faLock} size="6x" />
|
||||
</div>
|
||||
<div>
|
||||
<div className="text-4xl font-medium mb-2">Permission Denied</div>
|
||||
<div className="mb-2 text-4xl font-medium">Permission Denied</div>
|
||||
<div className="text-sm">
|
||||
You do not have permission to this page. <br /> Kindly contact your organization
|
||||
administrator
|
||||
|
||||
@@ -8,7 +8,7 @@ import { apiRequest } from "@app/config/request";
|
||||
import { OrgPermissionSet } from "@app/context/OrgPermissionContext/types";
|
||||
import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext/types";
|
||||
|
||||
import { OrgUser } from "../users/types";
|
||||
import { OrgUser, TProjectMembership } from "../users/types";
|
||||
import {
|
||||
TGetUserOrgPermissionsDTO,
|
||||
TGetUserProjectPermissionDTO,
|
||||
@@ -104,10 +104,13 @@ export const useGetUserOrgPermissions = ({ orgId }: TGetUserOrgPermissionsDTO) =
|
||||
|
||||
const getUserProjectPermissions = async ({ workspaceId }: TGetUserProjectPermissionDTO) => {
|
||||
const { data } = await apiRequest.get<{
|
||||
data: { permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[] };
|
||||
data: {
|
||||
permissions: PackRule<RawRuleOf<MongoAbility<OrgPermissionSet>>>[];
|
||||
membership: TProjectMembership;
|
||||
};
|
||||
}>(`/api/v1/workspace/${workspaceId}/permissions`, {});
|
||||
|
||||
return data.data.permissions;
|
||||
return data.data;
|
||||
};
|
||||
|
||||
export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPermissionDTO) =>
|
||||
@@ -116,8 +119,8 @@ export const useGetUserProjectPermissions = ({ workspaceId }: TGetUserProjectPer
|
||||
queryFn: () => getUserProjectPermissions({ workspaceId }),
|
||||
enabled: Boolean(workspaceId),
|
||||
select: (data) => {
|
||||
const rule = unpackRules<RawRuleOf<MongoAbility<ProjectPermissionSet>>>(data);
|
||||
const rule = unpackRules<RawRuleOf<MongoAbility<ProjectPermissionSet>>>(data.permissions);
|
||||
const ability = createMongoAbility<ProjectPermissionSet>(rule, { conditionsMatcher });
|
||||
return ability;
|
||||
return { permission: ability, membership: data.membership };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -52,6 +52,15 @@ export type OrgUser = {
|
||||
roleId: string;
|
||||
};
|
||||
|
||||
export type TProjectMembership = {
|
||||
id: string;
|
||||
role: string;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
projectId: string;
|
||||
roleId: string;
|
||||
};
|
||||
|
||||
export type TWorkspaceUser = OrgUser;
|
||||
|
||||
export type AddUserToWsDTO = {
|
||||
|
||||
@@ -30,7 +30,7 @@ export const CloudIntegrationSection = ({
|
||||
const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([
|
||||
"deleteConfirmation"
|
||||
] as const);
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
const { createNotification } = useNotificationContext();
|
||||
|
||||
const isEmpty = !isLoading && !cloudIntegrations?.length;
|
||||
@@ -43,7 +43,7 @@ export const CloudIntegrationSection = ({
|
||||
<h1 className="text-3xl font-semibold">{t("integrations.cloud-integrations")}</h1>
|
||||
<p className="text-base text-gray-400">{t("integrations.click-to-start")}</p>
|
||||
</div>
|
||||
<div className="mx-6 grid grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-4">
|
||||
<div className="mx-6 grid grid-cols-2 gap-4 lg:grid-cols-3 2xl:grid-cols-4">
|
||||
{isLoading &&
|
||||
Array.from({ length: 12 }).map((_, index) => (
|
||||
<Skeleton className="h-32" key={`cloud-integration-skeleton-${index + 1}`} />
|
||||
|
||||
@@ -44,7 +44,7 @@ export const SecretApprovalPolicyList = ({ workspaceId }: Props) => {
|
||||
"deletePolicy",
|
||||
"upgradePlan"
|
||||
] as const);
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
const { subscription } = useSubscription();
|
||||
const { createNotification } = useNotificationContext();
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ export const SecretApprovalPolicyRow = ({
|
||||
}: Props) => {
|
||||
const [selectedApprovers, setSelectedApprovers] = useState<string[]>([]);
|
||||
const { mutate: updateSecretApprovalPolicy, isLoading } = useUpdateSecretApprovalPolicy();
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
return (
|
||||
<Tr>
|
||||
|
||||
@@ -48,7 +48,7 @@ export const SecretMainPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const router = useRouter();
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const [isVisible, setIsVisible] = useState(false);
|
||||
const [sortDir, setSortDir] = useState<SortDir>(SortDir.ASC);
|
||||
|
||||
@@ -81,7 +81,7 @@ export const SecretDetailSidebar = ({
|
||||
resolver: zodResolver(formSchema),
|
||||
values: secret
|
||||
});
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
const cannotEditSecret = permission.cannot(
|
||||
ProjectPermissionActions.Edit,
|
||||
subject(ProjectPermissionSub.Secrets, { environment, secretPath })
|
||||
|
||||
@@ -85,7 +85,7 @@ export const SecretItem = memo(
|
||||
secretPath
|
||||
}: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
const isReadOnly =
|
||||
permission.can(
|
||||
ProjectPermissionActions.Read,
|
||||
|
||||
@@ -4,9 +4,15 @@ import {
|
||||
decryptSymmetric
|
||||
} from "@app/components/utilities/cryptography/crypto";
|
||||
import { Button, Spinner } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
} from "@app/context";
|
||||
import { useToggle } from "@app/hooks";
|
||||
import { useGetWorkspaceIndexStatus, useNameWorkspaceSecrets } from "@app/hooks/api";
|
||||
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
|
||||
import { UserWsKeyPair } from "@app/hooks/api/types";
|
||||
import { fetchWorkspaceSecrets } from "@app/hooks/api/workspace/queries";
|
||||
|
||||
@@ -18,6 +24,7 @@ type Props = {
|
||||
|
||||
export const ProjectIndexSecretsSection = ({ decryptFileKey }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { membership } = useProjectPermission();
|
||||
const { data: isBlindIndexed, isLoading: isBlindIndexedLoading } = useGetWorkspaceIndexStatus(
|
||||
currentWorkspace?.id ?? ""
|
||||
);
|
||||
@@ -78,13 +85,16 @@ export const ProjectIndexSecretsSection = ({ decryptFileKey }: Props) => {
|
||||
<p className="mb-4 leading-7 text-gray-400">
|
||||
Your project was created before the introduction of blind indexing. To continue accessing
|
||||
secrets by name through the SDK, public API and web dashboard, please enable blind indexing.{" "}
|
||||
<b>This is a one time process.</b>
|
||||
<b>
|
||||
This is a one time process.{" "}
|
||||
{membership.role !== ProjectMembershipRole.Admin && "Admin only operation"}
|
||||
</b>
|
||||
</p>
|
||||
<ProjectPermissionCan I={ProjectPermissionActions.Edit} a={ProjectPermissionSub.Settings}>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
onClick={onEnableBlindIndices}
|
||||
isDisabled={!isAllowed}
|
||||
isDisabled={!isAllowed || membership.role !== ProjectMembershipRole.Admin}
|
||||
color="mineshaft"
|
||||
type="submit"
|
||||
isLoading={isIndexing}
|
||||
|
||||
@@ -62,7 +62,7 @@ export const SecretRotationPage = withProjectPermission(
|
||||
() => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { t } = useTranslation();
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
const { createNotification } = useNotificationContext();
|
||||
const { popUp, handlePopUpOpen, handlePopUpToggle, handlePopUpClose } = usePopUp([
|
||||
"createRotation",
|
||||
|
||||
@@ -22,7 +22,7 @@ export const EnvironmentSection = () => {
|
||||
const { createNotification } = useNotificationContext();
|
||||
const { subscription } = useSubscription();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const permision = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const deleteWsEnvironment = useDeleteWsEnvironment();
|
||||
|
||||
@@ -94,7 +94,7 @@ export const EnvironmentSection = () => {
|
||||
Choose which environments will show up in your dashboard like development, staging,
|
||||
production
|
||||
</p>
|
||||
{permision.can(ProjectPermissionActions.Read, ProjectPermissionSub.Environments) ? (
|
||||
{permission.can(ProjectPermissionActions.Read, ProjectPermissionSub.Environments) ? (
|
||||
<EnvironmentTable handlePopUpOpen={handlePopUpOpen} />
|
||||
) : (
|
||||
<PermissionDeniedBanner />
|
||||
|
||||
@@ -4,7 +4,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
|
||||
import { PermissionDeniedBanner, ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useProjectPermission, useWorkspace } from "@app/context";
|
||||
import {
|
||||
ProjectPermissionActions,
|
||||
ProjectPermissionSub,
|
||||
useProjectPermission,
|
||||
useWorkspace
|
||||
} from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import { useDeleteWsTag } from "@app/hooks/api";
|
||||
|
||||
@@ -20,14 +25,14 @@ export const SecretTagsSection = (): JSX.Element => {
|
||||
"deleteTagConfirmation"
|
||||
] as const);
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const permission = useProjectPermission();
|
||||
const { permission } = useProjectPermission();
|
||||
|
||||
const deleteWsTag = useDeleteWsTag();
|
||||
|
||||
const onDeleteApproved = async () => {
|
||||
try {
|
||||
await deleteWsTag.mutateAsync({
|
||||
projectId:currentWorkspace?.id || "",
|
||||
projectId: currentWorkspace?.id || "",
|
||||
tagID: (popUp?.deleteTagConfirmation?.data as DeleteModalData)?.id
|
||||
});
|
||||
|
||||
@@ -47,8 +52,8 @@ export const SecretTagsSection = (): JSX.Element => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="mb-6 p-4 bg-mineshaft-900 rounded-lg border border-mineshaft-600">
|
||||
<div className="flex justify-between mb-8">
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-8 flex justify-between">
|
||||
<p className="mb-3 text-xl font-semibold">Secret Tags</p>
|
||||
<ProjectPermissionCan I={ProjectPermissionActions.Create} a={ProjectPermissionSub.Tags}>
|
||||
{(isAllowed) => (
|
||||
@@ -65,7 +70,7 @@ export const SecretTagsSection = (): JSX.Element => {
|
||||
)}
|
||||
</ProjectPermissionCan>
|
||||
</div>
|
||||
<p className="text-gray-400 mb-8">
|
||||
<p className="mb-8 text-gray-400">
|
||||
Every secret can be assigned to one or more tags. Here you can add and remove tags for the
|
||||
current project.
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user