mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 17:27:40 +00:00
feat: added no secret access views
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/* eslint-disable no-await-in-loop */
|
/* eslint-disable no-await-in-loop */
|
||||||
import { unpackRules } from "@casl/ability/extra";
|
import { packRules, unpackRules } from "@casl/ability/extra";
|
||||||
import { Knex } from "knex";
|
import { Knex } from "knex";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -764,7 +764,7 @@ export const backfillPermissionV1SchemaToV2Schema = (data: z.infer<typeof Projec
|
|||||||
|
|
||||||
const secretFolderPolicies = secretSubjects.map(({ subject, ...el }) => ({
|
const secretFolderPolicies = secretSubjects.map(({ subject, ...el }) => ({
|
||||||
...el,
|
...el,
|
||||||
subject: ProjectPermissionSub.DynamicSecrets
|
subject: ProjectPermissionSub.SecretFolders
|
||||||
}));
|
}));
|
||||||
|
|
||||||
const dynamicSecretPolicies = secretSubjects.map(({ subject, ...el }) => ({
|
const dynamicSecretPolicies = secretSubjects.map(({ subject, ...el }) => ({
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ import { ActionBar } from "./components/ActionBar";
|
|||||||
import { CreateSecretForm } from "./components/CreateSecretForm";
|
import { CreateSecretForm } from "./components/CreateSecretForm";
|
||||||
import { PitDrawer } from "./components/PitDrawer";
|
import { PitDrawer } from "./components/PitDrawer";
|
||||||
import { SecretDropzone } from "./components/SecretDropzone";
|
import { SecretDropzone } from "./components/SecretDropzone";
|
||||||
import { SecretListView } from "./components/SecretListView";
|
import { SecretListView, SecretNoAccessListView } from "./components/SecretListView";
|
||||||
import { SnapshotView } from "./components/SnapshotView";
|
import { SnapshotView } from "./components/SnapshotView";
|
||||||
import { StoreProvider } from "./SecretMainPage.store";
|
import { StoreProvider } from "./SecretMainPage.store";
|
||||||
import { Filter, RowType } from "./SecretMainPage.types";
|
import { Filter, RowType } from "./SecretMainPage.types";
|
||||||
@@ -315,7 +315,6 @@ export const SecretMainPage = () => {
|
|||||||
setFilter(defaultFilterState);
|
setFilter(defaultFilterState);
|
||||||
setDebouncedSearchFilter("");
|
setDebouncedSearchFilter("");
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StoreProvider>
|
<StoreProvider>
|
||||||
<div className="container mx-auto flex flex-col px-6 text-mineshaft-50 dark:[color-scheme:dark]">
|
<div className="container mx-auto flex flex-col px-6 text-mineshaft-50 dark:[color-scheme:dark]">
|
||||||
@@ -418,6 +417,17 @@ export const SecretMainPage = () => {
|
|||||||
isProtectedBranch={isProtectedBranch}
|
isProtectedBranch={isProtectedBranch}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
{canReadSecret && (
|
||||||
|
<SecretNoAccessListView
|
||||||
|
count={Math.max(
|
||||||
|
(page * perPage > totalCount ? totalCount % perPage : perPage) -
|
||||||
|
(folders?.length || 0) -
|
||||||
|
(secrets?.length || 0) -
|
||||||
|
(dynamicSecrets?.length || 0),
|
||||||
|
0
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{!canReadSecret &&
|
{!canReadSecret &&
|
||||||
!canReadDynamicSecret &&
|
!canReadDynamicSecret &&
|
||||||
!canReadSecretImports &&
|
!canReadSecretImports &&
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import { WsTag } from "@app/hooks/api/types";
|
|||||||
import { AddShareSecretModal } from "@app/views/ShareSecretPage/components/AddShareSecretModal";
|
import { AddShareSecretModal } from "@app/views/ShareSecretPage/components/AddShareSecretModal";
|
||||||
|
|
||||||
import { useSelectedSecretActions, useSelectedSecrets } from "../../SecretMainPage.store";
|
import { useSelectedSecretActions, useSelectedSecrets } from "../../SecretMainPage.store";
|
||||||
import { Filter } from "../../SecretMainPage.types";
|
|
||||||
import { SecretDetailSidebar } from "./SecretDetaiSidebar";
|
import { SecretDetailSidebar } from "./SecretDetaiSidebar";
|
||||||
import { SecretItem } from "./SecretItem";
|
import { SecretItem } from "./SecretItem";
|
||||||
import { FontAwesomeSpriteSymbols } from "./SecretListView.utils";
|
import { FontAwesomeSpriteSymbols } from "./SecretListView.utils";
|
||||||
@@ -31,16 +30,6 @@ type Props = {
|
|||||||
isProtectedBranch?: boolean;
|
isProtectedBranch?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const filterSecrets = (secrets: SecretV3RawSanitized[], filter: Filter) =>
|
|
||||||
secrets.filter(({ key, value, tags }) => {
|
|
||||||
const isTagFilterActive = Boolean(Object.keys(filter.tags).length);
|
|
||||||
const searchTerm = filter.searchFilter.toLowerCase();
|
|
||||||
return (
|
|
||||||
(!isTagFilterActive || tags?.some(({ id }) => filter.tags?.[id])) &&
|
|
||||||
(key.toLowerCase().includes(searchTerm) || value?.toLowerCase().includes(searchTerm))
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
export const SecretListView = ({
|
export const SecretListView = ({
|
||||||
secrets = [],
|
secrets = [],
|
||||||
environment,
|
environment,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import {
|
|||||||
faCopy,
|
faCopy,
|
||||||
faEllipsis,
|
faEllipsis,
|
||||||
faKey,
|
faKey,
|
||||||
|
faLock,
|
||||||
faShare,
|
faShare,
|
||||||
faTags
|
faTags
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
@@ -71,7 +72,8 @@ export enum FontAwesomeSpriteName {
|
|||||||
Close = "close",
|
Close = "close",
|
||||||
CheckedCircle = "check-circle",
|
CheckedCircle = "check-circle",
|
||||||
ReplicatedSecretKey = "secret-replicated",
|
ReplicatedSecretKey = "secret-replicated",
|
||||||
ShareSecret = "share-secret"
|
ShareSecret = "share-secret",
|
||||||
|
KeyLock = "key-lock"
|
||||||
}
|
}
|
||||||
|
|
||||||
// this is an optimization technique
|
// this is an optimization technique
|
||||||
@@ -88,5 +90,6 @@ export const FontAwesomeSpriteSymbols = [
|
|||||||
{ icon: faClose, symbol: FontAwesomeSpriteName.Close },
|
{ icon: faClose, symbol: FontAwesomeSpriteName.Close },
|
||||||
{ icon: faCheckCircle, symbol: FontAwesomeSpriteName.CheckedCircle },
|
{ icon: faCheckCircle, symbol: FontAwesomeSpriteName.CheckedCircle },
|
||||||
{ icon: faClone, symbol: FontAwesomeSpriteName.ReplicatedSecretKey },
|
{ icon: faClone, symbol: FontAwesomeSpriteName.ReplicatedSecretKey },
|
||||||
{ icon: faShare, symbol: FontAwesomeSpriteName.ShareSecret }
|
{ icon: faShare, symbol: FontAwesomeSpriteName.ShareSecret },
|
||||||
|
{ icon: faLock, symbol: FontAwesomeSpriteName.KeyLock }
|
||||||
];
|
];
|
||||||
|
|||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
import { FontAwesomeSymbol, Input } from "@app/components/v2";
|
||||||
|
|
||||||
|
import { FontAwesomeSpriteName } from "./SecretListView.utils";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
count: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SecretNoAccessListView = ({ count }: Props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{Array.from(Array(count)).map((_, i) => (
|
||||||
|
<div
|
||||||
|
className="flex border-b border-mineshaft-600 bg-mineshaft-800 shadow-none hover:bg-mineshaft-700"
|
||||||
|
key={`no-access-secret-${i + 1}`}
|
||||||
|
>
|
||||||
|
<div className="flex h-11 w-11 items-center justify-center px-4 py-3">
|
||||||
|
<FontAwesomeSymbol
|
||||||
|
className="ml-3 block h-3.5 w-3.5"
|
||||||
|
symbolName={FontAwesomeSpriteName.KeyLock}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="flex h-11 w-80 flex-shrink-0 items-center px-4 py-2">
|
||||||
|
<Input
|
||||||
|
autoComplete="off"
|
||||||
|
isReadOnly
|
||||||
|
variant="plain"
|
||||||
|
value="NO ACCESS"
|
||||||
|
isDisabled
|
||||||
|
className="w-full px-0 blur-sm placeholder:text-red-500 focus:text-bunker-100 focus:ring-transparent"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="flex w-80 flex-grow items-center border-x border-mineshaft-600 py-1 pl-4 pr-2"
|
||||||
|
tabIndex={0}
|
||||||
|
role="button"
|
||||||
|
>
|
||||||
|
<span className="blur">********</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1 +1,2 @@
|
|||||||
export { SecretListView } from "./SecretListView";
|
export { SecretListView } from "./SecretListView";
|
||||||
|
export { SecretNoAccessListView } from "./SecretNoAccessListView";
|
||||||
|
|||||||
+45
@@ -0,0 +1,45 @@
|
|||||||
|
import { faCircle } from "@fortawesome/free-regular-svg-icons";
|
||||||
|
import { faLock } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
|
import { Td, Tr } from "@app/components/v2";
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
environments: { name: string; slug: string }[];
|
||||||
|
count: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SecretNoAccessOverviewTableRow = ({ environments = [], count }: Props) => {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{Array.from(Array(count)).map((_, j) => (
|
||||||
|
<Tr key={`no-access-secret-overview-${j + 1}`} isHoverable isSelectable className="group">
|
||||||
|
<Td className="sticky left-0 z-10 bg-mineshaft-800 bg-clip-padding py-0 px-0 group-hover:bg-mineshaft-700">
|
||||||
|
<div className="h-full w-full border-r border-mineshaft-600 py-2.5 px-5">
|
||||||
|
<div className="flex items-center space-x-5">
|
||||||
|
<div className="text-bunker-300">
|
||||||
|
<FontAwesomeIcon className="block" icon={faLock} />
|
||||||
|
</div>
|
||||||
|
<div className="blur-sm">NO ACCESS</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
{environments.map(({ slug }, i) => {
|
||||||
|
return (
|
||||||
|
<Td
|
||||||
|
key={`sec-overview-${slug}-${i + 1}-value`}
|
||||||
|
className="py-0 px-0 group-hover:bg-mineshaft-700"
|
||||||
|
>
|
||||||
|
<div className="h-full w-full border-r border-mineshaft-600 py-[0.85rem] px-5">
|
||||||
|
<div className="flex justify-center">
|
||||||
|
<FontAwesomeIcon icon={faCircle} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Td>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Tr>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
@@ -1 +1,2 @@
|
|||||||
|
export { SecretNoAccessOverviewTableRow } from "./SecretNoAccessOverviewTableRow";
|
||||||
export { SecretOverviewTableRow } from "./SecretOverviewTableRow";
|
export { SecretOverviewTableRow } from "./SecretOverviewTableRow";
|
||||||
|
|||||||
Reference in New Issue
Block a user