Fix merge conflicts

This commit is contained in:
Vladyslav Matsiiako
2022-12-28 13:42:27 -05:00
89 changed files with 3019 additions and 887 deletions

View File

@@ -1,8 +1,9 @@
/* eslint-disable no-unexpected-multiline */
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useState } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/router";
import { useTranslation } from "next-i18next";
import {
faBookOpen,
faGear,
@@ -10,30 +11,30 @@ import {
faMobile,
faPlug,
faTimeline,
faUser
} from '@fortawesome/free-solid-svg-icons';
import { faPlus } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
faUser,
} from "@fortawesome/free-solid-svg-icons";
import { faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import getOrganizations from '~/pages/api/organization/getOrgs';
import getOrganizationUserProjects from '~/pages/api/organization/GetOrgUserProjects';
import getOrganizationUsers from '~/pages/api/organization/GetOrgUsers';
import checkUserAction from '~/pages/api/userActions/checkUserAction';
import addUserToWorkspace from '~/pages/api/workspace/addUserToWorkspace';
import createWorkspace from '~/pages/api/workspace/createWorkspace';
import getWorkspaces from '~/pages/api/workspace/getWorkspaces';
import uploadKeys from '~/pages/api/workspace/uploadKeys';
import getOrganizations from "~/pages/api/organization/getOrgs";
import getOrganizationUserProjects from "~/pages/api/organization/GetOrgUserProjects";
import getOrganizationUsers from "~/pages/api/organization/GetOrgUsers";
import checkUserAction from "~/pages/api/userActions/checkUserAction";
import addUserToWorkspace from "~/pages/api/workspace/addUserToWorkspace";
import createWorkspace from "~/pages/api/workspace/createWorkspace";
import getWorkspaces from "~/pages/api/workspace/getWorkspaces";
import uploadKeys from "~/pages/api/workspace/uploadKeys";
import NavBarDashboard from '../navigation/NavBarDashboard';
import onboardingCheck from '../utilities/checks/OnboardingCheck';
import { tempLocalStorage } from '../utilities/checks/tempLocalStorage';
import NavBarDashboard from "../navigation/NavBarDashboard";
import onboardingCheck from "../utilities/checks/OnboardingCheck";
import { tempLocalStorage } from "../utilities/checks/tempLocalStorage";
import {
decryptAssymmetric,
encryptAssymmetric
} from '../utilities/cryptography/crypto';
import Button from './buttons/Button';
import AddWorkspaceDialog from './dialog/AddWorkspaceDialog';
import Listbox from './Listbox';
encryptAssymmetric,
} from "../utilities/cryptography/crypto";
import Button from "./buttons/Button";
import AddWorkspaceDialog from "./dialog/AddWorkspaceDialog";
import Listbox from "./Listbox";
interface LayoutProps {
children: React.ReactNode;
@@ -42,15 +43,17 @@ interface LayoutProps {
export default function Layout({ children }: LayoutProps) {
const router = useRouter();
const [workspaceList, setWorkspaceList] = useState([]);
const [workspaceMapping, setWorkspaceMapping] = useState([{ '1': '2' }]);
const [workspaceSelected, setWorkspaceSelected] = useState('∞');
const [newWorkspaceName, setNewWorkspaceName] = useState('');
const [workspaceMapping, setWorkspaceMapping] = useState([{ "1": "2" }]);
const [workspaceSelected, setWorkspaceSelected] = useState("∞");
const [newWorkspaceName, setNewWorkspaceName] = useState("");
const [isOpen, setIsOpen] = useState(false);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
const [totalOnboardingActionsDone, setTotalOnboardingActionsDone] =
useState(0);
const { t } = useTranslation();
function closeModal() {
setIsOpen(false);
}
@@ -76,35 +79,35 @@ export default function Layout({ children }: LayoutProps) {
if (!currentWorkspaces.includes(workspaceName)) {
const newWorkspace = await createWorkspace({
workspaceName,
organizationId: tempLocalStorage('orgData.id')
organizationId: tempLocalStorage("orgData.id"),
});
const newWorkspaceId = newWorkspace._id;
if (addAllUsers) {
const orgUsers = await getOrganizationUsers({
orgId: tempLocalStorage('orgData.id')
orgId: tempLocalStorage("orgData.id"),
});
orgUsers.map(async (user: any) => {
if (user.status == 'accepted') {
if (user.status == "accepted") {
const result = await addUserToWorkspace(
user.user.email,
newWorkspaceId
);
if (result?.invitee && result?.latestKey) {
const PRIVATE_KEY = tempLocalStorage('PRIVATE_KEY');
const PRIVATE_KEY = tempLocalStorage("PRIVATE_KEY");
// assymmetrically decrypt symmetric key with local private key
const key = decryptAssymmetric({
ciphertext: result.latestKey.encryptedKey,
nonce: result.latestKey.nonce,
publicKey: result.latestKey.sender.publicKey,
privateKey: PRIVATE_KEY
privateKey: PRIVATE_KEY,
});
const { ciphertext, nonce } = encryptAssymmetric({
plaintext: key,
publicKey: result.invitee.publicKey,
privateKey: PRIVATE_KEY
privateKey: PRIVATE_KEY,
}) as { ciphertext: string; nonce: string };
uploadKeys(
@@ -117,11 +120,11 @@ export default function Layout({ children }: LayoutProps) {
}
});
}
router.push('/dashboard/' + newWorkspaceId + '?Development');
router.push("/dashboard/" + newWorkspaceId + "?Development");
setIsOpen(false);
setNewWorkspaceName('');
setNewWorkspaceName("");
} else {
console.error('A project with this name already exists.');
console.error("A project with this name already exists.");
setError(true);
setLoading(false);
}
@@ -132,67 +135,70 @@ export default function Layout({ children }: LayoutProps) {
}
}
const menuItems = [
{
href:
'/dashboard/' +
workspaceMapping[workspaceSelected as any] +
'?Development',
title: 'Secrets',
emoji: <FontAwesomeIcon icon={faKey} />
},
{
href: '/users/' + workspaceMapping[workspaceSelected as any],
title: 'Members',
emoji: <FontAwesomeIcon icon={faUser} />
},
{
href: '/integrations/' + workspaceMapping[workspaceSelected as any],
title: 'Integrations',
emoji: <FontAwesomeIcon icon={faPlug} />
},
{
href: '/activity/' + workspaceMapping[workspaceSelected as any],
title: 'Activity Logs',
emoji: <FontAwesomeIcon icon={faTimeline} />
},
{
href: '/settings/project/' + workspaceMapping[workspaceSelected as any],
title: 'Project Settings',
emoji: <FontAwesomeIcon icon={faGear} />
}
];
const menuItems = useMemo(
() => [
{
href:
"/dashboard/" +
workspaceMapping[workspaceSelected as any] +
"?Development",
title: t("nav:menu.secrets"),
emoji: <FontAwesomeIcon icon={faKey} />,
},
{
href: "/users/" + workspaceMapping[workspaceSelected as any],
title: t("nav:menu.members"),
emoji: <FontAwesomeIcon icon={faUser} />,
},
{
href: "/integrations/" + workspaceMapping[workspaceSelected as any],
title: t("nav:menu.integrations"),
emoji: <FontAwesomeIcon icon={faPlug} />,
},
{
href: '/activity/' + workspaceMapping[workspaceSelected as any],
title: 'Activity Logs',
emoji: <FontAwesomeIcon icon={faTimeline} />
},
{
href: "/settings/project/" + workspaceMapping[workspaceSelected as any],
title: t("nav:menu.project-settings"),
emoji: <FontAwesomeIcon icon={faGear} />,
},
],
[t, workspaceMapping, workspaceSelected]
);
useEffect(() => {
// Put a user in a workspace if they're not in one yet
const putUserInWorkSpace = async () => {
if (tempLocalStorage('orgData.id') === '') {
if (tempLocalStorage("orgData.id") === "") {
const userOrgs = await getOrganizations();
localStorage.setItem('orgData.id', userOrgs[0]._id);
localStorage.setItem("orgData.id", userOrgs[0]._id);
}
const orgUserProjects = await getOrganizationUserProjects({
orgId: tempLocalStorage('orgData.id')
orgId: tempLocalStorage("orgData.id"),
});
const userWorkspaces = orgUserProjects;
if (
userWorkspaces.length == 0 &&
router.asPath != '/noprojects' &&
!router.asPath.includes('settings')
router.asPath != "/noprojects" &&
!router.asPath.includes("settings")
) {
router.push('/noprojects');
} else if (router.asPath != '/noprojects') {
router.push("/noprojects");
} else if (router.asPath != "/noprojects") {
const intendedWorkspaceId = router.asPath
.split('/')
[router.asPath.split('/').length - 1].split('?')[0];
.split("/")
[router.asPath.split("/").length - 1].split("?")[0];
// If a user is not a member of a workspace they are trying to access, just push them to one of theirs
if (
intendedWorkspaceId != 'heroku' &&
intendedWorkspaceId != "heroku" &&
!userWorkspaces
.map((workspace: { _id: string }) => workspace._id)
.includes(intendedWorkspaceId)
) {
router.push('/dashboard/' + userWorkspaces[0]._id + '?Development');
router.push("/dashboard/" + userWorkspaces[0]._id + "?Development");
} else {
setWorkspaceList(
userWorkspaces.map((workspace: any) => workspace.name)
@@ -201,7 +207,7 @@ export default function Layout({ children }: LayoutProps) {
Object.fromEntries(
userWorkspaces.map((workspace: any) => [
workspace.name,
workspace._id
workspace._id,
])
) as any
);
@@ -209,12 +215,12 @@ export default function Layout({ children }: LayoutProps) {
Object.fromEntries(
userWorkspaces.map((workspace: any) => [
workspace._id,
workspace.name
workspace.name,
])
)[
router.asPath
.split('/')
[router.asPath.split('/').length - 1].split('?')[0]
.split("/")
[router.asPath.split("/").length - 1].split("?")[0]
]
);
}
@@ -230,16 +236,16 @@ export default function Layout({ children }: LayoutProps) {
workspaceMapping[workspaceSelected as any] &&
`${workspaceMapping[workspaceSelected as any]}` !==
router.asPath
.split('/')
[router.asPath.split('/').length - 1].split('?')[0]
.split("/")
[router.asPath.split("/").length - 1].split("?")[0]
) {
router.push(
'/dashboard/' +
"/dashboard/" +
workspaceMapping[workspaceSelected as any] +
'?Development'
"?Development"
);
localStorage.setItem(
'projectData.id',
"projectData.id",
`${workspaceMapping[workspaceSelected as any]}`
);
}
@@ -263,7 +269,7 @@ export default function Layout({ children }: LayoutProps) {
<div>
<div className="flex justify-center w-full mt-[4.5rem] mb-6 bg-bunker-600 h-20 flex-col items-center px-4">
<div className="text-gray-400 self-start ml-1 mb-1 text-xs font-semibold tracking-wide">
PROJECT
{t("nav:menu.project")}
</div>
{workspaceList.length > 0 ? (
<Listbox
@@ -288,11 +294,11 @@ export default function Layout({ children }: LayoutProps) {
{workspaceList.length > 0 &&
menuItems.map(({ href, title, emoji }) => (
<li className="mt-0.5 mx-2" key={title}>
{router.asPath.split('/')[1] === href.split('/')[1] &&
(['project', 'billing', 'org', 'personal'].includes(
router.asPath.split('/')[2]
{router.asPath.split("/")[1] === href.split("/")[1] &&
(["project", "billing", "org", "personal"].includes(
router.asPath.split("/")[2]
)
? router.asPath.split('/')[2] === href.split('/')[2]
? router.asPath.split("/")[2] === href.split("/")[2]
: true) ? (
<div
className={`flex relative px-0.5 py-2.5 text-white text-sm rounded cursor-pointer bg-primary-50/10`}
@@ -303,7 +309,7 @@ export default function Layout({ children }: LayoutProps) {
</p>
{title}
</div>
) : router.asPath == '/noprojects' ? (
) : router.asPath == "/noprojects" ? (
<div
className={`flex p-2.5 text-white text-sm rounded`}
>
@@ -329,7 +335,7 @@ export default function Layout({ children }: LayoutProps) {
</ul>
</div>
<div className="w-full mt-40 mb-4 px-2">
{router.asPath.split('/')[1] === 'home' ? (
{router.asPath.split("/")[1] === "home" ? (
<div
className={`flex relative px-0.5 py-2.5 text-white text-sm rounded cursor-pointer bg-primary-50/10`}
>
@@ -340,12 +346,12 @@ export default function Layout({ children }: LayoutProps) {
Infisical Guide
<img
src={`/images/progress-${
totalOnboardingActionsDone == 0 ? '0' : ''
}${totalOnboardingActionsDone == 1 ? '14' : ''}${
totalOnboardingActionsDone == 2 ? '28' : ''
}${totalOnboardingActionsDone == 3 ? '43' : ''}${
totalOnboardingActionsDone == 4 ? '57' : ''
}${totalOnboardingActionsDone == 5 ? '71' : ''}.svg`}
totalOnboardingActionsDone == 0 ? "0" : ""
}${totalOnboardingActionsDone == 1 ? "14" : ""}${
totalOnboardingActionsDone == 2 ? "28" : ""
}${totalOnboardingActionsDone == 3 ? "43" : ""}${
totalOnboardingActionsDone == 4 ? "57" : ""
}${totalOnboardingActionsDone == 5 ? "71" : ""}.svg`}
height={58}
width={58}
alt="progress bar"
@@ -365,12 +371,12 @@ export default function Layout({ children }: LayoutProps) {
Infisical Guide
<img
src={`/images/progress-${
totalOnboardingActionsDone == 0 ? '0' : ''
}${totalOnboardingActionsDone == 1 ? '14' : ''}${
totalOnboardingActionsDone == 2 ? '28' : ''
}${totalOnboardingActionsDone == 3 ? '43' : ''}${
totalOnboardingActionsDone == 4 ? '57' : ''
}${totalOnboardingActionsDone == 5 ? '71' : ''}.svg`}
totalOnboardingActionsDone == 0 ? "0" : ""
}${totalOnboardingActionsDone == 1 ? "14" : ""}${
totalOnboardingActionsDone == 2 ? "28" : ""
}${totalOnboardingActionsDone == 3 ? "43" : ""}${
totalOnboardingActionsDone == 4 ? "57" : ""
}${totalOnboardingActionsDone == 5 ? "71" : ""}.svg`}
height={58}
width={58}
alt="progress bar"
@@ -400,9 +406,7 @@ export default function Layout({ children }: LayoutProps) {
className="text-gray-300 text-7xl mb-8"
/>
<p className="text-gray-200 px-6 text-center text-lg max-w-sm">
{' '}
To use Infisical, please log in through a device with larger
dimensions.{' '}
{` ${t("common:no-mobile")} `}
</p>
</div>
</>

View File

@@ -64,7 +64,6 @@ export default function Toggle ({
id
])
} else {
setSharedToHide(sharedToHide!.filter(tempId => tempId != id))
deleteOverride(id);
}
setEnabled(!enabled);

View File

@@ -1,12 +1,7 @@
import { Fragment } from "react";
import { useTranslation } from "next-i18next";
import { Dialog, Transition } from "@headlessui/react";
import setBotActiveStatus from "../../../pages/api/bot/setBotActiveStatus";
import getLatestFileKey from "../../../pages/api/workspace/getLatestFileKey";
import {
decryptAssymmetric,
encryptAssymmetric
} from "../../utilities/cryptography/crypto";
import Button from "../buttons/Button";
const ActivateBotDialog = ({
@@ -16,6 +11,7 @@ const ActivateBotDialog = ({
handleBotActivate,
handleIntegrationOption
}) => {
const { t } = useTranslation();
const submit = async () => {
try {
@@ -64,18 +60,18 @@ const ActivateBotDialog = ({
as="h3"
className="text-lg font-medium leading-6 text-gray-400"
>
Grant Infisical access to your secrets
{t("integrations:grant-access-to-secrets")}
</Dialog.Title>
<div className="mt-2 mb-2">
<p className="text-sm text-gray-500">
Most cloud integrations require Infisical to be able to decrypt your secrets so they can be forwarded over.
{t("integrations:why-infisical-needs-access")}
</p>
</div>
<div className="mt-6 max-w-max">
<Button
onButtonPressed={submit}
color="mineshaft"
text="Grant access"
text={t("integrations:grant-access-button")}
size="md"
/>
</div>

View File

@@ -1,4 +1,5 @@
import { Fragment, useState } from "react";
import { useTranslation } from "next-i18next";
import { Dialog, Transition } from "@headlessui/react";
import addIncidentContact from "~/pages/api/organization/addIncidentContact";
@@ -14,6 +15,7 @@ const AddIncidentContactDialog = ({
setIncidentContacts,
}) => {
let [incidentContactEmail, setIncidentContactEmail] = useState("");
const { t } = useTranslation();
const submit = () => {
setIncidentContacts(
@@ -59,17 +61,16 @@ const AddIncidentContactDialog = ({
as="h3"
className="text-lg font-medium leading-6 text-gray-400"
>
Add an Incident Contact
{t("section-incident:add-dialog.title")}
</Dialog.Title>
<div className="mt-2 mb-2">
<p className="text-sm text-gray-500">
This contact will be notified in the unlikely event of a
severe incident.
{t("section-incident:add-dialog.description")}
</p>
</div>
<div className="max-h-28">
<InputField
label="Email"
label={t("common:email")}
onChangeHandler={setIncidentContactEmail}
type="varName"
value={incidentContactEmail}
@@ -81,7 +82,7 @@ const AddIncidentContactDialog = ({
<Button
onButtonPressed={submit}
color="mineshaft"
text="Add Incident Contact"
text={t("section-incident:add-dialog.add-incident")}
size="md"
/>
</div>

View File

@@ -1,5 +1,6 @@
import { Fragment, useState } from "react";
import { useRouter } from "next/router";
import { Trans, useTranslation } from "next-i18next";
import { Dialog, Transition } from "@headlessui/react";
import Button from "../buttons/Button";
@@ -15,6 +16,7 @@ const AddProjectMemberDialog = ({
setEmail,
}) => {
const router = useRouter();
const { t } = useTranslation();
return (
<div className="z-50">
@@ -49,48 +51,55 @@ const AddProjectMemberDialog = ({
as="h3"
className="text-lg font-medium leading-6 text-gray-400 z-50"
>
Add a member to your project
{t("section-members:add-dialog.add-member-to-project")}
</Dialog.Title>
) : (
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-400 z-50"
>
All the users in your organization are already invited.
{t("section-members:add-dialog.already-all-invited")}
</Dialog.Title>
)}
<div className="mt-2 mb-4">
{data?.length > 0 ? (
<div className="flex flex-col">
<p className="text-sm text-gray-500">
The user will receive an email with the instructions.
{t("section-members:add-dialog.user-will-email")}
</p>
<div className="">
<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"
onClick={() =>
router.push("/settings/org/" + router.query.id)
}
>
If you are looking to add users to your org,
</button>
<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"
onClick={() =>
router.push(
"/settings/org/" + router.query.id + "?invite"
)
}
>
click here.
</button>
<Trans
i18nKey="section-members:add-dialog.looking-add"
components={[
// eslint-disable-next-line react/jsx-key
<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"
onClick={() =>
router.push(
"/settings/org/" + router.query.id
)
}
/>,
// eslint-disable-next-line react/jsx-key
<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"
onClick={() =>
router.push(
"/settings/org/" +
router.query.id +
"?invite"
)
}
/>,
]}
/>
</div>
</div>
) : (
<p className="text-sm text-gray-500">
Add more users to the organization first.
{t("section-members:add-dialog.add-user-org-first")}
</p>
)}
</div>
@@ -110,7 +119,7 @@ const AddProjectMemberDialog = ({
<Button
onButtonPressed={submitModal}
color="mineshaft"
text="Add Member"
text={t("section-members:add-member")}
size="md"
/>
</div>
@@ -120,7 +129,7 @@ const AddProjectMemberDialog = ({
router.push("/settings/org/" + router.query.id)
}
color="mineshaft"
text="Add Users to Organization"
text={t("section-members:add-dialog.add-user-to-org")}
size="md"
/>
)}

View File

@@ -1,40 +1,42 @@
import { Fragment, useState } from 'react';
import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Dialog, Transition } from '@headlessui/react';
import nacl from 'tweetnacl';
import { Fragment, useState } from "react";
import { useTranslation } from "next-i18next";
import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Dialog, Transition } from "@headlessui/react";
import nacl from "tweetnacl";
import addServiceToken from '~/pages/api/serviceToken/addServiceToken';
import getLatestFileKey from '~/pages/api/workspace/getLatestFileKey';
import addServiceToken from "~/pages/api/serviceToken/addServiceToken";
import getLatestFileKey from "~/pages/api/workspace/getLatestFileKey";
import { envMapping } from '../../../public/data/frequentConstants';
import { envMapping } from "../../../public/data/frequentConstants";
import {
decryptAssymmetric,
encryptAssymmetric
} from '../../utilities/cryptography/crypto';
import Button from '../buttons/Button';
import InputField from '../InputField';
import ListBox from '../Listbox';
encryptAssymmetric,
} from "../../utilities/cryptography/crypto";
import Button from "../buttons/Button";
import InputField from "../InputField";
import ListBox from "../Listbox";
const expiryMapping = {
'1 day': 86400,
'7 days': 604800,
'1 month': 2592000,
'6 months': 15552000,
'12 months': 31104000
"1 day": 86400,
"7 days": 604800,
"1 month": 2592000,
"6 months": 15552000,
"12 months": 31104000,
};
const AddServiceTokenDialog = ({
isOpen,
closeModal,
workspaceId,
workspaceName
workspaceName,
}) => {
const [serviceToken, setServiceToken] = useState('');
const [serviceTokenName, setServiceTokenName] = useState('');
const [serviceTokenEnv, setServiceTokenEnv] = useState('Development');
const [serviceTokenExpiresIn, setServiceTokenExpiresIn] = useState('1 day');
const [serviceToken, setServiceToken] = useState("");
const [serviceTokenName, setServiceTokenName] = useState("");
const [serviceTokenEnv, setServiceTokenEnv] = useState("Development");
const [serviceTokenExpiresIn, setServiceTokenExpiresIn] = useState("1 day");
const [serviceTokenCopied, setServiceTokenCopied] = useState(false);
const { t } = useTranslation();
const generateServiceToken = async () => {
const latestFileKey = await getLatestFileKey({ workspaceId });
@@ -43,7 +45,7 @@ const AddServiceTokenDialog = ({
ciphertext: latestFileKey.latestKey.encryptedKey,
nonce: latestFileKey.latestKey.nonce,
publicKey: latestFileKey.latestKey.sender.publicKey,
privateKey: localStorage.getItem('PRIVATE_KEY')
privateKey: localStorage.getItem("PRIVATE_KEY"),
});
// generate new public/private key pair
@@ -55,7 +57,7 @@ const AddServiceTokenDialog = ({
const { ciphertext: encryptedKey, nonce } = encryptAssymmetric({
plaintext: key,
publicKey,
privateKey
privateKey,
});
let newServiceToken = await addServiceToken({
@@ -65,16 +67,16 @@ const AddServiceTokenDialog = ({
expiresIn: expiryMapping[serviceTokenExpiresIn],
publicKey,
encryptedKey,
nonce
nonce,
});
const serviceToken = newServiceToken + ',' + privateKey;
const serviceToken = newServiceToken + "," + privateKey;
setServiceToken(serviceToken);
};
function copyToClipboard() {
// Get the text field
var copyText = document.getElementById('serviceToken');
var copyText = document.getElementById("serviceToken");
// Select the text field
copyText.select();
@@ -91,8 +93,8 @@ const AddServiceTokenDialog = ({
const closeAddServiceTokenModal = () => {
closeModal();
setServiceTokenName('');
setServiceToken('');
setServiceTokenName("");
setServiceToken("");
};
return (
@@ -122,27 +124,26 @@ const AddServiceTokenDialog = ({
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
{serviceToken == '' ? (
{serviceToken == "" ? (
<Dialog.Panel className="w-full max-w-md transform rounded-md bg-bunker-800 border border-gray-700 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="text-lg font-medium leading-6 text-gray-400 z-50"
>
Add a service token for {workspaceName}
{t("section-token:add-dialog.title", {
target: workspaceName,
})}
</Dialog.Title>
<div className="mt-2 mb-4">
<div className="flex flex-col">
<p className="text-sm text-gray-500">
Specify the name, environment, and expiry period. When
a token is generated, you will only be able to see it
once before it disappears. Make sure to save it
somewhere.
{t("section-token:add-dialog.description")}
</p>
</div>
</div>
<div className="max-h-28 mb-2">
<InputField
label="Service Token Name"
label={t("section-token:add-dialog.name")}
onChangeHandler={setServiceTokenName}
type="varName"
value={serviceTokenName}
@@ -155,13 +156,13 @@ const AddServiceTokenDialog = ({
selected={serviceTokenEnv}
onChange={setServiceTokenEnv}
data={[
'Development',
'Staging',
'Production',
'Testing'
"Development",
"Staging",
"Production",
"Testing",
]}
isFull={true}
text="Environment: "
width="full"
text={`${t("common:environment")}: `}
/>
</div>
<div className="max-h-28">
@@ -169,14 +170,14 @@ const AddServiceTokenDialog = ({
selected={serviceTokenExpiresIn}
onChange={setServiceTokenExpiresIn}
data={[
'1 day',
'7 days',
'1 month',
'6 months',
'12 months'
"1 day",
"7 days",
"1 month",
"6 months",
"12 months",
]}
isFull={true}
text="Expires in: "
width="full"
text={`${t("common:expired-in")}: `}
/>
</div>
<div className="max-w-max">
@@ -184,10 +185,10 @@ const AddServiceTokenDialog = ({
<Button
onButtonPressed={() => generateServiceToken()}
color="mineshaft"
text="Add Service Token"
textDisabled="Add Service Token"
text={t("section-token:add-dialog.add")}
textDisabled={t("section-token:add-dialog.add")}
size="md"
active={serviceTokenName == '' ? false : true}
active={serviceTokenName == "" ? false : true}
/>
</div>
</div>
@@ -198,13 +199,14 @@ const AddServiceTokenDialog = ({
as="h3"
className="text-lg font-medium leading-6 text-gray-400 z-50"
>
Copy your service token
{t("section-token:add-dialog.copy-service-token")}
</Dialog.Title>
<div className="mt-2 mb-4">
<div className="flex flex-col">
<p className="text-sm text-gray-500">
Once you close this popup, you will never see your
service token again
{t(
"section-token:add-dialog.copy-service-token-description"
)}
</p>
</div>
</div>
@@ -234,7 +236,7 @@ const AddServiceTokenDialog = ({
)}
</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">
Click to Copy
{t("common.click-to-copy")}
</span>
</div>
</div>