Compare commits

...

4 Commits

Author SHA1 Message Date
1797e56f9f fixed sdk guides 2023-12-24 13:30:59 -08:00
597c9d6f2a fix docs sdk errors 2023-12-23 17:17:10 -08:00
24d2eea930 ui and docs improvements 2023-12-23 16:06:00 -08:00
6725475575 Merge pull request #1264 from Infisical/sdk/docs-update
SDK documentation update
2023-12-23 09:30:35 -08:00
17 changed files with 157 additions and 90 deletions

View File

@ -7,6 +7,7 @@ The changelog below reflects new product developments and updates on a monthly b
## December 2023 ## December 2023
- Added ability to [manage folders via CLI](https://infisical.com/docs/cli/commands/secrets). - Added ability to [manage folders via CLI](https://infisical.com/docs/cli/commands/secrets).
- Created new cross-language SDKs for [Python](https://infisical.com/docs/sdks/languages/python), [Node](https://infisical.com/docs/sdks/languages/node), and [Java](https://infisical.com/docs/sdks/languages/java).
## November 2023 ## November 2023

View File

@ -13,7 +13,8 @@ Prerequisites:
Follow the instructions for your language use the SDK for it: Follow the instructions for your language use the SDK for it:
- [Node SDK](https://github.com/Infisical/infisical-node) - [Node SDK](https://infisical.com/docs/sdks/languages/node)
- [Python SDK](https://github.com/Infisical/infisical-python) - [Python SDK](https://infisical.com/docs/sdks/languages/python)
- [Java SDK](https://infisical.com/docs/sdks/languages/java)
Missing a language? [Throw in a request](https://github.com/Infisical/infisical/issues). Missing a language? [Throw in a request](https://github.com/Infisical/infisical/issues).

View File

@ -240,12 +240,6 @@ At this stage, you know how to use the Infisical-Vercel integration to sync prod
Check out the [security guide](/security/overview). Check out the [security guide](/security/overview).
</Accordion> </Accordion>
<Accordion title="Is there way to retain end-to-end encryption for syncing production secrets to Vercel?">
Yes. You can also use the Infisical [Node SDK](https://github.com/Infisical/infisical-node) to fetch secrets back to your Next.js app
in both development and production.
Depending on how you use it, however, it may require certain pages to be server-side rendered.
</Accordion>
</AccordionGroup> </AccordionGroup>
See also: See also:

View File

@ -4,8 +4,7 @@ description: "Programmatically interact with Infisical"
--- ---
<Note> <Note>
Currently, identities can only be used to make authenticated requests to the Infisical API and do not work with any clients such as [Node SDK](https://github.com/Infisical/infisical-node) Currently, identities can only be used to make authenticated requests to the Infisical API and SDKs. They do not work with clients such as CLI, K8s Operator, Terraform Provider, etc.
, [Python SDK](https://github.com/Infisical/infisical-python), CLI, K8s operator, Terraform Provider, etc.
We will be releasing compatibility with it across clients in the coming quarter. We will be releasing compatibility with it across clients in the coming quarter.
</Note> </Note>

View File

@ -12,8 +12,8 @@ This means that updating the value of a base secret propagates directly to other
Currently, the secret referencing feature is only supported by the Currently, the secret referencing feature is only supported by the
[Infisical CLI](/cli/overview) and [native integrations](/integrations/overview). [Infisical CLI](/cli/overview) and [native integrations](/integrations/overview).
We intend to add support for it to the [Node SDK](https://github.com/Infisical/infisical-node) We intend to add support for it to the [Node SDK](https://infisical.com/docs/sdks/languages/node),
and [Python SDK](https://github.com/Infisical/infisical-python) this quarter. [Python SDK](https://infisical.com/docs/sdks/languages/python), and [Java SDK](https://infisical.com/docs/sdks/languages/java) this quarter.
</Note> </Note>
![secret referencing](../../images/platform/secret-references-imports/secret-reference.png) ![secret referencing](../../images/platform/secret-references-imports/secret-reference.png)

View File

@ -25,6 +25,6 @@ The Web UI is the browser-based portal that connects to the Infisical API.
Clients are any application or infrastructure that connecting to the Infisical API using one of the below methods: Clients are any application or infrastructure that connecting to the Infisical API using one of the below methods:
- Public API: Making API requests directly to the Infisical API. - Public API: Making API requests directly to the Infisical API.
- Client SDK: A platform-specific library with method abstractions for working with secrets. Currently, there are two official SDKs: [Node SDK](https://github.com/Infisical/infisical-node) and [Python SDK](https://github.com/Infisical/infisical-python). - Client SDK: A platform-specific library with method abstractions for working with secrets. Currently, there are three official SDKs: [Node SDK](https://infisical.com/docs/sdks/languages/node), [Python SDK](https://infisical.com/docs/sdks/languages/python), and [Java SDK](https://infisical.com/docs/sdks/languages/java).
- CLI: A terminal-based interface for interacting with the Infisical API. - CLI: A terminal-based interface for interacting with the Infisical API.
- Kubernetes Operator: This operator retrieves secrets from Infisical and securely store - Kubernetes Operator: This operator retrieves secrets from Infisical and securely store

View File

@ -716,6 +716,12 @@ export const AppLayout = ({ children }: LayoutProps) => {
</a> </a>
</DropdownMenuItem> </DropdownMenuItem>
))} ))}
{infisicalPlatformVersion && (
<div className="cursor-default mb-2 mt-2 w-full pl-5 duration-200 hover:text-mineshaft-200 text-sm">
<FontAwesomeIcon icon={faInfo} className="mr-4 px-[0.1rem]" />
Version: {infisicalPlatformVersion}
</div>
)}
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
{subscription && {subscription &&
@ -745,12 +751,6 @@ export const AppLayout = ({ children }: LayoutProps) => {
</div> </div>
</button> </button>
)} )}
{infisicalPlatformVersion && (
<div className="mb-2 w-full pl-5 duration-200 hover:text-mineshaft-200">
<FontAwesomeIcon icon={faInfo} className="mr-4 px-[0.1rem]" />
Version: {infisicalPlatformVersion}
</div>
)}
</div> </div>
</nav> </nav>
</aside> </aside>

View File

@ -67,8 +67,16 @@ const features = [
{ {
_id: 0, _id: 0,
name: "Kubernetes Operator", name: "Kubernetes Operator",
link: "https://infisical.com/docs/documentation/getting-started/kubernetes",
description: description:
"Pull secrets into your Kubernetes containers and automatically redeploy upon secret changes." "Pull secrets into your Kubernetes containers and automatically redeploy upon secret changes."
},
{
_id: 1,
name: "Infisical Agent",
link: "https://infisical.com/docs/infisical-agent/overview",
description:
"Inject secrets into your apps without modifying any application logic."
} }
]; ];
@ -691,11 +699,44 @@ const OrganizationPage = withPermission(
</div> </div>
)} )}
</div> </div>
<div className="mb-4 flex flex-col items-start justify-start px-6 py-6 pb-6 text-3xl">
<p className="mr-4 font-semibold text-white">Explore Infisical</p>
<div className="mt-4 grid grid-cols-3 w-full gap-4">
{features.map((feature) => (
<div
key={feature._id}
className="flex h-44 w-full flex-col justify-between rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4"
>
<div className="mt-0 text-lg text-mineshaft-100">{feature.name}</div>
<div className="mb-4 mt-2 text-[15px] font-light text-mineshaft-300">
{feature.description}
</div>
<div className="flex w-full items-center">
<div className="text-[15px] font-light text-mineshaft-300">
Setup time: 20 min
</div>
<a
target="_blank"
rel="noopener noreferrer"
className="group ml-auto w-max cursor-default rounded-full border border-mineshaft-600 bg-mineshaft-900 py-2 px-4 text-sm text-mineshaft-300 hover:border-primary-500/80 hover:bg-primary-800/20 hover:text-mineshaft-200"
href={feature.link}
>
Learn more{" "}
<FontAwesomeIcon
icon={faArrowRight}
className="pl-1.5 pr-0.5 duration-200 group-hover:pl-2 group-hover:pr-0"
/>
</a>
</div>
</div>
))}
</div>
</div>
{!( {!(
new Date().getTime() - new Date(user?.createdAt).getTime() < new Date().getTime() - new Date(user?.createdAt).getTime() <
30 * 24 * 60 * 60 * 1000 30 * 24 * 60 * 60 * 1000
) && ( ) && (
<div className="mb-4 flex flex-col items-start justify-start px-6 py-6 pb-0 text-3xl"> <div className="mb-4 flex flex-col items-start justify-start px-6 pb-6 pb-0 text-3xl">
<p className="mr-4 mb-4 font-semibold text-white">Onboarding Guide</p> <p className="mr-4 mb-4 font-semibold text-white">Onboarding Guide</p>
<div className="mb-3 grid w-full grid-cols-1 gap-3 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4"> <div className="mb-3 grid w-full grid-cols-1 gap-3 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
<LearningItemSquare <LearningItemSquare
@ -784,42 +825,6 @@ const OrganizationPage = withPermission(
)} )}
</div> </div>
)} )}
<div className="mb-4 flex flex-col items-start justify-start px-6 py-6 pb-6 text-3xl">
<p className="mr-4 font-semibold text-white">Explore More</p>
<div
className="mt-4 grid w-full grid-flow-dense gap-4"
style={{ gridTemplateColumns: "repeat(auto-fill, minmax(256px, 4fr))" }}
>
{features.map((feature) => (
<div
key={feature._id}
className="flex h-44 w-96 flex-col justify-between rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4"
>
<div className="mt-0 text-lg text-mineshaft-100">{feature.name}</div>
<div className="mb-4 mt-2 text-[15px] font-light text-mineshaft-300">
{feature.description}
</div>
<div className="flex w-full items-center">
<div className="text-[15px] font-light text-mineshaft-300">
Setup time: 20 min
</div>
<a
target="_blank"
rel="noopener noreferrer"
className="group ml-auto w-max cursor-default rounded-full border border-mineshaft-600 bg-mineshaft-900 py-2 px-4 text-sm text-mineshaft-300 hover:border-primary-500/80 hover:bg-primary-800/20 hover:text-mineshaft-200"
href="https://infisical.com/docs/documentation/getting-started/kubernetes"
>
Learn more{" "}
<FontAwesomeIcon
icon={faArrowRight}
className="pl-1.5 pr-0.5 duration-200 group-hover:pl-2 group-hover:pr-0"
/>
</a>
</div>
</div>
))}
</div>
</div>
<Modal <Modal
isOpen={popUp.addNewWs.isOpen} isOpen={popUp.addNewWs.isOpen}
onOpenChange={(isModalOpen) => { onOpenChange={(isModalOpen) => {

View File

@ -1,4 +1,5 @@
import { faPlus } from "@fortawesome/free-solid-svg-icons"; import Link from "next/link";
import { faArrowUpRightFromSquare, faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
@ -65,17 +66,24 @@ export const IdentitySection = withPermission(
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="flex justify-between mb-8"> <div className="flex justify-between mb-4">
<p className="text-xl font-semibold text-mineshaft-100"> <p className="text-xl font-semibold text-mineshaft-100">
Identities Identities
</p> </p>
<div className="flex justify-end w-full pr-4">
<Link href="https://infisical.com/docs/documentation/platform/identities/overview">
<span className="rounded-md px-4 py-2 w-max text-mineshaft-200 hover:text-white bg-mineshaft-600 border border-mineshaft-500 hover:bg-primary/10 hover:border-primary/40 duration-200 cursor-pointer">
Documentation <FontAwesomeIcon icon={faArrowUpRightFromSquare} className="text-xs mb-[0.06rem] ml-1"/>
</span>
</Link>
</div>
<OrgPermissionCan <OrgPermissionCan
I={OrgPermissionActions.Create} I={OrgPermissionActions.Create}
a={OrgPermissionSubjects.Identity} a={OrgPermissionSubjects.Identity}
> >
{(isAllowed) => ( {(isAllowed) => (
<Button <Button
colorSchema="secondary" colorSchema="primary"
type="submit" type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen("identity")} onClick={() => handlePopUpOpen("identity")}

View File

@ -89,7 +89,7 @@ export const OrgMembersSection = () => {
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="flex justify-between mb-8"> <div className="flex justify-between mb-4">
<p className="text-xl font-semibold text-mineshaft-100"> <p className="text-xl font-semibold text-mineshaft-100">
Members Members
</p> </p>
@ -99,7 +99,7 @@ export const OrgMembersSection = () => {
> >
{(isAllowed) => ( {(isAllowed) => (
<Button <Button
colorSchema="secondary" colorSchema="primary"
type="submit" type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handleAddMemberModal()} onClick={() => handleAddMemberModal()}

View File

@ -191,9 +191,9 @@ export const IdentityModal = ({
</form> </form>
) : ( ) : (
<div className="flex flex-col space-y-4"> <div className="flex flex-col space-y-4">
<div>All identities in your organization are already added.</div> <div className="text-sm">All identities in your organization have already been added to this project.</div>
<Link href={`/org/${currentWorkspace?.organization}/members`}> <Link href={`/org/${currentWorkspace?.organization}/members`}>
<Button variant="outline_bg">Create a new/another identities</Button> <Button variant="outline_bg">Create a new identity</Button>
</Link> </Link>
</div> </div>
)} )}

View File

@ -1,4 +1,5 @@
import { faPlus } from "@fortawesome/free-solid-svg-icons"; import Link from "next/link";
import { faArrowUpRightFromSquare, faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
@ -61,17 +62,24 @@ export const IdentitySection = withProjectPermission(
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="flex justify-between mb-8"> <div className="flex justify-between items-center mb-4">
<p className="text-xl font-semibold text-mineshaft-100"> <p className="text-xl font-semibold text-mineshaft-100">
Identities Identities
</p> </p>
<div className="flex justify-end w-full pr-4">
<Link href="https://infisical.com/docs/documentation/platform/identities/overview">
<span className="rounded-md px-4 py-2 w-max text-mineshaft-200 hover:text-white bg-mineshaft-600 border border-mineshaft-500 hover:bg-primary/10 hover:border-primary/40 duration-200 cursor-pointer">
Documentation <FontAwesomeIcon icon={faArrowUpRightFromSquare} className="text-xs mb-[0.06rem] ml-1"/>
</span>
</Link>
</div>
<ProjectPermissionCan <ProjectPermissionCan
I={ProjectPermissionActions.Create} I={ProjectPermissionActions.Create}
a={ProjectPermissionSub.Identity} a={ProjectPermissionSub.Identity}
> >
{(isAllowed) => ( {(isAllowed) => (
<Button <Button
colorSchema="secondary" colorSchema="primary"
type="submit" type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen("identity")} onClick={() => handlePopUpOpen("identity")}

View File

@ -254,7 +254,7 @@ export const MemberListTab = () => {
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="flex justify-between mb-8"> <div className="flex justify-between items-center mb-4">
<p className="text-xl font-semibold text-mineshaft-100"> <p className="text-xl font-semibold text-mineshaft-100">
Members Members
</p> </p>
@ -264,7 +264,7 @@ export const MemberListTab = () => {
> >
{(isAllowed) => ( {(isAllowed) => (
<Button <Button
colorSchema="secondary" colorSchema="primary"
type="submit" type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen("addMember")} onClick={() => handlePopUpOpen("addMember")}

View File

@ -1,3 +1,7 @@
import Link from "next/link";
import { faArrowUpRightFromSquare } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { useWorkspace } from "@app/context"; import { useWorkspace } from "@app/context";
@ -15,8 +19,18 @@ export const SecretApprovalPage = () => {
return ( return (
<div className="container mx-auto bg-bunker-800 text-white w-full h-full max-w-7xl px-6"> <div className="container mx-auto bg-bunker-800 text-white w-full h-full max-w-7xl px-6">
<div className="my-6"> <div className="py-6 flex justify-between items-center">
<p className="text-3xl font-semibold text-gray-200">Secret Approvals</p> <div className="flex flex-col w-full">
<h2 className="text-3xl font-semibold text-gray-200">Secret Approval Workflows</h2>
<p className="text-bunker-300">Create approval policies for any modifications to secrets in sensitive environments and folders.</p>
</div>
<div className="flex justify-center w-max">
<Link href="https://infisical.com/docs/documentation/platform/pr-workflows">
<span className="rounded-md px-4 py-2 w-max text-mineshaft-200 hover:text-white bg-mineshaft-600 border border-mineshaft-500 hover:bg-primary/10 hover:border-primary/40 duration-200 cursor-pointer">
Documentation <FontAwesomeIcon icon={faArrowUpRightFromSquare} className="text-xs mb-[0.06rem] ml-1"/>
</span>
</Link>
</div>
</div> </div>
<Tabs defaultValue={TabSection.ApprovalRequests}> <Tabs defaultValue={TabSection.ApprovalRequests}>
<TabList> <TabList>

View File

@ -108,11 +108,11 @@ export const FolderListView = ({
key={id} key={id}
className="flex group border-b border-mineshaft-600 hover:bg-mineshaft-700 cursor-pointer" className="flex group border-b border-mineshaft-600 hover:bg-mineshaft-700 cursor-pointer"
> >
<div className="w-12 px-4 py-2 text-yellow-700 flex items-center"> <div className="w-11 px-5 py-3 text-yellow-700 flex items-center">
<FontAwesomeIcon icon={faFolder} /> <FontAwesomeIcon icon={faFolder} />
</div> </div>
<div <div
className="flex-grow px-4 py-2 flex items-center" className="flex-grow px-4 py-3 flex items-center"
role="button" role="button"
tabIndex={0} tabIndex={0}
onKeyDown={(evt) => { onKeyDown={(evt) => {
@ -122,7 +122,7 @@ export const FolderListView = ({
> >
{name} {name}
</div> </div>
<div className="px-3 py-2 flex items-center space-x-4 border-l border-mineshaft-600"> <div className="px-3 py-3 flex items-center space-x-4 border-l border-mineshaft-600">
<ProjectPermissionCan <ProjectPermissionCan
I={ProjectPermissionActions.Edit} I={ProjectPermissionActions.Edit}
a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })} a={subject(ProjectPermissionSub.Secrets, { environment, secretPath })}

View File

@ -270,22 +270,39 @@ export const SecretOverviewPage = () => {
<p className="text-md text-bunker-300"> <p className="text-md text-bunker-300">
Inject your secrets using Inject your secrets using
<a <a
className="mx-1 text-primary/80 hover:text-primary" className="ml-1 text-mineshaft-300 underline underline-offset-4 decoration-primary-800 hover:decoration-primary-600 hover:text-mineshaft-100 duration-200"
href="https://infisical.com/docs/cli/overview" href="https://infisical.com/docs/cli/overview"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
Infisical CLI Infisical CLI
</a> </a>,
or
<a <a
className="mx-1 text-primary/80 hover:text-primary" className="ml-1 text-mineshaft-300 underline underline-offset-4 decoration-primary-800 hover:decoration-primary-600 hover:text-mineshaft-100 duration-200"
href="https://infisical.com/docs/documentation/getting-started/api"
target="_blank"
rel="noopener noreferrer"
>
Infisical API
</a>
,
<a
className="ml-1 text-mineshaft-300 underline underline-offset-4 decoration-primary-800 hover:decoration-primary-600 hover:text-mineshaft-100 duration-200"
href="https://infisical.com/docs/sdks/overview" href="https://infisical.com/docs/sdks/overview"
target="_blank" target="_blank"
rel="noopener noreferrer" rel="noopener noreferrer"
> >
Infisical SDKs Infisical SDKs
</a> </a>
, and
<a
className="ml-1 text-mineshaft-300 underline underline-offset-4 decoration-primary-800 hover:decoration-primary-600 hover:text-mineshaft-100 duration-200"
href="https://infisical.com/docs/documentation/getting-started/introduction"
target="_blank"
rel="noopener noreferrer"
>
more
</a>.
</p> </p>
</div> </div>
<div className="mt-8 flex items-center justify-between"> <div className="mt-8 flex items-center justify-between">
@ -306,7 +323,7 @@ export const SecretOverviewPage = () => {
<THead> <THead>
<Tr className="sticky top-0 z-20 border-0"> <Tr className="sticky top-0 z-20 border-0">
<Th className="sticky left-0 z-20 min-w-[20rem] border-b-0 p-0"> <Th className="sticky left-0 z-20 min-w-[20rem] border-b-0 p-0">
<div className="flex items-center border-b border-r border-mineshaft-600 px-5 pt-4 pb-3.5"> <div className="flex items-center border-b border-r border-mineshaft-600 px-5 pt-3.5 pb-3">
Name Name
<IconButton <IconButton
variant="plain" variant="plain"
@ -326,7 +343,7 @@ export const SecretOverviewPage = () => {
className="min-table-row min-w-[11rem] border-b-0 p-0 text-center" className="min-table-row min-w-[11rem] border-b-0 p-0 text-center"
key={`secret-overview-${name}-${index + 1}`} key={`secret-overview-${name}-${index + 1}`}
> >
<div className="flex items-center justify-center border-b border-mineshaft-600 px-5 pt-3.5 pb-3"> <div className="flex items-center justify-center border-b border-mineshaft-600 px-5 pt-3.5 pb-[0.83rem]">
<button <button
type="button" type="button"
className="text-sm font-medium duration-100 hover:text-mineshaft-100" className="text-sm font-medium duration-100 hover:text-mineshaft-100"
@ -382,7 +399,7 @@ export const SecretOverviewPage = () => {
</Td> </Td>
</Tr> </Tr>
)} )}
{filteredFolderNames.map((folderName, index) => ( {!isTableLoading && filteredFolderNames.map((folderName, index) => (
<SecretOverviewFolderRow <SecretOverviewFolderRow
folderName={folderName} folderName={folderName}
isFolderPresentInEnv={isFolderPresentInEnv} isFolderPresentInEnv={isFolderPresentInEnv}
@ -391,7 +408,7 @@ export const SecretOverviewPage = () => {
onClick={handleFolderClick} onClick={handleFolderClick}
/> />
))} ))}
{userAvailableEnvs?.length > 0 ? ( {!isTableLoading && (userAvailableEnvs?.length > 0 ? (
filteredSecretNames.map((key, index) => ( filteredSecretNames.map((key, index) => (
<SecretOverviewTableRow <SecretOverviewTableRow
secretPath={secretPath} secretPath={secretPath}
@ -407,7 +424,7 @@ export const SecretOverviewPage = () => {
)) ))
) : ( ) : (
<PermissionDeniedBanner /> <PermissionDeniedBanner />
)} ))}
</TBody> </TBody>
<TFoot> <TFoot>
<Tr className="sticky bottom-0 z-10 border-0 bg-mineshaft-800"> <Tr className="sticky bottom-0 z-10 border-0 bg-mineshaft-800">

View File

@ -1,9 +1,12 @@
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import Link from "next/link";
import { import {
faArrowsSpin, faArrowsSpin,
faArrowUpRightFromSquare,
faExclamationTriangle, faExclamationTriangle,
faFolder, faFolder,
faInfoCircle, faInfoCircle,
faPlus,
faRotate, faRotate,
faTrash faTrash
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
@ -180,12 +183,21 @@ export const SecretRotationPage = withProjectPermission(
return ( return (
<div className="container mx-auto bg-bunker-800 text-white w-full h-full max-w-7xl px-6"> <div className="container mx-auto bg-bunker-800 text-white w-full h-full max-w-7xl px-6">
<div className="my-6"> <div className="py-6 flex justify-between items-center">
<h2 className="text-3xl font-semibold text-gray-200">Secret Rotation</h2> <div className="flex flex-col w-full">
<p className="text-bunker-300">Auto rotate secrets for better security</p> <h2 className="text-3xl font-semibold text-gray-200">Secret Rotation</h2>
<p className="text-bunker-300">Stop manually rotating secrets and automate credential rotation.</p>
</div>
<div className="flex justify-center w-max">
<Link href="https://infisical.com/docs/documentation/platform/secret-rotation/overview">
<span className="rounded-md px-4 py-2 w-max text-mineshaft-200 hover:text-white bg-mineshaft-600 border border-mineshaft-500 hover:bg-primary/10 hover:border-primary/40 duration-200 cursor-pointer">
Documentation <FontAwesomeIcon icon={faArrowUpRightFromSquare} className="text-xs mb-[0.06rem] ml-1"/>
</span>
</Link>
</div>
</div> </div>
<div className="mb-6"> <div className="mb-6">
<div className="text-xl font-semibold text-gray-200 mb-2">Rotated Secrets</div> <div className="text-xl font-semibold text-gray-200 mb-2 mt-6">Rotated Secrets</div>
<div className="flex flex-col space-y-2"> <div className="flex flex-col space-y-2">
<TableContainer> <TableContainer>
<Table> <Table>
@ -322,7 +334,7 @@ export const SecretRotationPage = withProjectPermission(
</TableContainer> </TableContainer>
</div> </div>
</div> </div>
<div className="text-xl font-semibold text-gray-200 mb-2">Infisical Rotation Providers</div> <div className="text-xl font-semibold text-gray-200 mb-2 mt-12">Infisical Rotation Providers</div>
<div className="grid grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-4"> <div className="grid grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-4">
{isRotationProviderLoading && {isRotationProviderLoading &&
Array.from({ length: 12 }).map((_, index) => ( Array.from({ length: 12 }).map((_, index) => (
@ -331,7 +343,7 @@ export const SecretRotationPage = withProjectPermission(
{!isRotationProviderLoading && {!isRotationProviderLoading &&
secretRotationProviders?.providers.map((provider) => ( secretRotationProviders?.providers.map((provider) => (
<div <div
className="group relative cursor-pointer h-32 flex flex-row items-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4" className="group relative cursor-pointer h-32 flex flex-row items-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4 hover:border-primary/40 hover:bg-primary/10"
key={`infisical-rotation-provider-${provider.name}`} key={`infisical-rotation-provider-${provider.name}`}
tabIndex={0} tabIndex={0}
role="button" role="button"
@ -349,13 +361,21 @@ export const SecretRotationPage = withProjectPermission(
<div className="ml-4 max-w-xs text-xl font-semibold text-gray-300 duration-200 group-hover:text-gray-200"> <div className="ml-4 max-w-xs text-xl font-semibold text-gray-300 duration-200 group-hover:text-gray-200">
{provider.title} {provider.title}
</div> </div>
<div className="group-hover:opacity-100 transition-all opacity-0 absolute top-1 right-1"> <div className="group-hover:opacity-100 transition-all opacity-0 absolute top-1 right-1.5">
<Tooltip content={provider.description} sideOffset={10}> <Tooltip content={provider.description} sideOffset={10}>
<FontAwesomeIcon icon={faInfoCircle} className="text-bunker-300" /> <FontAwesomeIcon icon={faInfoCircle} className="text-primary" />
</Tooltip> </Tooltip>
</div> </div>
</div> </div>
))} ))}
<Link href="https://github.com/Infisical/infisical/issues">
<div className="group relative cursor-pointer h-32 flex flex-row items-center rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4 hover:border-primary/40 hover:bg-primary/10">
<FontAwesomeIcon icon={faPlus} className="text-gray-300 text-3xl pl-3 pr-2" />
<div className="ml-4 max-w-xs text-xl font-semibold text-gray-300 duration-200 group-hover:text-gray-200">
Request or create your own template
</div>
</div>
</Link>
</div> </div>
<CreateRotationForm <CreateRotationForm
isOpen={popUp.createRotation.isOpen} isOpen={popUp.createRotation.isOpen}