|
|
|
@ -17,8 +17,8 @@ import {
|
|
|
|
|
faPeopleGroup,
|
|
|
|
|
faPerson,
|
|
|
|
|
faPlus,
|
|
|
|
|
faShuffle,
|
|
|
|
|
faX,
|
|
|
|
|
faShuffle
|
|
|
|
|
} from "@fortawesome/free-solid-svg-icons";
|
|
|
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
|
|
|
import { Menu, Transition } from "@headlessui/react";
|
|
|
|
@ -116,9 +116,7 @@ const KeyPair = ({
|
|
|
|
|
<div
|
|
|
|
|
onClick={() =>
|
|
|
|
|
modifyVisibility(
|
|
|
|
|
keyPair[4] == "personal"
|
|
|
|
|
? "shared"
|
|
|
|
|
: "personal",
|
|
|
|
|
keyPair[4] == "personal" ? "shared" : "personal",
|
|
|
|
|
keyPair[1]
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
@ -126,16 +124,10 @@ const KeyPair = ({
|
|
|
|
|
>
|
|
|
|
|
<FontAwesomeIcon
|
|
|
|
|
className="text-lg pl-1.5 pr-3"
|
|
|
|
|
icon={
|
|
|
|
|
keyPair[4] == "personal"
|
|
|
|
|
? faPeopleGroup
|
|
|
|
|
: faPerson
|
|
|
|
|
}
|
|
|
|
|
icon={keyPair[4] == "personal" ? faPeopleGroup : faPerson}
|
|
|
|
|
/>
|
|
|
|
|
<div className="text-sm">
|
|
|
|
|
{keyPair[4] == "personal"
|
|
|
|
|
? "Make Shared"
|
|
|
|
|
: "Make Personal"}
|
|
|
|
|
{keyPair[4] == "personal" ? "Make Shared" : "Make Personal"}
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div
|
|
|
|
@ -145,18 +137,19 @@ const KeyPair = ({
|
|
|
|
|
} else if (randomStringLength < 2) {
|
|
|
|
|
setRandomStringLength(2);
|
|
|
|
|
} else {
|
|
|
|
|
modifyValue([...Array(randomStringLength)].map(() => Math.floor(Math.random() * 16).toString(16)).join(''), keyPair[1]);
|
|
|
|
|
modifyValue(
|
|
|
|
|
[...Array(randomStringLength)]
|
|
|
|
|
.map(() => Math.floor(Math.random() * 16).toString(16))
|
|
|
|
|
.join(""),
|
|
|
|
|
keyPair[1]
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
className="relative flex flex-row justify-start items-center cursor-pointer select-none py-2 px-2 rounded-md text-gray-400 hover:bg-white/10 duration-200 hover:text-gray-200 w-full"
|
|
|
|
|
>
|
|
|
|
|
<FontAwesomeIcon
|
|
|
|
|
className="text-lg pl-1.5 pr-3"
|
|
|
|
|
icon={
|
|
|
|
|
keyPair[3] == ""
|
|
|
|
|
? faPlus
|
|
|
|
|
: faShuffle
|
|
|
|
|
}
|
|
|
|
|
icon={keyPair[3] == "" ? faPlus : faShuffle}
|
|
|
|
|
/>
|
|
|
|
|
<div className="text-sm justify-between flex flex-row w-full">
|
|
|
|
|
<p>Generate Random Hex</p>
|
|
|
|
@ -168,14 +161,16 @@ const KeyPair = ({
|
|
|
|
|
className="m-0.5 px-1 cursor-pointer rounded-md hover:bg-chicago-700"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
if (randomStringLength > 1) {
|
|
|
|
|
setRandomStringLength(randomStringLength - 1)
|
|
|
|
|
setRandomStringLength(randomStringLength - 1);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
-
|
|
|
|
|
</div>
|
|
|
|
|
<input
|
|
|
|
|
onChange={(e) => setRandomStringLength(parseInt(e.target.value))}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setRandomStringLength(parseInt(e.target.value))
|
|
|
|
|
}
|
|
|
|
|
value={randomStringLength}
|
|
|
|
|
className="text-center z-20 peer text-sm bg-transparent w-full outline-none"
|
|
|
|
|
spellCheck="false"
|
|
|
|
@ -184,7 +179,7 @@ const KeyPair = ({
|
|
|
|
|
className="m-0.5 px-1 pb-0.5 cursor-pointer rounded-md hover:bg-chicago-700"
|
|
|
|
|
onClick={() => {
|
|
|
|
|
if (randomStringLength < 32) {
|
|
|
|
|
setRandomStringLength(randomStringLength + 1)
|
|
|
|
|
setRandomStringLength(randomStringLength + 1);
|
|
|
|
|
}
|
|
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
@ -280,13 +275,9 @@ export default function Dashboard() {
|
|
|
|
|
(async () => {
|
|
|
|
|
try {
|
|
|
|
|
let userWorkspaces = await getWorkspaces();
|
|
|
|
|
const listWorkspaces = userWorkspaces.map(
|
|
|
|
|
(workspace) => workspace._id
|
|
|
|
|
);
|
|
|
|
|
const listWorkspaces = userWorkspaces.map((workspace) => workspace._id);
|
|
|
|
|
if (
|
|
|
|
|
!listWorkspaces.includes(
|
|
|
|
|
router.asPath.split("/")[2].split("?")[0]
|
|
|
|
|
)
|
|
|
|
|
!listWorkspaces.includes(router.asPath.split("/")[2].split("?")[0])
|
|
|
|
|
) {
|
|
|
|
|
router.push("/dashboard/" + listWorkspaces[0]);
|
|
|
|
|
}
|
|
|
|
@ -307,9 +298,7 @@ export default function Dashboard() {
|
|
|
|
|
|
|
|
|
|
const user = await getUser();
|
|
|
|
|
setIsNew(
|
|
|
|
|
(Date.parse(new Date()) - Date.parse(user.createdAt)) /
|
|
|
|
|
60000 <
|
|
|
|
|
3
|
|
|
|
|
(Date.parse(new Date()) - Date.parse(user.createdAt)) / 60000 < 3
|
|
|
|
|
? true
|
|
|
|
|
: false
|
|
|
|
|
);
|
|
|
|
@ -428,9 +417,7 @@ export default function Dashboard() {
|
|
|
|
|
|
|
|
|
|
// This function downloads the secrets as a .env file
|
|
|
|
|
const download = () => {
|
|
|
|
|
const file = data
|
|
|
|
|
.map((item) => [item[2], item[3]].join("="))
|
|
|
|
|
.join("\n");
|
|
|
|
|
const file = data.map((item) => [item[2], item[3]].join("=")).join("\n");
|
|
|
|
|
const blob = new Blob([file]);
|
|
|
|
|
const fileDownloadUrl = URL.createObjectURL(blob);
|
|
|
|
|
let alink = document.createElement("a");
|
|
|
|
@ -464,10 +451,7 @@ export default function Dashboard() {
|
|
|
|
|
<title>Secrets</title>
|
|
|
|
|
<link rel="icon" href="/infisical.ico" />
|
|
|
|
|
<meta property="og:image" content="/images/message.png" />
|
|
|
|
|
<meta
|
|
|
|
|
property="og:title"
|
|
|
|
|
content="Manage your .env files in seconds"
|
|
|
|
|
/>
|
|
|
|
|
<meta property="og:title" content="Manage your .env files in seconds" />
|
|
|
|
|
<meta
|
|
|
|
|
name="og:description"
|
|
|
|
|
content="Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
|
|
|
@ -493,12 +477,7 @@ export default function Dashboard() {
|
|
|
|
|
{data?.length == 0 && (
|
|
|
|
|
<ListBox
|
|
|
|
|
selected={env}
|
|
|
|
|
data={[
|
|
|
|
|
"Development",
|
|
|
|
|
"Staging",
|
|
|
|
|
"Production",
|
|
|
|
|
"Testing",
|
|
|
|
|
]}
|
|
|
|
|
data={["Development", "Staging", "Production", "Testing"]}
|
|
|
|
|
// ref={useRef(123)}
|
|
|
|
|
onChange={setEnv}
|
|
|
|
|
className="z-40"
|
|
|
|
@ -507,9 +486,7 @@ export default function Dashboard() {
|
|
|
|
|
</div>
|
|
|
|
|
<div className="flex flex-row">
|
|
|
|
|
<div className="flex justify-end items-center bg-white/[0.07] text-base mt-2 mr-2 rounded-md text-gray-400">
|
|
|
|
|
<p className="mr-2 font-bold pl-4">
|
|
|
|
|
Project ID:
|
|
|
|
|
</p>
|
|
|
|
|
<p className="mr-2 font-bold pl-4">Project ID:</p>
|
|
|
|
|
<input
|
|
|
|
|
type="text"
|
|
|
|
|
value={workspaceId}
|
|
|
|
@ -523,10 +500,7 @@ export default function Dashboard() {
|
|
|
|
|
className="pl-4 pr-4 border-l border-white/20 py-2 hover:bg-white/[0.12] duration-200"
|
|
|
|
|
>
|
|
|
|
|
{projectIdCopied ? (
|
|
|
|
|
<FontAwesomeIcon
|
|
|
|
|
icon={faCheck}
|
|
|
|
|
className="pr-0.5"
|
|
|
|
|
/>
|
|
|
|
|
<FontAwesomeIcon icon={faCheck} className="pr-0.5" />
|
|
|
|
|
) : (
|
|
|
|
|
<FontAwesomeIcon icon={faCopy} />
|
|
|
|
|
)}
|
|
|
|
@ -537,9 +511,7 @@ export default function Dashboard() {
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
{(data?.length !== 0 || buttonReady) && (
|
|
|
|
|
<div
|
|
|
|
|
className={`flex justify-start max-w-sm mt-2`}
|
|
|
|
|
>
|
|
|
|
|
<div className={`flex justify-start max-w-sm mt-2`}>
|
|
|
|
|
<Button
|
|
|
|
|
text="Save Changes"
|
|
|
|
|
onButtonPressed={savePush}
|
|
|
|
@ -560,12 +532,7 @@ export default function Dashboard() {
|
|
|
|
|
<>
|
|
|
|
|
<ListBox
|
|
|
|
|
selected={env}
|
|
|
|
|
data={[
|
|
|
|
|
"Development",
|
|
|
|
|
"Staging",
|
|
|
|
|
"Production",
|
|
|
|
|
"Testing",
|
|
|
|
|
]}
|
|
|
|
|
data={["Development", "Staging", "Production", "Testing"]}
|
|
|
|
|
// ref={useRef(123)}
|
|
|
|
|
onChange={setEnv}
|
|
|
|
|
className="z-40"
|
|
|
|
@ -578,11 +545,7 @@ export default function Dashboard() {
|
|
|
|
|
<input
|
|
|
|
|
className="pl-2 text-gray-400 rounded-r-md bg-white/5 w-full h-full outline-none"
|
|
|
|
|
value={searchKeys}
|
|
|
|
|
onChange={(e) =>
|
|
|
|
|
setSearchKeys(
|
|
|
|
|
e.target.value
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
onChange={(e) => setSearchKeys(e.target.value)}
|
|
|
|
|
placeholder={"Search keys..."}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
@ -611,9 +574,7 @@ export default function Dashboard() {
|
|
|
|
|
onButtonPressed={changeBlurred}
|
|
|
|
|
color="mineshaft"
|
|
|
|
|
size="icon-md"
|
|
|
|
|
icon={
|
|
|
|
|
blurred ? faEye : faEyeSlash
|
|
|
|
|
}
|
|
|
|
|
icon={blurred ? faEye : faEyeSlash}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
<div className="relative ml-2 min-w-max flex flex-row items-start justify-end">
|
|
|
|
@ -646,17 +607,14 @@ export default function Dashboard() {
|
|
|
|
|
<div className="rounded-t-md sticky top-0 z-20 bg-bunker flex flex-row pl-4 pr-6 pt-4 pb-2 items-center justify-between text-gray-300 font-bold">
|
|
|
|
|
{/* <FontAwesomeIcon icon={faAngleDown} /> */}
|
|
|
|
|
<div className="flex flex-row items-center">
|
|
|
|
|
<p className="pl-2 text-lg">
|
|
|
|
|
Personal
|
|
|
|
|
</p>
|
|
|
|
|
<p className="pl-2 text-lg">Personal</p>
|
|
|
|
|
<div className="group font-normal group relative inline-block text-gray-300 underline hover:text-primary duration-200">
|
|
|
|
|
<FontAwesomeIcon
|
|
|
|
|
className="ml-3 mt-1 text-lg"
|
|
|
|
|
icon={faCircleInfo}
|
|
|
|
|
/>
|
|
|
|
|
<span className="absolute hidden group-hover:flex group-hover:animate-popdown duration-300 w-44 -left-16 -top-7 translate-y-full px-2 py-2 bg-gray-700 rounded-md text-center text-gray-100 text-sm after:content-[''] after:absolute after:left-1/2 after:bottom-[100%] after:-translate-x-1/2 after:border-8 after:border-x-transparent after:border-t-transparent after:border-b-gray-700">
|
|
|
|
|
Personal keys are only
|
|
|
|
|
visible to you
|
|
|
|
|
Personal keys are only visible to you
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -667,9 +625,7 @@ export default function Dashboard() {
|
|
|
|
|
(keyPair) =>
|
|
|
|
|
keyPair[2]
|
|
|
|
|
.toLowerCase()
|
|
|
|
|
.includes(
|
|
|
|
|
searchKeys.toLowerCase()
|
|
|
|
|
) &&
|
|
|
|
|
.includes(searchKeys.toLowerCase()) &&
|
|
|
|
|
keyPair[4] == "personal"
|
|
|
|
|
)
|
|
|
|
|
.sort((a, b) =>
|
|
|
|
@ -682,13 +638,9 @@ export default function Dashboard() {
|
|
|
|
|
key={keyPair[0]}
|
|
|
|
|
keyPair={keyPair}
|
|
|
|
|
deleteRow={deleteCertainRow}
|
|
|
|
|
modifyValue={
|
|
|
|
|
listenChangeValue
|
|
|
|
|
}
|
|
|
|
|
modifyValue={listenChangeValue}
|
|
|
|
|
modifyKey={listenChangeKey}
|
|
|
|
|
modifyVisibility={
|
|
|
|
|
listenChangeVisibility
|
|
|
|
|
}
|
|
|
|
|
modifyVisibility={listenChangeVisibility}
|
|
|
|
|
isBlurred={blurred}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
@ -702,17 +654,14 @@ export default function Dashboard() {
|
|
|
|
|
<div className="sticky top-0 z-40 bg-bunker flex flex-row pl-4 pr-5 pt-4 pb-2 items-center justify-between text-gray-300 font-bold">
|
|
|
|
|
{/* <FontAwesomeIcon icon={faAngleDown} /> */}
|
|
|
|
|
<div className="flex flex-row items-center">
|
|
|
|
|
<p className="pl-2 text-lg">
|
|
|
|
|
Shared
|
|
|
|
|
</p>
|
|
|
|
|
<p className="pl-2 text-lg">Shared</p>
|
|
|
|
|
<div className="group font-normal group relative inline-block text-gray-300 underline hover:text-primary duration-200">
|
|
|
|
|
<FontAwesomeIcon
|
|
|
|
|
className="ml-3 text-lg mt-1"
|
|
|
|
|
icon={faCircleInfo}
|
|
|
|
|
/>
|
|
|
|
|
<span className="absolute hidden group-hover:flex group-hover:animate-popdown duration-300 w-44 -left-16 -top-7 translate-y-full px-2 py-2 bg-gray-700 rounded-md text-center text-gray-100 text-sm after:content-[''] after:absolute after:left-1/2 after:bottom-[100%] after:-translate-x-1/2 after:border-8 after:border-x-transparent after:border-t-transparent after:border-b-gray-700">
|
|
|
|
|
Shared keys are visible to
|
|
|
|
|
your whole team
|
|
|
|
|
Shared keys are visible to your whole team
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
@ -723,9 +672,7 @@ export default function Dashboard() {
|
|
|
|
|
(keyPair) =>
|
|
|
|
|
keyPair[2]
|
|
|
|
|
.toLowerCase()
|
|
|
|
|
.includes(
|
|
|
|
|
searchKeys.toLowerCase()
|
|
|
|
|
) &&
|
|
|
|
|
.includes(searchKeys.toLowerCase()) &&
|
|
|
|
|
keyPair[4] == "shared"
|
|
|
|
|
)
|
|
|
|
|
.sort((a, b) =>
|
|
|
|
@ -738,13 +685,9 @@ export default function Dashboard() {
|
|
|
|
|
key={keyPair[0]}
|
|
|
|
|
keyPair={keyPair}
|
|
|
|
|
deleteRow={deleteCertainRow}
|
|
|
|
|
modifyValue={
|
|
|
|
|
listenChangeValue
|
|
|
|
|
}
|
|
|
|
|
modifyValue={listenChangeValue}
|
|
|
|
|
modifyKey={listenChangeKey}
|
|
|
|
|
modifyVisibility={
|
|
|
|
|
listenChangeVisibility
|
|
|
|
|
}
|
|
|
|
|
modifyVisibility={listenChangeVisibility}
|
|
|
|
|
isBlurred={blurred}
|
|
|
|
|
/>
|
|
|
|
|
))}
|
|
|
|
@ -753,9 +696,7 @@ export default function Dashboard() {
|
|
|
|
|
<div className="w-full max-w-5xl">
|
|
|
|
|
<DropZone
|
|
|
|
|
setData={addData}
|
|
|
|
|
setErrorDragAndDrop={
|
|
|
|
|
setErrorDragAndDrop
|
|
|
|
|
}
|
|
|
|
|
setErrorDragAndDrop={setErrorDragAndDrop}
|
|
|
|
|
createNewFile={addRow}
|
|
|
|
|
errorDragAndDrop={errorDragAndDrop}
|
|
|
|
|
setButtonReady={setButtonReady}
|
|
|
|
@ -766,23 +707,19 @@ export default function Dashboard() {
|
|
|
|
|
</div>
|
|
|
|
|
) : (
|
|
|
|
|
<div className="flex flex-col items-center justify-center h-full text-xl text-gray-400 max-w-5xl mt-28">
|
|
|
|
|
{fileState.message !=
|
|
|
|
|
"There's nothing to pull" &&
|
|
|
|
|
{fileState.message != "There's nothing to pull" &&
|
|
|
|
|
fileState.message != undefined && (
|
|
|
|
|
<FontAwesomeIcon
|
|
|
|
|
className="text-7xl mb-8"
|
|
|
|
|
icon={faFolderOpen}
|
|
|
|
|
/>
|
|
|
|
|
)}
|
|
|
|
|
{(fileState.message ==
|
|
|
|
|
"There's nothing to pull" ||
|
|
|
|
|
{(fileState.message == "There's nothing to pull" ||
|
|
|
|
|
fileState.message == undefined) &&
|
|
|
|
|
isKeyAvailable && (
|
|
|
|
|
<DropZone
|
|
|
|
|
setData={setData}
|
|
|
|
|
setErrorDragAndDrop={
|
|
|
|
|
setErrorDragAndDrop
|
|
|
|
|
}
|
|
|
|
|
setErrorDragAndDrop={setErrorDragAndDrop}
|
|
|
|
|
createNewFile={addRow}
|
|
|
|
|
errorDragAndDrop={errorDragAndDrop}
|
|
|
|
|
setButtonReady={setButtonReady}
|
|
|
|
@ -791,13 +728,9 @@ export default function Dashboard() {
|
|
|
|
|
)}
|
|
|
|
|
{fileState.message ==
|
|
|
|
|
"Failed membership validation for workspace" && (
|
|
|
|
|
<p>
|
|
|
|
|
You are not authorized to view this
|
|
|
|
|
project.
|
|
|
|
|
</p>
|
|
|
|
|
<p>You are not authorized to view this project.</p>
|
|
|
|
|
)}
|
|
|
|
|
{fileState.message ==
|
|
|
|
|
"Access needed to pull the latest file" ||
|
|
|
|
|
{fileState.message == "Access needed to pull the latest file" ||
|
|
|
|
|
(!isKeyAvailable && (
|
|
|
|
|
<>
|
|
|
|
|
<FontAwesomeIcon
|
|
|
|
@ -805,12 +738,11 @@ export default function Dashboard() {
|
|
|
|
|
icon={faFolderOpen}
|
|
|
|
|
/>
|
|
|
|
|
<p>
|
|
|
|
|
To view this file, contact your
|
|
|
|
|
administrator for permission.
|
|
|
|
|
To view this file, contact your administrator for
|
|
|
|
|
permission.
|
|
|
|
|
</p>
|
|
|
|
|
<p className="mt-1">
|
|
|
|
|
They need to grant you access in
|
|
|
|
|
the team tab.
|
|
|
|
|
They need to grant you access in the team tab.
|
|
|
|
|
</p>
|
|
|
|
|
</>
|
|
|
|
|
))}
|
|
|
|
|