mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 10:28:00 +00:00
lint(frontend): apply two space instead of tab
This commit is contained in:
@@ -2,9 +2,8 @@ import { useEffect, useState } from "react";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
|
|
||||||
import checkAuth from "~/pages/api/auth/CheckAuth";
|
|
||||||
|
|
||||||
import { publicPaths } from "~/const";
|
import { publicPaths } from "~/const";
|
||||||
|
import checkAuth from "~/pages/api/auth/CheckAuth";
|
||||||
|
|
||||||
// #TODO: finish spinner only when the data loads fully
|
// #TODO: finish spinner only when the data loads fully
|
||||||
// #TODO: Redirect somewhere if the page does not exist
|
// #TODO: Redirect somewhere if the page does not exist
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import posthog from "posthog-js";
|
import posthog from "posthog-js";
|
||||||
|
|
||||||
import { ENV, POSTHOG_API_KEY, POSTHOG_HOST, TELEMETRY_ENABLED } from "../utilities/config";
|
import {
|
||||||
|
ENV,
|
||||||
|
POSTHOG_API_KEY,
|
||||||
|
POSTHOG_HOST,
|
||||||
|
TELEMETRY_ENABLED,
|
||||||
|
} from "../utilities/config";
|
||||||
|
|
||||||
export const initPostHog = () => {
|
export const initPostHog = () => {
|
||||||
if (typeof window !== "undefined") {
|
if (typeof window !== "undefined") {
|
||||||
|
|||||||
@@ -10,9 +10,7 @@ export default function Error({ text }) {
|
|||||||
className="text-white mt-1.5 mb-2 mx-2"
|
className="text-white mt-1.5 mb-2 mx-2"
|
||||||
/>
|
/>
|
||||||
{text && (
|
{text && (
|
||||||
<p className="relative top-0 text-white mr-2 text-sm py-1">
|
<p className="relative top-0 text-white mr-2 text-sm py-1">{text}</p>
|
||||||
{text}
|
|
||||||
</p>
|
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -76,9 +76,7 @@ const InputField = (props) => {
|
|||||||
? "text-bunker-800 group-hover:text-gray-400 focus:text-gray-400 active:text-gray-400"
|
? "text-bunker-800 group-hover:text-gray-400 focus:text-gray-400 active:text-gray-400"
|
||||||
: ""
|
: ""
|
||||||
} ${
|
} ${
|
||||||
props.error
|
props.error ? "focus:ring-red/50" : "focus:ring-primary/50"
|
||||||
? "focus:ring-red/50"
|
|
||||||
: "focus:ring-primary/50"
|
|
||||||
} relative peer bg-bunker-800 rounded-md text-gray-400 text-md p-2 w-full min-w-16 outline-none focus:ring-4 duration-200`}
|
} relative peer bg-bunker-800 rounded-md text-gray-400 text-md p-2 w-full min-w-16 outline-none focus:ring-4 duration-200`}
|
||||||
name={props.name}
|
name={props.name}
|
||||||
spellCheck="false"
|
spellCheck="false"
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Fragment } from "react";
|
import { Fragment } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { faAngleDown,faCheck, faPlus } from "@fortawesome/free-solid-svg-icons";
|
import {
|
||||||
|
faAngleDown,
|
||||||
|
faCheck,
|
||||||
|
faPlus,
|
||||||
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { Listbox, Transition } from "@headlessui/react";
|
import { Listbox, Transition } from "@headlessui/react";
|
||||||
|
|
||||||
@@ -38,7 +42,7 @@ export default function ListBox({
|
|||||||
</div>
|
</div>
|
||||||
{data && (
|
{data && (
|
||||||
<div className="cursor-pointer pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
<div className="cursor-pointer pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
|
||||||
<FontAwesomeIcon icon={faAngleDown} className="text-md mr-1.5"/>
|
<FontAwesomeIcon icon={faAngleDown} className="text-md mr-1.5" />
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</Listbox.Button>
|
</Listbox.Button>
|
||||||
@@ -55,9 +59,7 @@ export default function ListBox({
|
|||||||
key={personIdx}
|
key={personIdx}
|
||||||
className={({ active, selected }) =>
|
className={({ active, selected }) =>
|
||||||
`my-0.5 relative cursor-default select-none py-2 pl-10 pr-4 rounded-md ${
|
`my-0.5 relative cursor-default select-none py-2 pl-10 pr-4 rounded-md ${
|
||||||
selected
|
selected ? "bg-white/10 text-gray-400 font-bold" : ""
|
||||||
? "bg-white/10 text-gray-400 font-bold"
|
|
||||||
: ""
|
|
||||||
} ${
|
} ${
|
||||||
active & !selected
|
active & !selected
|
||||||
? "bg-white/5 text-mineshaft-200 cursor-pointer"
|
? "bg-white/5 text-mineshaft-200 cursor-pointer"
|
||||||
@@ -70,16 +72,17 @@ export default function ListBox({
|
|||||||
<>
|
<>
|
||||||
<span
|
<span
|
||||||
className={`block truncate text-primary${
|
className={`block truncate text-primary${
|
||||||
selected
|
selected ? "font-medium" : "font-normal"
|
||||||
? "font-medium"
|
|
||||||
: "font-normal"
|
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{person}
|
{person}
|
||||||
</span>
|
</span>
|
||||||
{selected ? (
|
{selected ? (
|
||||||
<span className="text-primary rounded-lg absolute inset-y-0 left-0 flex items-center pl-3">
|
<span className="text-primary rounded-lg absolute inset-y-0 left-0 flex items-center pl-3">
|
||||||
<FontAwesomeIcon icon={faCheck} className="text-md ml-1"/>
|
<FontAwesomeIcon
|
||||||
|
icon={faCheck}
|
||||||
|
className="text-md ml-1"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
) : null}
|
) : null}
|
||||||
</>
|
</>
|
||||||
@@ -93,7 +96,7 @@ export default function ListBox({
|
|||||||
>
|
>
|
||||||
<div className="my-0.5 relative flex justify-start cursor-pointer select-none py-2 pl-10 pr-4 rounded-md text-gray-400 hover:bg-lime-300 duration-200 hover:text-black hover:font-semibold mt-2">
|
<div className="my-0.5 relative flex justify-start cursor-pointer select-none py-2 pl-10 pr-4 rounded-md text-gray-400 hover:bg-lime-300 duration-200 hover:text-black hover:font-semibold mt-2">
|
||||||
<span className="rounded-lg absolute inset-y-0 left-0 flex items-center pl-3 pr-4">
|
<span className="rounded-lg absolute inset-y-0 left-0 flex items-center pl-3 pr-4">
|
||||||
<FontAwesomeIcon icon={faPlus} className="text-lg"/>
|
<FontAwesomeIcon icon={faPlus} className="text-lg" />
|
||||||
</span>
|
</span>
|
||||||
Add Project
|
Add Project
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ export default function Button({
|
|||||||
icon,
|
icon,
|
||||||
active = true,
|
active = true,
|
||||||
iconDisabled,
|
iconDisabled,
|
||||||
textDisabled
|
textDisabled,
|
||||||
}) {
|
}) {
|
||||||
let styleButton = classNames(
|
let styleButton = classNames(
|
||||||
"group m-auto md:m-0 inline-block rounded-md duration-200",
|
"group m-auto md:m-0 inline-block rounded-md duration-200",
|
||||||
@@ -36,7 +36,7 @@ export default function Button({
|
|||||||
size == "lg" && "h-12 w-full px-2 md:px-8",
|
size == "lg" && "h-12 w-full px-2 md:px-8",
|
||||||
!size && "md:py-1 px-3 md:px-8",
|
!size && "md:py-1 px-3 md:px-8",
|
||||||
size == "icon-md" && "h-10 w-10 flex items-center justify-center",
|
size == "icon-md" && "h-10 w-10 flex items-center justify-center",
|
||||||
size == "icon-sm" && "h-9 w-9 flex items-center justify-center",
|
size == "icon-sm" && "h-9 w-9 flex items-center justify-center"
|
||||||
);
|
);
|
||||||
|
|
||||||
let styleMainDiv = classNames(
|
let styleMainDiv = classNames(
|
||||||
@@ -48,7 +48,7 @@ export default function Button({
|
|||||||
color == "red" && "text-gray-200",
|
color == "red" && "text-gray-200",
|
||||||
active && color != "red" ? "group-hover:text-black" : "",
|
active && color != "red" ? "group-hover:text-black" : "",
|
||||||
|
|
||||||
size == "icon" && "flex items-center justify-center",
|
size == "icon" && "flex items-center justify-center"
|
||||||
);
|
);
|
||||||
|
|
||||||
let textStyle = classNames(
|
let textStyle = classNames(
|
||||||
@@ -80,25 +80,25 @@ export default function Button({
|
|||||||
className={`rounded-xl`}
|
className={`rounded-xl`}
|
||||||
></Image>
|
></Image>
|
||||||
</div>
|
</div>
|
||||||
{icon &&
|
{icon && (
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={icon}
|
icon={icon}
|
||||||
className={`flex my-auto font-extrabold ${size == "icon-sm" ? "text-sm" : "text-md"} ${(text || textDisabled) && "mr-2"}`}
|
className={`flex my-auto font-extrabold ${
|
||||||
|
size == "icon-sm" ? "text-sm" : "text-md"
|
||||||
|
} ${(text || textDisabled) && "mr-2"}`}
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
{iconDisabled &&
|
{iconDisabled && (
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={iconDisabled}
|
icon={iconDisabled}
|
||||||
className={`flex my-auto font-extrabold ${size == "icon-sm" ? "text-sm" : "text-md"} ${(text || textDisabled) && "mr-2"}`}
|
className={`flex my-auto font-extrabold ${
|
||||||
|
size == "icon-sm" ? "text-sm" : "text-md"
|
||||||
|
} ${(text || textDisabled) && "mr-2"}`}
|
||||||
/>
|
/>
|
||||||
}
|
)}
|
||||||
{(text || textDisabled) &&
|
{(text || textDisabled) && (
|
||||||
<p
|
<p className={textStyle}>{active ? text : textDisabled}</p>
|
||||||
className={textStyle}
|
)}
|
||||||
>
|
|
||||||
{active ? text : textDisabled}
|
|
||||||
</p>
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ const AddIncidentContactDialog = ({
|
|||||||
? incidentContacts.concat([incidentContactEmail])
|
? incidentContacts.concat([incidentContactEmail])
|
||||||
: [incidentContactEmail]
|
: [incidentContactEmail]
|
||||||
);
|
);
|
||||||
addIncidentContact(localStorage.getItem("orgData.id"), incidentContactEmail);
|
addIncidentContact(
|
||||||
|
localStorage.getItem("orgData.id"),
|
||||||
|
incidentContactEmail
|
||||||
|
);
|
||||||
closeModal();
|
closeModal();
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
@@ -60,16 +63,14 @@ const AddIncidentContactDialog = ({
|
|||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2 mb-2">
|
<div className="mt-2 mb-2">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
This contact will be notified in the
|
This contact will be notified in the unlikely event of a
|
||||||
unlikely event of a severe incident.
|
severe incident.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-h-28">
|
<div className="max-h-28">
|
||||||
<InputField
|
<InputField
|
||||||
label="Email"
|
label="Email"
|
||||||
onChangeHandler={
|
onChangeHandler={setIncidentContactEmail}
|
||||||
setIncidentContactEmail
|
|
||||||
}
|
|
||||||
type="varName"
|
type="varName"
|
||||||
value={incidentContactEmail}
|
value={incidentContactEmail}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
|
|||||||
@@ -56,26 +56,21 @@ const AddProjectMemberDialog = ({
|
|||||||
as="h3"
|
as="h3"
|
||||||
className="text-lg font-medium leading-6 text-gray-400 z-50"
|
className="text-lg font-medium leading-6 text-gray-400 z-50"
|
||||||
>
|
>
|
||||||
All the users in your organization
|
All the users in your organization are already invited.
|
||||||
are already invited.
|
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
)}
|
)}
|
||||||
<div className="mt-2 mb-4">
|
<div className="mt-2 mb-4">
|
||||||
{data?.length > 0 ? (
|
{data?.length > 0 ? (
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
The user will receive an email
|
The user will receive an email with the instructions.
|
||||||
with the instructions.
|
|
||||||
</p>
|
</p>
|
||||||
<div className="">
|
<div className="">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="inline-flex justify-center rounded-md py-1 text-sm text-gray-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
className="inline-flex justify-center rounded-md py-1 text-sm text-gray-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push("/settings/org/" + router.query.id)
|
||||||
"/settings/org/" +
|
|
||||||
router.query.id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
If you are looking to add users to your org,
|
If you are looking to add users to your org,
|
||||||
@@ -85,9 +80,7 @@ const AddProjectMemberDialog = ({
|
|||||||
className="ml-1 inline-flex justify-center rounded-md py-1 text-sm text-gray-500 hover:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
className="ml-1 inline-flex justify-center rounded-md py-1 text-sm text-gray-500 hover:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push(
|
||||||
"/settings/org/" +
|
"/settings/org/" + router.query.id + "?invite"
|
||||||
router.query.id +
|
|
||||||
"?invite"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -97,17 +90,14 @@ const AddProjectMemberDialog = ({
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
Add more users to the
|
Add more users to the organization first.
|
||||||
organization first.
|
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="max-h-28">
|
<div className="max-h-28">
|
||||||
{data?.length > 0 && (
|
{data?.length > 0 && (
|
||||||
<ListBox
|
<ListBox
|
||||||
selected={
|
selected={email ? email : data[0]}
|
||||||
email ? email : data[0]
|
|
||||||
}
|
|
||||||
onChange={setEmail}
|
onChange={setEmail}
|
||||||
data={data}
|
data={data}
|
||||||
width="full"
|
width="full"
|
||||||
@@ -127,10 +117,7 @@ const AddProjectMemberDialog = ({
|
|||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() =>
|
||||||
router.push(
|
router.push("/settings/org/" + router.query.id)
|
||||||
"/settings/org/" +
|
|
||||||
router.query.id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
text="Add Users to Organization"
|
text="Add Users to Organization"
|
||||||
|
|||||||
@@ -8,7 +8,10 @@ import nacl from "tweetnacl";
|
|||||||
import addServiceToken from "~/pages/api/serviceToken/addServiceToken";
|
import addServiceToken from "~/pages/api/serviceToken/addServiceToken";
|
||||||
import getLatestFileKey from "~/pages/api/workspace/getLatestFileKey";
|
import getLatestFileKey from "~/pages/api/workspace/getLatestFileKey";
|
||||||
|
|
||||||
import { decryptAssymmetric, encryptAssymmetric } from "../../utilities/cryptography/crypto";
|
import {
|
||||||
|
decryptAssymmetric,
|
||||||
|
encryptAssymmetric,
|
||||||
|
} from "../../utilities/cryptography/crypto";
|
||||||
import Button from "../buttons/Button";
|
import Button from "../buttons/Button";
|
||||||
import InputField from "../InputField";
|
import InputField from "../InputField";
|
||||||
import ListBox from "../Listbox";
|
import ListBox from "../Listbox";
|
||||||
@@ -131,28 +134,22 @@ const AddServiceTokenDialog = ({
|
|||||||
as="h3"
|
as="h3"
|
||||||
className="text-lg font-medium leading-6 text-gray-400 z-50"
|
className="text-lg font-medium leading-6 text-gray-400 z-50"
|
||||||
>
|
>
|
||||||
Add a service token for{" "}
|
Add a service token for {workspaceName}
|
||||||
{workspaceName}
|
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2 mb-4">
|
<div className="mt-2 mb-4">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
Specify the name,
|
Specify the name, environment, and expiry period. When
|
||||||
environment, and expiry
|
a token is generated, you will only be able to see it
|
||||||
period. When a token is
|
once before it disappears. Make sure to save it
|
||||||
generated, you will only be
|
somewhere.
|
||||||
able to see it once before
|
|
||||||
it disappears. Make sure to
|
|
||||||
save it somewhere.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-h-28 mb-2">
|
<div className="max-h-28 mb-2">
|
||||||
<InputField
|
<InputField
|
||||||
label="Service Token Name"
|
label="Service Token Name"
|
||||||
onChangeHandler={
|
onChangeHandler={setServiceTokenName}
|
||||||
setServiceTokenName
|
|
||||||
}
|
|
||||||
type="varName"
|
type="varName"
|
||||||
value={serviceTokenName}
|
value={serviceTokenName}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
@@ -176,14 +173,8 @@ const AddServiceTokenDialog = ({
|
|||||||
<div className="max-h-28">
|
<div className="max-h-28">
|
||||||
<ListBox
|
<ListBox
|
||||||
selected={serviceTokenExpiresIn}
|
selected={serviceTokenExpiresIn}
|
||||||
onChange={
|
onChange={setServiceTokenExpiresIn}
|
||||||
setServiceTokenExpiresIn
|
data={["1 day", "7 days", "1 month"]}
|
||||||
}
|
|
||||||
data={[
|
|
||||||
"1 day",
|
|
||||||
"7 days",
|
|
||||||
"1 month",
|
|
||||||
]}
|
|
||||||
width="full"
|
width="full"
|
||||||
text="Expires in: "
|
text="Expires in: "
|
||||||
/>
|
/>
|
||||||
@@ -191,18 +182,12 @@ const AddServiceTokenDialog = ({
|
|||||||
<div className="max-w-max">
|
<div className="max-w-max">
|
||||||
<div className="mt-6 flex flex-col justify-start w-max">
|
<div className="mt-6 flex flex-col justify-start w-max">
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() => generateServiceToken()}
|
||||||
generateServiceToken()
|
|
||||||
}
|
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
text="Add Service Token"
|
text="Add Service Token"
|
||||||
textDisabled="Add Service Token"
|
textDisabled="Add Service Token"
|
||||||
size="md"
|
size="md"
|
||||||
active={
|
active={serviceTokenName == "" ? false : true}
|
||||||
serviceTokenName == ""
|
|
||||||
? false
|
|
||||||
: true
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -218,8 +203,7 @@ const AddServiceTokenDialog = ({
|
|||||||
<div className="mt-2 mb-4">
|
<div className="mt-2 mb-4">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
Once you close this popup,
|
Once you close this popup, you will never see your
|
||||||
you will never see your
|
|
||||||
service token again
|
service token again
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -237,9 +221,7 @@ const AddServiceTokenDialog = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="group font-normal h-full relative inline-block text-gray-400 underline hover:text-primary duration-200">
|
<div className="group font-normal h-full relative inline-block text-gray-400 underline hover:text-primary duration-200">
|
||||||
<button
|
<button
|
||||||
onClick={
|
onClick={copyToClipboard}
|
||||||
copyToClipboard
|
|
||||||
}
|
|
||||||
className="h-full pl-3.5 pr-4 border-l border-white/20 py-2 hover:bg-white/[0.12] duration-200"
|
className="h-full pl-3.5 pr-4 border-l border-white/20 py-2 hover:bg-white/[0.12] duration-200"
|
||||||
>
|
>
|
||||||
{serviceTokenCopied ? (
|
{serviceTokenCopied ? (
|
||||||
@@ -248,9 +230,7 @@ const AddServiceTokenDialog = ({
|
|||||||
className="pr-0.5"
|
className="pr-0.5"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon icon={faCopy} />
|
||||||
icon={faCopy}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
<span className="absolute hidden group-hover:flex group-hover:animate-popup duration-300 w-28 -left-8 -top-20 translate-y-full px-3 py-2 bg-chicago-900 rounded-md text-center text-gray-400 text-sm">
|
<span className="absolute hidden group-hover:flex group-hover:animate-popup duration-300 w-28 -left-8 -top-20 translate-y-full px-3 py-2 bg-chicago-900 rounded-md text-center text-gray-400 text-sm">
|
||||||
@@ -261,9 +241,7 @@ const AddServiceTokenDialog = ({
|
|||||||
</div>
|
</div>
|
||||||
<div className="mt-6 flex flex-col justify-start w-max">
|
<div className="mt-6 flex flex-col justify-start w-max">
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() => closeAddServiceTokenModal()}
|
||||||
closeAddServiceTokenModal()
|
|
||||||
}
|
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
text="Close"
|
text="Close"
|
||||||
size="md"
|
size="md"
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ const AddUserDialog = ({
|
|||||||
workspaceId,
|
workspaceId,
|
||||||
setEmail,
|
setEmail,
|
||||||
currentPlan,
|
currentPlan,
|
||||||
orgName
|
orgName,
|
||||||
}) => {
|
}) => {
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
submitModal(email);
|
submitModal(email);
|
||||||
@@ -57,9 +57,9 @@ const AddUserDialog = ({
|
|||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2 mb-4">
|
<div className="mt-2 mb-4">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
An invite is specific to an email address
|
An invite is specific to an email address and expires
|
||||||
and expires after 1 day. For security reasons,
|
after 1 day. For security reasons, you will need to
|
||||||
you will need to separately add members to projects.
|
separately add members to projects.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-h-28">
|
<div className="max-h-28">
|
||||||
@@ -72,15 +72,13 @@ const AddUserDialog = ({
|
|||||||
isRequired
|
isRequired
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{currentPlan == STRIPE_PRODUCT_STARTER && <div className="flex flex-row">
|
{currentPlan == STRIPE_PRODUCT_STARTER && (
|
||||||
|
<div className="flex flex-row">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="inline-flex justify-center rounded-md py-1 text-sm text-gray-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
className="inline-flex justify-center rounded-md py-1 text-sm text-gray-500 focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push("/settings/billing/" + router.query.id)
|
||||||
"/settings/billing/" +
|
|
||||||
router.query.id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
You can add up to 5 members on a Free tier.
|
You can add up to 5 members on a Free tier.
|
||||||
@@ -89,15 +87,13 @@ const AddUserDialog = ({
|
|||||||
type="button"
|
type="button"
|
||||||
className="ml-1 inline-flex justify-center rounded-md py-1 text-sm text-gray-500 hover:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
className="ml-1 inline-flex justify-center rounded-md py-1 text-sm text-gray-500 hover:text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push("/settings/billing/" + router.query.id)
|
||||||
"/settings/billing/" +
|
|
||||||
router.query.id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Upgrade now.
|
Upgrade now.
|
||||||
</button>
|
</button>
|
||||||
</div>}
|
</div>
|
||||||
|
)}
|
||||||
<div className="mt-4 max-w-max">
|
<div className="mt-4 max-w-max">
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={submit}
|
onButtonPressed={submit}
|
||||||
|
|||||||
@@ -61,8 +61,7 @@ const AddWorkspaceDialog = ({
|
|||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
This project will contain your
|
This project will contain your environmental variables.
|
||||||
environmental variables.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="max-h-28 mt-4">
|
<div className="max-h-28 mt-4">
|
||||||
|
|||||||
@@ -1,15 +1,19 @@
|
|||||||
import { Fragment, useState } from 'react'
|
import { Fragment, useState } from "react";
|
||||||
import { Dialog, Transition } from '@headlessui/react'
|
import { Dialog, Transition } from "@headlessui/react";
|
||||||
|
|
||||||
import InputField from '../InputField';
|
import InputField from "../InputField";
|
||||||
|
|
||||||
// #TODO: USE THIS. Currently it's not. Kinda complicated to set up because of state.
|
// #TODO: USE THIS. Currently it's not. Kinda complicated to set up because of state.
|
||||||
|
|
||||||
|
const DeleteUserDialog = ({
|
||||||
const DeleteUserDialog = ({isOpen, closeModal, submitModal, userIdToBeDeleted}) => {
|
isOpen,
|
||||||
|
closeModal,
|
||||||
|
submitModal,
|
||||||
|
userIdToBeDeleted,
|
||||||
|
}) => {
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
submitModal(userIdToBeDeleted);
|
submitModal(userIdToBeDeleted);
|
||||||
}
|
};
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Transition appear show={isOpen} as={Fragment}>
|
<Transition appear show={isOpen} as={Fragment}>
|
||||||
@@ -42,7 +46,8 @@ const DeleteUserDialog = ({isOpen, closeModal, submitModal, userIdToBeDeleted})
|
|||||||
as="h3"
|
as="h3"
|
||||||
className="text-lg font-medium leading-6 text-gray-400"
|
className="text-lg font-medium leading-6 text-gray-400"
|
||||||
>
|
>
|
||||||
Are you sure you want to remove this user from the workspace?
|
Are you sure you want to remove this user from the
|
||||||
|
workspace?
|
||||||
</Dialog.Title>
|
</Dialog.Title>
|
||||||
<div className="mt-2">
|
<div className="mt-2">
|
||||||
<p className="text-sm text-gray-500">
|
<p className="text-sm text-gray-500">
|
||||||
|
|||||||
@@ -20,7 +20,10 @@ import createWorkspace from "~/pages/api/workspace/createWorkspace";
|
|||||||
import getWorkspaces from "~/pages/api/workspace/getWorkspaces";
|
import getWorkspaces from "~/pages/api/workspace/getWorkspaces";
|
||||||
|
|
||||||
import NavBarDashboard from "../navigation/NavBarDashboard";
|
import NavBarDashboard from "../navigation/NavBarDashboard";
|
||||||
import { decryptAssymmetric, encryptAssymmetric } from "../utilities/cryptography/crypto";
|
import {
|
||||||
|
decryptAssymmetric,
|
||||||
|
encryptAssymmetric,
|
||||||
|
} from "../utilities/cryptography/crypto";
|
||||||
import Button from "./buttons/Button";
|
import Button from "./buttons/Button";
|
||||||
import AddWorkspaceDialog from "./dialog/AddWorkspaceDialog";
|
import AddWorkspaceDialog from "./dialog/AddWorkspaceDialog";
|
||||||
import Listbox from "./Listbox";
|
import Listbox from "./Listbox";
|
||||||
@@ -72,8 +75,7 @@ export default function Layout({ children }) {
|
|||||||
newWorkspaceId
|
newWorkspaceId
|
||||||
);
|
);
|
||||||
if (result?.invitee && result?.latestKey) {
|
if (result?.invitee && result?.latestKey) {
|
||||||
const PRIVATE_KEY =
|
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");
|
||||||
localStorage.getItem("PRIVATE_KEY");
|
|
||||||
|
|
||||||
// assymmetrically decrypt symmetric key with local private key
|
// assymmetrically decrypt symmetric key with local private key
|
||||||
const key = decryptAssymmetric({
|
const key = decryptAssymmetric({
|
||||||
@@ -89,12 +91,7 @@ export default function Layout({ children }) {
|
|||||||
privateKey: PRIVATE_KEY,
|
privateKey: PRIVATE_KEY,
|
||||||
});
|
});
|
||||||
|
|
||||||
uploadKeys(
|
uploadKeys(newWorkspaceId, result.invitee._id, ciphertext, nonce);
|
||||||
newWorkspaceId,
|
|
||||||
result.invitee._id,
|
|
||||||
ciphertext,
|
|
||||||
nonce
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -115,9 +112,7 @@ export default function Layout({ children }) {
|
|||||||
const menuItems = [
|
const menuItems = [
|
||||||
{
|
{
|
||||||
href:
|
href:
|
||||||
"/dashboard/" +
|
"/dashboard/" + workspaceMapping[workspaceSelected] + "?Development",
|
||||||
workspaceMapping[workspaceSelected] +
|
|
||||||
"?Development",
|
|
||||||
title: "Secrets",
|
title: "Secrets",
|
||||||
emoji: <FontAwesomeIcon icon={faHouse} />,
|
emoji: <FontAwesomeIcon icon={faHouse} />,
|
||||||
},
|
},
|
||||||
@@ -170,27 +165,17 @@ export default function Layout({ children }) {
|
|||||||
.map((workspace) => workspace._id)
|
.map((workspace) => workspace._id)
|
||||||
.includes(intendedWorkspaceId)
|
.includes(intendedWorkspaceId)
|
||||||
) {
|
) {
|
||||||
router.push(
|
router.push("/dashboard/" + userWorkspaces[0]._id + "?Development");
|
||||||
"/dashboard/" + userWorkspaces[0]._id + "?Development"
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
setWorkspaceList(
|
setWorkspaceList(userWorkspaces.map((workspace) => workspace.name));
|
||||||
userWorkspaces.map((workspace) => workspace.name)
|
|
||||||
);
|
|
||||||
setWorkspaceMapping(
|
setWorkspaceMapping(
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
userWorkspaces.map((workspace) => [
|
userWorkspaces.map((workspace) => [workspace.name, workspace._id])
|
||||||
workspace.name,
|
|
||||||
workspace._id,
|
|
||||||
])
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
setWorkspaceSelected(
|
setWorkspaceSelected(
|
||||||
Object.fromEntries(
|
Object.fromEntries(
|
||||||
userWorkspaces.map((workspace) => [
|
userWorkspaces.map((workspace) => [workspace._id, workspace.name])
|
||||||
workspace._id,
|
|
||||||
workspace.name,
|
|
||||||
])
|
|
||||||
)[
|
)[
|
||||||
router.asPath
|
router.asPath
|
||||||
.split("/")
|
.split("/")
|
||||||
@@ -211,9 +196,7 @@ export default function Layout({ children }) {
|
|||||||
[router.asPath.split("/").length - 1].split("?")[0]
|
[router.asPath.split("/").length - 1].split("?")[0]
|
||||||
) {
|
) {
|
||||||
router.push(
|
router.push(
|
||||||
"/dashboard/" +
|
"/dashboard/" + workspaceMapping[workspaceSelected] + "?Development"
|
||||||
workspaceMapping[workspaceSelected] +
|
|
||||||
"?Development"
|
|
||||||
);
|
);
|
||||||
localStorage.setItem(
|
localStorage.setItem(
|
||||||
"projectData.id",
|
"projectData.id",
|
||||||
@@ -260,37 +243,22 @@ export default function Layout({ children }) {
|
|||||||
{workspaceList.length > 0 &&
|
{workspaceList.length > 0 &&
|
||||||
menuItems.map(({ href, title, emoji }) => (
|
menuItems.map(({ href, title, emoji }) => (
|
||||||
<li className="mt-1.5 mx-2" key={title}>
|
<li className="mt-1.5 mx-2" key={title}>
|
||||||
{router.asPath.split("/")[1] ===
|
{router.asPath.split("/")[1] === href.split("/")[1] &&
|
||||||
href.split("/")[1] &&
|
(["project", "billing", "org", "personal"].includes(
|
||||||
([
|
|
||||||
"project",
|
|
||||||
"billing",
|
|
||||||
"org",
|
|
||||||
"personal",
|
|
||||||
].includes(
|
|
||||||
router.asPath.split("/")[2]
|
router.asPath.split("/")[2]
|
||||||
)
|
)
|
||||||
? router.asPath.split(
|
? router.asPath.split("/")[2] === href.split("/")[2]
|
||||||
"/"
|
|
||||||
)[2] === href.split("/")[2]
|
|
||||||
: true) ? (
|
: true) ? (
|
||||||
<div
|
<div
|
||||||
className={`flex p-2 text-white text-sm rounded cursor-pointer bg-mineshaft-50/10`}
|
className={`flex p-2 text-white text-sm rounded cursor-pointer bg-mineshaft-50/10`}
|
||||||
>
|
>
|
||||||
<div className="bg-primary w-1 rounded-xl mr-1"></div>
|
<div className="bg-primary w-1 rounded-xl mr-1"></div>
|
||||||
<p className="ml-2 mr-4">
|
<p className="ml-2 mr-4">{emoji}</p>
|
||||||
{emoji}
|
|
||||||
</p>
|
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
) : router.asPath ==
|
) : router.asPath == "/noprojects" ? (
|
||||||
"/noprojects" ? (
|
<div className={`flex p-2 text-white text-sm rounded`}>
|
||||||
<div
|
<p className="ml-2 mr-4">{emoji}</p>
|
||||||
className={`flex p-2 text-white text-sm rounded`}
|
|
||||||
>
|
|
||||||
<p className="ml-2 mr-4">
|
|
||||||
{emoji}
|
|
||||||
</p>
|
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -298,9 +266,7 @@ export default function Layout({ children }) {
|
|||||||
<div
|
<div
|
||||||
className={`flex p-2 text-white text-sm rounded cursor-pointer hover:bg-mineshaft-50/5`}
|
className={`flex p-2 text-white text-sm rounded cursor-pointer hover:bg-mineshaft-50/5`}
|
||||||
>
|
>
|
||||||
<p className="ml-2 mr-4">
|
<p className="ml-2 mr-4">{emoji}</p>
|
||||||
{emoji}
|
|
||||||
</p>
|
|
||||||
{title}
|
{title}
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ import Button from "../buttons/Button";
|
|||||||
const roles = ["admin", "user"];
|
const roles = ["admin", "user"];
|
||||||
|
|
||||||
const reverseEnvMapping = {
|
const reverseEnvMapping = {
|
||||||
"dev": "Development",
|
dev: "Development",
|
||||||
"staging": "Staging",
|
staging: "Staging",
|
||||||
"prod": "Production",
|
prod: "Production",
|
||||||
"test": "Testing"
|
test: "Testing",
|
||||||
}
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the component that we utilize for the user table - in future, can reuse it for some other purposes too.
|
* This is the component that we utilize for the user table - in future, can reuse it for some other purposes too.
|
||||||
@@ -20,10 +20,7 @@ const reverseEnvMapping = {
|
|||||||
* @param {*} props
|
* @param {*} props
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
const ServiceTokenTable = ({
|
const ServiceTokenTable = ({ data, workspaceName }) => {
|
||||||
data,
|
|
||||||
workspaceName
|
|
||||||
}) => {
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -40,11 +37,13 @@ const ServiceTokenTable = ({
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{data?.length > 0
|
{data?.length > 0 ? (
|
||||||
? data
|
data.map((row, index) => {
|
||||||
.map((row, index) => {
|
|
||||||
return (
|
return (
|
||||||
<tr key={guidGenerator()} className="bg-bunker-800 hover:bg-bunker-800/5 duration-100">
|
<tr
|
||||||
|
key={guidGenerator()}
|
||||||
|
className="bg-bunker-800 hover:bg-bunker-800/5 duration-100"
|
||||||
|
>
|
||||||
<td className="pl-6 py-2 border-mineshaft-700 border-t text-gray-300">
|
<td className="pl-6 py-2 border-mineshaft-700 border-t text-gray-300">
|
||||||
{row.name}
|
{row.name}
|
||||||
</td>
|
</td>
|
||||||
@@ -70,9 +69,13 @@ const ServiceTokenTable = ({
|
|||||||
</tr>
|
</tr>
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
: <tr>
|
) : (
|
||||||
<td colSpan="4" className="text-center pt-7 pb-4 text-bunker-400">No service tokens yet</td>
|
<tr>
|
||||||
</tr>}
|
<td colSpan="4" className="text-center pt-7 pb-4 text-bunker-400">
|
||||||
|
No service tokens yet
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
)}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -137,12 +137,8 @@ const UserTable = ({
|
|||||||
userData
|
userData
|
||||||
?.filter(
|
?.filter(
|
||||||
(user) =>
|
(user) =>
|
||||||
user.firstName
|
user.firstName?.toLowerCase().includes(filter) ||
|
||||||
?.toLowerCase()
|
user.lastName?.toLowerCase().includes(filter) ||
|
||||||
.includes(filter) ||
|
|
||||||
user.lastName
|
|
||||||
?.toLowerCase()
|
|
||||||
.includes(filter) ||
|
|
||||||
user.email?.toLowerCase().includes(filter)
|
user.email?.toLowerCase().includes(filter)
|
||||||
)
|
)
|
||||||
.map((row, index) => {
|
.map((row, index) => {
|
||||||
@@ -163,51 +159,32 @@ const UserTable = ({
|
|||||||
<td className="flex flex-row justify-end pr-8 py-2 border-t border-0.5 border-mineshaft-700">
|
<td className="flex flex-row justify-end pr-8 py-2 border-t border-0.5 border-mineshaft-700">
|
||||||
<div className="flex justify-end mr-6 w-3/4 mx-2 w-full h-full flex flex-row items-center">
|
<div className="flex justify-end mr-6 w-3/4 mx-2 w-full h-full flex flex-row items-center">
|
||||||
{row.status == "granted" &&
|
{row.status == "granted" &&
|
||||||
((myRole == "admin" &&
|
((myRole == "admin" && row.role != "owner") ||
|
||||||
row.role != "owner") ||
|
|
||||||
myRole == "owner") &&
|
myRole == "owner") &&
|
||||||
myUser !== row.email ? (
|
myUser !== row.email ? (
|
||||||
<Listbox
|
<Listbox
|
||||||
selected={row.role}
|
selected={row.role}
|
||||||
onChange={(e) =>
|
onChange={(e) => handleRoleUpdate(index, e)}
|
||||||
handleRoleUpdate(
|
|
||||||
index,
|
|
||||||
e
|
|
||||||
)
|
|
||||||
}
|
|
||||||
data={
|
data={
|
||||||
myRole == "owner"
|
myRole == "owner"
|
||||||
? [
|
? ["owner", "admin", "member"]
|
||||||
"owner",
|
: ["admin", "member"]
|
||||||
"admin",
|
|
||||||
"member",
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
"admin",
|
|
||||||
"member",
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
text="Role: "
|
text="Role: "
|
||||||
membershipId={
|
membershipId={row.membershipId}
|
||||||
row.membershipId
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
row.status != "invited" &&
|
row.status != "invited" &&
|
||||||
row.status !=
|
row.status != "verified" && (
|
||||||
"verified" && (
|
|
||||||
<Listbox
|
<Listbox
|
||||||
selected={row.role}
|
selected={row.role}
|
||||||
text="Role: "
|
text="Role: "
|
||||||
membershipId={
|
membershipId={row.membershipId}
|
||||||
row.membershipId
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
{(row.status == "invited" ||
|
{(row.status == "invited" ||
|
||||||
row.status ==
|
row.status == "verified") && (
|
||||||
"verified") && (
|
|
||||||
<div className="w-full pl-12">
|
<div className="w-full pl-12">
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() =>
|
||||||
@@ -222,15 +199,11 @@ const UserTable = ({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{row.status == "completed" &&
|
{row.status == "completed" && myUser !== row.email && (
|
||||||
myUser !== row.email && (
|
|
||||||
<div className="border border-mineshaft-700 rounded-md bg-white/5 hover:bg-primary text-white hover:text-black duration-200">
|
<div className="border border-mineshaft-700 rounded-md bg-white/5 hover:bg-primary text-white hover:text-black duration-200">
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() =>
|
||||||
grantAccess(
|
grantAccess(row.userId, row.publicKey)
|
||||||
row.userId,
|
|
||||||
row.publicKey
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
text="Grant Access"
|
text="Grant Access"
|
||||||
@@ -245,11 +218,7 @@ const UserTable = ({
|
|||||||
<div className="opacity-50 hover:opacity-100 flex items-center">
|
<div className="opacity-50 hover:opacity-100 flex items-center">
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={(e) =>
|
onButtonPressed={(e) =>
|
||||||
handleDelete(
|
handleDelete(row.membershipId, index, e)
|
||||||
row.membershipId,
|
|
||||||
index,
|
|
||||||
e
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
color="red"
|
color="red"
|
||||||
size="icon-sm"
|
size="icon-sm"
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ export default function Plan({ plan }) {
|
|||||||
>
|
>
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="flex flex-row justify-between items-center relative z-10">
|
<div className="flex flex-row justify-between items-center relative z-10">
|
||||||
<p
|
<p className={`px-6 py-4 text-3xl font-semibold text-gray-400`}>
|
||||||
className={`px-6 py-4 text-3xl font-semibold text-gray-400`}
|
|
||||||
>
|
|
||||||
{plan.name}
|
{plan.name}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -39,10 +37,7 @@ export default function Plan({ plan }) {
|
|||||||
{plan.current == false ? (
|
{plan.current == false ? (
|
||||||
<>
|
<>
|
||||||
{plan.buttonTextMain == "Schedule a Demo" ? (
|
{plan.buttonTextMain == "Schedule a Demo" ? (
|
||||||
<a
|
<a href="/scheduledemo" target='_blank rel="noopener"'>
|
||||||
href="/scheduledemo"
|
|
||||||
target='_blank rel="noopener"'
|
|
||||||
>
|
|
||||||
<div className="relative z-10 mx-5 mt-3 mb-4 py-2 px-4 border border-1 border-gray-600 hover:text-black hover:border-primary text-gray-400 font-semibold hover:bg-primary bg-bunker duration-200 cursor-pointer rounded-md flex w-max">
|
<div className="relative z-10 mx-5 mt-3 mb-4 py-2 px-4 border border-1 border-gray-600 hover:text-black hover:border-primary text-gray-400 font-semibold hover:bg-primary bg-bunker duration-200 cursor-pointer rounded-md flex w-max">
|
||||||
{plan.buttonTextMain}
|
{plan.buttonTextMain}
|
||||||
</div>
|
</div>
|
||||||
@@ -58,9 +53,7 @@ export default function Plan({ plan }) {
|
|||||||
<button
|
<button
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
StripeRedirect({
|
StripeRedirect({
|
||||||
orgId: localStorage.getItem(
|
orgId: localStorage.getItem("orgData.id"),
|
||||||
"orgData.id"
|
|
||||||
),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
@@ -82,9 +75,7 @@ export default function Plan({ plan }) {
|
|||||||
: "bg-chicago-700"
|
: "bg-chicago-700"
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<p className="text-xs text-black font-semibold">
|
<p className="text-xs text-black font-semibold">CURRENT PLAN</p>
|
||||||
CURRENT PLAN
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -89,30 +89,18 @@ const DashboardInputField = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<span
|
<span className="ph-no-capture text-yellow" key={id}>
|
||||||
className="ph-no-capture text-yellow"
|
|
||||||
key={id}
|
|
||||||
>
|
|
||||||
{texts.slice(0, 2)}
|
{texts.slice(0, 2)}
|
||||||
<span className="ph-no-capture text-yellow-200/80">
|
<span className="ph-no-capture text-yellow-200/80">
|
||||||
{texts.slice(2, texts.length - 1)}
|
{texts.slice(2, texts.length - 1)}
|
||||||
</span>
|
</span>
|
||||||
{texts.slice(
|
{texts.slice(texts.length - 1, texts.length) == "}" ? (
|
||||||
texts.length - 1,
|
|
||||||
texts.length
|
|
||||||
) == "}" ? (
|
|
||||||
<span className="ph-no-capture text-yellow">
|
<span className="ph-no-capture text-yellow">
|
||||||
{texts.slice(
|
{texts.slice(texts.length - 1, texts.length)}{" "}
|
||||||
texts.length - 1,
|
|
||||||
texts.length
|
|
||||||
)}{" "}
|
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="ph-no-capture text-yellow-400">
|
<span className="ph-no-capture text-yellow-400">
|
||||||
{texts.slice(
|
{texts.slice(texts.length - 1, texts.length)}{" "}
|
||||||
texts.length - 1,
|
|
||||||
texts.length
|
|
||||||
)}{" "}
|
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ const DropZone = ({
|
|||||||
addPresetRow,
|
addPresetRow,
|
||||||
setButtonReady,
|
setButtonReady,
|
||||||
keysExist,
|
keysExist,
|
||||||
numCurrentRows
|
numCurrentRows,
|
||||||
}) => {
|
}) => {
|
||||||
const handleDragEnter = (e) => {
|
const handleDragEnter = (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@@ -49,9 +49,8 @@ const DropZone = ({
|
|||||||
var file = e.dataTransfer.files[0],
|
var file = e.dataTransfer.files[0],
|
||||||
reader = new FileReader();
|
reader = new FileReader();
|
||||||
reader.onload = function (event) {
|
reader.onload = function (event) {
|
||||||
const keyPairs = parse(event.target.result)
|
const keyPairs = parse(event.target.result);
|
||||||
const newData = Object.keys(keyPairs)
|
const newData = Object.keys(keyPairs).map((key, index) => [
|
||||||
.map((key, index) => [
|
|
||||||
guidGenerator(),
|
guidGenerator(),
|
||||||
numCurrentRows + index,
|
numCurrentRows + index,
|
||||||
key,
|
key,
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
/* eslint-disable react/jsx-key */
|
/* eslint-disable react/jsx-key */
|
||||||
import React, { Fragment, useEffect,useState } from "react";
|
import React, { Fragment, useEffect, useState } from "react";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { faGithub,faSlack } from "@fortawesome/free-brands-svg-icons";
|
import { faGithub, faSlack } from "@fortawesome/free-brands-svg-icons";
|
||||||
import { faCircleQuestion } from "@fortawesome/free-regular-svg-icons";
|
import { faCircleQuestion } from "@fortawesome/free-regular-svg-icons";
|
||||||
import {
|
import {
|
||||||
faAngleDown,
|
faAngleDown,
|
||||||
@@ -82,19 +82,14 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
alt="logo"
|
alt="logo"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<a className="text-2xl text-white font-semibold mx-2">
|
<a className="text-2xl text-white font-semibold mx-2">Infisical</a>
|
||||||
Infisical
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative flex justify-start items-center mx-2 z-40">
|
<div className="relative flex justify-start items-center mx-2 z-40">
|
||||||
<Menu as="div" className="relative inline-block text-left">
|
<Menu as="div" className="relative inline-block text-left">
|
||||||
<div className="mr-4">
|
<div className="mr-4">
|
||||||
<Menu.Button className="inline-flex w-full justify-center rounded-md px-2 py-2 text-sm font-medium text-gray-200 rounded-md hover:bg-white/10 duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
|
<Menu.Button className="inline-flex w-full justify-center rounded-md px-2 py-2 text-sm font-medium text-gray-200 rounded-md hover:bg-white/10 duration-200 focus:outline-none focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon className="text-xl" icon={faCircleQuestion} />
|
||||||
className="text-xl"
|
|
||||||
icon={faCircleQuestion}
|
|
||||||
/>
|
|
||||||
</Menu.Button>
|
</Menu.Button>
|
||||||
</div>
|
</div>
|
||||||
<Transition
|
<Transition
|
||||||
@@ -118,9 +113,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
>
|
>
|
||||||
<div className="relative flex 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">
|
<div className="relative flex 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">
|
||||||
{option[0]}
|
{option[0]}
|
||||||
<div className="text-sm">
|
<div className="text-sm">{option[1]}</div>
|
||||||
{option[1]}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
@@ -153,10 +146,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push("/settings/personal/" + router.query.id)
|
||||||
"/settings/personal/" +
|
|
||||||
router.query.id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
className="flex flex-row items-center px-1 mx-1 my-1 hover:bg-white/5 cursor-pointer rounded-md"
|
className="flex flex-row items-center px-1 mx-1 my-1 hover:bg-white/5 cursor-pointer rounded-md"
|
||||||
>
|
>
|
||||||
@@ -167,8 +157,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
<div>
|
<div>
|
||||||
<p className="text-gray-300 px-2 pt-1 text-sm">
|
<p className="text-gray-300 px-2 pt-1 text-sm">
|
||||||
{" "}
|
{" "}
|
||||||
{user?.firstName}{" "}
|
{user?.firstName} {user?.lastName}
|
||||||
{user?.lastName}
|
|
||||||
</p>
|
</p>
|
||||||
<p className="text-gray-400 px-2 pb-1 text-xs">
|
<p className="text-gray-400 px-2 pb-1 text-xs">
|
||||||
{" "}
|
{" "}
|
||||||
@@ -188,9 +177,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push("/settings/org/" + router.query.id)
|
||||||
"/settings/org/" + router.query.id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
className="flex flex-row items-center px-2 mt-2 py-1 hover:bg-white/5 cursor-pointer rounded-md"
|
className="flex flex-row items-center px-2 mt-2 py-1 hover:bg-white/5 cursor-pointer rounded-md"
|
||||||
>
|
>
|
||||||
@@ -213,10 +200,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push("/settings/billing/" + router.query.id)
|
||||||
"/settings/billing/" +
|
|
||||||
router.query.id
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
className="mt-1 relative flex justify-start cursor-pointer select-none py-2 px-2 rounded-md text-gray-400 hover:bg-white/5 duration-200 hover:text-gray-200"
|
className="mt-1 relative flex justify-start cursor-pointer select-none py-2 px-2 rounded-md text-gray-400 hover:bg-white/5 duration-200 hover:text-gray-200"
|
||||||
>
|
>
|
||||||
@@ -224,9 +208,7 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
className="text-lg pl-1.5 pr-3"
|
className="text-lg pl-1.5 pr-3"
|
||||||
icon={faCoins}
|
icon={faCoins}
|
||||||
/>
|
/>
|
||||||
<div className="text-sm">
|
<div className="text-sm">Usage & Billing</div>
|
||||||
Usage & Billing
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@@ -236,22 +218,15 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
router.push(
|
router.push(
|
||||||
"/settings/org/" +
|
"/settings/org/" + router.query.id + "?invite"
|
||||||
router.query.id +
|
|
||||||
"?invite"
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
className="relative flex justify-start cursor-pointer select-none py-2 pl-10 pr-4 rounded-md text-gray-400 hover:bg-primary/100 duration-200 hover:text-black hover:font-semibold mt-1"
|
className="relative flex justify-start cursor-pointer select-none py-2 pl-10 pr-4 rounded-md text-gray-400 hover:bg-primary/100 duration-200 hover:text-black hover:font-semibold mt-1"
|
||||||
>
|
>
|
||||||
<span className="rounded-lg absolute inset-y-0 left-0 flex items-center pl-3 pr-4">
|
<span className="rounded-lg absolute inset-y-0 left-0 flex items-center pl-3 pr-4">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon icon={faPlus} className="ml-1" />
|
||||||
icon={faPlus}
|
|
||||||
className="ml-1"
|
|
||||||
/>
|
|
||||||
</span>
|
</span>
|
||||||
<div className="text-sm ml-1">
|
<div className="text-sm ml-1">Invite Members</div>
|
||||||
Invite Members
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -263,20 +238,13 @@ export default function Navbar({ onButtonPressed }) {
|
|||||||
<div className="flex flex-col items-start px-1 mt-3 mb-2">
|
<div className="flex flex-col items-start px-1 mt-3 mb-2">
|
||||||
{orgs
|
{orgs
|
||||||
.filter(
|
.filter(
|
||||||
(org) =>
|
(org) => org._id != localStorage.getItem("orgData.id")
|
||||||
org._id !=
|
|
||||||
localStorage.getItem(
|
|
||||||
"orgData.id"
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
.map((org) => (
|
.map((org) => (
|
||||||
<div
|
<div
|
||||||
key={guidGenerator()}
|
key={guidGenerator()}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
localStorage.setItem(
|
localStorage.setItem("orgData.id", org._id);
|
||||||
"orgData.id",
|
|
||||||
org._id
|
|
||||||
);
|
|
||||||
router.reload();
|
router.reload();
|
||||||
}}
|
}}
|
||||||
className="flex flex-row justify-start items-center hover:bg-white/5 w-full p-1.5 cursor-pointer rounded-md"
|
className="flex flex-row justify-start items-center hover:bg-white/5 w-full p-1.5 cursor-pointer rounded-md"
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import token from "~/pages/api/auth/Token";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import token from "~/pages/api/auth/Token";
|
||||||
|
|
||||||
export default class SecurityClient {
|
export default class SecurityClient {
|
||||||
static authOrigins = [PATH];
|
static authOrigins = [PATH];
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ import getOrganizations from "~/pages/api/organization/getOrgs";
|
|||||||
import getOrganizationUserProjects from "~/pages/api/organization/GetOrgUserProjects";
|
import getOrganizationUserProjects from "~/pages/api/organization/GetOrgUserProjects";
|
||||||
|
|
||||||
import { initPostHog } from "../analytics/posthog";
|
import { initPostHog } from "../analytics/posthog";
|
||||||
import { ENV } from "./config";
|
|
||||||
import pushKeys from "./secrets/pushKeys";
|
import pushKeys from "./secrets/pushKeys";
|
||||||
|
import { ENV } from "./config";
|
||||||
import SecurityClient from "./SecurityClient";
|
import SecurityClient from "./SecurityClient";
|
||||||
|
|
||||||
const nacl = require("tweetnacl");
|
const nacl = require("tweetnacl");
|
||||||
@@ -69,8 +69,7 @@ const attemptLogin = async (
|
|||||||
response = await response.json();
|
response = await response.json();
|
||||||
SecurityClient.setToken(response["token"]);
|
SecurityClient.setToken(response["token"]);
|
||||||
const publicKey = response["publicKey"];
|
const publicKey = response["publicKey"];
|
||||||
const encryptedPrivateKey =
|
const encryptedPrivateKey = response["encryptedPrivateKey"];
|
||||||
response["encryptedPrivateKey"];
|
|
||||||
const iv = response["iv"];
|
const iv = response["iv"];
|
||||||
const tag = response["tag"];
|
const tag = response["tag"];
|
||||||
|
|
||||||
@@ -82,26 +81,21 @@ const attemptLogin = async (
|
|||||||
.slice(0, 32)
|
.slice(0, 32)
|
||||||
.padStart(
|
.padStart(
|
||||||
32 +
|
32 +
|
||||||
(password.slice(0, 32).length -
|
(password.slice(0, 32).length - new Blob([password]).size),
|
||||||
new Blob([password]).size),
|
|
||||||
"0"
|
"0"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
localStorage.setItem("publicKey", publicKey);
|
localStorage.setItem("publicKey", publicKey);
|
||||||
localStorage.setItem(
|
localStorage.setItem("encryptedPrivateKey", encryptedPrivateKey);
|
||||||
"encryptedPrivateKey",
|
|
||||||
encryptedPrivateKey
|
|
||||||
);
|
|
||||||
localStorage.setItem("iv", iv);
|
localStorage.setItem("iv", iv);
|
||||||
localStorage.setItem("tag", tag);
|
localStorage.setItem("tag", tag);
|
||||||
localStorage.setItem("PRIVATE_KEY", PRIVATE_KEY);
|
localStorage.setItem("PRIVATE_KEY", PRIVATE_KEY);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setErrorLogin(true);
|
setErrorLogin(true);
|
||||||
console.error(
|
console.error(
|
||||||
"Unable to send the tokens in local storage:" +
|
"Unable to send the tokens in local storage:" + err.message
|
||||||
err.message
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -112,11 +106,7 @@ const attemptLogin = async (
|
|||||||
const userOrgsData = userOrgs.map((org) => org._id);
|
const userOrgsData = userOrgs.map((org) => org._id);
|
||||||
|
|
||||||
let orgToLogin;
|
let orgToLogin;
|
||||||
if (
|
if (userOrgsData.includes(localStorage.getItem("orgData.id"))) {
|
||||||
userOrgsData.includes(
|
|
||||||
localStorage.getItem("orgData.id")
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
orgToLogin = localStorage.getItem("orgData.id");
|
orgToLogin = localStorage.getItem("orgData.id");
|
||||||
} else {
|
} else {
|
||||||
orgToLogin = userOrgsData[0];
|
orgToLogin = userOrgsData[0];
|
||||||
@@ -127,28 +117,18 @@ const attemptLogin = async (
|
|||||||
orgId: orgToLogin,
|
orgId: orgToLogin,
|
||||||
});
|
});
|
||||||
|
|
||||||
orgUserProjects = orgUserProjects?.map(
|
orgUserProjects = orgUserProjects?.map((project) => project._id);
|
||||||
(project) => project._id
|
|
||||||
);
|
|
||||||
let projectToLogin;
|
let projectToLogin;
|
||||||
if (
|
if (
|
||||||
orgUserProjects.includes(
|
orgUserProjects.includes(localStorage.getItem("projectData.id"))
|
||||||
localStorage.getItem("projectData.id")
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
projectToLogin = localStorage.getItem("projectData.id");
|
projectToLogin = localStorage.getItem("projectData.id");
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
projectToLogin = orgUserProjects[0];
|
projectToLogin = orgUserProjects[0];
|
||||||
localStorage.setItem(
|
localStorage.setItem("projectData.id", projectToLogin);
|
||||||
"projectData.id",
|
|
||||||
projectToLogin
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(
|
console.log("ERROR: User likely has no projects. ", error);
|
||||||
"ERROR: User likely has no projects. ",
|
|
||||||
error
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,14 +144,8 @@ const attemptLogin = async (
|
|||||||
"hgSIwDAKvz8PJfkj6xkzYqzGmAP3HLuG",
|
"hgSIwDAKvz8PJfkj6xkzYqzGmAP3HLuG",
|
||||||
"shared",
|
"shared",
|
||||||
],
|
],
|
||||||
WEBSITE_URL: [
|
WEBSITE_URL: ["http://localhost:3000", "shared"],
|
||||||
"http://localhost:3000",
|
STRIPE_SECRET_KEY: ["sk_test_7348oyho4hfq398HIUOH78", "shared"],
|
||||||
"shared",
|
|
||||||
],
|
|
||||||
STRIPE_SECRET_KEY: [
|
|
||||||
"sk_test_7348oyho4hfq398HIUOH78",
|
|
||||||
"shared",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
projectToLogin,
|
projectToLogin,
|
||||||
"Development"
|
"Development"
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
const ENV = process.env.NEXT_PUBLIC_ENV! || 'development'; // investigate
|
const ENV = process.env.NEXT_PUBLIC_ENV! || "development"; // investigate
|
||||||
const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY!;
|
const POSTHOG_API_KEY = process.env.NEXT_PUBLIC_POSTHOG_API_KEY!;
|
||||||
const POSTHOG_HOST = process.env.NEXT_PUBLIC_POSTHOG_HOST! || 'https://app.posthog.com';
|
const POSTHOG_HOST =
|
||||||
|
process.env.NEXT_PUBLIC_POSTHOG_HOST! || "https://app.posthog.com";
|
||||||
const STRIPE_PRODUCT_PRO = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_PRO!;
|
const STRIPE_PRODUCT_PRO = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_PRO!;
|
||||||
const STRIPE_PRODUCT_STARTER = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_STARTER!;
|
const STRIPE_PRODUCT_STARTER = process.env.NEXT_PUBLIC_STRIPE_PRODUCT_STARTER!;
|
||||||
const TELEMETRY_ENABLED = (process.env.NEXT_PUBLIC_TELEMETRY_ENABLED! !== 'false');
|
const TELEMETRY_ENABLED =
|
||||||
|
process.env.NEXT_PUBLIC_TELEMETRY_ENABLED! !== "false";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
ENV,
|
ENV,
|
||||||
@@ -11,5 +13,5 @@ export {
|
|||||||
POSTHOG_HOST,
|
POSTHOG_HOST,
|
||||||
STRIPE_PRODUCT_PRO,
|
STRIPE_PRODUCT_PRO,
|
||||||
STRIPE_PRODUCT_STARTER,
|
STRIPE_PRODUCT_STARTER,
|
||||||
TELEMETRY_ENABLED
|
TELEMETRY_ENABLED,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -61,8 +61,7 @@ const changePassword = async (
|
|||||||
password: newPassword,
|
password: newPassword,
|
||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
clientNewPassword.createVerifier(
|
clientNewPassword.createVerifier(async (err, result) => {
|
||||||
async (err, result) => {
|
|
||||||
// The Blob part here is needed to account for symbols that count as 2+ bytes (e.g., é, å, ø)
|
// The Blob part here is needed to account for symbols that count as 2+ bytes (e.g., é, å, ø)
|
||||||
let { ciphertext, iv, tag } = Aes256Gcm.encrypt(
|
let { ciphertext, iv, tag } = Aes256Gcm.encrypt(
|
||||||
localStorage.getItem("PRIVATE_KEY"),
|
localStorage.getItem("PRIVATE_KEY"),
|
||||||
@@ -70,19 +69,14 @@ const changePassword = async (
|
|||||||
.slice(0, 32)
|
.slice(0, 32)
|
||||||
.padStart(
|
.padStart(
|
||||||
32 +
|
32 +
|
||||||
(newPassword.slice(0, 32)
|
(newPassword.slice(0, 32).length -
|
||||||
.length -
|
new Blob([newPassword]).size),
|
||||||
new Blob([newPassword])
|
|
||||||
.size),
|
|
||||||
"0"
|
"0"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ciphertext) {
|
if (ciphertext) {
|
||||||
localStorage.setItem(
|
localStorage.setItem("encryptedPrivateKey", ciphertext);
|
||||||
"encryptedPrivateKey",
|
|
||||||
ciphertext
|
|
||||||
);
|
|
||||||
localStorage.setItem("iv", iv);
|
localStorage.setItem("iv", iv);
|
||||||
localStorage.setItem("tag", tag);
|
localStorage.setItem("tag", tag);
|
||||||
|
|
||||||
@@ -108,8 +102,7 @@ const changePassword = async (
|
|||||||
console.log(err);
|
console.log(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import issueBackupPrivateKey from "~/pages/api/auth/IssueBackupPrivateKey";
|
import issueBackupPrivateKey from "~/pages/api/auth/IssueBackupPrivateKey";
|
||||||
import SRP1 from "~/pages/api/auth/SRP1";
|
import SRP1 from "~/pages/api/auth/SRP1";
|
||||||
|
|
||||||
import Aes256Gcm from "./aes-256-gcm";
|
|
||||||
import generateBackupPDF from "../generateBackupPDF";
|
import generateBackupPDF from "../generateBackupPDF";
|
||||||
|
import Aes256Gcm from "./aes-256-gcm";
|
||||||
|
|
||||||
const nacl = require("tweetnacl");
|
const nacl = require("tweetnacl");
|
||||||
nacl.util = require("tweetnacl-util");
|
nacl.util = require("tweetnacl-util");
|
||||||
@@ -80,11 +80,7 @@ const issueBackupKey = async ({
|
|||||||
if (res.status == 400) {
|
if (res.status == 400) {
|
||||||
setBackupKeyError(true);
|
setBackupKeyError(true);
|
||||||
} else if (res.status == 200) {
|
} else if (res.status == 200) {
|
||||||
generateBackupPDF(
|
generateBackupPDF(personalName, email, generatedKey);
|
||||||
personalName,
|
|
||||||
email,
|
|
||||||
generatedKey
|
|
||||||
);
|
|
||||||
setBackupKeyIssued(true);
|
setBackupKeyIssued(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,11 +9,11 @@ function generateBackupPDF(personalName, personalEmail, generatedKey) {
|
|||||||
|
|
||||||
// new jsPDF('p', 'mm', [297, 210]);
|
// new jsPDF('p', 'mm', [297, 210]);
|
||||||
var today = new Date();
|
var today = new Date();
|
||||||
var dd = String(today.getDate()).padStart(2, '0');
|
var dd = String(today.getDate()).padStart(2, "0");
|
||||||
var mm = String(today.getMonth() + 1).padStart(2, '0'); //January is 0!
|
var mm = String(today.getMonth() + 1).padStart(2, "0"); //January is 0!
|
||||||
var yyyy = today.getFullYear();
|
var yyyy = today.getFullYear();
|
||||||
|
|
||||||
today = mm + '/' + dd + '/' + yyyy;
|
today = mm + "/" + dd + "/" + yyyy;
|
||||||
|
|
||||||
var doc = new jsPDF("p", "pt");
|
var doc = new jsPDF("p", "pt");
|
||||||
doc.setFillColor(13, 17, 23);
|
doc.setFillColor(13, 17, 23);
|
||||||
@@ -34,28 +34,16 @@ function generateBackupPDF(personalName, personalEmail, generatedKey) {
|
|||||||
180,
|
180,
|
||||||
"In case you get locked out of you Infisical account, you`ll need these account details"
|
"In case you get locked out of you Infisical account, you`ll need these account details"
|
||||||
);
|
);
|
||||||
doc.text(
|
doc.text(32, 200, "to sign in —");
|
||||||
32,
|
|
||||||
200,
|
|
||||||
"to sign in —"
|
|
||||||
);
|
|
||||||
doc.setFont(undefined, "bold");
|
doc.setFont(undefined, "bold");
|
||||||
doc.text(
|
doc.text(
|
||||||
110,
|
110,
|
||||||
200,
|
200,
|
||||||
"including your Secret Key, which we absolutely cannot access or"
|
"including your Secret Key, which we absolutely cannot access or"
|
||||||
);
|
);
|
||||||
doc.text(
|
doc.text(32, 220, "recover for you. ");
|
||||||
32,
|
|
||||||
220,
|
|
||||||
"recover for you. "
|
|
||||||
);
|
|
||||||
doc.setFont(undefined, "normal");
|
doc.setFont(undefined, "normal");
|
||||||
doc.text(
|
doc.text(32, 250, "Recommendations:");
|
||||||
32,
|
|
||||||
250,
|
|
||||||
"Recommendations:"
|
|
||||||
);
|
|
||||||
doc.text(
|
doc.text(
|
||||||
32,
|
32,
|
||||||
280,
|
280,
|
||||||
@@ -66,70 +54,33 @@ function generateBackupPDF(personalName, personalEmail, generatedKey) {
|
|||||||
310,
|
310,
|
||||||
"2. Store it somewhere safe (such as with your birth certificate, your will, or on your"
|
"2. Store it somewhere safe (such as with your birth certificate, your will, or on your"
|
||||||
);
|
);
|
||||||
doc.text(
|
doc.text(32, 330, "personal cloud storage).");
|
||||||
32,
|
|
||||||
330,
|
|
||||||
"personal cloud storage)."
|
|
||||||
);
|
|
||||||
doc.setFillColor(206, 217, 111);
|
doc.setFillColor(206, 217, 111);
|
||||||
doc.roundedRect(32, 350, 530, 190, 5, 5, 'F');
|
doc.roundedRect(32, 350, 530, 190, 5, 5, "F");
|
||||||
doc.setDrawColor(228, 255, 0)
|
doc.setDrawColor(228, 255, 0);
|
||||||
doc.setLineWidth(1)
|
doc.setLineWidth(1);
|
||||||
doc.roundedRect(32, 350, 530, 190, 5, 5, 'S');
|
doc.roundedRect(32, 350, 530, 190, 5, 5, "S");
|
||||||
doc.setTextColor(43, 43, 43);
|
doc.setTextColor(43, 43, 43);
|
||||||
doc.setFont(undefined, "bold");
|
doc.setFont(undefined, "bold");
|
||||||
doc.setFontSize(15);
|
doc.setFontSize(15);
|
||||||
doc.text(
|
doc.text(290, 375, "Infisical Account Details", "center");
|
||||||
290,
|
|
||||||
375,
|
|
||||||
"Infisical Account Details",
|
|
||||||
"center"
|
|
||||||
);
|
|
||||||
doc.setFont(undefined, "normal");
|
doc.setFont(undefined, "normal");
|
||||||
doc.setFontSize(12);
|
doc.setFontSize(12);
|
||||||
doc.text(
|
doc.text(50, 420, "SIGN-IN URL");
|
||||||
50,
|
doc.text(50, 465, "EMAIL ADDRESS");
|
||||||
420,
|
doc.text(50, 510, "SECRET KEY");
|
||||||
"SIGN-IN URL"
|
|
||||||
);
|
|
||||||
doc.text(
|
|
||||||
50,
|
|
||||||
465,
|
|
||||||
"EMAIL ADDRESS"
|
|
||||||
);
|
|
||||||
doc.text(
|
|
||||||
50,
|
|
||||||
510,
|
|
||||||
"SECRET KEY"
|
|
||||||
);
|
|
||||||
doc.setFillColor(23, 27, 33);
|
doc.setFillColor(23, 27, 33);
|
||||||
doc.roundedRect(170, 398, 375, 35, 5, 5, 'F');
|
doc.roundedRect(170, 398, 375, 35, 5, 5, "F");
|
||||||
doc.roundedRect(170, 443, 375, 35, 5, 5, 'F');
|
doc.roundedRect(170, 443, 375, 35, 5, 5, "F");
|
||||||
doc.roundedRect(170, 488, 375, 35, 5, 5, 'F');
|
doc.roundedRect(170, 488, 375, 35, 5, 5, "F");
|
||||||
doc.setTextColor(227, 227, 227);
|
doc.setTextColor(227, 227, 227);
|
||||||
doc.setFontSize(14);
|
doc.setFontSize(14);
|
||||||
doc.text(
|
doc.text(180, 420, "https://app.infisical.com/login");
|
||||||
180,
|
doc.text(180, 465, personalEmail);
|
||||||
420,
|
doc.text(180, 510, generatedKey);
|
||||||
"https://app.infisical.com/login"
|
doc.text(32, 575, "Need help? Contact us at support@infisical.com");
|
||||||
);
|
|
||||||
doc.text(
|
|
||||||
180,
|
|
||||||
465,
|
|
||||||
personalEmail
|
|
||||||
);
|
|
||||||
doc.text(
|
|
||||||
180,
|
|
||||||
510,
|
|
||||||
generatedKey
|
|
||||||
);
|
|
||||||
doc.text(
|
|
||||||
32,
|
|
||||||
575,
|
|
||||||
"Need help? Contact us at [email protected]"
|
|
||||||
);
|
|
||||||
|
|
||||||
doc.save("Infisical Emergency Kit.pdf");
|
doc.save("Infisical Emergency Kit.pdf");
|
||||||
};
|
}
|
||||||
|
|
||||||
export default generateBackupPDF;
|
export default generateBackupPDF;
|
||||||
|
|||||||
@@ -95,9 +95,7 @@ const getSecretsForProject = async ({
|
|||||||
line["type"],
|
line["type"],
|
||||||
]);
|
]);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(
|
console.log("Something went wrong during accessing or decripting secrets.");
|
||||||
"Something went wrong during accessing or decripting secrets."
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -69,10 +69,7 @@ const pushKeys = async (obj, workspaceId, env) => {
|
|||||||
ciphertextValue,
|
ciphertextValue,
|
||||||
ivValue,
|
ivValue,
|
||||||
tagValue,
|
tagValue,
|
||||||
hashValue: crypto
|
hashValue: crypto.createHash("sha256").update(obj[key][0]).digest("hex"),
|
||||||
.createHash("sha256")
|
|
||||||
.update(obj[key][0])
|
|
||||||
.digest("hex"),
|
|
||||||
type: visibility,
|
type: visibility,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,7 +2,10 @@ import publicKeyInfical from "~/pages/api/auth/publicKeyInfisical";
|
|||||||
import changeHerokuConfigVars from "~/pages/api/integrations/ChangeHerokuConfigVars";
|
import changeHerokuConfigVars from "~/pages/api/integrations/ChangeHerokuConfigVars";
|
||||||
|
|
||||||
const crypto = require("crypto");
|
const crypto = require("crypto");
|
||||||
const { encryptSymmetric, encryptAssymmetric } = require("../cryptography/crypto");
|
const {
|
||||||
|
encryptSymmetric,
|
||||||
|
encryptAssymmetric,
|
||||||
|
} = require("../cryptography/crypto");
|
||||||
const nacl = require("tweetnacl");
|
const nacl = require("tweetnacl");
|
||||||
nacl.util = require("tweetnacl-util");
|
nacl.util = require("tweetnacl-util");
|
||||||
|
|
||||||
@@ -42,10 +45,7 @@ const pushKeysIntegration = async ({ obj, integrationId }) => {
|
|||||||
ciphertextValue,
|
ciphertextValue,
|
||||||
ivValue,
|
ivValue,
|
||||||
tagValue,
|
tagValue,
|
||||||
hashValue: crypto
|
hashValue: crypto.createHash("sha256").update(obj[key]).digest("hex"),
|
||||||
.createHash("sha256")
|
|
||||||
.update(obj[key])
|
|
||||||
.digest("hex"),
|
|
||||||
type: visibility,
|
type: visibility,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
const ContentSecurityPolicy = `
|
const ContentSecurityPolicy = `
|
||||||
default-src ${process.env.NEXT_PUBLIC_WEBSITE_URL};
|
default-src ${process.env.NEXT_PUBLIC_WEBSITE_URL};
|
||||||
script-src ${process.env.NEXT_PUBLIC_WEBSITE_URL} https://app.posthog.com https://infisical.com https://assets.calendly.com/ https://js.stripe.com https://api.stripe.com 'unsafe-inline' 'unsafe-eval';
|
script-src ${
|
||||||
|
process.env.NEXT_PUBLIC_WEBSITE_URL
|
||||||
|
} https://app.posthog.com https://infisical.com https://assets.calendly.com/ https://js.stripe.com https://api.stripe.com 'unsafe-inline' 'unsafe-eval';
|
||||||
style-src 'self' https://rsms.me 'unsafe-inline';
|
style-src 'self' https://rsms.me 'unsafe-inline';
|
||||||
child-src https://infisical.com https://api.stripe.com;
|
child-src https://infisical.com https://api.stripe.com;
|
||||||
frame-src https://js.stripe.com/ https://api.stripe.com;
|
frame-src https://js.stripe.com/ https://api.stripe.com;
|
||||||
connect-src ws://${process.env.NEXT_PUBLIC_WEBSITE_URL?.split('//')[1]} ${process.env.NEXT_PUBLIC_WEBSITE_URL} https://api.github.com/repos/Infisical/infisical-cli https://api.heroku.com/ https://id.heroku.com/oauth/authorize https://id.heroku.com/oauth/token https://checkout.stripe.com https://app.posthog.com https://infisical.com https://api.stripe.com https://vitals.vercel-insights.com/v1/vitals;
|
connect-src ws://${process.env.NEXT_PUBLIC_WEBSITE_URL?.split("//")[1]} ${
|
||||||
|
process.env.NEXT_PUBLIC_WEBSITE_URL
|
||||||
|
} https://api.github.com/repos/Infisical/infisical-cli https://api.heroku.com/ https://id.heroku.com/oauth/authorize https://id.heroku.com/oauth/token https://checkout.stripe.com https://app.posthog.com https://infisical.com https://api.stripe.com https://vitals.vercel-insights.com/v1/vitals;
|
||||||
img-src 'self' https://*.stripe.com https://i.ytimg.com/ data:;
|
img-src 'self' https://*.stripe.com https://i.ytimg.com/ data:;
|
||||||
media-src;
|
media-src;
|
||||||
font-src 'self' https://maxcdn.bootstrapcdn.com https://rsms.me https://fonts.gstatic.com;
|
font-src 'self' https://maxcdn.bootstrapcdn.com https://rsms.me https://fonts.gstatic.com;
|
||||||
@@ -50,7 +54,7 @@ const securityHeaders = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
output: 'standalone',
|
output: "standalone",
|
||||||
async headers() {
|
async headers() {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -5,9 +5,8 @@ import { config } from "@fortawesome/fontawesome-svg-core";
|
|||||||
import { initPostHog } from "~/components/analytics/posthog";
|
import { initPostHog } from "~/components/analytics/posthog";
|
||||||
import Layout from "~/components/basic/layout";
|
import Layout from "~/components/basic/layout";
|
||||||
import RouteGuard from "~/components/RouteGuard";
|
import RouteGuard from "~/components/RouteGuard";
|
||||||
import { ENV } from "~/utilities/config";
|
|
||||||
|
|
||||||
import { publicPaths } from "~/const";
|
import { publicPaths } from "~/const";
|
||||||
|
import { ENV } from "~/utilities/config";
|
||||||
|
|
||||||
import "@fortawesome/fontawesome-svg-core/styles.css";
|
import "@fortawesome/fontawesome-svg-core/styles.css";
|
||||||
import "../styles/globals.css";
|
import "../styles/globals.css";
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the second step of the change password process (pake)
|
* This is the second step of the change password process (pake)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient.js";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is used to check if the user is authenticated.
|
* This function is used to check if the user is authenticated.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the route that issues a backup private key that will afterwards be added into a pdf
|
* This is the route that issues a backup private key that will afterwards be added into a pdf
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route logs the user out. Note: the user should authorized to do this.
|
* This route logs the user out. Note: the user should authorized to do this.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the first step of the change password process (pake)
|
* This is the first step of the change password process (pake)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient.js";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function fetches the encrypted secrets from the .env file
|
* This function fetches the encrypted secrets from the .env file
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function uploads the encrypted .env file
|
* This function uploads the encrypted .env file
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
const changeHerokuConfigVars = ({ integrationId, key, secrets }) => {
|
const changeHerokuConfigVars = ({ integrationId, key, secrets }) => {
|
||||||
return SecurityClient.fetchCall(
|
return SecurityClient.fetchCall(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route deletes an integration from a certain project
|
* This route deletes an integration from a certain project
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route deletes an integration authorization from a certain project
|
* This route deletes an integration authorization from a certain project
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
const getIntegrationApps = ({ integrationAuthId }) => {
|
const getIntegrationApps = ({ integrationAuthId }) => {
|
||||||
return SecurityClient.fetchCall(
|
return SecurityClient.fetchCall(
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
const getIntegrations = () => {
|
const getIntegrations = () => {
|
||||||
return SecurityClient.fetchCall(PATH + "/api/v1/integration/integrations", {
|
return SecurityClient.fetchCall(PATH + "/api/v1/integration/integrations", {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route starts the integration after teh default one if gonna set up.
|
* This route starts the integration after teh default one if gonna set up.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the first step of the change password process (pake)
|
* This is the first step of the change password process (pake)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route gets authorizations of a certain project (Heroku, etc.)
|
* This route gets authorizations of a certain project (Heroku, etc.)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route gets integrations of a certain project (Heroku, etc.)
|
* This route gets integrations of a certain project (Heroku, etc.)
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get info about a certain org
|
* This route lets us get info about a certain org
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get all the users in an org.
|
* This route lets us get all the users in an org.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get the current subscription of an org.
|
* This route lets us get the current subscription of an org.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get all the projects of a certain user in an org.
|
* This route lets us get all the projects of a certain user in an org.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get all the users in an org.
|
* This route lets us get all the users in an org.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route redirects the user to the right stripe billing page.
|
* This route redirects the user to the right stripe billing page.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route add an incident contact email to a certain organization
|
* This route add an incident contact email to a certain organization
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function sends an email invite to a user to join an org
|
* This function sends an email invite to a user to join an org
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route deletes an incident Contact from a certain organization
|
* This route deletes an incident Contact from a certain organization
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function removes a certain member from a certain organization
|
* This function removes a certain member from a certain organization
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This routes gets all the incident contacts of a certain organization
|
* This routes gets all the incident contacts of a certain organization
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get the all the orgs of a certain user.
|
* This route lets us get the all the orgs of a certain user.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us rename a certain org.
|
* This route lets us rename a certain org.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route gets service tokens for a specific user in a project
|
* This route gets service tokens for a specific user in a project
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route gets service tokens for a specific user in a project
|
* This route gets service tokens for a specific user in a project
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route gets the information about a specific user.
|
* This route gets the information about a specific user.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route registers a certain action for a user
|
* This route registers a certain action for a user
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route registers a certain action for a user
|
* This route registers a certain action for a user
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function adds a user to a project
|
* This function adds a user to a project
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function change the access of a user in a certain workspace
|
* This function change the access of a user in a certain workspace
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route creates a new workspace for a user.
|
* This route creates a new workspace for a user.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function removes a certain member from a certain workspace
|
* This function removes a certain member from a certain workspace
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route deletes a specified workspace.
|
* This route deletes a specified workspace.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the latest key pairs from a certain workspace
|
* Get the latest key pairs from a certain workspace
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get the information of a certain project.
|
* This route lets us get the information of a certain project.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get the public keys of everyone in your workspace.
|
* This route lets us get the public keys of everyone in your workspace.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get all the users in the workspace.
|
* This route lets us get all the users in the workspace.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us get the public keys of everyone in your workspace.
|
* This route lets us get the public keys of everyone in your workspace.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route lets us rename a certain workspace.
|
* This route lets us rename a certain workspace.
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import SecurityClient from "~/utilities/SecurityClient";
|
|
||||||
|
|
||||||
import { PATH } from "~/const";
|
import { PATH } from "~/const";
|
||||||
|
import SecurityClient from "~/utilities/SecurityClient";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This route uplods the keys in an encrypted format.
|
* This route uplods the keys in an encrypted format.
|
||||||
|
|||||||
@@ -15,9 +15,7 @@ export default function DashboardRedirect() {
|
|||||||
let userWorkspace;
|
let userWorkspace;
|
||||||
try {
|
try {
|
||||||
if (localStorage.getItem("projectData.id")) {
|
if (localStorage.getItem("projectData.id")) {
|
||||||
router.push(
|
router.push("/dashboard/" + localStorage.getItem("projectData.id"));
|
||||||
"/dashboard/" + localStorage.getItem("projectData.id")
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const userWorkspaces = await getWorkspaces();
|
const userWorkspaces = await getWorkspaces();
|
||||||
userWorkspace = userWorkspaces[0]._id;
|
userWorkspace = userWorkspaces[0]._id;
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import {
|
|||||||
faPeopleGroup,
|
faPeopleGroup,
|
||||||
faPerson,
|
faPerson,
|
||||||
faPlus,
|
faPlus,
|
||||||
|
faShuffle,
|
||||||
faX,
|
faX,
|
||||||
faShuffle
|
|
||||||
} from "@fortawesome/free-solid-svg-icons";
|
} from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
import { Menu, Transition } from "@headlessui/react";
|
import { Menu, Transition } from "@headlessui/react";
|
||||||
@@ -116,9 +116,7 @@ const KeyPair = ({
|
|||||||
<div
|
<div
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
modifyVisibility(
|
modifyVisibility(
|
||||||
keyPair[4] == "personal"
|
keyPair[4] == "personal" ? "shared" : "personal",
|
||||||
? "shared"
|
|
||||||
: "personal",
|
|
||||||
keyPair[1]
|
keyPair[1]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -126,16 +124,10 @@ const KeyPair = ({
|
|||||||
>
|
>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
className="text-lg pl-1.5 pr-3"
|
className="text-lg pl-1.5 pr-3"
|
||||||
icon={
|
icon={keyPair[4] == "personal" ? faPeopleGroup : faPerson}
|
||||||
keyPair[4] == "personal"
|
|
||||||
? faPeopleGroup
|
|
||||||
: faPerson
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
{keyPair[4] == "personal"
|
{keyPair[4] == "personal" ? "Make Shared" : "Make Personal"}
|
||||||
? "Make Shared"
|
|
||||||
: "Make Personal"}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -145,18 +137,19 @@ const KeyPair = ({
|
|||||||
} else if (randomStringLength < 2) {
|
} else if (randomStringLength < 2) {
|
||||||
setRandomStringLength(2);
|
setRandomStringLength(2);
|
||||||
} else {
|
} 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"
|
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
|
<FontAwesomeIcon
|
||||||
className="text-lg pl-1.5 pr-3"
|
className="text-lg pl-1.5 pr-3"
|
||||||
icon={
|
icon={keyPair[3] == "" ? faPlus : faShuffle}
|
||||||
keyPair[3] == ""
|
|
||||||
? faPlus
|
|
||||||
: faShuffle
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
<div className="text-sm justify-between flex flex-row w-full">
|
<div className="text-sm justify-between flex flex-row w-full">
|
||||||
<p>Generate Random Hex</p>
|
<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"
|
className="m-0.5 px-1 cursor-pointer rounded-md hover:bg-chicago-700"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (randomStringLength > 1) {
|
if (randomStringLength > 1) {
|
||||||
setRandomStringLength(randomStringLength - 1)
|
setRandomStringLength(randomStringLength - 1);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
-
|
-
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
onChange={(e) => setRandomStringLength(parseInt(e.target.value))}
|
onChange={(e) =>
|
||||||
|
setRandomStringLength(parseInt(e.target.value))
|
||||||
|
}
|
||||||
value={randomStringLength}
|
value={randomStringLength}
|
||||||
className="text-center z-20 peer text-sm bg-transparent w-full outline-none"
|
className="text-center z-20 peer text-sm bg-transparent w-full outline-none"
|
||||||
spellCheck="false"
|
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"
|
className="m-0.5 px-1 pb-0.5 cursor-pointer rounded-md hover:bg-chicago-700"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (randomStringLength < 32) {
|
if (randomStringLength < 32) {
|
||||||
setRandomStringLength(randomStringLength + 1)
|
setRandomStringLength(randomStringLength + 1);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
@@ -280,13 +275,9 @@ export default function Dashboard() {
|
|||||||
(async () => {
|
(async () => {
|
||||||
try {
|
try {
|
||||||
let userWorkspaces = await getWorkspaces();
|
let userWorkspaces = await getWorkspaces();
|
||||||
const listWorkspaces = userWorkspaces.map(
|
const listWorkspaces = userWorkspaces.map((workspace) => workspace._id);
|
||||||
(workspace) => workspace._id
|
|
||||||
);
|
|
||||||
if (
|
if (
|
||||||
!listWorkspaces.includes(
|
!listWorkspaces.includes(router.asPath.split("/")[2].split("?")[0])
|
||||||
router.asPath.split("/")[2].split("?")[0]
|
|
||||||
)
|
|
||||||
) {
|
) {
|
||||||
router.push("/dashboard/" + listWorkspaces[0]);
|
router.push("/dashboard/" + listWorkspaces[0]);
|
||||||
}
|
}
|
||||||
@@ -307,9 +298,7 @@ export default function Dashboard() {
|
|||||||
|
|
||||||
const user = await getUser();
|
const user = await getUser();
|
||||||
setIsNew(
|
setIsNew(
|
||||||
(Date.parse(new Date()) - Date.parse(user.createdAt)) /
|
(Date.parse(new Date()) - Date.parse(user.createdAt)) / 60000 < 3
|
||||||
60000 <
|
|
||||||
3
|
|
||||||
? true
|
? true
|
||||||
: false
|
: false
|
||||||
);
|
);
|
||||||
@@ -428,9 +417,7 @@ export default function Dashboard() {
|
|||||||
|
|
||||||
// This function downloads the secrets as a .env file
|
// This function downloads the secrets as a .env file
|
||||||
const download = () => {
|
const download = () => {
|
||||||
const file = data
|
const file = data.map((item) => [item[2], item[3]].join("=")).join("\n");
|
||||||
.map((item) => [item[2], item[3]].join("="))
|
|
||||||
.join("\n");
|
|
||||||
const blob = new Blob([file]);
|
const blob = new Blob([file]);
|
||||||
const fileDownloadUrl = URL.createObjectURL(blob);
|
const fileDownloadUrl = URL.createObjectURL(blob);
|
||||||
let alink = document.createElement("a");
|
let alink = document.createElement("a");
|
||||||
@@ -464,10 +451,7 @@ export default function Dashboard() {
|
|||||||
<title>Secrets</title>
|
<title>Secrets</title>
|
||||||
<link rel="icon" href="/infisical.ico" />
|
<link rel="icon" href="/infisical.ico" />
|
||||||
<meta property="og:image" content="/images/message.png" />
|
<meta property="og:image" content="/images/message.png" />
|
||||||
<meta
|
<meta property="og:title" content="Manage your .env files in seconds" />
|
||||||
property="og:title"
|
|
||||||
content="Manage your .env files in seconds"
|
|
||||||
/>
|
|
||||||
<meta
|
<meta
|
||||||
name="og:description"
|
name="og:description"
|
||||||
content="Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
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 && (
|
{data?.length == 0 && (
|
||||||
<ListBox
|
<ListBox
|
||||||
selected={env}
|
selected={env}
|
||||||
data={[
|
data={["Development", "Staging", "Production", "Testing"]}
|
||||||
"Development",
|
|
||||||
"Staging",
|
|
||||||
"Production",
|
|
||||||
"Testing",
|
|
||||||
]}
|
|
||||||
// ref={useRef(123)}
|
// ref={useRef(123)}
|
||||||
onChange={setEnv}
|
onChange={setEnv}
|
||||||
className="z-40"
|
className="z-40"
|
||||||
@@ -507,9 +486,7 @@ export default function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row">
|
<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">
|
<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">
|
<p className="mr-2 font-bold pl-4">Project ID:</p>
|
||||||
Project ID:
|
|
||||||
</p>
|
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={workspaceId}
|
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"
|
className="pl-4 pr-4 border-l border-white/20 py-2 hover:bg-white/[0.12] duration-200"
|
||||||
>
|
>
|
||||||
{projectIdCopied ? (
|
{projectIdCopied ? (
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon icon={faCheck} className="pr-0.5" />
|
||||||
icon={faCheck}
|
|
||||||
className="pr-0.5"
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<FontAwesomeIcon icon={faCopy} />
|
<FontAwesomeIcon icon={faCopy} />
|
||||||
)}
|
)}
|
||||||
@@ -537,9 +511,7 @@ export default function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{(data?.length !== 0 || buttonReady) && (
|
{(data?.length !== 0 || buttonReady) && (
|
||||||
<div
|
<div className={`flex justify-start max-w-sm mt-2`}>
|
||||||
className={`flex justify-start max-w-sm mt-2`}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
text="Save Changes"
|
text="Save Changes"
|
||||||
onButtonPressed={savePush}
|
onButtonPressed={savePush}
|
||||||
@@ -560,12 +532,7 @@ export default function Dashboard() {
|
|||||||
<>
|
<>
|
||||||
<ListBox
|
<ListBox
|
||||||
selected={env}
|
selected={env}
|
||||||
data={[
|
data={["Development", "Staging", "Production", "Testing"]}
|
||||||
"Development",
|
|
||||||
"Staging",
|
|
||||||
"Production",
|
|
||||||
"Testing",
|
|
||||||
]}
|
|
||||||
// ref={useRef(123)}
|
// ref={useRef(123)}
|
||||||
onChange={setEnv}
|
onChange={setEnv}
|
||||||
className="z-40"
|
className="z-40"
|
||||||
@@ -578,11 +545,7 @@ export default function Dashboard() {
|
|||||||
<input
|
<input
|
||||||
className="pl-2 text-gray-400 rounded-r-md bg-white/5 w-full h-full outline-none"
|
className="pl-2 text-gray-400 rounded-r-md bg-white/5 w-full h-full outline-none"
|
||||||
value={searchKeys}
|
value={searchKeys}
|
||||||
onChange={(e) =>
|
onChange={(e) => setSearchKeys(e.target.value)}
|
||||||
setSearchKeys(
|
|
||||||
e.target.value
|
|
||||||
)
|
|
||||||
}
|
|
||||||
placeholder={"Search keys..."}
|
placeholder={"Search keys..."}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -611,9 +574,7 @@ export default function Dashboard() {
|
|||||||
onButtonPressed={changeBlurred}
|
onButtonPressed={changeBlurred}
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
size="icon-md"
|
size="icon-md"
|
||||||
icon={
|
icon={blurred ? faEye : faEyeSlash}
|
||||||
blurred ? faEye : faEyeSlash
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="relative ml-2 min-w-max flex flex-row items-start justify-end">
|
<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">
|
<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} /> */}
|
{/* <FontAwesomeIcon icon={faAngleDown} /> */}
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<p className="pl-2 text-lg">
|
<p className="pl-2 text-lg">Personal</p>
|
||||||
Personal
|
|
||||||
</p>
|
|
||||||
<div className="group font-normal group relative inline-block text-gray-300 underline hover:text-primary duration-200">
|
<div className="group font-normal group relative inline-block text-gray-300 underline hover:text-primary duration-200">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
className="ml-3 mt-1 text-lg"
|
className="ml-3 mt-1 text-lg"
|
||||||
icon={faCircleInfo}
|
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">
|
<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
|
Personal keys are only visible to you
|
||||||
visible to you
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -667,9 +625,7 @@ export default function Dashboard() {
|
|||||||
(keyPair) =>
|
(keyPair) =>
|
||||||
keyPair[2]
|
keyPair[2]
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(
|
.includes(searchKeys.toLowerCase()) &&
|
||||||
searchKeys.toLowerCase()
|
|
||||||
) &&
|
|
||||||
keyPair[4] == "personal"
|
keyPair[4] == "personal"
|
||||||
)
|
)
|
||||||
.sort((a, b) =>
|
.sort((a, b) =>
|
||||||
@@ -682,13 +638,9 @@ export default function Dashboard() {
|
|||||||
key={keyPair[0]}
|
key={keyPair[0]}
|
||||||
keyPair={keyPair}
|
keyPair={keyPair}
|
||||||
deleteRow={deleteCertainRow}
|
deleteRow={deleteCertainRow}
|
||||||
modifyValue={
|
modifyValue={listenChangeValue}
|
||||||
listenChangeValue
|
|
||||||
}
|
|
||||||
modifyKey={listenChangeKey}
|
modifyKey={listenChangeKey}
|
||||||
modifyVisibility={
|
modifyVisibility={listenChangeVisibility}
|
||||||
listenChangeVisibility
|
|
||||||
}
|
|
||||||
isBlurred={blurred}
|
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">
|
<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} /> */}
|
{/* <FontAwesomeIcon icon={faAngleDown} /> */}
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<p className="pl-2 text-lg">
|
<p className="pl-2 text-lg">Shared</p>
|
||||||
Shared
|
|
||||||
</p>
|
|
||||||
<div className="group font-normal group relative inline-block text-gray-300 underline hover:text-primary duration-200">
|
<div className="group font-normal group relative inline-block text-gray-300 underline hover:text-primary duration-200">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
className="ml-3 text-lg mt-1"
|
className="ml-3 text-lg mt-1"
|
||||||
icon={faCircleInfo}
|
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">
|
<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
|
Shared keys are visible to your whole team
|
||||||
your whole team
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -723,9 +672,7 @@ export default function Dashboard() {
|
|||||||
(keyPair) =>
|
(keyPair) =>
|
||||||
keyPair[2]
|
keyPair[2]
|
||||||
.toLowerCase()
|
.toLowerCase()
|
||||||
.includes(
|
.includes(searchKeys.toLowerCase()) &&
|
||||||
searchKeys.toLowerCase()
|
|
||||||
) &&
|
|
||||||
keyPair[4] == "shared"
|
keyPair[4] == "shared"
|
||||||
)
|
)
|
||||||
.sort((a, b) =>
|
.sort((a, b) =>
|
||||||
@@ -738,13 +685,9 @@ export default function Dashboard() {
|
|||||||
key={keyPair[0]}
|
key={keyPair[0]}
|
||||||
keyPair={keyPair}
|
keyPair={keyPair}
|
||||||
deleteRow={deleteCertainRow}
|
deleteRow={deleteCertainRow}
|
||||||
modifyValue={
|
modifyValue={listenChangeValue}
|
||||||
listenChangeValue
|
|
||||||
}
|
|
||||||
modifyKey={listenChangeKey}
|
modifyKey={listenChangeKey}
|
||||||
modifyVisibility={
|
modifyVisibility={listenChangeVisibility}
|
||||||
listenChangeVisibility
|
|
||||||
}
|
|
||||||
isBlurred={blurred}
|
isBlurred={blurred}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
@@ -753,9 +696,7 @@ export default function Dashboard() {
|
|||||||
<div className="w-full max-w-5xl">
|
<div className="w-full max-w-5xl">
|
||||||
<DropZone
|
<DropZone
|
||||||
setData={addData}
|
setData={addData}
|
||||||
setErrorDragAndDrop={
|
setErrorDragAndDrop={setErrorDragAndDrop}
|
||||||
setErrorDragAndDrop
|
|
||||||
}
|
|
||||||
createNewFile={addRow}
|
createNewFile={addRow}
|
||||||
errorDragAndDrop={errorDragAndDrop}
|
errorDragAndDrop={errorDragAndDrop}
|
||||||
setButtonReady={setButtonReady}
|
setButtonReady={setButtonReady}
|
||||||
@@ -766,23 +707,19 @@ export default function Dashboard() {
|
|||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex flex-col items-center justify-center h-full text-xl text-gray-400 max-w-5xl mt-28">
|
<div className="flex flex-col items-center justify-center h-full text-xl text-gray-400 max-w-5xl mt-28">
|
||||||
{fileState.message !=
|
{fileState.message != "There's nothing to pull" &&
|
||||||
"There's nothing to pull" &&
|
|
||||||
fileState.message != undefined && (
|
fileState.message != undefined && (
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
className="text-7xl mb-8"
|
className="text-7xl mb-8"
|
||||||
icon={faFolderOpen}
|
icon={faFolderOpen}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{(fileState.message ==
|
{(fileState.message == "There's nothing to pull" ||
|
||||||
"There's nothing to pull" ||
|
|
||||||
fileState.message == undefined) &&
|
fileState.message == undefined) &&
|
||||||
isKeyAvailable && (
|
isKeyAvailable && (
|
||||||
<DropZone
|
<DropZone
|
||||||
setData={setData}
|
setData={setData}
|
||||||
setErrorDragAndDrop={
|
setErrorDragAndDrop={setErrorDragAndDrop}
|
||||||
setErrorDragAndDrop
|
|
||||||
}
|
|
||||||
createNewFile={addRow}
|
createNewFile={addRow}
|
||||||
errorDragAndDrop={errorDragAndDrop}
|
errorDragAndDrop={errorDragAndDrop}
|
||||||
setButtonReady={setButtonReady}
|
setButtonReady={setButtonReady}
|
||||||
@@ -791,13 +728,9 @@ export default function Dashboard() {
|
|||||||
)}
|
)}
|
||||||
{fileState.message ==
|
{fileState.message ==
|
||||||
"Failed membership validation for workspace" && (
|
"Failed membership validation for workspace" && (
|
||||||
<p>
|
<p>You are not authorized to view this project.</p>
|
||||||
You are not authorized to view this
|
|
||||||
project.
|
|
||||||
</p>
|
|
||||||
)}
|
)}
|
||||||
{fileState.message ==
|
{fileState.message == "Access needed to pull the latest file" ||
|
||||||
"Access needed to pull the latest file" ||
|
|
||||||
(!isKeyAvailable && (
|
(!isKeyAvailable && (
|
||||||
<>
|
<>
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
@@ -805,12 +738,11 @@ export default function Dashboard() {
|
|||||||
icon={faFolderOpen}
|
icon={faFolderOpen}
|
||||||
/>
|
/>
|
||||||
<p>
|
<p>
|
||||||
To view this file, contact your
|
To view this file, contact your administrator for
|
||||||
administrator for permission.
|
permission.
|
||||||
</p>
|
</p>
|
||||||
<p className="mt-1">
|
<p className="mt-1">
|
||||||
They need to grant you access in
|
They need to grant you access in the team tab.
|
||||||
the team tab.
|
|
||||||
</p>
|
</p>
|
||||||
</>
|
</>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -22,9 +22,7 @@ export default function Heroku() {
|
|||||||
code,
|
code,
|
||||||
integration: "heroku",
|
integration: "heroku",
|
||||||
});
|
});
|
||||||
router.push(
|
router.push("/integrations/" + localStorage.getItem("projectData.id"));
|
||||||
"/integrations/" + localStorage.getItem("projectData.id")
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error - Not logged in yet");
|
console.log("Error - Not logged in yet");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect,useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
@@ -61,9 +61,7 @@ const Integration = ({ projectIntegration }) => {
|
|||||||
const tempHerokuAppNames = tempHerokuApps.map((app) => app.name);
|
const tempHerokuAppNames = tempHerokuApps.map((app) => app.name);
|
||||||
setApps(tempHerokuAppNames);
|
setApps(tempHerokuAppNames);
|
||||||
setIntegrationApp(
|
setIntegrationApp(
|
||||||
projectIntegration.app
|
projectIntegration.app ? projectIntegration.app : tempHerokuAppNames[0]
|
||||||
? projectIntegration.app
|
|
||||||
: tempHerokuAppNames[0]
|
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
@@ -96,9 +94,7 @@ const Integration = ({ projectIntegration }) => {
|
|||||||
INTEGRATION
|
INTEGRATION
|
||||||
</div>
|
</div>
|
||||||
<div className="py-2.5 bg-white/[.07] rounded-md pl-4 pr-20 text-sm font-semibold text-gray-300">
|
<div className="py-2.5 bg-white/[.07] rounded-md pl-4 pr-20 text-sm font-semibold text-gray-300">
|
||||||
{projectIntegration.integration
|
{projectIntegration.integration.charAt(0).toUpperCase() +
|
||||||
.charAt(0)
|
|
||||||
.toUpperCase() +
|
|
||||||
projectIntegration.integration.slice(1)}
|
projectIntegration.integration.slice(1)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -120,9 +116,7 @@ const Integration = ({ projectIntegration }) => {
|
|||||||
icon={faRotate}
|
icon={faRotate}
|
||||||
className="text-lg mr-2.5 text-primary animate-spin"
|
className="text-lg mr-2.5 text-primary animate-spin"
|
||||||
/>
|
/>
|
||||||
<div className="text-gray-300 font-semibold">
|
<div className="text-gray-300 font-semibold">In Sync</div>
|
||||||
In Sync
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
@@ -130,13 +124,11 @@ const Integration = ({ projectIntegration }) => {
|
|||||||
onButtonPressed={async () => {
|
onButtonPressed={async () => {
|
||||||
const result = await startIntegration({
|
const result = await startIntegration({
|
||||||
integrationId: projectIntegration._id,
|
integrationId: projectIntegration._id,
|
||||||
environment:
|
environment: envMapping[integrationEnvironment],
|
||||||
envMapping[integrationEnvironment],
|
|
||||||
appName: integrationApp,
|
appName: integrationApp,
|
||||||
});
|
});
|
||||||
if (result?.status == 200) {
|
if (result?.status == 200) {
|
||||||
let currentSecrets =
|
let currentSecrets = await getSecretsForProject({
|
||||||
await getSecretsForProject({
|
|
||||||
env: integrationEnvironment,
|
env: integrationEnvironment,
|
||||||
setFileState,
|
setFileState,
|
||||||
setIsKeyAvailable,
|
setIsKeyAvailable,
|
||||||
@@ -216,10 +208,7 @@ export default function Integrations() {
|
|||||||
<title>Dashboard</title>
|
<title>Dashboard</title>
|
||||||
<link rel="icon" href="/infisical.ico" />
|
<link rel="icon" href="/infisical.ico" />
|
||||||
<meta property="og:image" content="/images/message.png" />
|
<meta property="og:image" content="/images/message.png" />
|
||||||
<meta
|
<meta property="og:title" content="Manage your .env files in seconds" />
|
||||||
property="og:title"
|
|
||||||
content="Manage your .env files in seconds"
|
|
||||||
/>
|
|
||||||
<meta
|
<meta
|
||||||
name="og:description"
|
name="og:description"
|
||||||
content="Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
content="Infisical a simple end-to-end encrypted platform that enables teams to sync and manage their .env files."
|
||||||
@@ -227,19 +216,13 @@ export default function Integrations() {
|
|||||||
</Head>
|
</Head>
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<div className="w-full max-h-96 pb-2 h-screen max-h-[calc(100vh-10px)] overflow-y-scroll no-scrollbar no-scrollbar::-webkit-scrollbar">
|
<div className="w-full max-h-96 pb-2 h-screen max-h-[calc(100vh-10px)] overflow-y-scroll no-scrollbar no-scrollbar::-webkit-scrollbar">
|
||||||
<NavHeader
|
<NavHeader pageName="Project Integrations" isProjectRelated={true} />
|
||||||
pageName="Project Integrations"
|
|
||||||
isProjectRelated={true}
|
|
||||||
/>
|
|
||||||
<div className="flex flex-col justify-between items-start mx-4 mt-6 mb-4 text-xl max-w-5xl px-2">
|
<div className="flex flex-col justify-between items-start mx-4 mt-6 mb-4 text-xl max-w-5xl px-2">
|
||||||
<div className="flex flex-row justify-start items-center text-3xl">
|
<div className="flex flex-row justify-start items-center text-3xl">
|
||||||
<p className="font-semibold mr-4">
|
<p className="font-semibold mr-4">Current Project Integrations</p>
|
||||||
Current Project Integrations
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="mr-4 text-base text-gray-400">
|
<p className="mr-4 text-base text-gray-400">
|
||||||
Manage your integrations of Infisical with
|
Manage your integrations of Infisical with third-party services.
|
||||||
third-party services.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{projectIntegrations.length > 0 ? (
|
{projectIntegrations.length > 0 ? (
|
||||||
@@ -253,46 +236,40 @@ export default function Integrations() {
|
|||||||
<div className="flex flex-col max-w-5xl justify-center bg-white/5 p-6 rounded-md mx-6 mt-8">
|
<div className="flex flex-col max-w-5xl justify-center bg-white/5 p-6 rounded-md mx-6 mt-8">
|
||||||
<div className="relative px-4 flex flex-col text-gray-400 items-center justify-center">
|
<div className="relative px-4 flex flex-col text-gray-400 items-center justify-center">
|
||||||
<div className="mb-1">
|
<div className="mb-1">
|
||||||
You {"don't"} have any integrations set up
|
You {"don't"} have any integrations set up yet. When you do,
|
||||||
yet. When you do, they will appear here.
|
they will appear here.
|
||||||
</div>
|
</div>
|
||||||
<div className="">
|
<div className="">
|
||||||
To start, click on any of the options below.
|
To start, click on any of the options below. It takes 5 clicks
|
||||||
It takes 5 clicks to set up.
|
to set up.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="flex flex-col justify-between items-start mx-4 mt-12 mb-4 text-xl max-w-5xl px-2">
|
<div className="flex flex-col justify-between items-start mx-4 mt-12 mb-4 text-xl max-w-5xl px-2">
|
||||||
<div className="flex flex-row justify-start items-center text-3xl">
|
<div className="flex flex-row justify-start items-center text-3xl">
|
||||||
<p className="font-semibold mr-4">
|
<p className="font-semibold mr-4">Available Integrations</p>
|
||||||
Available Integrations
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="mr-4 text-base text-gray-400">
|
<p className="mr-4 text-base text-gray-400">
|
||||||
Click on the itegration you want to connect. This
|
Click on the itegration you want to connect. This will let your
|
||||||
will let your environment variables flow
|
environment variables flow automatically into selected third-party
|
||||||
automatically into selected third-party services.
|
services.
|
||||||
</p>
|
</p>
|
||||||
<p className="mr-4 text-xs text-gray-600 mt-1">
|
<p className="mr-4 text-xs text-gray-600 mt-1">
|
||||||
Note: during an integration with Heroku, for
|
Note: during an integration with Heroku, for security reasons, it
|
||||||
security reasons, it is impossible to maintain
|
is impossible to maintain end-to-end encryption. In theory, this
|
||||||
end-to-end encryption. In theory, this lets
|
lets Infisical decrypt yor environment variables. In practice, we
|
||||||
Infisical decrypt yor environment variables. In
|
can assure you that this will never be done, and it allows us to
|
||||||
practice, we can assure you that this will never be
|
protect your secrets from bad actors online. The core Infisical
|
||||||
done, and it allows us to protect your secrets from
|
service will always stay end-to-end encrypted. With any questions,
|
||||||
bad actors online. The core Infisical service will
|
reach out support@infisical.com.
|
||||||
always stay end-to-end encrypted. With any
|
|
||||||
questions, reach out support@infisical.com.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid gap-4 grid-cols-3 grid-rows-3 mx-6 mt-4 max-w-5xl">
|
<div className="grid gap-4 grid-cols-3 grid-rows-3 mx-6 mt-4 max-w-5xl">
|
||||||
{Object.keys(integrations).map((integration) => (
|
{Object.keys(integrations).map((integration) => (
|
||||||
<div
|
<div
|
||||||
className={`relative ${
|
className={`relative ${
|
||||||
["Heroku"].includes(
|
["Heroku"].includes(integrations[integration].name)
|
||||||
integrations[integration].name
|
|
||||||
)
|
|
||||||
? ""
|
? ""
|
||||||
: "opacity-50"
|
: "opacity-50"
|
||||||
}`}
|
}`}
|
||||||
@@ -300,17 +277,13 @@ export default function Integrations() {
|
|||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href={`${
|
href={`${
|
||||||
["Heroku"].includes(
|
["Heroku"].includes(integrations[integration].name)
|
||||||
integrations[integration].name
|
|
||||||
)
|
|
||||||
? `https://id.heroku.com/oauth/authorize?client_id=bc132901-935a-4590-b010-f1857efc380d&response_type=code&scope=write-protected&state=${csrfToken}`
|
? `https://id.heroku.com/oauth/authorize?client_id=bc132901-935a-4590-b010-f1857efc380d&response_type=code&scope=write-protected&state=${csrfToken}`
|
||||||
: "#"
|
: "#"
|
||||||
}`}
|
}`}
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
className={`relative flex flex-row bg-white/5 h-32 rounded-md p-4 items-center ${
|
className={`relative flex flex-row bg-white/5 h-32 rounded-md p-4 items-center ${
|
||||||
["Heroku"].includes(
|
["Heroku"].includes(integrations[integration].name)
|
||||||
integrations[integration].name
|
|
||||||
)
|
|
||||||
? "hover:bg-white/10 duration-200 cursor-pointer"
|
? "hover:bg-white/10 duration-200 cursor-pointer"
|
||||||
: "cursor-default grayscale"
|
: "cursor-default grayscale"
|
||||||
}`}
|
}`}
|
||||||
@@ -321,27 +294,12 @@ export default function Integrations() {
|
|||||||
width={100}
|
width={100}
|
||||||
alt="integration logo"
|
alt="integration logo"
|
||||||
></Image>
|
></Image>
|
||||||
{integrations[integration].name.split(" ")
|
{integrations[integration].name.split(" ").length > 2 ? (
|
||||||
.length > 2 ? (
|
|
||||||
<div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-3xl ml-8 max-w-xs">
|
<div className="font-semibold text-gray-300 group-hover:text-gray-200 duration-200 text-3xl ml-8 max-w-xs">
|
||||||
<div>
|
<div>{integrations[integration].name.split(" ")[0]}</div>
|
||||||
{
|
|
||||||
integrations[
|
|
||||||
integration
|
|
||||||
].name.split(" ")[0]
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
<div className="text-base">
|
<div className="text-base">
|
||||||
{
|
{integrations[integration].name.split(" ")[1]}{" "}
|
||||||
integrations[
|
{integrations[integration].name.split(" ")[2]}
|
||||||
integration
|
|
||||||
].name.split(" ")[1]
|
|
||||||
}{" "}
|
|
||||||
{
|
|
||||||
integrations[
|
|
||||||
integration
|
|
||||||
].name.split(" ")[2]
|
|
||||||
}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
@@ -350,40 +308,21 @@ export default function Integrations() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</a>
|
</a>
|
||||||
{["Heroku"].includes(
|
{["Heroku"].includes(integrations[integration].name) &&
|
||||||
integrations[integration].name
|
|
||||||
) &&
|
|
||||||
authorizations
|
authorizations
|
||||||
.map(
|
.map((authorization) => authorization.integration)
|
||||||
(authorization) =>
|
.includes(integrations[integration].name.toLowerCase()) && (
|
||||||
authorization.integration
|
|
||||||
)
|
|
||||||
.includes(
|
|
||||||
integrations[
|
|
||||||
integration
|
|
||||||
].name.toLowerCase()
|
|
||||||
) && (
|
|
||||||
<div className="absolute group z-50 top-0 right-0 flex flex-row">
|
<div className="absolute group z-50 top-0 right-0 flex flex-row">
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
deleteIntegrationAuth({
|
deleteIntegrationAuth({
|
||||||
integrationAuthId:
|
integrationAuthId: authorizations
|
||||||
authorizations
|
|
||||||
.filter(
|
.filter(
|
||||||
(
|
(authorization) =>
|
||||||
authorization
|
|
||||||
) =>
|
|
||||||
authorization.integration ==
|
authorization.integration ==
|
||||||
integrations[
|
integrations[integration].name.toLowerCase()
|
||||||
integration
|
|
||||||
].name.toLowerCase()
|
|
||||||
)
|
)
|
||||||
.map(
|
.map((authorization) => authorization._id)[0],
|
||||||
(
|
|
||||||
authorization
|
|
||||||
) =>
|
|
||||||
authorization._id
|
|
||||||
)[0],
|
|
||||||
});
|
});
|
||||||
router.reload();
|
router.reload();
|
||||||
}}
|
}}
|
||||||
@@ -404,9 +343,7 @@ export default function Integrations() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{!["Heroku"].includes(
|
{!["Heroku"].includes(integrations[integration].name) && (
|
||||||
integrations[integration].name
|
|
||||||
) && (
|
|
||||||
<div className="absolute group z-50 top-0 right-0 flex flex-row">
|
<div className="absolute group z-50 top-0 right-0 flex flex-row">
|
||||||
<div className="w-max bg-yellow py-0.5 px-2 rounded-bl-md rounded-tr-md text-xs flex flex-row items-center text-black opacity-90">
|
<div className="w-max bg-yellow py-0.5 px-2 rounded-bl-md rounded-tr-md text-xs flex flex-row items-center text-black opacity-90">
|
||||||
Coming Soon
|
Coming Soon
|
||||||
|
|||||||
+5
-11
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect,useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
@@ -110,9 +110,7 @@ export default function Login() {
|
|||||||
isRequired
|
isRequired
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{errorLogin && (
|
{errorLogin && <Error text="Your email and/or password are wrong." />}
|
||||||
<Error text="Your email and/or password are wrong." />
|
|
||||||
)}
|
|
||||||
<div className="flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm">
|
<div className="flex flex-col items-center justify-center w-full md:p-2 max-h-20 max-w-md mt-4 mx-auto text-sm">
|
||||||
<div className="text-l mt-6 m-8 px-8 py-3 text-lg">
|
<div className="text-l mt-6 m-8 px-8 py-3 text-lg">
|
||||||
<Button
|
<Button
|
||||||
@@ -129,13 +127,9 @@ export default function Login() {
|
|||||||
</div>
|
</div>
|
||||||
{false && (
|
{false && (
|
||||||
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-300 rounded-md max-w-md mx-auto mt-4">
|
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-300 rounded-md max-w-md mx-auto mt-4">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon icon={faWarning} className="ml-2 mr-6 text-6xl" />
|
||||||
icon={faWarning}
|
We are experiencing minor technical difficulties. We are working on
|
||||||
className="ml-2 mr-6 text-6xl"
|
solving it right now. Please come back in a few minutes.
|
||||||
/>
|
|
||||||
We are experiencing minor technical difficulties. We are
|
|
||||||
working on solving it right now. Please come back in a few
|
|
||||||
minutes.
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,13 +5,17 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|||||||
export default function NoProjects() {
|
export default function NoProjects() {
|
||||||
return (
|
return (
|
||||||
<div className="h-full flex flex-col items-center justify-center text-gray-300 text-lg text-center w-11/12 mr-auto">
|
<div className="h-full flex flex-col items-center justify-center text-gray-300 text-lg text-center w-11/12 mr-auto">
|
||||||
<FontAwesomeIcon icon={faFolderOpen} className="text-7xl mb-8 w-full px-auto" />
|
<FontAwesomeIcon
|
||||||
|
icon={faFolderOpen}
|
||||||
|
className="text-7xl mb-8 w-full px-auto"
|
||||||
|
/>
|
||||||
<div className="max-w-md">
|
<div className="max-w-md">
|
||||||
You are not part of any projects in this organization yet. When you do, they will appear here.
|
You are not part of any projects in this organization yet. When you do,
|
||||||
|
they will appear here.
|
||||||
</div>
|
</div>
|
||||||
<div className="max-w-md mt-4">
|
<div className="max-w-md mt-4">
|
||||||
Create a new project, or ask
|
Create a new project, or ask other organization members to give you
|
||||||
other organization members to give you neccessary permissions.
|
neccessary permissions.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ export default function Activity() {
|
|||||||
<p className="mt-2 mb-1 text-xl">Your invite has expired. </p>
|
<p className="mt-2 mb-1 text-xl">Your invite has expired. </p>
|
||||||
<p className="text-xl">Ask the administrator for a new one.</p>
|
<p className="text-xl">Ask the administrator for a new one.</p>
|
||||||
<p className="text-md mt-8 text-gray-600 max-w-sm text-center">
|
<p className="text-md mt-8 text-gray-600 max-w-sm text-center">
|
||||||
Note: If it still {"doesn't work"}, please reach out to us
|
Note: If it still {"doesn't work"}, please reach out to us at
|
||||||
at support@infisical.com
|
support@infisical.com
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect,useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
|
|
||||||
import Plan from "~/components/billing/Plan";
|
import Plan from "~/components/billing/Plan";
|
||||||
@@ -73,8 +73,7 @@ export default function SettingsBilling() {
|
|||||||
Usage & Billing
|
Usage & Billing
|
||||||
</p>
|
</p>
|
||||||
<p className="font-normal mr-4 text-gray-400 text-base">
|
<p className="font-normal mr-4 text-gray-400 text-base">
|
||||||
View and manage your {"organization's"}{" "}
|
View and manage your {"organization's"} subscription here.
|
||||||
subscription here.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect,useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import {
|
import {
|
||||||
@@ -33,8 +33,7 @@ export default function SettingsOrg() {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [orgName, setOrgName] = useState("");
|
const [orgName, setOrgName] = useState("");
|
||||||
const [emailUser, setEmailUser] = useState("");
|
const [emailUser, setEmailUser] = useState("");
|
||||||
const [workspaceToBeDeletedName, setWorkspaceToBeDeletedName] =
|
const [workspaceToBeDeletedName, setWorkspaceToBeDeletedName] = useState("");
|
||||||
useState("");
|
|
||||||
const [searchUsers, setSearchUsers] = useState("");
|
const [searchUsers, setSearchUsers] = useState("");
|
||||||
const [workspaceId, setWorkspaceId] = useState("");
|
const [workspaceId, setWorkspaceId] = useState("");
|
||||||
const [isAddIncidentContactOpen, setIsAddIncidentContactOpen] =
|
const [isAddIncidentContactOpen, setIsAddIncidentContactOpen] =
|
||||||
@@ -60,9 +59,7 @@ export default function SettingsOrg() {
|
|||||||
localStorage.getItem("orgData.id")
|
localStorage.getItem("orgData.id")
|
||||||
);
|
);
|
||||||
|
|
||||||
setIncidentContacts(
|
setIncidentContacts(incidentContactsData?.map((contact) => contact.email));
|
||||||
incidentContactsData?.map((contact) => contact.email)
|
|
||||||
);
|
|
||||||
|
|
||||||
const user = await getUser();
|
const user = await getUser();
|
||||||
setPersonalEmail(user.email);
|
setPersonalEmail(user.email);
|
||||||
@@ -76,10 +73,7 @@ export default function SettingsOrg() {
|
|||||||
key: guidGenerator(),
|
key: guidGenerator(),
|
||||||
firstName: user.user?.firstName,
|
firstName: user.user?.firstName,
|
||||||
lastName: user.user?.lastName,
|
lastName: user.user?.lastName,
|
||||||
email:
|
email: user.user?.email == null ? user.inviteEmail : user.user?.email,
|
||||||
user.user?.email == null
|
|
||||||
? user.inviteEmail
|
|
||||||
: user.user?.email,
|
|
||||||
role: user?.role,
|
role: user?.role,
|
||||||
status: user?.status,
|
status: user?.status,
|
||||||
userId: user.user?._id,
|
userId: user.user?._id,
|
||||||
@@ -134,10 +128,7 @@ export default function SettingsOrg() {
|
|||||||
setIncidentContacts(
|
setIncidentContacts(
|
||||||
incidentContacts.filter((contact) => contact != incidentContact)
|
incidentContacts.filter((contact) => contact != incidentContact)
|
||||||
);
|
);
|
||||||
deleteIncidentContact(
|
deleteIncidentContact(localStorage.getItem("orgData.id"), incidentContact);
|
||||||
localStorage.getItem("orgData.id"),
|
|
||||||
incidentContact
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -206,14 +197,10 @@ export default function SettingsOrg() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-start w-full">
|
<div className="flex justify-start w-full">
|
||||||
<div
|
<div className={`flex justify-start max-w-sm mt-4 mb-2`}>
|
||||||
className={`flex justify-start max-w-sm mt-4 mb-2`}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
text="Save Changes"
|
text="Save Changes"
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() => submitChanges(orgName)}
|
||||||
submitChanges(orgName)
|
|
||||||
}
|
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
size="md"
|
size="md"
|
||||||
active={buttonReady}
|
active={buttonReady}
|
||||||
@@ -230,8 +217,8 @@ export default function SettingsOrg() {
|
|||||||
Organization Members
|
Organization Members
|
||||||
</p>
|
</p>
|
||||||
<p className="mr-4 text-gray-400 mt-2 mb-2">
|
<p className="mr-4 text-gray-400 mt-2 mb-2">
|
||||||
Manage members of your organization. These users
|
Manage members of your organization. These users could
|
||||||
could afterwards be formed into projects.
|
afterwards be formed into projects.
|
||||||
</p>
|
</p>
|
||||||
<AddUserDialog
|
<AddUserDialog
|
||||||
isOpen={isAddUserOpen}
|
isOpen={isAddUserOpen}
|
||||||
@@ -253,9 +240,7 @@ export default function SettingsOrg() {
|
|||||||
<input
|
<input
|
||||||
className="pl-2 text-gray-400 rounded-r-md bg-white/5 w-full h-full outline-none"
|
className="pl-2 text-gray-400 rounded-r-md bg-white/5 w-full h-full outline-none"
|
||||||
value={searchUsers}
|
value={searchUsers}
|
||||||
onChange={(e) =>
|
onChange={(e) => setSearchUsers(e.target.value)}
|
||||||
setSearchUsers(e.target.value)
|
|
||||||
}
|
|
||||||
placeholder={"Search members..."}
|
placeholder={"Search members..."}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -294,16 +279,14 @@ export default function SettingsOrg() {
|
|||||||
Incident Contacts
|
Incident Contacts
|
||||||
</p>
|
</p>
|
||||||
<p className="text-xs text-gray-500 mb-2 min-w-max">
|
<p className="text-xs text-gray-500 mb-2 min-w-max">
|
||||||
These contacts will be notified in the
|
These contacts will be notified in the unlikely event of a
|
||||||
unlikely event of a severe incident.
|
severe incident.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-4 mb-2 min-w-max flex flex-row items-end justify-end justify-center">
|
<div className="mt-4 mb-2 min-w-max flex flex-row items-end justify-end justify-center">
|
||||||
<Button
|
<Button
|
||||||
text="Add Contact"
|
text="Add Contact"
|
||||||
onButtonPressed={
|
onButtonPressed={openAddIncidentContactModal}
|
||||||
openAddIncidentContactModal
|
|
||||||
}
|
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
size="md"
|
size="md"
|
||||||
icon={faPlus}
|
icon={faPlus}
|
||||||
@@ -318,9 +301,7 @@ export default function SettingsOrg() {
|
|||||||
<input
|
<input
|
||||||
className="pl-2 text-gray-400 rounded-tr-md bg-white/5 w-full h-full outline-none"
|
className="pl-2 text-gray-400 rounded-tr-md bg-white/5 w-full h-full outline-none"
|
||||||
value={searchIncidentContact}
|
value={searchIncidentContact}
|
||||||
onChange={(e) =>
|
onChange={(e) => setSearchIncidentContact(e.target.value)}
|
||||||
setSearchIncidentContact(e.target.value)
|
|
||||||
}
|
|
||||||
placeholder={"Search..."}
|
placeholder={"Search..."}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -328,23 +309,17 @@ export default function SettingsOrg() {
|
|||||||
email.includes(searchIncidentContact)
|
email.includes(searchIncidentContact)
|
||||||
).length > 0 ? (
|
).length > 0 ? (
|
||||||
incidentContacts
|
incidentContacts
|
||||||
.filter((email) =>
|
.filter((email) => email.includes(searchIncidentContact))
|
||||||
email.includes(searchIncidentContact)
|
|
||||||
)
|
|
||||||
.map((contact) => (
|
.map((contact) => (
|
||||||
<div
|
<div
|
||||||
key={guidGenerator()}
|
key={guidGenerator()}
|
||||||
className="flex flex-row items-center justify-between max-w-5xl px-4 py-3 hover:bg-white/5 border-t border-gray-600 w-full"
|
className="flex flex-row items-center justify-between max-w-5xl px-4 py-3 hover:bg-white/5 border-t border-gray-600 w-full"
|
||||||
>
|
>
|
||||||
<p className="text-gray-300">
|
<p className="text-gray-300">{contact}</p>
|
||||||
{contact}
|
|
||||||
</p>
|
|
||||||
<div className="opacity-50 hover:opacity-100 duration-200">
|
<div className="opacity-50 hover:opacity-100 duration-200">
|
||||||
<Button
|
<Button
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() =>
|
||||||
deleteIncidentContactFully(
|
deleteIncidentContactFully(contact)
|
||||||
contact
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
color="red"
|
color="red"
|
||||||
size="icon-sm"
|
size="icon-sm"
|
||||||
@@ -355,9 +330,7 @@ export default function SettingsOrg() {
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full flex flex-row justify-center mt-6 max-w-4xl ml-6">
|
<div className="w-full flex flex-row justify-center mt-6 max-w-4xl ml-6">
|
||||||
<p className="text-gray-400">
|
<p className="text-gray-400">No incident contacts found.</p>
|
||||||
No incident contacts found.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect,useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";
|
import { faCheck, faX } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
@@ -7,8 +7,8 @@ import Button from "~/components/basic/buttons/Button";
|
|||||||
import InputField from "~/components/basic/InputField";
|
import InputField from "~/components/basic/InputField";
|
||||||
import NavHeader from "~/components/navigation/NavHeader";
|
import NavHeader from "~/components/navigation/NavHeader";
|
||||||
import changePassword from "~/components/utilities/cryptography/changePassword";
|
import changePassword from "~/components/utilities/cryptography/changePassword";
|
||||||
import passwordCheck from "~/utilities/checks/PasswordCheck";
|
|
||||||
import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
|
import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
|
||||||
|
import passwordCheck from "~/utilities/checks/PasswordCheck";
|
||||||
|
|
||||||
import getUser from "../../api/user/getUser";
|
import getUser from "../../api/user/getUser";
|
||||||
|
|
||||||
@@ -40,10 +40,7 @@ export default function PersonalSettings() {
|
|||||||
</Head>
|
</Head>
|
||||||
<div className="flex flex-row">
|
<div className="flex flex-row">
|
||||||
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
||||||
<NavHeader
|
<NavHeader pageName="Personal Settings" isProjectRelated={false} />
|
||||||
pageName="Personal Settings"
|
|
||||||
isProjectRelated={false}
|
|
||||||
/>
|
|
||||||
<div className="flex flex-row justify-between items-center ml-6 mt-8 mb-6 text-xl max-w-5xl">
|
<div className="flex flex-row justify-between items-center ml-6 mt-8 mb-6 text-xl max-w-5xl">
|
||||||
<div className="flex flex-col justify-start items-start text-3xl">
|
<div className="flex flex-col justify-start items-start text-3xl">
|
||||||
<p className="font-semibold mr-4 text-gray-200">
|
<p className="font-semibold mr-4 text-gray-200">
|
||||||
@@ -150,9 +147,7 @@ export default function PersonalSettings() {
|
|||||||
passwordErrorLowerCase ||
|
passwordErrorLowerCase ||
|
||||||
passwordErrorNumber ? (
|
passwordErrorNumber ? (
|
||||||
<div className="w-full mt-3 bg-white/5 px-2 flex flex-col items-start py-2 rounded-md max-w-xl mb-2">
|
<div className="w-full mt-3 bg-white/5 px-2 flex flex-col items-start py-2 rounded-md max-w-xl mb-2">
|
||||||
<div
|
<div className={`text-gray-400 text-sm mb-1`}>
|
||||||
className={`text-gray-400 text-sm mb-1`}
|
|
||||||
>
|
|
||||||
Password should contain at least:
|
Password should contain at least:
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row justify-start items-center ml-1">
|
<div className="flex flex-row justify-start items-center ml-1">
|
||||||
@@ -169,9 +164,7 @@ export default function PersonalSettings() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorLength
|
passwordErrorLength ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
14 characters
|
14 characters
|
||||||
@@ -213,9 +206,7 @@ export default function PersonalSettings() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorNumber
|
passwordErrorNumber ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
1 number
|
1 number
|
||||||
@@ -261,9 +252,7 @@ export default function PersonalSettings() {
|
|||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faCheck}
|
icon={faCheck}
|
||||||
className={`ml-4 text-primary text-3xl ${
|
className={`ml-4 text-primary text-3xl ${
|
||||||
passwordChanged
|
passwordChanged ? "opacity-100" : "opacity-0"
|
||||||
? "opacity-100"
|
|
||||||
: "opacity-0"
|
|
||||||
} duration-300`}
|
} duration-300`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -276,14 +265,12 @@ export default function PersonalSettings() {
|
|||||||
Emergency Kit
|
Emergency Kit
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-mineshaft-300 min-w-max">
|
<p className="text-sm text-mineshaft-300 min-w-max">
|
||||||
Your Emergency Kit contains the
|
Your Emergency Kit contains the information you’ll need to
|
||||||
information you’ll need to sign in to
|
sign in to your Infisical account.
|
||||||
your Infisical account.
|
|
||||||
</p>
|
</p>
|
||||||
<p className="text-sm text-mineshaft-300 mb-5 min-w-max">
|
<p className="text-sm text-mineshaft-300 mb-5 min-w-max">
|
||||||
Only the latest issued Emergency Kit
|
Only the latest issued Emergency Kit remains valid. To get a
|
||||||
remains valid. To get a new Emergency
|
new Emergency Kit, verify your password.
|
||||||
Kit, verify your password.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -318,9 +305,7 @@ export default function PersonalSettings() {
|
|||||||
<FontAwesomeIcon
|
<FontAwesomeIcon
|
||||||
icon={faCheck}
|
icon={faCheck}
|
||||||
className={`ml-4 text-primary text-3xl ${
|
className={`ml-4 text-primary text-3xl ${
|
||||||
backupKeyIssued
|
backupKeyIssued ? "opacity-100" : "opacity-0"
|
||||||
? "opacity-100"
|
|
||||||
: "opacity-0"
|
|
||||||
} duration-300`}
|
} duration-300`}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect,useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
import Head from "next/head";
|
import Head from "next/head";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { faCheck, faPlus } from "@fortawesome/free-solid-svg-icons";
|
import { faCheck, faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||||
@@ -19,8 +19,7 @@ export default function SettingsBasic() {
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [workspaceName, setWorkspaceName] = useState("");
|
const [workspaceName, setWorkspaceName] = useState("");
|
||||||
const [serviceTokens, setServiceTokens] = useState([]);
|
const [serviceTokens, setServiceTokens] = useState([]);
|
||||||
const [workspaceToBeDeletedName, setWorkspaceToBeDeletedName] =
|
const [workspaceToBeDeletedName, setWorkspaceToBeDeletedName] = useState("");
|
||||||
useState("");
|
|
||||||
const [workspaceId, setWorkspaceId] = useState("");
|
const [workspaceId, setWorkspaceId] = useState("");
|
||||||
const [isAddOpen, setIsAddOpen] = useState(false);
|
const [isAddOpen, setIsAddOpen] = useState(false);
|
||||||
let [isAddServiceTokenDialogOpen, setIsAddServiceTokenDialogOpen] =
|
let [isAddServiceTokenDialogOpen, setIsAddServiceTokenDialogOpen] =
|
||||||
@@ -101,18 +100,14 @@ export default function SettingsBasic() {
|
|||||||
/>
|
/>
|
||||||
<div className="flex flex-row mr-6 max-w-5xl">
|
<div className="flex flex-row mr-6 max-w-5xl">
|
||||||
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
<div className="w-full max-h-screen pb-2 overflow-y-auto">
|
||||||
<NavHeader
|
<NavHeader pageName="Project Settings" isProjectRelated={true} />
|
||||||
pageName="Project Settings"
|
|
||||||
isProjectRelated={true}
|
|
||||||
/>
|
|
||||||
<div className="flex flex-row justify-between items-center ml-6 my-8 text-xl max-w-5xl">
|
<div className="flex flex-row justify-between items-center ml-6 my-8 text-xl max-w-5xl">
|
||||||
<div className="flex flex-col justify-start items-start text-3xl">
|
<div className="flex flex-col justify-start items-start text-3xl">
|
||||||
<p className="font-semibold mr-4 text-gray-200">
|
<p className="font-semibold mr-4 text-gray-200">
|
||||||
Project Settings
|
Project Settings
|
||||||
</p>
|
</p>
|
||||||
<p className="font-normal mr-4 text-gray-400 text-base">
|
<p className="font-normal mr-4 text-gray-400 text-base">
|
||||||
These settings only apply to the currently
|
These settings only apply to the currently selected Project.
|
||||||
selected Project.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -120,14 +115,10 @@ export default function SettingsBasic() {
|
|||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<div className="min-w-md mt-2 flex flex-col items-start">
|
<div className="min-w-md mt-2 flex flex-col items-start">
|
||||||
<div className="bg-white/5 rounded-md px-6 pt-6 pb-4 flex flex-col items-start flex flex-col items-start w-full mb-6 pt-2">
|
<div className="bg-white/5 rounded-md px-6 pt-6 pb-4 flex flex-col items-start flex flex-col items-start w-full mb-6 pt-2">
|
||||||
<p className="text-xl font-semibold mb-4">
|
<p className="text-xl font-semibold mb-4">Display Name</p>
|
||||||
Display Name
|
|
||||||
</p>
|
|
||||||
<div className="max-h-28 w-full max-w-md mr-auto">
|
<div className="max-h-28 w-full max-w-md mr-auto">
|
||||||
<InputField
|
<InputField
|
||||||
onChangeHandler={
|
onChangeHandler={modifyWorkspaceName}
|
||||||
modifyWorkspaceName
|
|
||||||
}
|
|
||||||
type="varName"
|
type="varName"
|
||||||
value={workspaceName}
|
value={workspaceName}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
@@ -135,14 +126,10 @@ export default function SettingsBasic() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-start w-full">
|
<div className="flex justify-start w-full">
|
||||||
<div
|
<div className={`flex justify-start max-w-sm mt-4 mb-2`}>
|
||||||
className={`flex justify-start max-w-sm mt-4 mb-2`}
|
|
||||||
>
|
|
||||||
<Button
|
<Button
|
||||||
text="Save Changes"
|
text="Save Changes"
|
||||||
onButtonPressed={() =>
|
onButtonPressed={() => submitChanges(workspaceName)}
|
||||||
submitChanges(workspaceName)
|
|
||||||
}
|
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
size="md"
|
size="md"
|
||||||
active={buttonReady}
|
active={buttonReady}
|
||||||
@@ -153,19 +140,15 @@ export default function SettingsBasic() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white/5 rounded-md px-6 pt-6 pb-2 flex flex-col items-start flex flex-col items-start w-full mb-6 mt-4">
|
<div className="bg-white/5 rounded-md px-6 pt-6 pb-2 flex flex-col items-start flex flex-col items-start w-full mb-6 mt-4">
|
||||||
<p className="text-xl font-semibold self-start">
|
<p className="text-xl font-semibold self-start">Project ID</p>
|
||||||
Project ID
|
|
||||||
</p>
|
|
||||||
<p className="text-base text-gray-400 font-normal self-start mt-4">
|
<p className="text-base text-gray-400 font-normal self-start mt-4">
|
||||||
To integrate Infisical into your code
|
To integrate Infisical into your code base and get automatic
|
||||||
base and get automatic injection of
|
injection of environmental variables, you should use the
|
||||||
environmental variables, you should use
|
following Project ID.
|
||||||
the following Project ID.
|
|
||||||
</p>
|
</p>
|
||||||
<p className="text-base text-gray-400 font-normal self-start">
|
<p className="text-base text-gray-400 font-normal self-start">
|
||||||
For more guidance, including code
|
For more guidance, including code snipets for various
|
||||||
snipets for various languages and
|
languages and frameworks, see{" "}
|
||||||
frameworks, see{" "}
|
|
||||||
{/* eslint-disable-next-line react/jsx-no-target-blank */}
|
{/* eslint-disable-next-line react/jsx-no-target-blank */}
|
||||||
<a
|
<a
|
||||||
href="https://infisical.com/docs/getting-started/introduction"
|
href="https://infisical.com/docs/getting-started/introduction"
|
||||||
@@ -194,19 +177,15 @@ export default function SettingsBasic() {
|
|||||||
Service Tokens
|
Service Tokens
|
||||||
</p>
|
</p>
|
||||||
<p className="text-base text-gray-400 mb-4">
|
<p className="text-base text-gray-400 mb-4">
|
||||||
Every service token is specific
|
Every service token is specific to you, a certain
|
||||||
to you, a certain project and a
|
project and a certain environment within this project.
|
||||||
certain environment within this
|
|
||||||
project.
|
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-48">
|
<div className="w-48">
|
||||||
<Button
|
<Button
|
||||||
text="Add New Token"
|
text="Add New Token"
|
||||||
onButtonPressed={() => {
|
onButtonPressed={() => {
|
||||||
setIsAddServiceTokenDialogOpen(
|
setIsAddServiceTokenDialogOpen(true);
|
||||||
true
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
color="mineshaft"
|
color="mineshaft"
|
||||||
icon={faPlus}
|
icon={faPlus}
|
||||||
@@ -258,21 +237,16 @@ export default function SettingsBasic() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="bg-white/5 rounded-md px-6 pt-6 pb-6 border-l border-red pl-6 flex flex-col items-start flex flex-col items-start w-full mb-6 mt-4 pb-4 pt-2">
|
<div className="bg-white/5 rounded-md px-6 pt-6 pb-6 border-l border-red pl-6 flex flex-col items-start flex flex-col items-start w-full mb-6 mt-4 pb-4 pt-2">
|
||||||
<p className="text-xl font-bold text-red">
|
<p className="text-xl font-bold text-red">Danger Zone</p>
|
||||||
Danger Zone
|
|
||||||
</p>
|
|
||||||
<p className="mt-2 text-md text-gray-400">
|
<p className="mt-2 text-md text-gray-400">
|
||||||
As soon as you delete this project, you will not
|
As soon as you delete this project, you will not be able to undo
|
||||||
be able to undo it. This will immediately remove
|
it. This will immediately remove all the keys. If you still want
|
||||||
all the keys. If you still want to do that,
|
to do that, please enter the name of the project below.
|
||||||
please enter the name of the project below.
|
|
||||||
</p>
|
</p>
|
||||||
<div className="max-h-28 w-full max-w-md mr-auto mt-4">
|
<div className="max-h-28 w-full max-w-md mr-auto mt-4">
|
||||||
<InputField
|
<InputField
|
||||||
label="Project to be Deleted"
|
label="Project to be Deleted"
|
||||||
onChangeHandler={
|
onChangeHandler={setWorkspaceToBeDeletedName}
|
||||||
setWorkspaceToBeDeletedName
|
|
||||||
}
|
|
||||||
type="varName"
|
type="varName"
|
||||||
value={workspaceToBeDeletedName}
|
value={workspaceToBeDeletedName}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
@@ -287,8 +261,8 @@ export default function SettingsBasic() {
|
|||||||
Delete Project
|
Delete Project
|
||||||
</button>
|
</button>
|
||||||
<p className="mt-0.5 ml-1 text-xs text-gray-500">
|
<p className="mt-0.5 ml-1 text-xs text-gray-500">
|
||||||
Note: You can only delete a project in case you
|
Note: You can only delete a project in case you have more than
|
||||||
have more than one.
|
one.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+20
-52
@@ -7,13 +7,13 @@ import { useRouter } from "next/router";
|
|||||||
import { faCheck, faWarning, faX } from "@fortawesome/free-solid-svg-icons";
|
import { faCheck, faWarning, faX } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
import Aes256Gcm from "~/components/utilities/cryptography/aes-256-gcm";
|
|
||||||
import Button from "~/components/basic/buttons/Button";
|
import Button from "~/components/basic/buttons/Button";
|
||||||
import Error from "~/components/basic/Error";
|
import Error from "~/components/basic/Error";
|
||||||
import InputField from "~/components/basic/InputField";
|
import InputField from "~/components/basic/InputField";
|
||||||
|
import Aes256Gcm from "~/components/utilities/cryptography/aes-256-gcm";
|
||||||
|
import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
|
||||||
import attemptLogin from "~/utilities/attemptLogin";
|
import attemptLogin from "~/utilities/attemptLogin";
|
||||||
import passwordCheck from "~/utilities/checks/PasswordCheck";
|
import passwordCheck from "~/utilities/checks/PasswordCheck";
|
||||||
import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
|
|
||||||
|
|
||||||
import checkEmailVerificationCode from "./api/auth/CheckEmailVerificationCode";
|
import checkEmailVerificationCode from "./api/auth/CheckEmailVerificationCode";
|
||||||
import completeAccountInformationSignup from "./api/auth/CompleteAccountInformationSignup";
|
import completeAccountInformationSignup from "./api/auth/CompleteAccountInformationSignup";
|
||||||
@@ -184,9 +184,7 @@ export default function SignUp() {
|
|||||||
password
|
password
|
||||||
.slice(0, 32)
|
.slice(0, 32)
|
||||||
.padStart(
|
.padStart(
|
||||||
32 +
|
32 + (password.slice(0, 32).length - new Blob([password]).size),
|
||||||
(password.slice(0, 32).length -
|
|
||||||
new Blob([password]).size),
|
|
||||||
"0"
|
"0"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -199,8 +197,7 @@ export default function SignUp() {
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
client.createVerifier(async (err, result) => {
|
client.createVerifier(async (err, result) => {
|
||||||
const response = await completeAccountInformationSignup(
|
const response = await completeAccountInformationSignup({
|
||||||
{
|
|
||||||
email,
|
email,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
@@ -212,18 +209,14 @@ export default function SignUp() {
|
|||||||
salt: result.salt,
|
salt: result.salt,
|
||||||
verifier: result.verifier,
|
verifier: result.verifier,
|
||||||
token: verificationToken,
|
token: verificationToken,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
// if everything works, go the main dashboard page.
|
// if everything works, go the main dashboard page.
|
||||||
if (!errorCheck && response.status == "200") {
|
if (!errorCheck && response.status == "200") {
|
||||||
response = await response.json();
|
response = await response.json();
|
||||||
|
|
||||||
localStorage.setItem("publicKey", PUBLIC_KEY);
|
localStorage.setItem("publicKey", PUBLIC_KEY);
|
||||||
localStorage.setItem(
|
localStorage.setItem("encryptedPrivateKey", ciphertext);
|
||||||
"encryptedPrivateKey",
|
|
||||||
ciphertext
|
|
||||||
);
|
|
||||||
localStorage.setItem("iv", iv);
|
localStorage.setItem("iv", iv);
|
||||||
localStorage.setItem("tag", tag);
|
localStorage.setItem("tag", tag);
|
||||||
|
|
||||||
@@ -282,15 +275,11 @@ export default function SignUp() {
|
|||||||
</div> */}
|
</div> */}
|
||||||
<div className="flex flex-col items-center justify-center w-5/6 md:w-full md:p-2 max-h-28 max-w-xs md:max-w-md mx-auto mt-4 md:mt-4 text-sm text-center md:text-left">
|
<div className="flex flex-col items-center justify-center w-5/6 md:w-full md:p-2 max-h-28 max-w-xs md:max-w-md mx-auto mt-4 md:mt-4 text-sm text-center md:text-left">
|
||||||
<p className="text-gray-400 mt-2 md:mx-0.5">
|
<p className="text-gray-400 mt-2 md:mx-0.5">
|
||||||
By creating an account, you agree to our Terms and have read
|
By creating an account, you agree to our Terms and have read and
|
||||||
and acknowledged the Privacy Policy.
|
acknowledged the Privacy Policy.
|
||||||
</p>
|
</p>
|
||||||
<div className="text-l mt-6 m-2 md:m-8 px-8 py-1 text-lg">
|
<div className="text-l mt-6 m-2 md:m-8 px-8 py-1 text-lg">
|
||||||
<Button
|
<Button text="Get Started" onButtonPressed={emailCheck} size="lg" />
|
||||||
text="Get Started"
|
|
||||||
onButtonPressed={emailCheck}
|
|
||||||
size="lg"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -327,11 +316,7 @@ export default function SignUp() {
|
|||||||
<Error text="Oops. Your code is wrong. Please try again." />
|
<Error text="Oops. Your code is wrong. Please try again." />
|
||||||
)}
|
)}
|
||||||
<div className="flex max-w-min flex-col items-center justify-center md:p-2 max-h-24 max-w-md mx-auto text-lg px-4 mt-4 mb-2">
|
<div className="flex max-w-min flex-col items-center justify-center md:p-2 max-h-24 max-w-md mx-auto text-lg px-4 mt-4 mb-2">
|
||||||
<Button
|
<Button text="Verify" onButtonPressed={incrementStep} size="lg" />
|
||||||
text="Verify"
|
|
||||||
onButtonPressed={incrementStep}
|
|
||||||
size="lg"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col items-center justify-center w-full max-h-24 max-w-md mx-auto pt-2">
|
<div className="flex flex-col items-center justify-center w-full max-h-24 max-w-md mx-auto pt-2">
|
||||||
{/* <Link href="/login">
|
{/* <Link href="/login">
|
||||||
@@ -393,9 +378,7 @@ export default function SignUp() {
|
|||||||
value={password}
|
value={password}
|
||||||
isRequired
|
isRequired
|
||||||
error={
|
error={
|
||||||
passwordErrorLength &&
|
passwordErrorLength && passwordErrorNumber && passwordErrorLowerCase
|
||||||
passwordErrorNumber &&
|
|
||||||
passwordErrorLowerCase
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{passwordErrorLength ||
|
{passwordErrorLength ||
|
||||||
@@ -419,9 +402,7 @@ export default function SignUp() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorLength
|
passwordErrorLength ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
14 characters
|
14 characters
|
||||||
@@ -441,9 +422,7 @@ export default function SignUp() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorLowerCase
|
passwordErrorLowerCase ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
1 lowercase character
|
1 lowercase character
|
||||||
@@ -463,9 +442,7 @@ export default function SignUp() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorNumber
|
passwordErrorNumber ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
1 number
|
1 number
|
||||||
@@ -495,20 +472,17 @@ export default function SignUp() {
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col items-center justify-center w-full mt-4 md:mt-8 max-w-md text-gray-400 text-md rounded-md px-2">
|
<div className="flex flex-col items-center justify-center w-full mt-4 md:mt-8 max-w-md text-gray-400 text-md rounded-md px-2">
|
||||||
<div>
|
<div>
|
||||||
If you get locked out of your account, your Emergency Kit is
|
If you get locked out of your account, your Emergency Kit is the only
|
||||||
the only way to sign in.
|
way to sign in.
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3">
|
<div className="mt-3">
|
||||||
We recommend you download it and keep it somewhere safe.
|
We recommend you download it and keep it somewhere safe.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-400 rounded-md max-w-xs md:max-w-md mx-auto mt-4">
|
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-400 rounded-md max-w-xs md:max-w-md mx-auto mt-4">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon icon={faWarning} className="ml-2 mr-4 text-4xl" />
|
||||||
icon={faWarning}
|
It contains your Secret Key which we cannot access or recover for you if
|
||||||
className="ml-2 mr-4 text-4xl"
|
you lose it.
|
||||||
/>
|
|
||||||
It contains your Secret Key which we cannot access or recover
|
|
||||||
for you if you lose it.
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row items-center justify-center w-3/4 md:w-full md:p-2 max-h-28 max-w-max mx-auto mt-6 py-1 md:mt-4 text-lg text-center md:text-left">
|
<div className="flex flex-row items-center justify-center w-3/4 md:w-full md:p-2 max-h-28 max-w-max mx-auto mt-6 py-1 md:mt-4 text-lg text-center md:text-left">
|
||||||
<Button
|
<Button
|
||||||
@@ -567,13 +541,7 @@ export default function SignUp() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
{step == 1
|
{step == 1 ? step1 : step == 2 ? step2 : step == 3 ? step3 : step4}
|
||||||
? step1
|
|
||||||
: step == 2
|
|
||||||
? step2
|
|
||||||
: step == 3
|
|
||||||
? step3
|
|
||||||
: step4}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -3,15 +3,15 @@ import Head from "next/head";
|
|||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import { faCheck, faWarning,faX } from "@fortawesome/free-solid-svg-icons";
|
import { faCheck, faWarning, faX } from "@fortawesome/free-solid-svg-icons";
|
||||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||||
|
|
||||||
import Aes256Gcm from "~/components/utilities/cryptography/aes-256-gcm";
|
|
||||||
import Button from "~/components/basic/buttons/Button";
|
import Button from "~/components/basic/buttons/Button";
|
||||||
import InputField from "~/components/basic/InputField";
|
import InputField from "~/components/basic/InputField";
|
||||||
|
import Aes256Gcm from "~/components/utilities/cryptography/aes-256-gcm";
|
||||||
|
import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
|
||||||
import attemptLogin from "~/utilities/attemptLogin";
|
import attemptLogin from "~/utilities/attemptLogin";
|
||||||
import passwordCheck from "~/utilities/checks/PasswordCheck";
|
import passwordCheck from "~/utilities/checks/PasswordCheck";
|
||||||
import issueBackupKey from "~/components/utilities/cryptography/issueBackupKey";
|
|
||||||
|
|
||||||
import completeAccountInformationSignupInvite from "./api/auth/CompleteAccountInformationSignupInvite";
|
import completeAccountInformationSignupInvite from "./api/auth/CompleteAccountInformationSignupInvite";
|
||||||
import verifySignupInvite from "./api/auth/VerifySignupInvite";
|
import verifySignupInvite from "./api/auth/VerifySignupInvite";
|
||||||
@@ -79,9 +79,7 @@ export default function SignupInvite() {
|
|||||||
password
|
password
|
||||||
.slice(0, 32)
|
.slice(0, 32)
|
||||||
.padStart(
|
.padStart(
|
||||||
32 +
|
32 + (password.slice(0, 32).length - new Blob([password]).size),
|
||||||
(password.slice(0, 32).length -
|
|
||||||
new Blob([password]).size),
|
|
||||||
"0"
|
"0"
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@@ -94,8 +92,7 @@ export default function SignupInvite() {
|
|||||||
},
|
},
|
||||||
async () => {
|
async () => {
|
||||||
client.createVerifier(async (err, result) => {
|
client.createVerifier(async (err, result) => {
|
||||||
const response =
|
const response = await completeAccountInformationSignupInvite({
|
||||||
await completeAccountInformationSignupInvite({
|
|
||||||
email,
|
email,
|
||||||
firstName,
|
firstName,
|
||||||
lastName,
|
lastName,
|
||||||
@@ -113,10 +110,7 @@ export default function SignupInvite() {
|
|||||||
response = await response.json();
|
response = await response.json();
|
||||||
|
|
||||||
localStorage.setItem("publicKey", PUBLIC_KEY);
|
localStorage.setItem("publicKey", PUBLIC_KEY);
|
||||||
localStorage.setItem(
|
localStorage.setItem("encryptedPrivateKey", ciphertext);
|
||||||
"encryptedPrivateKey",
|
|
||||||
ciphertext
|
|
||||||
);
|
|
||||||
localStorage.setItem("iv", iv);
|
localStorage.setItem("iv", iv);
|
||||||
localStorage.setItem("tag", tag);
|
localStorage.setItem("tag", tag);
|
||||||
|
|
||||||
@@ -222,9 +216,7 @@ export default function SignupInvite() {
|
|||||||
value={password}
|
value={password}
|
||||||
isRequired
|
isRequired
|
||||||
error={
|
error={
|
||||||
passwordErrorLength &&
|
passwordErrorLength && passwordErrorNumber && passwordErrorLowerCase
|
||||||
passwordErrorNumber &&
|
|
||||||
passwordErrorLowerCase
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{passwordErrorLength ||
|
{passwordErrorLength ||
|
||||||
@@ -248,9 +240,7 @@ export default function SignupInvite() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorLength
|
passwordErrorLength ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
14 characters
|
14 characters
|
||||||
@@ -270,9 +260,7 @@ export default function SignupInvite() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorLowerCase
|
passwordErrorLowerCase ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
1 lowercase character
|
1 lowercase character
|
||||||
@@ -292,9 +280,7 @@ export default function SignupInvite() {
|
|||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={`${
|
className={`${
|
||||||
passwordErrorNumber
|
passwordErrorNumber ? "text-gray-400" : "text-gray-600"
|
||||||
? "text-gray-400"
|
|
||||||
: "text-gray-600"
|
|
||||||
} text-sm`}
|
} text-sm`}
|
||||||
>
|
>
|
||||||
1 number
|
1 number
|
||||||
@@ -326,20 +312,17 @@ export default function SignupInvite() {
|
|||||||
</p>
|
</p>
|
||||||
<div className="flex flex-col items-center justify-center w-full mt-4 md:mt-8 max-w-md text-gray-400 text-md rounded-md px-2">
|
<div className="flex flex-col items-center justify-center w-full mt-4 md:mt-8 max-w-md text-gray-400 text-md rounded-md px-2">
|
||||||
<div>
|
<div>
|
||||||
If you get locked out of your account, your Emergency Kit is
|
If you get locked out of your account, your Emergency Kit is the only
|
||||||
the only way to sign in.
|
way to sign in.
|
||||||
</div>
|
</div>
|
||||||
<div className="mt-3">
|
<div className="mt-3">
|
||||||
We recommend you download it and keep it somewhere safe.
|
We recommend you download it and keep it somewhere safe.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-400 rounded-md max-w-xs md:max-w-md mx-auto mt-4">
|
<div className="w-full p-2 flex flex-row items-center bg-white/10 text-gray-400 rounded-md max-w-xs md:max-w-md mx-auto mt-4">
|
||||||
<FontAwesomeIcon
|
<FontAwesomeIcon icon={faWarning} className="ml-2 mr-4 text-4xl" />
|
||||||
icon={faWarning}
|
It contains your Secret Key which we cannot access or recover for you if
|
||||||
className="ml-2 mr-4 text-4xl"
|
you lose it.
|
||||||
/>
|
|
||||||
It contains your Secret Key which we cannot access or recover
|
|
||||||
for you if you lose it.
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row items-center justify-center w-3/4 md:w-full md:p-2 max-h-28 max-w-xs md:max-w-md mx-auto mt-6 md:mt-8 py-1 text-lg text-center md:text-left">
|
<div className="flex flex-row items-center justify-center w-3/4 md:w-full md:p-2 max-h-28 max-w-xs md:max-w-md mx-auto mt-6 md:mt-8 py-1 text-lg text-center md:text-left">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -99,8 +99,7 @@ export default function Users() {
|
|||||||
key: guidGenerator(),
|
key: guidGenerator(),
|
||||||
firstName: user.user?.firstName,
|
firstName: user.user?.firstName,
|
||||||
lastName: user.user?.lastName,
|
lastName: user.user?.lastName,
|
||||||
email:
|
email: user.user?.email == null ? user.inviteEmail : user.user?.email,
|
||||||
user.user?.email == null ? user.inviteEmail : user.user?.email,
|
|
||||||
role: user?.role,
|
role: user?.role,
|
||||||
status: user?.status,
|
status: user?.status,
|
||||||
userId: user.user?._id,
|
userId: user.user?._id,
|
||||||
@@ -117,10 +116,7 @@ export default function Users() {
|
|||||||
?.filter((user) => user.status == "accepted")
|
?.filter((user) => user.status == "accepted")
|
||||||
.map((user) => user.user.email)
|
.map((user) => user.user.email)
|
||||||
.filter(
|
.filter(
|
||||||
(email) =>
|
(email) => !tempUserList?.map((user1) => user1.email).includes(email)
|
||||||
!tempUserList
|
|
||||||
?.map((user1) => user1.email)
|
|
||||||
.includes(email)
|
|
||||||
)[0]
|
)[0]
|
||||||
);
|
);
|
||||||
}, []);
|
}, []);
|
||||||
@@ -147,10 +143,7 @@ export default function Users() {
|
|||||||
?.filter((user) => user.status == "accepted")
|
?.filter((user) => user.status == "accepted")
|
||||||
.map((user) => user.user.email)
|
.map((user) => user.user.email)
|
||||||
.filter(
|
.filter(
|
||||||
(email) =>
|
(email) => !userList?.map((user1) => user1.email).includes(email)
|
||||||
!userList
|
|
||||||
?.map((user1) => user1.email)
|
|
||||||
.includes(email)
|
|
||||||
)}
|
)}
|
||||||
workspaceId={workspaceId}
|
workspaceId={workspaceId}
|
||||||
setEmail={setEmail}
|
setEmail={setEmail}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ module.exports = {
|
|||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
autoprefixer: {},
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
}
|
};
|
||||||
|
|||||||
+72
-73
@@ -1244,101 +1244,101 @@ module.exports = {
|
|||||||
colors: {
|
colors: {
|
||||||
// You can generate your own colors with this tool: https://javisperez.github.io/tailwindcolorshades/
|
// You can generate your own colors with this tool: https://javisperez.github.io/tailwindcolorshades/
|
||||||
primary: {
|
primary: {
|
||||||
50: '#fcfdf7',
|
50: "#fcfdf7",
|
||||||
100: '#f8fcee',
|
100: "#f8fcee",
|
||||||
200: '#eef6d5',
|
200: "#eef6d5",
|
||||||
300: '#e3f1bc',
|
300: "#e3f1bc",
|
||||||
400: '#cfe78a',
|
400: "#cfe78a",
|
||||||
500: '#badc58',
|
500: "#badc58",
|
||||||
600: '#a7c64f',
|
600: "#a7c64f",
|
||||||
700: '#8ca542',
|
700: "#8ca542",
|
||||||
800: '#708435',
|
800: "#708435",
|
||||||
900: '#5b6c2b',
|
900: "#5b6c2b",
|
||||||
DEFAULT: "#badc58",
|
DEFAULT: "#badc58",
|
||||||
},
|
},
|
||||||
grey: "#0d1117",
|
grey: "#0d1117",
|
||||||
mineshaft: {
|
mineshaft: {
|
||||||
50: '#f5f5f5',
|
50: "#f5f5f5",
|
||||||
100: '#ebebeb',
|
100: "#ebebeb",
|
||||||
200: '#ccccce',
|
200: "#ccccce",
|
||||||
300: '#adaeb0',
|
300: "#adaeb0",
|
||||||
400: '#707174',
|
400: "#707174",
|
||||||
500: '#323439',
|
500: "#323439",
|
||||||
600: '#2d2f33',
|
600: "#2d2f33",
|
||||||
700: '#26272b',
|
700: "#26272b",
|
||||||
800: '#1e1f22',
|
800: "#1e1f22",
|
||||||
900: '#19191c',
|
900: "#19191c",
|
||||||
DEFAULT: "#323439",
|
DEFAULT: "#323439",
|
||||||
},
|
},
|
||||||
chicago: {
|
chicago: {
|
||||||
50: '#f7f7f7',
|
50: "#f7f7f7",
|
||||||
100: '#efefef',
|
100: "#efefef",
|
||||||
200: '#d6d6d7',
|
200: "#d6d6d7",
|
||||||
300: '#bdbebf',
|
300: "#bdbebf",
|
||||||
400: '#8c8d8e',
|
400: "#8c8d8e",
|
||||||
500: '#5b5c5e',
|
500: "#5b5c5e",
|
||||||
600: '#525355',
|
600: "#525355",
|
||||||
700: '#444547',
|
700: "#444547",
|
||||||
800: '#373738',
|
800: "#373738",
|
||||||
900: '#2d2d2e',
|
900: "#2d2d2e",
|
||||||
DEFAULT: "#5b5c5e",
|
DEFAULT: "#5b5c5e",
|
||||||
},
|
},
|
||||||
bunker: {
|
bunker: {
|
||||||
50: '#f3f4f4',
|
50: "#f3f4f4",
|
||||||
100: '#e8e8e9',
|
100: "#e8e8e9",
|
||||||
200: '#c5c6c8',
|
200: "#c5c6c8",
|
||||||
300: '#a2a4a6',
|
300: "#a2a4a6",
|
||||||
400: '#5d5f64',
|
400: "#5d5f64",
|
||||||
500: '#171b21',
|
500: "#171b21",
|
||||||
600: '#15181e',
|
600: "#15181e",
|
||||||
700: '#111419',
|
700: "#111419",
|
||||||
800: '#0e1014',
|
800: "#0e1014",
|
||||||
900: '#0b0d10',
|
900: "#0b0d10",
|
||||||
DEFAULT: "#171B21",
|
DEFAULT: "#171B21",
|
||||||
},
|
},
|
||||||
githubblack: "#020409",
|
githubblack: "#020409",
|
||||||
blue2: "#130f40",
|
blue2: "#130f40",
|
||||||
blue1: "#3498db",
|
blue1: "#3498db",
|
||||||
yellow: {
|
yellow: {
|
||||||
50: '#fefcf3',
|
50: "#fefcf3",
|
||||||
100: '#fef9e7',
|
100: "#fef9e7",
|
||||||
200: '#fcf0c3',
|
200: "#fcf0c3",
|
||||||
300: '#f9e79f',
|
300: "#f9e79f",
|
||||||
400: '#f5d657',
|
400: "#f5d657",
|
||||||
500: '#f1c40f',
|
500: "#f1c40f",
|
||||||
600: '#d9b00e',
|
600: "#d9b00e",
|
||||||
700: '#b5930b',
|
700: "#b5930b",
|
||||||
800: '#917609',
|
800: "#917609",
|
||||||
900: '#766007',
|
900: "#766007",
|
||||||
DEFAULT: "#f1c40f",
|
DEFAULT: "#f1c40f",
|
||||||
},
|
},
|
||||||
red: {
|
red: {
|
||||||
50: '#fef6f5',
|
50: "#fef6f5",
|
||||||
100: '#fdedec',
|
100: "#fdedec",
|
||||||
200: '#f9d2ce',
|
200: "#f9d2ce",
|
||||||
300: '#f5b7b1',
|
300: "#f5b7b1",
|
||||||
400: '#ee8277',
|
400: "#ee8277",
|
||||||
500: '#e74c3c',
|
500: "#e74c3c",
|
||||||
600: '#d04436',
|
600: "#d04436",
|
||||||
700: '#ad392d',
|
700: "#ad392d",
|
||||||
800: '#8b2e24',
|
800: "#8b2e24",
|
||||||
900: '#71251d',
|
900: "#71251d",
|
||||||
DEFAULT: "#e74c3c",
|
DEFAULT: "#e74c3c",
|
||||||
},
|
},
|
||||||
orange: "#f39c12",
|
orange: "#f39c12",
|
||||||
green: {
|
green: {
|
||||||
50: '#f5fcf8',
|
50: "#f5fcf8",
|
||||||
100: '#eafaf1',
|
100: "#eafaf1",
|
||||||
200: '#cbf2dc',
|
200: "#cbf2dc",
|
||||||
300: '#abebc6',
|
300: "#abebc6",
|
||||||
400: '#6ddb9c',
|
400: "#6ddb9c",
|
||||||
500: '#2ecc71',
|
500: "#2ecc71",
|
||||||
600: '#29b866',
|
600: "#29b866",
|
||||||
700: '#239955',
|
700: "#239955",
|
||||||
800: '#1c7a44',
|
800: "#1c7a44",
|
||||||
900: '#176437',
|
900: "#176437",
|
||||||
DEFAULT: "#2ecc71",
|
DEFAULT: "#2ecc71",
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
keyframes: {
|
keyframes: {
|
||||||
@@ -1425,8 +1425,7 @@ module.exports = {
|
|||||||
spin: "spin 4000ms ease-in-out infinite",
|
spin: "spin 4000ms ease-in-out infinite",
|
||||||
cursor: "cursor .6s linear infinite alternate",
|
cursor: "cursor .6s linear infinite alternate",
|
||||||
type: "type 2.7s ease-out .8s infinite alternate both",
|
type: "type 2.7s ease-out .8s infinite alternate both",
|
||||||
"type-reverse":
|
"type-reverse": "type 1.8s ease-out 0s infinite alternate-reverse both",
|
||||||
"type 1.8s ease-out 0s infinite alternate-reverse both",
|
|
||||||
wiggle: "wiggle 200ms ease-in-out",
|
wiggle: "wiggle 200ms ease-in-out",
|
||||||
ping: "ping 1000ms ease-in-out infinite",
|
ping: "ping 1000ms ease-in-out infinite",
|
||||||
popup: "popup 300ms ease-in-out",
|
popup: "popup 300ms ease-in-out",
|
||||||
|
|||||||
Reference in New Issue
Block a user