Add eslint rule and fix as many issues as possible

This commit is contained in:
Khoa Le
2023-06-19 23:42:04 -04:00
parent e9eacc445d
commit 9d33e4756b
689 changed files with 9446 additions and 21821 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
const Error = ({ text }: { text: string }): JSX.Element => {
return (
+16 -16
View File
@@ -1,5 +1,5 @@
import React, { Fragment } from 'react';
import { useTranslation } from 'react-i18next';
import React, { Fragment } from "react";
import { useTranslation } from "react-i18next";
import {
faAngleDown,
faEye,
@@ -7,9 +7,9 @@ import {
faShuffle,
faTrash,
faX
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Listbox, Transition } from '@headlessui/react';
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Listbox, Transition } from "@headlessui/react";
interface ListBoxProps {
selected: string;
@@ -18,19 +18,19 @@ interface ListBoxProps {
const eventOptions = [
{
name: 'addSecrets',
name: "addSecrets",
icon: faPlus
},
{
name: 'readSecrets',
name: "readSecrets",
icon: faEye
},
{
name: 'updateSecrets',
name: "updateSecrets",
icon: faShuffle
},
{
name: 'deleteSecrets',
name: "deleteSecrets",
icon: faTrash
}
];
@@ -48,13 +48,13 @@ const EventFilter = ({ selected, select }: ListBoxProps): JSX.Element => {
<Listbox value={t(`activity.event.${selected}`)} onChange={select}>
<div className="relative">
<Listbox.Button className="flex h-10 w-52 cursor-pointer items-center justify-between rounded-md bg-mineshaft-800 pl-4 pr-2 text-sm text-bunker-200 duration-200 hover:bg-mineshaft-700">
{selected !== '' ? (
{selected !== "" ? (
<p className="select-none text-bunker-100">{t(`activity.event.${selected}`)}</p>
) : (
<p className="select-none">{String(t('common.select-event'))}</p>
<p className="select-none">{String(t("common.select-event"))}</p>
)}
{selected !== '' ? (
<FontAwesomeIcon icon={faX} className="w-2 p-2 pl-2" onClick={() => select('')} />
{selected !== "" ? (
<FontAwesomeIcon icon={faX} className="w-2 p-2 pl-2" onClick={() => select("")} />
) : (
<FontAwesomeIcon icon={faAngleDown} className="pl-4 pr-2" />
)}
@@ -70,15 +70,15 @@ const EventFilter = ({ selected, select }: ListBoxProps): JSX.Element => {
<Listbox.Option
key={`${event.name}.${id + 1}`}
className={`flex h-10 cursor-pointer items-center rounded-md px-4 text-sm text-bunker-200 hover:bg-mineshaft-700 ${
selected === t(`activity.event.${event.name}`) && 'bg-mineshaft-700'
selected === t(`activity.event.${event.name}`) && "bg-mineshaft-700"
}`}
value={event.name}
>
{({ selected: isSelected }) => (
<span
className={`block truncate ${isSelected ? 'font-semibold' : 'font-normal'}`}
className={`block truncate ${isSelected ? "font-semibold" : "font-normal"}`}
>
<FontAwesomeIcon icon={event.icon} className="pr-4" />{' '}
<FontAwesomeIcon icon={event.icon} className="pr-4" />{" "}
{t(`activity.event.${event.name}`)}
</span>
)}
+12 -12
View File
@@ -1,8 +1,8 @@
import { memo, useState } from 'react';
import { faCircle, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { memo, useState } from "react";
import { faCircle, faEye, faEyeSlash } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import guidGenerator from '../utilities/randomId';
import guidGenerator from "../utilities/randomId";
interface InputFieldProps {
isStatic?: boolean;
@@ -34,7 +34,7 @@ const InputField = ({
placeholder,
isStatic,
text
}: InputFieldProps & Pick<JSX.IntrinsicElements['input'], 'autoComplete' | 'id'>) => {
}: InputFieldProps & Pick<JSX.IntrinsicElements["input"], "autoComplete" | "id">) => {
const [passwordVisible, setPasswordVisible] = useState(false);
if (isStatic === true) {
@@ -64,28 +64,28 @@ const InputField = ({
</div>
<div
className={`group relative flex flex-col justify-center w-full max-w-2xl border ${
error ? 'border-red' : 'border-mineshaft-500'
error ? "border-red" : "border-mineshaft-500"
} rounded-md`}
>
<input
onChange={(e) => onChangeHandler(e.target.value)}
type={passwordVisible === false ? type : 'text'}
type={passwordVisible === false ? type : "text"}
placeholder={placeholder}
value={value}
required={isRequired}
className={`${
blurred
? '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"
: ""
} ${
error ? 'focus:ring-red/50' : 'focus:ring-primary/50'
error ? "focus:ring-red/50" : "focus:ring-primary/50"
} relative peer bg-mineshaft-900 rounded-md text-gray-400 text-md p-2 w-full min-w-16 outline-none focus:ring-4 duration-200`}
name={name}
spellCheck="false"
autoComplete={autoComplete}
id={id}
/>
{label?.includes('Password') && (
{label?.includes("Password") && (
<button
type="button"
onClick={() => {
@@ -104,7 +104,7 @@ const InputField = ({
<div className="peer group-hover:hidden peer-hover:hidden peer-focus:hidden peer-active:invisible absolute h-10 w-fit max-w-xl rounded-md flex items-center text-gray-400/50 text-clip overflow-hidden">
<p className="ml-2" />
{value
.split('')
.split("")
.slice(0, 54)
.map(() => (
<FontAwesomeIcon
+75 -75
View File
@@ -1,12 +1,12 @@
/* eslint-disable no-nested-ternary */
/* eslint-disable no-unexpected-multiline */
/* eslint-disable react-hooks/exhaustive-deps */
import crypto from 'crypto';
import crypto from "crypto";
import { useEffect, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect, useMemo, useState } from "react";
import { useTranslation } from "react-i18next";
import Link from "next/link";
import { useRouter } from "next/router";
import {
faBookOpen,
faFileLines,
@@ -16,25 +16,25 @@ import {
faPlug,
faPlus,
faUser
} from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import getOrganizations from '@app/pages/api/organization/getOrgs';
import getOrganizationUserProjects from '@app/pages/api/organization/GetOrgUserProjects';
import getOrganizationUsers from '@app/pages/api/organization/GetOrgUsers';
import getUser from '@app/pages/api/user/getUser';
import addUserToWorkspace from '@app/pages/api/workspace/addUserToWorkspace';
import createWorkspace from '@app/pages/api/workspace/createWorkspace';
import getWorkspaces from '@app/pages/api/workspace/getWorkspaces';
import uploadKeys from '@app/pages/api/workspace/uploadKeys';
import getOrganizations from "@app/pages/api/organization/getOrgs";
import getOrganizationUserProjects from "@app/pages/api/organization/GetOrgUserProjects";
import getOrganizationUsers from "@app/pages/api/organization/GetOrgUsers";
import getUser from "@app/pages/api/user/getUser";
import addUserToWorkspace from "@app/pages/api/workspace/addUserToWorkspace";
import createWorkspace from "@app/pages/api/workspace/createWorkspace";
import getWorkspaces from "@app/pages/api/workspace/getWorkspaces";
import uploadKeys from "@app/pages/api/workspace/uploadKeys";
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';
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";
interface LayoutProps {
children: React.ReactNode;
@@ -43,8 +43,8 @@ interface LayoutProps {
const Layout = ({ children }: LayoutProps) => {
const router = useRouter();
const [workspaceMapping, setWorkspaceMapping] = useState<Map<string, string>[]>([]);
const [workspaceSelected, setWorkspaceSelected] = useState('∞');
const [newWorkspaceName, setNewWorkspaceName] = useState('');
const [workspaceSelected, setWorkspaceSelected] = useState("∞");
const [newWorkspaceName, setNewWorkspaceName] = useState("");
const [isOpen, setIsOpen] = useState(false);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(false);
@@ -77,12 +77,12 @@ const Layout = ({ children }: LayoutProps) => {
if (!currentWorkspaces.includes(workspaceName)) {
const newWorkspace = await createWorkspace({
workspaceName,
organizationId: tempLocalStorage('orgData.id')
organizationId: tempLocalStorage("orgData.id")
});
const newWorkspaceId = newWorkspace._id;
const randomBytes = crypto.randomBytes(16).toString('hex');
const PRIVATE_KEY = String(localStorage.getItem('PRIVATE_KEY'));
const randomBytes = crypto.randomBytes(16).toString("hex");
const PRIVATE_KEY = String(localStorage.getItem("PRIVATE_KEY"));
const myUser = await getUser();
@@ -95,15 +95,15 @@ const Layout = ({ children }: LayoutProps) => {
await uploadKeys(newWorkspaceId, myUser._id, ciphertext, nonce);
if (addAllUsers) {
console.log('adding other users');
console.log("adding other users");
const orgUsers = await getOrganizationUsers({
orgId: tempLocalStorage('orgData.id')
orgId: tempLocalStorage("orgData.id")
});
orgUsers.map(async (user: any) => {
if (user.status === 'accepted' && user.email !== myUser.email) {
if (user.status === "accepted" && user.email !== myUser.email) {
const result = await addUserToWorkspace(user.user.email, newWorkspaceId);
if (result?.invitee && result?.latestKey) {
const TEMP_PRIVATE_KEY = tempLocalStorage('PRIVATE_KEY');
const TEMP_PRIVATE_KEY = tempLocalStorage("PRIVATE_KEY");
// assymmetrically decrypt symmetric key with local private key
const key = decryptAssymmetric({
@@ -130,9 +130,9 @@ const Layout = ({ children }: LayoutProps) => {
}));
setWorkspaceSelected(workspaceName);
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);
}
@@ -147,27 +147,27 @@ const Layout = ({ children }: LayoutProps) => {
() => [
{
href: `/dashboard/${workspaceMapping[workspaceSelected as any]}`,
title: t('nav.menu.secrets'),
title: t("nav.menu.secrets"),
emoji: <FontAwesomeIcon icon={faKey} />
},
{
href: `/users/${workspaceMapping[workspaceSelected as any]}`,
title: t('nav.menu.members'),
title: t("nav.menu.members"),
emoji: <FontAwesomeIcon icon={faUser} />
},
{
href: `/integrations/${workspaceMapping[workspaceSelected as any]}`,
title: t('nav.menu.integrations'),
title: t("nav.menu.integrations"),
emoji: <FontAwesomeIcon icon={faPlug} />
},
{
href: `/activity/${workspaceMapping[workspaceSelected as any]}`,
title: 'Audit Logs',
title: "Audit Logs",
emoji: <FontAwesomeIcon icon={faFileLines} />
},
{
href: `/settings/project/${workspaceMapping[workspaceSelected as any]}`,
title: t('nav.menu.project-settings'),
title: t("nav.menu.project-settings"),
emoji: <FontAwesomeIcon icon={faGear} />
}
],
@@ -178,35 +178,35 @@ const Layout = ({ children }: LayoutProps) => {
// 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('home') &&
!router.asPath.includes('settings')) ||
router.asPath === '/dashboard/undefined'
router.asPath !== "/noprojects" &&
!router.asPath.includes("home") &&
!router.asPath.includes("settings")) ||
router.asPath === "/dashboard/undefined"
) {
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 (!['callback', 'create', 'authorize'].includes(intendedWorkspaceId)) {
localStorage.setItem('projectData.id', intendedWorkspaceId);
if (!["callback", "create", "authorize"].includes(intendedWorkspaceId)) {
localStorage.setItem("projectData.id", intendedWorkspaceId);
}
// If a user is not a member of a workspace they are trying to access, just push them to one of theirs
if (
!['callback', 'create', 'authorize'].includes(intendedWorkspaceId) &&
!["callback", "create", "authorize"].includes(intendedWorkspaceId) &&
!userWorkspaces
.map((workspace: { _id: string }) => workspace._id)
.includes(intendedWorkspaceId)
@@ -221,7 +221,7 @@ const Layout = ({ children }: LayoutProps) => {
setWorkspaceSelected(
Object.fromEntries(
userWorkspaces.map((workspace: any) => [workspace._id, workspace.name])
)[router.asPath.split('/')[router.asPath.split('/').length - 1].split('?')[0]]
)[router.asPath.split("/")[router.asPath.split("/").length - 1].split("?")[0]]
);
}
}
@@ -235,9 +235,9 @@ const Layout = ({ children }: LayoutProps) => {
if (
workspaceMapping[workspaceSelected as any] &&
`${workspaceMapping[workspaceSelected as any]}` !==
router.asPath.split('/')[router.asPath.split('/').length - 1].split('?')[0]
router.asPath.split("/")[router.asPath.split("/").length - 1].split("?")[0]
) {
localStorage.setItem('projectData.id', `${workspaceMapping[workspaceSelected as any]}`);
localStorage.setItem("projectData.id", `${workspaceMapping[workspaceSelected as any]}`);
router.push(`/dashboard/${workspaceMapping[workspaceSelected as any]}`);
}
} catch (err) {
@@ -256,7 +256,7 @@ const Layout = ({ children }: LayoutProps) => {
<div>
<div className="mt-6 mb-6 flex h-20 w-full flex-col items-center justify-center bg-bunker-600 px-4">
<div className="ml-1 mb-1 self-start text-xs font-semibold tracking-wide text-gray-400">
{t('nav.menu.project')}
{t("nav.menu.project")}
</div>
{Object.keys(workspaceMapping).length > 0 ? (
<Listbox
@@ -280,11 +280,11 @@ const Layout = ({ children }: LayoutProps) => {
{Object.keys(workspaceMapping).length > 0 &&
menuItems.map(({ href, title, emoji }) => (
<li className="mx-2 mt-0.5" 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="relative flex cursor-pointer rounded bg-primary-50/10 px-0.5 py-2.5 text-sm text-white">
<div className="absolute inset-0 top-0 my-1 ml-1 mr-1 w-1 rounded-xl bg-primary" />
@@ -293,7 +293,7 @@ const Layout = ({ children }: LayoutProps) => {
</p>
{title}
</div>
) : router.asPath === '/noprojects' ? (
) : router.asPath === "/noprojects" ? (
<div className="flex rounded p-2.5 text-sm text-white">
<p className="flex w-10 items-center justify-center text-lg">{emoji}</p>
{title}
@@ -313,7 +313,7 @@ const Layout = ({ children }: LayoutProps) => {
</ul>
</div>
<div className="mt-40 mb-4 w-full px-2">
{router.asPath.split('/')[1] === 'home' ? (
{router.asPath.split("/")[1] === "home" ? (
<div className="relative flex cursor-pointer rounded bg-primary-50/10 px-0.5 py-2.5 text-sm text-white">
<div className="absolute inset-0 top-0 my-1 ml-1 mr-1 w-1 rounded-xl bg-primary" />
<p className="ml-4 mr-2 flex w-6 items-center justify-center text-lg">
@@ -321,12 +321,12 @@ const Layout = ({ children }: LayoutProps) => {
</p>
Infisical Guide
<img
src={`/images/progress-${totalOnboardingActionsDone === 0 ? '0' : ''}${
totalOnboardingActionsDone === 1 ? '14' : ''
}${totalOnboardingActionsDone === 2 ? '28' : ''}${
totalOnboardingActionsDone === 3 ? '43' : ''
}${totalOnboardingActionsDone === 4 ? '57' : ''}${
totalOnboardingActionsDone === 5 ? '71' : ''
src={`/images/progress-${totalOnboardingActionsDone === 0 ? "0" : ""}${
totalOnboardingActionsDone === 1 ? "14" : ""
}${totalOnboardingActionsDone === 2 ? "28" : ""}${
totalOnboardingActionsDone === 3 ? "43" : ""
}${totalOnboardingActionsDone === 4 ? "57" : ""}${
totalOnboardingActionsDone === 5 ? "71" : ""
}.svg`}
height={58}
width={58}
@@ -342,12 +342,12 @@ const Layout = ({ children }: LayoutProps) => {
</p>
Infisical Guide
<img
src={`/images/progress-${totalOnboardingActionsDone === 0 ? '0' : ''}${
totalOnboardingActionsDone === 1 ? '14' : ''
}${totalOnboardingActionsDone === 2 ? '28' : ''}${
totalOnboardingActionsDone === 3 ? '43' : ''
}${totalOnboardingActionsDone === 4 ? '57' : ''}${
totalOnboardingActionsDone === 5 ? '71' : ''
src={`/images/progress-${totalOnboardingActionsDone === 0 ? "0" : ""}${
totalOnboardingActionsDone === 1 ? "14" : ""
}${totalOnboardingActionsDone === 2 ? "28" : ""}${
totalOnboardingActionsDone === 3 ? "43" : ""
}${totalOnboardingActionsDone === 4 ? "57" : ""}${
totalOnboardingActionsDone === 5 ? "71" : ""
}.svg`}
height={58}
width={58}
@@ -375,7 +375,7 @@ const Layout = ({ children }: LayoutProps) => {
<div className="flex h-screen w-screen flex-col items-center justify-center bg-bunker-800 z-[200] md:hidden">
<FontAwesomeIcon icon={faMobile} className="mb-8 text-7xl text-gray-300" />
<p className="max-w-sm px-6 text-center text-lg text-gray-200">
{` ${t('common.no-mobile')} `}
{` ${t("common.no-mobile")} `}
</p>
</div>
</>
+10 -10
View File
@@ -1,7 +1,7 @@
import React, { Fragment } from 'react';
import { faAngleDown, faCheck, faPlus } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Listbox, Transition } from '@headlessui/react';
import React, { Fragment } from "react";
import { faAngleDown, faCheck, faPlus } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Listbox, Transition } from "@headlessui/react";
interface ListBoxProps {
isSelected: string;
@@ -35,13 +35,13 @@ const ListBox = ({
<div className="relative">
<Listbox.Button
className={`text-gray-400 relative ${
isFull ? 'w-full' : 'w-52'
isFull ? "w-full" : "w-52"
} cursor-default rounded-md bg-white/[0.07] hover:bg-white/[0.11] duration-200 py-2.5 pl-3 pr-10 text-left shadow-md focus:outline-none focus-visible:border-indigo-500 focus-visible:ring-2 focus-visible:ring-white focus-visible:ring-opacity-75 focus-visible:ring-offset-2 focus-visible:ring-offset-orange-300 sm:text-sm`}
>
<div className="flex flex-row">
{text}
<span className="ml-1 cursor-pointer block truncate font-semibold text-gray-300">
{' '}
{" "}
{isSelected}
</span>
</div>
@@ -64,11 +64,11 @@ const ListBox = ({
key={`${person}.${personIdx + 1}`}
className={({ active, selected }) =>
`my-0.5 relative cursor-default select-none py-2 pl-10 pr-4 rounded-md ${
selected ? 'bg-white/10 text-gray-400 font-bold' : ''
selected ? "bg-white/10 text-gray-400 font-bold" : ""
} ${
active && !selected
? 'bg-white/5 text-mineshaft-200 cursor-pointer'
: 'text-gray-400'
? "bg-white/5 text-mineshaft-200 cursor-pointer"
: "text-gray-400"
} `
}
value={person}
@@ -77,7 +77,7 @@ const ListBox = ({
<>
<span
className={`block truncate text-primary${
selected ? 'font-medium' : 'font-normal'
selected ? "font-medium" : "font-normal"
}`}
>
{person}
+4 -4
View File
@@ -1,4 +1,4 @@
import { Switch } from '@headlessui/react';
import { Switch } from "@headlessui/react";
interface ToggleProps {
enabled: boolean;
@@ -22,20 +22,20 @@ const Toggle = ({ enabled, setEnabled, addOverride, id }: ToggleProps): JSX.Elem
checked={enabled}
onChange={() => {
if (enabled === false) {
addOverride('', id);
addOverride("", id);
} else {
addOverride(undefined, id);
}
setEnabled(!enabled);
}}
className={`${
enabled ? 'bg-primary' : 'bg-bunker-400'
enabled ? "bg-primary" : "bg-bunker-400"
} relative inline-flex h-5 w-9 items-center rounded-full`}
>
<span className="sr-only">Enable notifications</span>
<span
className={`${
enabled ? 'translate-x-[1.26rem]' : 'translate-x-0.5'
enabled ? "translate-x-[1.26rem]" : "translate-x-0.5"
} inline-block h-3.5 w-3.5 transform rounded-full bg-bunker-800 transition`}
/>
</Switch>
@@ -1,10 +1,10 @@
/* eslint-disable react/button-has-type */
import React, { ButtonHTMLAttributes } from 'react';
import Image from 'next/image';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { ButtonHTMLAttributes } from "react";
import Image from "next/image";
import { IconProp } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
const classNames = require('classnames');
const classNames = require("classnames");
type ButtonProps = {
text?: string;
@@ -47,49 +47,49 @@ const Button = ({
}: ButtonProps): JSX.Element => {
// Check if the button show always be 'active' - then true;
// or if it should switch between 'active' and 'disabled' - then give the status
const activityStatus = active || (text !== '' && textDisabled === undefined);
const activityStatus = active || (text !== "" && textDisabled === undefined);
const 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",
// Setting background colors and hover modes
color === 'mineshaft' && activityStatus && 'bg-mineshaft-800 border border-mineshaft-600 hover:bg-primary/[0.15] hover:border-primary/60',
color === 'mineshaft' && !activityStatus && 'bg-mineshaft',
(color === 'primary' || !color) && activityStatus && 'bg-primary border border-primary-400 opacity-80 hover:opacity-100',
(color === 'primary' || !color) && !activityStatus && 'bg-primary',
color === 'red' && 'bg-red-800 border border-red',
color === "mineshaft" && activityStatus && "bg-mineshaft-800 border border-mineshaft-600 hover:bg-primary/[0.15] hover:border-primary/60",
color === "mineshaft" && !activityStatus && "bg-mineshaft",
(color === "primary" || !color) && activityStatus && "bg-primary border border-primary-400 opacity-80 hover:opacity-100",
(color === "primary" || !color) && !activityStatus && "bg-primary",
color === "red" && "bg-red-800 border border-red",
// Changing the opacity when active vs when not
activityStatus ? 'opacity-100 cursor-pointer' : 'opacity-40',
activityStatus ? "opacity-100 cursor-pointer" : "opacity-40",
// Setting the button sizes
size === 'md' && 'h-10 w-full px-2 md:px-4',
size === 'lg' && 'h-12 w-full px-2 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-sm' && 'h-9 w-9 flex items-center justify-center'
size === "md" && "h-10 w-full px-2 md:px-4",
size === "lg" && "h-12 w-full px-2 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-sm" && "h-9 w-9 flex items-center justify-center"
);
const styleMainDiv = classNames(
'relative font-medium flex items-center',
"relative font-medium flex items-center",
// Setting the text color for the text and icon
color === 'mineshaft' && 'text-bunker-200',
color !== 'mineshaft' && color !== 'red' && color !== 'none' && 'text-black',
color === 'red' && 'text-gray-200',
color === 'none' && 'text-gray-200 text-xl',
activityStatus && color !== 'red' && color !== 'mineshaft' && color !== 'none' ? 'group-hover:text-black' : '',
color === "mineshaft" && "text-bunker-200",
color !== "mineshaft" && color !== "red" && color !== "none" && "text-black",
color === "red" && "text-gray-200",
color === "none" && "text-gray-200 text-xl",
activityStatus && color !== "red" && color !== "mineshaft" && color !== "none" ? "group-hover:text-black" : "",
size === 'icon' && 'flex items-center justify-center'
size === "icon" && "flex items-center justify-center"
);
const textStyle = classNames(
'relative duration-200 text-center w-full',
"relative duration-200 text-center w-full",
// Show the loading sign if the loading indicator is on
loading ? 'opacity-0' : 'opacity-100',
size === 'md' && 'text-sm',
size === 'lg' && 'text-lg'
loading ? "opacity-0" : "opacity-100",
size === "md" && "text-sm",
size === "lg" && "text-lg"
);
const button = (
@@ -102,7 +102,7 @@ const Button = ({
<div className={styleMainDiv}>
<div
className={`${
loading === true ? 'opacity-100' : 'opacity-0'
loading === true ? "opacity-100" : "opacity-0"
} absolute flex items-center px-3 bg-primary duration-200 w-full`}
>
<Image
@@ -116,16 +116,16 @@ const Button = ({
{icon && (
<FontAwesomeIcon
icon={icon}
className={`flex my-auto font-extrabold ${size === 'icon-sm' ? 'text-sm' : 'text-sm'} ${
(text || textDisabled) && 'mr-2'
className={`flex my-auto font-extrabold ${size === "icon-sm" ? "text-sm" : "text-sm"} ${
(text || textDisabled) && "mr-2"
}`}
/>
)}
{iconDisabled && (
<FontAwesomeIcon
icon={iconDisabled as IconProp}
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"
}`}
/>
)}
@@ -1,8 +1,8 @@
import { Fragment } from 'react';
import { useTranslation } from 'react-i18next';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from "react";
import { useTranslation } from "react-i18next";
import { Dialog, Transition } from "@headlessui/react";
import Button from '../buttons/Button';
import Button from "../buttons/Button";
interface IntegrationOption {
clientId: string;
@@ -72,18 +72,18 @@ const ActivateBotDialog = ({
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-gray-700 bg-bunker-800 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-400">
{t('integrations.grant-access-to-secrets')}
{t("integrations.grant-access-to-secrets")}
</Dialog.Title>
<div className="mt-2 mb-2">
<p className="text-sm text-gray-500">
{t('integrations.why-infisical-needs-access')}
{t("integrations.why-infisical-needs-access")}
</p>
</div>
<div className="mt-6 max-w-max">
<Button
onButtonPressed={submit}
color="mineshaft"
text={t('integrations.grant-access-button') as string}
text={t("integrations.grant-access-button") as string}
size="md"
/>
</div>
@@ -1,21 +1,21 @@
import { Fragment, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Dialog, Transition } from "@headlessui/react";
import addAPIKey from '@app/pages/api/apiKey/addAPIKey';
import addAPIKey from "@app/pages/api/apiKey/addAPIKey";
import Button from '../buttons/Button';
import InputField from '../InputField';
import ListBox from '../Listbox';
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
};
type Props = {
@@ -28,9 +28,9 @@ type Props = {
// TODO: convert to TS
const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) => {
const [apiKey, setApiKey] = useState('');
const [apiKeyName, setApiKeyName] = useState('');
const [apiKeyExpiresIn, setApiKeyExpiresIn] = useState('1 day');
const [apiKey, setApiKey] = useState("");
const [apiKeyName, setApiKeyName] = useState("");
const [apiKeyExpiresIn, setApiKeyExpiresIn] = useState("1 day");
const [apiKeyCopied, setApiKeyCopied] = useState(false);
const { t } = useTranslation();
@@ -46,7 +46,7 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
function copyToClipboard() {
// Get the text field
const copyText = document.getElementById('apiKey') as HTMLInputElement;
const copyText = document.getElementById("apiKey") as HTMLInputElement;
// Select the text field
copyText.select();
@@ -63,8 +63,8 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
const closeAddApiKeyModal = () => {
closeModal();
setApiKeyName('');
setApiKey('');
setApiKeyName("");
setApiKey("");
};
return (
@@ -94,24 +94,24 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
leaveFrom="opacity-100 scale-100"
leaveTo="opacity-0 scale-95"
>
{apiKey === '' ? (
{apiKey === "" ? (
<Dialog.Panel className="w-full max-w-md transform rounded-md border border-gray-700 bg-bunker-800 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="z-50 text-lg font-medium leading-6 text-gray-400"
>
{t('section.api-key.add-dialog.title')}
{t("section.api-key.add-dialog.title")}
</Dialog.Title>
<div className="mt-2 mb-4">
<div className="flex flex-col">
<p className="text-sm text-gray-500">
{t('section.api-key.add-dialog.description')}
{t("section.api-key.add-dialog.description")}
</p>
</div>
</div>
<div className="mb-2 max-h-28">
<InputField
label={t('section.api-key.add-dialog.name')}
label={t("section.api-key.add-dialog.name")}
onChangeHandler={setApiKeyName}
type="varName"
value={apiKeyName}
@@ -123,9 +123,9 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
<ListBox
isSelected={apiKeyExpiresIn}
onChange={setApiKeyExpiresIn}
data={['1 day', '7 days', '1 month', '6 months', '12 months']}
data={["1 day", "7 days", "1 month", "6 months", "12 months"]}
isFull
text={`${t('common.expired-in')}: `}
text={`${t("common.expired-in")}: `}
/>
</div>
<div className="max-w-max">
@@ -133,10 +133,10 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
<Button
onButtonPressed={() => generateAPIKey()}
color="mineshaft"
text={t('section.api-key.add-dialog.add') as string}
textDisabled={t('section.api-key.add-dialog.add') as string}
text={t("section.api-key.add-dialog.add") as string}
textDisabled={t("section.api-key.add-dialog.add") as string}
size="md"
active={apiKeyName !== ''}
active={apiKeyName !== ""}
/>
</div>
</div>
@@ -147,12 +147,12 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
as="h3"
className="z-50 text-lg font-medium leading-6 text-gray-400"
>
{t('section.api-key.add-dialog.copy-service-token')}
{t("section.api-key.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">
{t('section.api-key.add-dialog.copy-service-token-description')}
{t("section.api-key.add-dialog.copy-service-token-description")}
</p>
</div>
</div>
@@ -181,7 +181,7 @@ const AddApiKeyDialog = ({ isOpen, closeModal, apiKeys, setApiKeys }: Props) =>
)}
</button>
<span className="absolute -left-8 -top-20 hidden w-28 translate-y-full rounded-md bg-chicago-900 px-3 py-2 text-center text-sm text-gray-400 duration-300 group-hover:flex group-hover:animate-popup">
{t('common.click-to-copy')}
{t("common.click-to-copy")}
</span>
</div>
</div>
@@ -1,11 +1,11 @@
import { Fragment, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import { Dialog, Transition } from "@headlessui/react";
import addIncidentContact from '@app/pages/api/organization/addIncidentContact';
import addIncidentContact from "@app/pages/api/organization/addIncidentContact";
import Button from '../buttons/Button';
import InputField from '../InputField';
import Button from "../buttons/Button";
import InputField from "../InputField";
type Props = {
isOpen: boolean;
@@ -20,7 +20,7 @@ const AddIncidentContactDialog = ({
incidentContacts,
setIncidentContacts
}: Props) => {
const [incidentContactEmail, setIncidentContactEmail] = useState('');
const [incidentContactEmail, setIncidentContactEmail] = useState("");
const { t } = useTranslation();
const submit = () => {
@@ -29,7 +29,7 @@ const AddIncidentContactDialog = ({
? incidentContacts.concat([incidentContactEmail])
: [incidentContactEmail]
);
addIncidentContact(localStorage.getItem('orgData.id') as string, incidentContactEmail);
addIncidentContact(localStorage.getItem("orgData.id") as string, incidentContactEmail);
closeModal();
};
return (
@@ -61,16 +61,16 @@ const AddIncidentContactDialog = ({
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md border border-gray-700 bg-bunker-800 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-gray-400">
{t('section.incident.add-dialog.title')}
{t("section.incident.add-dialog.title")}
</Dialog.Title>
<div className="mt-2 mb-2">
<p className="text-sm text-gray-500">
{t('section.incident.add-dialog.description')}
{t("section.incident.add-dialog.description")}
</p>
</div>
<div className="max-h-28">
<InputField
label={t('common.email')}
label={t("common.email")}
onChangeHandler={setIncidentContactEmail}
type="varName"
value={incidentContactEmail}
@@ -82,7 +82,7 @@ const AddIncidentContactDialog = ({
<Button
onButtonPressed={submit}
color="mineshaft"
text={t('section.incident.add-dialog.add-incident') as string}
text={t("section.incident.add-dialog.add-incident") as string}
size="md"
/>
</div>
@@ -1,10 +1,10 @@
import { Fragment } from 'react';
import { Trans, useTranslation } from 'react-i18next';
import { useRouter } from 'next/router';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from "react";
import { Trans, useTranslation } from "react-i18next";
import { useRouter } from "next/router";
import { Dialog, Transition } from "@headlessui/react";
import Button from '../buttons/Button';
import ListBox from '../Listbox';
import Button from "../buttons/Button";
import ListBox from "../Listbox";
type Props = {
isOpen: boolean;
@@ -59,21 +59,21 @@ const AddProjectMemberDialog = ({
as="h3"
className="z-50 text-lg font-medium leading-6 text-gray-400"
>
{t('section.members.add-dialog.add-member-to-project')}
{t("section.members.add-dialog.add-member-to-project")}
</Dialog.Title>
) : (
<Dialog.Title
as="h3"
className="z-50 text-lg font-medium text-mineshaft-300 mb-4"
>
{t('section.members.add-dialog.already-all-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">
{t('section.members.add-dialog.user-will-email')}
{t("section.members.add-dialog.user-will-email")}
</p>
<div className="">
<Trans
@@ -101,7 +101,7 @@ const AddProjectMemberDialog = ({
</div>
) : (
<p className="text-sm text-gray-500">
{t('section.members.add-dialog.add-user-org-first')}
{t("section.members.add-dialog.add-user-org-first")}
</p>
)}
</div>
@@ -121,7 +121,7 @@ const AddProjectMemberDialog = ({
<Button
onButtonPressed={submitModal}
color="mineshaft"
text={t('section.members.add-member') as string}
text={t("section.members.add-member") as string}
size="md"
/>
</div>
@@ -129,7 +129,7 @@ const AddProjectMemberDialog = ({
<Button
onButtonPressed={() => router.push(`/settings/org/${router.query.id}`)}
color="mineshaft"
text={t('section.members.add-dialog.add-user-to-org') as string}
text={t("section.members.add-dialog.add-user-to-org") as string}
size="md"
/>
)}
@@ -1,25 +1,25 @@
import crypto from 'crypto';
import crypto from "crypto";
import { Fragment, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { faCheck, faCopy } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment, useState } from "react";
import { useTranslation } from "react-i18next";
import { faCheck, faCopy } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Dialog, Transition } from "@headlessui/react";
import addServiceToken from '@app/pages/api/serviceToken/addServiceToken';
import getLatestFileKey from '@app/pages/api/workspace/getLatestFileKey';
import addServiceToken from "@app/pages/api/serviceToken/addServiceToken";
import getLatestFileKey from "@app/pages/api/workspace/getLatestFileKey";
import { decryptAssymmetric, encryptSymmetric } from '../../utilities/cryptography/crypto';
import Button from '../buttons/Button';
import InputField from '../InputField';
import ListBox from '../Listbox';
import { decryptAssymmetric, encryptSymmetric } 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
};
type Props = {
@@ -41,10 +41,10 @@ const AddServiceTokenDialog = ({
environments,
setServiceTokens
}: Props) => {
const [serviceToken, setServiceToken] = useState('');
const [serviceTokenName, setServiceTokenName] = useState('');
const [serviceToken, setServiceToken] = useState("");
const [serviceTokenName, setServiceTokenName] = useState("");
const [selectedServiceTokenEnv, setSelectedServiceTokenEnv] = useState(environments?.[0]);
const [serviceTokenExpiresIn, setServiceTokenExpiresIn] = useState('1 day');
const [serviceTokenExpiresIn, setServiceTokenExpiresIn] = useState("1 day");
const [serviceTokenCopied, setServiceTokenCopied] = useState(false);
const { t } = useTranslation();
@@ -55,10 +55,10 @@ const AddServiceTokenDialog = ({
ciphertext: latestFileKey.latestKey.encryptedKey,
nonce: latestFileKey.latestKey.nonce,
publicKey: latestFileKey.latestKey.sender.publicKey,
privateKey: localStorage.getItem('PRIVATE_KEY') as string
privateKey: localStorage.getItem("PRIVATE_KEY") as string
});
const randomBytes = crypto.randomBytes(16).toString('hex');
const randomBytes = crypto.randomBytes(16).toString("hex");
const { ciphertext, iv, tag } = encryptSymmetric({
plaintext: key,
key: randomBytes
@@ -88,7 +88,7 @@ const AddServiceTokenDialog = ({
function copyToClipboard() {
// Get the text field
const copyText = document.getElementById('serviceToken') as HTMLInputElement;
const copyText = document.getElementById("serviceToken") as HTMLInputElement;
// Select the text field
copyText.select();
@@ -105,8 +105,8 @@ const AddServiceTokenDialog = ({
const closeAddServiceTokenModal = () => {
closeModal();
setServiceTokenName('');
setServiceToken('');
setServiceTokenName("");
setServiceToken("");
};
return (
@@ -136,26 +136,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 border border-gray-700 bg-bunker-800 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title
as="h3"
className="z-50 text-lg font-medium leading-6 text-gray-400"
>
{t('section.token.add-dialog.title', {
{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">
{t('section.token.add-dialog.description')}
{t("section.token.add-dialog.description")}
</p>
</div>
</div>
<div className="mb-2 max-h-28">
<InputField
label={t('section.token.add-dialog.name')}
label={t("section.token.add-dialog.name")}
onChangeHandler={setServiceTokenName}
type="varName"
value={serviceTokenName}
@@ -174,22 +174,22 @@ const AddServiceTokenDialog = ({
onChange={(envName) =>
setSelectedServiceTokenEnv(
environments.find(({ name }) => envName === name) || {
name: 'unknown',
slug: 'unknown'
name: "unknown",
slug: "unknown"
}
)
}
isFull
text={`${t('common.environment')}: `}
text={`${t("common.environment")}: `}
/>
</div>
<div className="max-h-28">
<ListBox
isSelected={serviceTokenExpiresIn}
onChange={setServiceTokenExpiresIn}
data={['1 day', '7 days', '1 month', '6 months', '12 months']}
data={["1 day", "7 days", "1 month", "6 months", "12 months"]}
isFull
text={`${t('common.expired-in')}: `}
text={`${t("common.expired-in")}: `}
/>
</div>
<div className="max-w-max">
@@ -197,10 +197,10 @@ const AddServiceTokenDialog = ({
<Button
onButtonPressed={() => generateServiceToken()}
color="mineshaft"
text={t('section.token.add-dialog.add') as string}
textDisabled={t('section.token.add-dialog.add') as string}
text={t("section.token.add-dialog.add") as string}
textDisabled={t("section.token.add-dialog.add") as string}
size="md"
active={serviceTokenName !== ''}
active={serviceTokenName !== ""}
/>
</div>
</div>
@@ -211,12 +211,12 @@ const AddServiceTokenDialog = ({
as="h3"
className="z-50 text-lg font-medium leading-6 text-gray-400"
>
{t('section.token.add-dialog.copy-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">
{t('section.token.add-dialog.copy-service-token-description')}
{t("section.token.add-dialog.copy-service-token-description")}
</p>
</div>
</div>
@@ -244,7 +244,7 @@ const AddServiceTokenDialog = ({
)}
</button>
<span className="absolute -left-8 -top-20 hidden w-28 translate-y-full rounded-md bg-chicago-900 px-3 py-2 text-center text-sm text-gray-400 duration-300 group-hover:flex group-hover:animate-popup">
{t('common.click-to-copy')}
{t("common.click-to-copy")}
</span>
</div>
</div>
@@ -1,8 +1,8 @@
import { FormEventHandler, Fragment, useEffect, useState } from 'react';
import { Dialog, Transition } from '@headlessui/react';
import { FormEventHandler, Fragment, useEffect, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import Button from '../buttons/Button';
import InputField from '../InputField';
import Button from "../buttons/Button";
import InputField from "../InputField";
type FormFields = { name: string; slug: string };
@@ -31,14 +31,14 @@ export const AddUpdateEnvironmentDialog = ({
isEditMode,
}: Props) => {
const [formInput, setFormInput] = useState<FormFields>({
name: '',
slug: '',
name: "",
slug: "",
});
// This use effect can be removed when the unmount is happening from outside the component
// When unmount happens outside state gets unmounted also
useEffect(() => {
setFormInput(initialValues || { name: '', slug: '' });
setFormInput(initialValues || { name: "", slug: "" });
}, [isOpen]);
// REFACTOR: Move to react-hook-form with yup for better form management
@@ -92,14 +92,14 @@ export const AddUpdateEnvironmentDialog = ({
className='text-lg font-medium leading-6 text-gray-400'
>
{isEditMode
? 'Update environment'
: 'Create a new environment'}
? "Update environment"
: "Create a new environment"}
</Dialog.Title>
<form onSubmit={onFormSubmit}>
<div className='max-h-28 mt-4'>
<InputField
label='Environment Name'
onChangeHandler={(val) => onInputChange('name', val)}
onChangeHandler={(val) => onInputChange("name", val)}
type='varName'
value={formInput.name}
placeholder=''
@@ -111,7 +111,7 @@ export const AddUpdateEnvironmentDialog = ({
<div className='max-h-28 mt-4'>
<InputField
label='Environment Slug'
onChangeHandler={(val) => onInputChange('slug', val)}
onChangeHandler={(val) => onInputChange("slug", val)}
type='varName'
value={formInput.slug}
placeholder=''
@@ -128,8 +128,8 @@ export const AddUpdateEnvironmentDialog = ({
onButtonPressed={() => null}
type='submit'
color='mineshaft'
text={isEditMode ? 'Update' : 'Create'}
active={formInput.name !== '' && formInput.slug !== ''}
text={isEditMode ? "Update" : "Create"}
active={formInput.name !== "" && formInput.slug !== ""}
size='md'
/>
</div>
@@ -1,8 +1,8 @@
import { Fragment } from 'react';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from "react";
import { Dialog, Transition } from "@headlessui/react";
import Button from '../buttons/Button';
import InputField from '../InputField';
import Button from "../buttons/Button";
import InputField from "../InputField";
type Props = {
isOpen: boolean;
@@ -1,7 +1,7 @@
import { Fragment, useEffect, useState } from 'react';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment, useEffect, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import InputField from '../InputField';
import InputField from "../InputField";
// REFACTOR: Move all these modals into one reusable one
type Props = {
@@ -47,11 +47,11 @@ export const DeleteEnvVar = ({ isOpen, onClose, onSubmit }: Props) => {
>
<Dialog.Panel className="w-full max-w-md transform overflow-hidden rounded-md bg-bunker border border-mineshaft-600 p-6 text-left align-middle shadow-xl transition-all">
<Dialog.Title as="h3" className="text-lg font-medium leading-6 text-bunker-200">
{t('dashboard:sidebar.delete-key-dialog.title')}
{t("dashboard:sidebar.delete-key-dialog.title")}
</Dialog.Title>
<div className="mt-2">
<p className="text-sm text-bunker-300">
{t('dashboard:sidebar.delete-key-dialog.confirm-delete-message')}
{t("dashboard:sidebar.delete-key-dialog.confirm-delete-message")}
</p>
</div>
<div className="mt-6 flex justify-start">
@@ -1,5 +1,5 @@
import { Fragment } from 'react';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from "react";
import { Dialog, Transition } from "@headlessui/react";
// #TODO: USE THIS. Currently it's not. Kinda complicated to set up because of state.
@@ -1,6 +1,6 @@
import { Fragment } from 'react';
import { useRouter } from 'next/router';
import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from "react";
import { useRouter } from "next/router";
import { Dialog, Transition } from "@headlessui/react";
// REFACTOR: Move all these modals into one reusable one
type Props = {
@@ -1,5 +1,5 @@
import { faXmark } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faXmark } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
interface PopupProps {
buttonText: string;
@@ -1,10 +1,10 @@
import { faX } from '@fortawesome/free-solid-svg-icons';
import { faX } from "@fortawesome/free-solid-svg-icons";
import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import deleteAPIKey from '../../../pages/api/apiKey/deleteAPIKey';
import guidGenerator from '../../utilities/randomId';
import Button from '../buttons/Button';
import deleteAPIKey from "../../../pages/api/apiKey/deleteAPIKey";
import guidGenerator from "../../utilities/randomId";
import Button from "../buttons/Button";
interface TokenProps {
_id: string;
@@ -58,7 +58,7 @@ const ApiKeyTable = ({ data, setApiKeys }: ServiceTokensProps) => {
setApiKeys(data.filter((token) => token._id !== row._id));
createNotification({
text: `'${row.name}' API key has been revoked.`,
type: 'error'
type: "error"
});
}}
color="red"
@@ -1,13 +1,13 @@
import { useEffect, useState } from 'react';
import { faPencil, faPlus, faX } from '@fortawesome/free-solid-svg-icons';
import { plans } from 'public/data/frequentConstants';
import { useEffect, useState } from "react";
import { faPencil, faPlus, faX } from "@fortawesome/free-solid-svg-icons";
import { plans } from "public/data/frequentConstants";
import { usePopUp } from '../../../hooks/usePopUp';
import getOrganizationSubscriptions from '../../../pages/api/organization/GetOrgSubscription';
import Button from '../buttons/Button';
import { AddUpdateEnvironmentDialog } from '../dialog/AddUpdateEnvironmentDialog';
import DeleteActionModal from '../dialog/DeleteActionModal';
import UpgradePlanModal from '../dialog/UpgradePlan';
import { usePopUp } from "../../../hooks/usePopUp";
import getOrganizationSubscriptions from "../../../pages/api/organization/GetOrgSubscription";
import Button from "../buttons/Button";
import { AddUpdateEnvironmentDialog } from "../dialog/AddUpdateEnvironmentDialog";
import DeleteActionModal from "../dialog/DeleteActionModal";
import UpgradePlanModal from "../dialog/UpgradePlan";
type Env = { name: string; slug: string };
@@ -20,17 +20,17 @@ type Props = {
const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }: Props) => {
const { popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([
'createUpdateEnv',
'deleteEnv',
'upgradePlan'
"createUpdateEnv",
"deleteEnv",
"upgradePlan"
] as const);
const [plan, setPlan] = useState('');
const [plan, setPlan] = useState("");
const host = window.location.origin;
useEffect(() => {
// on initial load - run auth check
(async () => {
const orgId = localStorage.getItem('orgData.id') as string;
const orgId = localStorage.getItem("orgData.id") as string;
const subscriptions = await getOrganizationSubscriptions({
orgId
});
@@ -44,7 +44,7 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
const onEnvCreateCB = async (env: Env) => {
try {
await onCreateEnv(env);
handlePopUpClose('createUpdateEnv');
handlePopUpClose("createUpdateEnv");
} catch (error) {
console.error(error);
}
@@ -52,8 +52,8 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
const onEnvUpdateCB = async (env: Env) => {
try {
await onUpdateEnv((popUp.createUpdateEnv?.data as Pick<Env, 'slug'>)?.slug, env);
handlePopUpClose('createUpdateEnv');
await onUpdateEnv((popUp.createUpdateEnv?.data as Pick<Env, "slug">)?.slug, env);
handlePopUpClose("createUpdateEnv");
} catch (error) {
console.error(error);
}
@@ -61,8 +61,8 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
const onEnvDeleteCB = async () => {
try {
await onDeleteEnv((popUp.deleteEnv?.data as Pick<Env, 'slug'>)?.slug);
handlePopUpClose('deleteEnv');
await onDeleteEnv((popUp.deleteEnv?.data as Pick<Env, "slug">)?.slug);
handlePopUpClose("deleteEnv");
} catch (error) {
console.error(error);
}
@@ -85,10 +85,10 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
<Button
text="Add New Environment"
onButtonPressed={() => {
if (plan !== plans.starter || host !== 'https://app.infisical.com' || localStorage.getItem('projectData.id') === '63ea8121b6e2b0543ba79616') {
handlePopUpOpen('createUpdateEnv');
if (plan !== plans.starter || host !== "https://app.infisical.com" || localStorage.getItem("projectData.id") === "63ea8121b6e2b0543ba79616") {
handlePopUpOpen("createUpdateEnv");
} else {
handlePopUpOpen('upgradePlan');
handlePopUpOpen("upgradePlan");
}
}}
color="mineshaft"
@@ -117,10 +117,10 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
<div className="mr-2 flex items-center duration-200 hover:opacity-100">
<Button
onButtonPressed={() => {
if (plan !== plans.starter || host !== 'https://app.infisical.com') {
handlePopUpOpen('createUpdateEnv', { name, slug });
if (plan !== plans.starter || host !== "https://app.infisical.com") {
handlePopUpOpen("createUpdateEnv", { name, slug });
} else {
handlePopUpOpen('upgradePlan');
handlePopUpOpen("upgradePlan");
}
}}
color="mineshaft"
@@ -131,10 +131,10 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
<div className="mr-6 flex items-center opacity-50 duration-200 hover:opacity-100">
<Button
onButtonPressed={() => {
if (plan !== plans.starter || host !== 'https://app.infisical.com') {
handlePopUpOpen('deleteEnv', { name, slug });
if (plan !== plans.starter || host !== "https://app.infisical.com") {
handlePopUpOpen("deleteEnv", { name, slug });
} else {
handlePopUpOpen('upgradePlan');
handlePopUpOpen("upgradePlan");
}
}}
color="red"
@@ -157,23 +157,23 @@ const EnvironmentTable = ({ data = [], onCreateEnv, onDeleteEnv, onUpdateEnv }:
<DeleteActionModal
isOpen={popUp.deleteEnv.isOpen}
title={`Are you sure want to delete ${
(popUp?.deleteEnv?.data as { name: string })?.name || ' '
(popUp?.deleteEnv?.data as { name: string })?.name || " "
}?`}
deleteKey={(popUp?.deleteEnv?.data as { slug: string })?.slug || ''}
onClose={() => handlePopUpClose('deleteEnv')}
deleteKey={(popUp?.deleteEnv?.data as { slug: string })?.slug || ""}
onClose={() => handlePopUpClose("deleteEnv")}
onSubmit={onEnvDeleteCB}
/>
<AddUpdateEnvironmentDialog
isOpen={popUp.createUpdateEnv.isOpen}
isEditMode={Boolean(popUp.createUpdateEnv?.data)}
initialValues={popUp?.createUpdateEnv?.data as any}
onClose={() => handlePopUpClose('createUpdateEnv')}
onClose={() => handlePopUpClose("createUpdateEnv")}
onCreateSubmit={onEnvCreateCB}
onEditSubmit={onEnvUpdateCB}
/>
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
onClose={() => handlePopUpClose('upgradePlan')}
onClose={() => handlePopUpClose("upgradePlan")}
text="You can add custom environments if you switch to Infisical's Team plan."
/>
</div>
@@ -1,22 +1,22 @@
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import { faEye, faEyeSlash, faPenToSquare, faPlus, faX } from '@fortawesome/free-solid-svg-icons';
import { plans } from 'public/data/frequentConstants';
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { faEye, faEyeSlash, faPenToSquare, faPlus, faX } from "@fortawesome/free-solid-svg-icons";
import { plans } from "public/data/frequentConstants";
import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
import { Select, SelectItem } from '@app/components/v2';
import updateUserProjectPermission from '@app/ee/api/memberships/UpdateUserProjectPermission';
import getOrganizationSubscriptions from '@app/pages/api/organization/GetOrgSubscription';
import changeUserRoleInWorkspace from '@app/pages/api/workspace/changeUserRoleInWorkspace';
import deleteUserFromWorkspace from '@app/pages/api/workspace/deleteUserFromWorkspace';
import getLatestFileKey from '@app/pages/api/workspace/getLatestFileKey';
import getProjectInfo from '@app/pages/api/workspace/getProjectInfo';
import uploadKeys from '@app/pages/api/workspace/uploadKeys';
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import { Select, SelectItem } from "@app/components/v2";
import updateUserProjectPermission from "@app/ee/api/memberships/UpdateUserProjectPermission";
import getOrganizationSubscriptions from "@app/pages/api/organization/GetOrgSubscription";
import changeUserRoleInWorkspace from "@app/pages/api/workspace/changeUserRoleInWorkspace";
import deleteUserFromWorkspace from "@app/pages/api/workspace/deleteUserFromWorkspace";
import getLatestFileKey from "@app/pages/api/workspace/getLatestFileKey";
import getProjectInfo from "@app/pages/api/workspace/getProjectInfo";
import uploadKeys from "@app/pages/api/workspace/uploadKeys";
import { decryptAssymmetric, encryptAssymmetric } from '../../utilities/cryptography/crypto';
import guidGenerator from '../../utilities/randomId';
import Button from '../buttons/Button';
import UpgradePlanModal from '../dialog/UpgradePlan';
import { decryptAssymmetric, encryptAssymmetric } from "../../utilities/cryptography/crypto";
import guidGenerator from "../../utilities/randomId";
import Button from "../buttons/Button";
import UpgradePlanModal from "../dialog/UpgradePlan";
// const roles = ['admin', 'user'];
// TODO: Set type for this
@@ -45,8 +45,8 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
);
const host = window.location.origin;
const router = useRouter();
const [myRole, setMyRole] = useState('member');
const [currentPlan, setCurrentPlan] = useState('');
const [myRole, setMyRole] = useState("member");
const [currentPlan, setCurrentPlan] = useState("");
const [workspaceEnvs, setWorkspaceEnvs] = useState<EnvironmentProps[]>([]);
const [isUpgradeModalOpen, setIsUpgradeModalOpen] = useState(false);
const { createNotification } = useNotificationContext();
@@ -87,8 +87,8 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
...userData.slice(index + 1, userData?.length)
]);
createNotification({
text: `Successfully changed user role.`,
type: 'success'
text: "Successfully changed user role.",
type: "success"
});
};
@@ -99,28 +99,28 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
slug: string
) => {
let denials: { ability: string; environmentSlug: string }[];
if (val === 'Read Only') {
if (val === "Read Only") {
denials = [
{
ability: 'write',
ability: "write",
environmentSlug: slug
}
];
} else if (val === 'No Access') {
} else if (val === "No Access") {
denials = [
{
ability: 'write',
ability: "write",
environmentSlug: slug
},
{
ability: 'read',
ability: "read",
environmentSlug: slug
}
];
} else if (val === 'Add Only') {
} else if (val === "Add Only") {
denials = [
{
ability: 'read',
ability: "read",
environmentSlug: slug
}
];
@@ -128,7 +128,7 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
denials = [];
}
if (currentPlan !== plans.professional && host === 'https://app.infisical.com' && workspaceId !== '63ea8121b6e2b0543ba79616') {
if (currentPlan !== plans.professional && host === "https://app.infisical.com" && workspaceId !== "63ea8121b6e2b0543ba79616") {
setIsUpgradeModalOpen(true);
} else {
const allDenials = userData[index].deniedPermissions
@@ -156,8 +156,8 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
...userData.slice(index + 1, userData?.length)
]);
createNotification({
text: `Successfully changed user permissions.`,
type: 'success'
text: "Successfully changed user permissions.",
type: "success"
});
}
};
@@ -168,7 +168,7 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
const result = await getProjectInfo({ projectId: workspaceId });
setWorkspaceEnvs(result.environments);
const orgId = localStorage.getItem('orgData.id') as string;
const orgId = localStorage.getItem("orgData.id") as string;
const subscriptions = await getOrganizationSubscriptions({
orgId
});
@@ -181,7 +181,7 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
const grantAccess = async (id: string, publicKey: string) => {
const result = await getLatestFileKey({ workspaceId });
const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY') as string;
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string;
// assymmetrically decrypt symmetric key with local private key
const key = decryptAssymmetric({
@@ -261,13 +261,13 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
// open={isOpen}
onValueChange={(e) => handleRoleUpdate(index, e)}
value={row.role}
isDisabled={myRole !== 'admin' || myUser === row.email}
isDisabled={myRole !== "admin" || myUser === row.email}
// onOpenChange={(open) => setIsOpen(open)}
>
<SelectItem value="admin">Admin</SelectItem>
<SelectItem value="member">Member</SelectItem>
</Select>
{row.status === 'completed' && myUser !== row.email && (
{row.status === "completed" && myUser !== row.email && (
<div className="rounded-md border border-mineshaft-700 bg-white/5 text-white duration-200 hover:bg-primary hover:text-black">
<Button
onButtonPressed={() => grantAccess(row.userId, row.publicKey)}
@@ -297,66 +297,66 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('write') &&
.includes("write") &&
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('read')
? 'No Access'
.includes("read")
? "No Access"
: // eslint-disable-next-line no-nested-ternary
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('write') &&
.includes("write") &&
!row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('read')
? 'Read Only'
.includes("read")
? "Read Only"
: !row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('write') &&
.includes("write") &&
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('read')
? 'Add Only'
: 'Read & Write'
.includes("read")
? "Add Only"
: "Read & Write"
}
icon={
// eslint-disable-next-line no-nested-ternary
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('write') &&
.includes("write") &&
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('read')
.includes("read")
? faEyeSlash
: // eslint-disable-next-line no-nested-ternary
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('write') &&
.includes("write") &&
!row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('read')
.includes("read")
? faEye
: !row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('write') &&
.includes("write") &&
row.deniedPermissions
.filter((perm: any) => perm.environmentSlug === env.slug)
.map((perm: { ability: string }) => perm.ability)
.includes('read')
.includes("read")
? faPlus
: faPenToSquare
}
isDisabled={myRole !== 'admin'}
isDisabled={myRole !== "admin"}
// onOpenChange={(open) => setIsOpen(open)}
>
<SelectItem value="No Access" customIcon={faEyeSlash}>
@@ -377,7 +377,7 @@ const ProjectUsersTable = ({ userData, changeData, myUser, filter, isUserListLoa
<td className="border-0.5 flex flex-row justify-end border-t border-mineshaft-700 py-2 pl-8 pr-8">
{myUser !== row.email &&
// row.role !== "admin" &&
myRole !== 'member' ? (
myRole !== "member" ? (
<div className="mt-0.5 flex items-center opacity-50 hover:opacity-100">
<Button
onButtonPressed={() => handleDelete(row.membershipId, index)}
@@ -1,10 +1,10 @@
import { faX } from '@fortawesome/free-solid-svg-icons';
import { faX } from "@fortawesome/free-solid-svg-icons";
import { useNotificationContext } from '@app/components/context/Notifications/NotificationProvider';
import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider";
import deleteServiceToken from '../../../pages/api/serviceToken/deleteServiceToken';
import guidGenerator from '../../utilities/randomId';
import Button from '../buttons/Button';
import deleteServiceToken from "../../../pages/api/serviceToken/deleteServiceToken";
import guidGenerator from "../../utilities/randomId";
import Button from "../buttons/Button";
interface TokenProps {
_id: string;
@@ -71,7 +71,7 @@ const ServiceTokenTable = ({ data, workspaceName, setServiceTokens }: ServiceTok
setServiceTokens(data.filter((token) => token._id !== row._id));
createNotification({
text: `'${row.name}' token has been revoked.`,
type: 'error'
type: "error"
});
}}
color="red"
@@ -1,18 +1,18 @@
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import { faX } from '@fortawesome/free-solid-svg-icons';
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { faX } from "@fortawesome/free-solid-svg-icons";
import changeUserRoleInOrganization from '@app/pages/api/organization/changeUserRoleInOrganization';
import deleteUserFromOrganization from '@app/pages/api/organization/deleteUserFromOrganization';
import getOrganizationProjectMemberships from '@app/pages/api/organization/GetOrgProjectMemberships';
import deleteUserFromWorkspace from '@app/pages/api/workspace/deleteUserFromWorkspace';
import getLatestFileKey from '@app/pages/api/workspace/getLatestFileKey';
import uploadKeys from '@app/pages/api/workspace/uploadKeys';
import changeUserRoleInOrganization from "@app/pages/api/organization/changeUserRoleInOrganization";
import deleteUserFromOrganization from "@app/pages/api/organization/deleteUserFromOrganization";
import getOrganizationProjectMemberships from "@app/pages/api/organization/GetOrgProjectMemberships";
import deleteUserFromWorkspace from "@app/pages/api/workspace/deleteUserFromWorkspace";
import getLatestFileKey from "@app/pages/api/workspace/getLatestFileKey";
import uploadKeys from "@app/pages/api/workspace/uploadKeys";
import { decryptAssymmetric, encryptAssymmetric } from '../../utilities/cryptography/crypto';
import guidGenerator from '../../utilities/randomId';
import Button from '../buttons/Button';
import Listbox from '../Listbox';
import { decryptAssymmetric, encryptAssymmetric } from "../../utilities/cryptography/crypto";
import guidGenerator from "../../utilities/randomId";
import Button from "../buttons/Button";
import Listbox from "../Listbox";
// const roles = ['admin', 'user'];
// TODO: Set type for this
@@ -36,7 +36,7 @@ const UserTable = ({ userData, changeData, myUser, filter, resendInvite, isOrg }
Array(userData?.length).fill(userData.map((user) => user.role))
);
const router = useRouter();
const [myRole, setMyRole] = useState('member');
const [myRole, setMyRole] = useState("member");
const [userProjectMemberships, setUserProjectMemberships] = useState<any[]>([]);
const workspaceId = router.query.id as string;
@@ -90,7 +90,7 @@ const UserTable = ({ userData, changeData, myUser, filter, resendInvite, isOrg }
const grantAccess = async (id: string, publicKey: string) => {
const result = await getLatestFileKey({ workspaceId });
const PRIVATE_KEY = localStorage.getItem('PRIVATE_KEY') as string;
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY") as string;
// assymmetrically decrypt symmetric key with local private key
const key = decryptAssymmetric({
@@ -152,29 +152,29 @@ const UserTable = ({ userData, changeData, myUser, filter, resendInvite, isOrg }
</td>
<td className="pl-6 pr-10 py-2 border-mineshaft-700 border-t text-gray-300">
<div className="justify-start h-full flex flex-row items-center">
{row.status === 'accepted' &&
((myRole === 'admin' && row.role !== 'owner') || myRole === 'owner') &&
{row.status === "accepted" &&
((myRole === "admin" && row.role !== "owner") || myRole === "owner") &&
(myUser !== row.email) ? (
<Listbox
isSelected={row.role}
onChange={(e) => handleRoleUpdate(index, e)}
data={
myRole === 'owner' ? ['owner', 'admin', 'member'] : ['admin', 'member']
myRole === "owner" ? ["owner", "admin", "member"] : ["admin", "member"]
}
/>
) : (
row.status !== 'invited' &&
row.status !== 'verified' && (
row.status !== "invited" &&
row.status !== "verified" && (
<Listbox
isSelected={row.role}
onChange={() => {
throw new Error('Function not implemented.');
throw new Error("Function not implemented.");
}}
data={null}
/>
)
)}
{(row.status === 'invited' || row.status === 'verified') && (
{(row.status === "invited" || row.status === "verified") && (
<div className="w-full pr-20">
<Button
onButtonPressed={() => deleteMembershipAndResendInvite(row.email)}
@@ -184,7 +184,7 @@ const UserTable = ({ userData, changeData, myUser, filter, resendInvite, isOrg }
/>
</div>
)}
{row.status === 'completed' && myUser !== row.email && (
{row.status === "completed" && myUser !== row.email && (
<div className="border border-mineshaft-700 rounded-md bg-white/5 hover:bg-primary text-white hover:text-black duration-200">
<Button
onButtonPressed={() => grantAccess(row.userId, row.publicKey)}
@@ -210,7 +210,7 @@ const UserTable = ({ userData, changeData, myUser, filter, resendInvite, isOrg }
<td className="flex flex-row justify-end pl-8 pr-8 py-2 border-t border-0.5 border-mineshaft-700">
{myUser !== row.email &&
// row.role !== "admin" &&
myRole !== 'member' ? (
myRole !== "member" ? (
<div className="opacity-50 hover:opacity-100 flex items-center mt-0.5">
<Button
onButtonPressed={() => handleDelete(row.membershipId, index)}