diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml
index 1b80aa784..770fa7e83 100644
--- a/.github/workflows/docker-image.yml
+++ b/.github/workflows/docker-image.yml
@@ -6,6 +6,8 @@ jobs:
docker:
runs-on: ubuntu-latest
steps:
+ - name: Checkout
+ uses: actions/checkout@v2
-
name: Set up QEMU
uses: docker/setup-qemu-action@v2
@@ -23,12 +25,13 @@ jobs:
uses: docker/build-push-action@v3
with:
push: true
- context: /backend
- tags: infisical/backend:latest
+ context: backend
+ tags: infisical/backend:test
-
name: Build and push frontend
uses: docker/build-push-action@v3
with:
push: true
- context: /frontend
- tags: infisical/frontend:latest
+ file: frontend/Dockerfile.dev
+ context: frontend
+ tags: infisical/frontend:test
diff --git a/.github/workflows/helm-chart-release.yaml b/.github/workflows/helm-chart-release.yaml
new file mode 100644
index 000000000..e3a3e32bc
--- /dev/null
+++ b/.github/workflows/helm-chart-release.yaml
@@ -0,0 +1,33 @@
+name: Release Charts
+
+on: [workflow_dispatch]
+
+jobs:
+ release:
+ # depending on default permission settings for your org (contents being read-only or read-write for workloads), you will have to add permissions
+ # see: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#modifying-the-permissions-for-the-github_token
+ permissions:
+ contents: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+
+ - name: Configure Git
+ run: |
+ git config user.name "$GITHUB_ACTOR"
+ git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
+
+ - name: Install Helm
+ uses: azure/setup-helm@v3
+ with:
+ version: v3.10.0
+
+ - name: Run chart-releaser
+ uses: helm/chart-releaser-action@v1.4.1
+ with:
+ charts_dir: helm-charts
+ env:
+ CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/README.md b/README.md
index 6b1fc9436..4215a9fa8 100644
--- a/README.md
+++ b/README.md
@@ -54,15 +54,13 @@ To quickly get started, visit our [get started guide](https://infisical.com/docs
## What's cool about this?
-Infisical is simple, E2EE, and (soon to be) complete.
+Infisical makes secret management simple and end-to-end encrypted by default. We're on a mission to make it more accessible to all developers, not just security teams .
According to a [report](https://www.ekransystem.com/en/blog/secrets-management) in 2019, only 10% of organizations use secret management solutions despite all using digital secrets to some extent.
-We're on a mission to make secret management more accessible to everyone β that means building for developers, not just security teams.
-
If you care about efficiency and security, then Infisical is right for you.
-Need any integrations or want a new feature? Feel free to [create an issue](https://github.com/Infisical/infisical/issues) or [contribute](https://infisical.com/docs/contributing/overview) directly to the repository.
+We are currently working hard to make Infisical more extensive. Need any integrations or want a new feature? Feel free to [create an issue](https://github.com/Infisical/infisical/issues) or [contribute](https://infisical.com/docs/contributing/overview) directly to the repository.
## Contributing
@@ -124,7 +122,7 @@ We're currently setting the foundation and building [integrations](https://infis
- π Vercel
+ π Vercel (https://github.com/Infisical/infisical/issues/60)
π GitLab CI/CD
@@ -279,4 +277,4 @@ Looking to report a security vulnerability? Please don't post about it in GitHub
-
+
diff --git a/cli/packages/cmd/root.go b/cli/packages/cmd/root.go
index 826ccb4df..42d85e5b2 100644
--- a/cli/packages/cmd/root.go
+++ b/cli/packages/cmd/root.go
@@ -15,7 +15,7 @@ var rootCmd = &cobra.Command{
Short: "Infisical CLI is used to inject environment variables into any process",
Long: `Infisical is a simple, end-to-end encrypted service that enables teams to sync and manage their environment variables across their development life cycle.`,
CompletionOptions: cobra.CompletionOptions{DisableDefaultCmd: true},
- Version: "0.1.5",
+ Version: "0.1.6",
}
// Execute adds all child commands to the root command and sets flags appropriately.
diff --git a/docs/contributing/FAQ.mdx b/docs/contributing/FAQ.mdx
new file mode 100644
index 000000000..be65f5ca7
--- /dev/null
+++ b/docs/contributing/FAQ.mdx
@@ -0,0 +1,16 @@
+---
+title: "Frequently Asked Questions"
+description: "Have any questions? [Join our Slack community](https://join.slack.com/t/infisical-users/shared_invite/zt-1kdbk07ro-RtoyEt_9E~fyzGo_xQYP6g)."
+---
+
+## Problem with SMTP
+
+You can normally populate `SMTP_USERNAME` and `SMTP_PASSWORD` with your usual login and password (you could also create a 'burner' email). Sometimes, there still are problems.
+
+You can go to your Gmail account settings > security and enable βless secure appsβ. This would allow Infisical to use your Gmail to send emails.
+
+If it still doesn't work, [this](https://stackoverflow.com/questions/72547853/unable-to-send-email-in-c-sharp-less-secure-app-access-not-longer-available/72553362#72553362) should help.
+
+## `MONGO_URL` issues
+
+Your `MONGO_URL` should be something like `mongodb://root:example@mongo:27017/?authSource=admin`. If you want to change it (not recommended), you should make sure that you keep this URL in line with `MONGO_USERNAME=root` and `MONGO_PASSWORD=example`.
\ No newline at end of file
diff --git a/docs/mint.json b/docs/mint.json
index 7d0317f0e..4ff49b5b9 100644
--- a/docs/mint.json
+++ b/docs/mint.json
@@ -162,7 +162,8 @@
"pages": [
"contributing/overview",
"contributing/code-of-conduct",
- "contributing/developing"
+ "contributing/developing",
+ "contributing/FAQ"
]
}
],
diff --git a/frontend/.eslintrc.json b/frontend/.eslintrc
similarity index 65%
rename from frontend/.eslintrc.json
rename to frontend/.eslintrc
index 0c5504b90..b562aaa1f 100644
--- a/frontend/.eslintrc.json
+++ b/frontend/.eslintrc
@@ -1,10 +1,21 @@
{
- "extends": "next/core-web-vitals",
- "plugins": [
- "simple-import-sort"
+ "extends": [
+ "eslint:recommended",
+ "plugin:@typescript-eslint/recommended",
+ "next",
+ "next/core-web-vitals"
],
+ "parser": "@typescript-eslint/parser",
+ "plugins": ["simple-import-sort", "@typescript-eslint"],
"rules": {
"react-hooks/exhaustive-deps": "off",
+ "no-unused-vars": "off",
+ "@typescript-eslint/no-unused-vars": "off",
+ "@typescript-eslint/no-var-requires": "off",
+ "@typescript-eslint/no-empty-function": "off",
+ "@typescript-eslint/no-explicit-any": "off",
+ "@typescript-eslint/no-non-null-assertion": "off",
+
"simple-import-sort/exports": "warn",
"simple-import-sort/imports": [
"warn",
@@ -18,15 +29,9 @@
"^(assert|buffer|child_process|cluster|console|constants|crypto|dgram|dns|domain|events|fs|http|https|module|net|os|path|punycode|querystring|readline|repl|stream|string_decoder|sys|timers|tls|tty|url|util|vm|zlib|freelist|v8|process|async_hooks|http2|perf_hooks)(/.*|$)"
],
// Packages `react` related packages
- [
- "^react",
- "^next",
- "^@?\\w"
- ],
+ ["^react", "^next", "^@?\\w"],
// Internal packages.
- [
- "^~(/.*|$)"
- ],
+ ["^~(/.*|$)"],
// Relative imports
[
"^\\.\\.(?!/?$)",
@@ -36,11 +41,9 @@
"^\\./?$"
],
// Style imports.
- [
- "^.+\\.?(css|scss)$"
- ]
+ ["^.+\\.?(css|scss)$"]
]
}
]
}
-}
\ No newline at end of file
+}
diff --git a/frontend/README.md b/frontend/README.md
index b33ff4335..d97bb4bef 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -1,20 +1,22 @@
This is the client repository for Infisical.
-## Before you get started with development locally
+## Before you get started with development locally
+
Please ensure you have Docker and Docker Compose installed for your OS.
-### Steps to start server
+### Steps to start server
+
- `CD` into the repo
- run command `docker-compose -f docker-compose.dev.yml up --build --force-recreate`
-- Vist localhost:3000 and the website should be live
+- Visit localhost:3000 and the website should be live
+
+### Steps to shutdown this Docker compose
-### Steps to shutdown this Docker compose
- `CD` into this repo
-- run command `docker-compose -f docker-compose-dev.yml down`
+- run command `docker-compose -f docker-compose.dev.yml down`
### Notes
-Any changes made to local files in the `/components`, `/pages`, `styles` will be hot reloaded. If would like like to watch for other files or folders live, please add them to the docker volume.
+
+Any changes made to local files in the `/components`, `/pages`, `/styles` will be hot reloaded. If would like like to watch for other files or folders live, please add them to the docker volume.
You will also need to ensure that a .env.local file exists with all required environment variables
-
-
diff --git a/frontend/components/basic/buttons/Button.tsx b/frontend/components/basic/buttons/Button.tsx
index 40251be93..5fe2db803 100644
--- a/frontend/components/basic/buttons/Button.tsx
+++ b/frontend/components/basic/buttons/Button.tsx
@@ -1,25 +1,28 @@
import React from "react";
import Image from "next/image";
import { IconProp } from "@fortawesome/fontawesome-svg-core";
-import { FontAwesomeIcon, FontAwesomeIconProps } from "@fortawesome/react-fontawesome";
+import {
+ FontAwesomeIcon,
+ FontAwesomeIconProps,
+} from "@fortawesome/react-fontawesome";
-var classNames = require("classnames");
+const classNames = require("classnames");
type ButtonProps = {
text: string;
onButtonPressed: () => void;
- loading: boolean;
+ loading?: boolean;
color: string;
size: string;
- icon: IconProp;
- active: boolean;
- iconDisabled: string;
- textDisabled: string;
-}
+ icon?: IconProp;
+ active?: boolean;
+ iconDisabled?: string;
+ textDisabled?: string;
+};
/**
* This is the main butto component in the app.
- * @param {object} props
+ * @param {object} props
* @param {string} props.text - text inside the button
* @param {function} props.onButtonPressed - the action that happens when the button is clicked
* @param {boolean} props.loading - if a button is currently in the laoding state
@@ -29,21 +32,28 @@ type ButtonProps = {
* @param {boolean} props.active - if the button is active or disabled
* @param {FontAwesomeIconProps} props.text - the icon inside the button when it is disabled
* @param {string} props.textDisable - text inside the button when it is disabled
- * @returns
+ * @returns
*/
-export default function Button (props: ButtonProps): JSX.Element {
+export default function Button(props: 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 = props.active || (props.text != "" && props.textDisabled == undefined)
-
- let styleButton = classNames(
+ const activityStatus =
+ props.active || (props.text != "" && props.textDisabled == undefined);
+
+ const styleButton = classNames(
"group m-auto md:m-0 inline-block rounded-md duration-200",
// Setting background colors and hover modes
- props.color == "mineshaft" && activityStatus && "bg-mineshaft-700 hover:bg-primary",
+ props.color == "mineshaft" &&
+ activityStatus &&
+ "bg-mineshaft-700 hover:bg-primary",
props.color == "mineshaft" && !activityStatus && "bg-mineshaft",
- (props.color == "primary" || !props.color) && activityStatus && "bg-primary hover:opacity-80",
- (props.color == "primary" || !props.color) && !activityStatus && "bg-primary",
+ (props.color == "primary" || !props.color) &&
+ activityStatus &&
+ "bg-primary hover:opacity-80",
+ (props.color == "primary" || !props.color) &&
+ !activityStatus &&
+ "bg-primary",
props.color == "red" && "bg-red",
// Changing the opacity when active vs when not
@@ -57,7 +67,7 @@ export default function Button (props: ButtonProps): JSX.Element {
props.size == "icon-sm" && "h-9 w-9 flex items-center justify-center"
);
- let styleMainDiv = classNames(
+ const styleMainDiv = classNames(
"relative font-medium flex items-center",
// Setting the text color for the text and icon
@@ -69,11 +79,11 @@ export default function Button (props: ButtonProps): JSX.Element {
props.size == "icon" && "flex items-center justify-center"
);
- let textStyle = classNames(
+ const textStyle = classNames(
"relative duration-200",
// Show the loading sign if the loading indicator is on
- props.loading == true ? "opacity-0" : "opacity-100",
+ props.loading ? "opacity-0" : "opacity-100",
props.size == "md" && "text-sm",
props.size == "lg" && "text-lg"
);
@@ -100,7 +110,7 @@ export default function Button (props: ButtonProps): JSX.Element {
{props.icon && (
)}
{(props.text || props.textDisabled) && (
- {activityStatus ? props.text : props.textDisabled}
+
+ {activityStatus ? props.text : props.textDisabled}
+
)}
diff --git a/frontend/components/basic/dialog/AddServiceTokenDialog.js b/frontend/components/basic/dialog/AddServiceTokenDialog.js
index 8147253b5..7ff1789b8 100644
--- a/frontend/components/basic/dialog/AddServiceTokenDialog.js
+++ b/frontend/components/basic/dialog/AddServiceTokenDialog.js
@@ -37,7 +37,7 @@ const AddServiceTokenDialog = ({
const [serviceTokenCopied, setServiceTokenCopied] = useState(false);
const generateServiceToken = async () => {
- const latestFileKey = await getLatestFileKey(workspaceId);
+ const latestFileKey = await getLatestFileKey({ workspaceId });
const key = decryptAssymmetric({
ciphertext: latestFileKey.latestKey.encryptedKey,
diff --git a/frontend/components/basic/layout.js b/frontend/components/basic/layout.js
index 0a8cb3ebd..effe38942 100644
--- a/frontend/components/basic/layout.js
+++ b/frontend/components/basic/layout.js
@@ -3,8 +3,9 @@ import { useEffect, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/router";
import {
+ faBookOpen,
faGear,
- faHouse,
+ faKey,
faMobile,
faPlug,
faUser,
@@ -18,6 +19,7 @@ import getOrganizationUsers from "~/pages/api/organization/GetOrgUsers";
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 {
@@ -54,10 +56,10 @@ export default function Layout({ children }) {
const workspaces = await getWorkspaces();
const currentWorkspaces = workspaces.map((workspace) => workspace.name);
if (!currentWorkspaces.includes(workspaceName)) {
- const newWorkspace = await createWorkspace(
+ const newWorkspace = await createWorkspace({
workspaceName,
- localStorage.getItem("orgData.id")
- );
+ organizationId: localStorage.getItem("orgData.id")
+ });
let newWorkspaceId;
try {
newWorkspaceId = newWorkspace._id;
@@ -114,7 +116,7 @@ export default function Layout({ children }) {
href:
"/dashboard/" + workspaceMapping[workspaceSelected] + "?Development",
title: "Secrets",
- emoji: ,
+ emoji: ,
},
{
href: "/users/" + workspaceMapping[workspaceSelected],
@@ -155,9 +157,7 @@ export default function Layout({ children }) {
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" &&
@@ -178,9 +178,7 @@ export default function Layout({ children }) {
userWorkspaces.map((workspace) => [workspace._id, workspace.name])
)[
router.asPath
- .split("/")
- [router.asPath.split("/").length - 1].split("?")[0]
- ]
+ .split("/")[router.asPath.split("/").length - 1].split("?")[0]]
);
}
}
@@ -192,12 +190,9 @@ export default function Layout({ children }) {
workspaceMapping[workspaceSelected] &&
workspaceMapping[workspaceSelected] !==
router.asPath
- .split("/")
- [router.asPath.split("/").length - 1].split("?")[0]
+ .split("/")[router.asPath.split("/").length - 1].split("?")[0]
) {
- router.push(
- "/dashboard/" + workspaceMapping[workspaceSelected] + "?Development"
- );
+ router.push("/dashboard/" + workspaceMapping[workspaceSelected] + "?Development");
localStorage.setItem(
"projectData.id",
workspaceMapping[workspaceSelected]
@@ -214,66 +209,88 @@ export default function Layout({ children }) {
-
-
-
-
- PROJECT
+
+ {/*
*/}
+
+
+
+ PROJECT
+
+ {workspaceList.length > 0 ? (
+
+ ) : (
+
+ )}
- {workspaceList.length > 0 ? (
-
- ) : (
-
- )}
-
-
- {workspaceList.length > 0 &&
- menuItems.map(({ href, title, emoji }) => (
-
- {router.asPath.split("/")[1] === href.split("/")[1] &&
- (["project", "billing", "org", "personal"].includes(
- router.asPath.split("/")[2]
- )
- ? router.asPath.split("/")[2] === href.split("/")[2]
- : true) ? (
-
- ) : router.asPath == "/noprojects" ? (
-
- ) : (
-
+
+ {workspaceList.length > 0 &&
+ menuItems.map(({ href, title, emoji }) => (
+
+ {router.asPath.split("/")[1] === href.split("/")[1] &&
+ (["project", "billing", "org", "personal"].includes(
+ router.asPath.split("/")[2]
+ )
+ ? router.asPath.split("/")[2] === href.split("/")[2]
+ : true) ? (
+ ) : router.asPath == "/noprojects" ? (
+
-
- )}
-
- ))}
-
+ ) : (
+
+
+
+ )}
+
+ ))}
+
+
+
+ {router.asPath.split("/")[1] === "home" ? (
+
+ ) : (
+
+
+
+ )}
+
{
- let result = await getLatestFileKey(router.query.id);
+ let result = await getLatestFileKey({workspaceId: router.query.id});
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");
diff --git a/frontend/components/billing/Plan.js b/frontend/components/billing/Plan.js
index f156cf76d..427469635 100644
--- a/frontend/components/billing/Plan.js
+++ b/frontend/components/billing/Plan.js
@@ -61,7 +61,7 @@ export default function Plan({ plan }) {
)}
-
+
{plan.buttonTextSecondary}
diff --git a/frontend/components/dashboard/DashboardInputField.js b/frontend/components/dashboard/DashboardInputField.tsx
similarity index 58%
rename from frontend/components/dashboard/DashboardInputField.js
rename to frontend/components/dashboard/DashboardInputField.tsx
index 634591c07..7a5b4a048 100644
--- a/frontend/components/dashboard/DashboardInputField.js
+++ b/frontend/components/dashboard/DashboardInputField.tsx
@@ -1,4 +1,4 @@
-import React, { useRef } from "react";
+import React, { SyntheticEvent, useRef } from "react";
import { faCircle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -6,6 +6,15 @@ import guidGenerator from "../utilities/randomId";
const REGEX = /([$]{.*?})/g;
+interface DashboardInputFieldProps {
+ index: number;
+ onChangeHandler: (value: string, index: number) => void;
+ value: string;
+ type: "varName" | "value";
+ blurred: boolean;
+ duplicates: string[];
+}
+
/**
* This component renders the input fields on the dashboard
* @param {object} obj - the order number of a keyPair
@@ -14,51 +23,60 @@ const REGEX = /([$]{.*?})/g;
* @param {string} obj.type - whether the input field is for a Key Name or for a Key Value
* @param {string} obj.value - value of the InputField
* @param {boolean} obj.blurred - whether the input field should be blurred (behind the gray dots) or not; this can be turned on/off in the dashboard
- * @param {string[]} obj.duplicates - list of all the suplicated key names on the dashboard
+ * @param {string[]} obj.duplicates - list of all the duplicated key names on the dashboard
* @returns
*/
+
const DashboardInputField = ({
index,
onChangeHandler,
type,
value,
blurred,
- duplicates
-}) => {
- const ref = useRef(null);
- const syncScroll = (e) => {
- ref.current.scrollTop = e.target.scrollTop;
- ref.current.scrollLeft = e.target.scrollLeft;
+ duplicates,
+}: DashboardInputFieldProps) => {
+ const ref = useRef(null);
+ const syncScroll = (e: SyntheticEvent) => {
+ if (ref.current == null) return;
+
+ ref.current.scrollTop = e.currentTarget.scrollTop;
+ ref.current.scrollLeft = e.currentTarget.scrollLeft;
};
-
+
if (type === "varName") {
- const startsWithNumber = !isNaN(value.charAt(0)) && value != "";
+ const startsWithNumber = !isNaN(Number(value.charAt(0))) && value != "";
const hasDuplicates = duplicates?.includes(value);
const error = startsWithNumber || hasDuplicates;
return (
onChangeHandler(e.target.value.toUpperCase(), index)}
+ onChange={(e) =>
+ onChangeHandler(e.target.value.toUpperCase(), index)
+ }
type={type}
value={value}
- className={`asolute z-10 peer font-mono ph-no-capture bg-bunker-800 rounded-md caret-white text-gray-400 text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 ${error ? "focus:ring-red/50" : "focus:ring-primary/50"} duration-200`}
+ className={`z-10 peer font-mono ph-no-capture bg-bunker-800 rounded-md caret-white text-gray-400 text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 ${
+ error ? "focus:ring-red/50" : "focus:ring-primary/50"
+ } duration-200`}
spellCheck="false"
/>
- {startsWithNumber &&
+ {startsWithNumber && (
Should not start with a number
- }
- {hasDuplicates && !startsWithNumber &&
+ )}
+ {hasDuplicates && !startsWithNumber && (
Secret names should be unique
- }
+ )}
);
} else if (type === "value") {
@@ -78,61 +96,61 @@ const DashboardInputField = ({
} z-10 peer font-mono ph-no-capture bg-transparent rounded-md caret-white text-transparent text-md px-2 py-1.5 w-full min-w-16 outline-none focus:ring-2 focus:ring-primary/50 duration-200 no-scrollbar no-scrollbar::-webkit-scrollbar`}
spellCheck="false"
/>
-
- {
- value
- .split(REGEX)
- .map((word, id) => {
- if (word.match(REGEX) !== null) {
- return (
-
- {word.slice(0, 2)}
-
- {word.slice(2, word.length - 1)}
-
- {word.slice(word.length - 1, word.length) == "}" ? (
-
- {word.slice(word.length - 1, word.length)}
-
- ) : (
-
- {word.slice(word.length - 1, word.length)}
-
- )}
+ {value.split(REGEX).map((word, id) => {
+ if (word.match(REGEX) !== null) {
+ return (
+
+ {word.slice(0, 2)}
+
+ {word.slice(2, word.length - 1)}
- );
- } else {
- return {word} ;
- }
- })
- }
+ {word.slice(word.length - 1, word.length) == "}" ? (
+
+ {word.slice(word.length - 1, word.length)}
+
+ ) : (
+
+ {word.slice(word.length - 1, word.length)}
+
+ )}
+
+ );
+ } else {
+ return (
+
+ {word}
+
+ );
+ }
+ })}
{blurred && (
- {value
- .split("")
- .map(() => (
-
- ))}
+ {value.split("").map(() => (
+
+ ))}
- )}
+ )}
);
}
+
+ return <>Something Wrong>;
};
export default React.memo(DashboardInputField);
diff --git a/frontend/components/dashboard/DropZone.js b/frontend/components/dashboard/DropZone.tsx
similarity index 69%
rename from frontend/components/dashboard/DropZone.js
rename to frontend/components/dashboard/DropZone.tsx
index 6171e682f..7519bca10 100644
--- a/frontend/components/dashboard/DropZone.js
+++ b/frontend/components/dashboard/DropZone.tsx
@@ -1,4 +1,4 @@
-import { useState } from "react";
+import { type ChangeEvent, type DragEvent, useState } from "react";
import Image from "next/image";
import { faUpload } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -8,27 +8,37 @@ import Error from "../basic/Error";
import parse from "../utilities/file";
import guidGenerator from "../utilities/randomId";
+interface DropZoneProps {
+ // TODO: change Data type from any
+ setData: (data: any) => void;
+ setErrorDragAndDrop: (hasError: boolean) => void;
+ createNewFile: () => void;
+ errorDragAndDrop: boolean;
+ setButtonReady: (isReady: boolean) => void;
+ keysExist: boolean;
+ numCurrentRows: number;
+}
+
const DropZone = ({
setData,
setErrorDragAndDrop,
createNewFile,
errorDragAndDrop,
- addPresetRow,
setButtonReady,
keysExist,
numCurrentRows,
-}) => {
- const handleDragEnter = (e) => {
+}: DropZoneProps) => {
+ const handleDragEnter = (e: DragEvent) => {
e.preventDefault();
e.stopPropagation();
};
- const handleDragLeave = (e) => {
+ const handleDragLeave = (e: DragEvent) => {
e.preventDefault();
e.stopPropagation();
};
- const handleDragOver = (e) => {
+ const handleDragOver = (e: DragEvent) => {
e.preventDefault();
e.stopPropagation();
@@ -39,22 +49,25 @@ const DropZone = ({
const [loading, setLoading] = useState(false);
// This function function immediately parses the file after it is dropped
- const handleDrop = async (e) => {
+ const handleDrop = async (e: DragEvent) => {
setLoading(true);
setTimeout(() => setLoading(false), 5000);
e.preventDefault();
e.stopPropagation();
e.dataTransfer.dropEffect = "copy";
- var file = e.dataTransfer.files[0],
- reader = new FileReader();
- reader.onload = function (event) {
- const keyPairs = parse(event.target.result);
+ const file = e.dataTransfer.files[0];
+ const reader = new FileReader();
+
+ reader.onload = (event) => {
+ if (event.target === null || event.target.result === null) return;
+ // parse function's argument looks like to be ArrayBuffer
+ const keyPairs = parse(event.target.result as Buffer);
const newData = Object.keys(keyPairs).map((key, index) => [
guidGenerator(),
numCurrentRows + index,
key,
- keyPairs[key],
+ keyPairs[key as keyof typeof keyPairs],
"shared",
]);
setData(newData);
@@ -72,23 +85,28 @@ const DropZone = ({
};
// This function is used when the user manually selects a file from the in-browser dircetory (not drag and drop)
- const handleFileSelect = (e) => {
+ const handleFileSelect = (e: ChangeEvent) => {
setLoading(true);
setTimeout(() => setLoading(false), 5000);
- var file = e.target.files[0],
- reader = new FileReader();
- reader.onload = function (event) {
- const newData = event.target.result
- .split("\n")
- .map((line, index) => [
- guidGenerator(),
- numCurrentRows + index,
- line.split("=")[0],
- line.split("=").slice(1, line.split("=").length).join("="),
- "shared",
- ]);
- setData(newData);
- setButtonReady(true);
+ if (e.currentTarget.files === null) return;
+ const file = e.currentTarget.files[0];
+ const reader = new FileReader();
+ reader.onload = (event) => {
+ if (event.target === null || event.target.result === null) return;
+ const { result } = event.target;
+ if (typeof result === "string") {
+ const newData = result
+ .split("\n")
+ .map((line: string, index: number) => [
+ guidGenerator(),
+ numCurrentRows + index,
+ line.split("=")[0],
+ line.split("=").slice(1, line.split("=").length).join("="),
+ "shared",
+ ]);
+ setData(newData);
+ setButtonReady(true);
+ }
};
reader.readAsText(file);
};
@@ -105,17 +123,17 @@ const DropZone = ({
) : keysExist ? (
handleDragEnter(e)}
- onDragOver={(e) => handleDragOver(e)}
- onDragLeave={(e) => handleDragLeave(e)}
- onDrop={(e) => handleDrop(e)}
+ onDragEnter={handleDragEnter}
+ onDragOver={handleDragOver}
+ onDragLeave={handleDragLeave}
+ onDrop={handleDrop}
>
handleFileSelect(e)}
+ onChange={handleFileSelect}
/>
{errorDragAndDrop ? (
@@ -142,10 +160,10 @@ const DropZone = ({
) : (
handleDragEnter(e)}
- onDragOver={(e) => handleDragOver(e)}
- onDragLeave={(e) => handleDragLeave(e)}
- onDrop={(e) => handleDrop(e)}
+ onDragEnter={handleDragEnter}
+ onDragOver={handleDragOver}
+ onDragLeave={handleDragLeave}
+ onDrop={handleDrop}
>
Drag and drop your .env file here.
@@ -154,7 +172,7 @@ const DropZone = ({
type="file"
className="opacity-0 absolute w-full h-full"
accept=".txt,.env"
- onChange={(e) => handleFileSelect(e)}
+ onChange={handleFileSelect}
/>
diff --git a/frontend/components/navigation/NavBarDashboard.js b/frontend/components/navigation/NavBarDashboard.tsx
similarity index 91%
rename from frontend/components/navigation/NavBarDashboard.js
rename to frontend/components/navigation/NavBarDashboard.tsx
index 80537dc1a..5a6d63b8e 100644
--- a/frontend/components/navigation/NavBarDashboard.js
+++ b/frontend/components/navigation/NavBarDashboard.tsx
@@ -47,27 +47,44 @@ const supportOptions = [
],
];
-export default function Navbar({ onButtonPressed }) {
- const router = useRouter();
- const [user, setUser] = useState({});
- const [orgs, setOrgs] = useState([]);
- const [currentOrg, setCurrentOrg] = useState([]);
+export interface ICurrentOrg {
+ name: string;
+}
- useEffect(async () => {
- const userData = await getUser();
- setUser(userData);
- const orgsData = await getOrganizations();
- setOrgs(orgsData);
- const currentOrg = await getOrganization({
- orgId: localStorage.getItem("orgData.id"),
- });
- setCurrentOrg(currentOrg);
+export interface IUser {
+ firstName: string;
+ lastName: string;
+ email: string;
+}
+
+/**
+ * This is the navigation bar in the main app.
+ * It has two main components: support options and user menu (inlcudes billing, logout, org/user settings)
+ * @returns NavBar
+ */
+export default function Navbar() {
+ const router = useRouter();
+ const [user, setUser] = useState
();
+ const [orgs, setOrgs] = useState([]);
+ const [currentOrg, setCurrentOrg] = useState();
+
+ useEffect(() => {
+ (async () => {
+ const userData = await getUser();
+ setUser(userData);
+ const orgsData = await getOrganizations();
+ setOrgs(orgsData);
+ const currentOrg = await getOrganization({
+ orgId: String(localStorage.getItem("orgData.id")),
+ });
+ setCurrentOrg(currentOrg);
+ })();
}, []);
const closeApp = async () => {
console.log("Logging out...");
await logout();
- router.push("/");
+ router.push("/login");
};
return (
@@ -108,7 +125,7 @@ export default function Navbar({ onButtonPressed }) {
key={guidGenerator()}
target="_blank"
rel="noopener"
- href={option[2]}
+ href={String(option[2])}
className="font-normal text-gray-300 duration-200 rounded-md w-full flex items-center py-0.5"
>
@@ -238,9 +255,9 @@ export default function Navbar({ onButtonPressed }) {
{orgs
.filter(
- (org) => org._id != localStorage.getItem("orgData.id")
+ (org : { _id: string }) => org._id != localStorage.getItem("orgData.id")
)
- .map((org) => (
+ .map((org : { _id: string; name: string; }) => (
{
diff --git a/frontend/components/navigation/NavHeader.js b/frontend/components/navigation/NavHeader.tsx
similarity index 67%
rename from frontend/components/navigation/NavHeader.js
rename to frontend/components/navigation/NavHeader.tsx
index 3f65a5aa6..3d64c2eda 100644
--- a/frontend/components/navigation/NavHeader.js
+++ b/frontend/components/navigation/NavHeader.tsx
@@ -1,29 +1,37 @@
import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
-import { faCcMastercard, faCcVisa } from "@fortawesome/free-brands-svg-icons";
import {
faAngleRight,
- faQuestionCircle,
} from "@fortawesome/free-solid-svg-icons";
-import { faCircle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import getOrganization from "~/pages/api/organization/GetOrg";
-import getWorkspaceInfo from "~/pages/api/workspace/getWorkspaceInfo";
+import getProjectInfo from "~/pages/api/workspace/getProjectInfo";
-export default function NavHeader({ pageName, isProjectRelated }) {
+/**
+ * This is the component at the top of almost every page.
+ * It shows how to navigate to a certain page.
+ * It future these links should also be clickable and hoverable
+ * @param obj
+ * @param obj.pageName - Name of the page
+ * @param obj.isProjectRelated - whether this page is related to project or now (determine if it's 2 or 3 navigation steps)
+ * @returns
+ */
+export default function NavHeader({ pageName, isProjectRelated } : { pageName: string; isProjectRelated: boolean; }): JSX.Element {
const [orgName, setOrgName] = useState("");
const [workspaceName, setWorkspaceName] = useState("");
const router = useRouter();
useEffect(() => {
(async () => {
- let org = await getOrganization({
- orgId: localStorage.getItem("orgData.id"),
+ const orgId = localStorage.getItem("orgData.id")
+ const org = await getOrganization({
+ orgId: orgId ? orgId : "",
});
setOrgName(org.name);
- let workspace = await getWorkspaceInfo({
- workspaceId: router.query.id,
+
+ const workspace = await getProjectInfo({
+ projectId: String(router.query.id),
});
setWorkspaceName(workspace.name);
})();
diff --git a/frontend/components/utilities/attemptLogin.js b/frontend/components/utilities/attemptLogin.js
index 4e74a40ab..767fcb400 100644
--- a/frontend/components/utilities/attemptLogin.js
+++ b/frontend/components/utilities/attemptLogin.js
@@ -43,7 +43,7 @@ const attemptLogin = async (
let serverPublicKey, salt;
try {
- const res = await login1(email, clientPublicKey);
+ let res = await login1(email, clientPublicKey);
res = await res.json();
serverPublicKey = res.serverPublicKey;
salt = res.salt;
@@ -137,7 +137,15 @@ const attemptLogin = async (
await pushKeys(
{
DATABASE_URL: [
- "mongodb+srv://this_is:an_example@mongodb.net",
+ "mongodb+srv://${DB_USERNAME}:${DB_PASSWORD}@mongodb.net",
+ "personal",
+ ],
+ DB_USERNAME: [
+ "user1234",
+ "personal",
+ ],
+ DB_PASSWORD: [
+ "ah8jak3hk8dhiu4dw7whxwe1l",
"personal",
],
TWILIO_AUTH_TOKEN: [
diff --git a/frontend/components/utilities/cryptography/changePassword.js b/frontend/components/utilities/cryptography/changePassword.js
index 8bfaad674..de0fd9c3a 100644
--- a/frontend/components/utilities/cryptography/changePassword.js
+++ b/frontend/components/utilities/cryptography/changePassword.js
@@ -108,11 +108,7 @@ const changePassword = async (
}
);
} catch (error) {
- console.log(
- "Something went wrong during changing the password",
- slat,
- serverPublicKey
- );
+ console.log("Something went wrong during changing the password");
}
return true;
};
diff --git a/frontend/components/utilities/secrets/pushKeys.js b/frontend/components/utilities/secrets/pushKeys.ts
similarity index 69%
rename from frontend/components/utilities/secrets/pushKeys.js
rename to frontend/components/utilities/secrets/pushKeys.ts
index fde5b45a4..0d570f273 100644
--- a/frontend/components/utilities/secrets/pushKeys.js
+++ b/frontend/components/utilities/secrets/pushKeys.ts
@@ -7,20 +7,30 @@ import { envMapping } from "../../../public/data/frequentConstants";
const crypto = require("crypto");
const {
decryptAssymmetric,
- decryptSymmetric,
encryptSymmetric,
encryptAssymmetric,
} = require("../cryptography/crypto");
const nacl = require("tweetnacl");
nacl.util = require("tweetnacl-util");
+export interface IK {
+ publicKey: string;
+ userId: string;
+}
-const pushKeys = async (obj, workspaceId, env) => {
- let sharedKey = await getLatestFileKey(workspaceId);
+/**
+ * This function pushes the keys to the database after decrypting them end-to-end
+ * @param {object} obj
+ * @param {object} obj.obj - object with all the key pairs
+ * @param {object} obj.workspaceId - the id of a project to which a user is pushing
+ * @param {object} obj.env - which environment a user is pushing to
+ */
+const pushKeys = async({ obj, workspaceId, env }: { obj: object; workspaceId: string; env: string; }) => {
+ const sharedKey = await getLatestFileKey({ workspaceId });
const PRIVATE_KEY = localStorage.getItem("PRIVATE_KEY");
- let randomBytes;
+ let randomBytes: string;
if (Object.keys(sharedKey).length > 0) {
// case: a (shared) key exists for the workspace
randomBytes = decryptAssymmetric({
@@ -51,11 +61,11 @@ const pushKeys = async (obj, workspaceId, env) => {
iv: ivValue,
tag: tagValue,
} = encryptSymmetric({
- plaintext: obj[key][0],
+ plaintext: obj[key as keyof typeof obj][0],
key: randomBytes,
});
- const visibility = obj[key][1] != null ? obj[key][1] : "personal";
+ const visibility = obj[key as keyof typeof obj][1] != null ? obj[key as keyof typeof obj][1] : "personal";
return {
ciphertextKey,
@@ -65,7 +75,7 @@ const pushKeys = async (obj, workspaceId, env) => {
ciphertextValue,
ivValue,
tagValue,
- hashValue: crypto.createHash("sha256").update(obj[key][0]).digest("hex"),
+ hashValue: crypto.createHash("sha256").update(obj[key as keyof typeof obj][0]).digest("hex"),
type: visibility,
};
});
@@ -76,7 +86,7 @@ const pushKeys = async (obj, workspaceId, env) => {
});
// assymmetrically encrypt key with each receiver public keys
- const keys = publicKeys.map((k) => {
+ const keys = publicKeys.map((k: IK) => {
const { ciphertext, nonce } = encryptAssymmetric({
plaintext: randomBytes,
publicKey: k.publicKey,
@@ -95,7 +105,7 @@ const pushKeys = async (obj, workspaceId, env) => {
workspaceId,
secrets,
keys,
- environment: envMapping[env],
+ environment: envMapping[env as keyof typeof envMapping],
});
};
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index ad2ecb75e..7a560ad3f 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -50,9 +50,13 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.4",
"@types/node": "18.11.9",
+ "@typescript-eslint/eslint-plugin": "^5.45.0",
+ "@typescript-eslint/parser": "^5.45.0",
"autoprefixer": "^10.4.7",
- "eslint": "^8.28.0",
+ "eslint": "^8.29.0",
"eslint-config-next": "^13.0.5",
+ "eslint-import-resolver-typescript": "^3.5.2",
+ "eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-simple-import-sort": "^8.0.0",
"postcss": "^8.4.14",
"prettier": "2.7.1",
@@ -60,32 +64,6 @@
"typescript": "^4.9.3"
}
},
- "node_modules/@ampproject/remapping": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
- "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
- "peer": true,
- "dependencies": {
- "@jridgewell/gen-mapping": "^0.1.0",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
- "node_modules/@ampproject/remapping/node_modules/@jridgewell/gen-mapping": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
- "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
- "peer": true,
- "dependencies": {
- "@jridgewell/set-array": "^1.0.0",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- },
- "engines": {
- "node": ">=6.0.0"
- }
- },
"node_modules/@babel/code-frame": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
@@ -97,77 +75,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/compat-data": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz",
- "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==",
- "peer": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/core": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz",
- "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==",
- "peer": true,
- "dependencies": {
- "@ampproject/remapping": "^2.1.0",
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.19.0",
- "@babel/helper-compilation-targets": "^7.19.1",
- "@babel/helper-module-transforms": "^7.19.0",
- "@babel/helpers": "^7.19.0",
- "@babel/parser": "^7.19.1",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.1",
- "@babel/types": "^7.19.0",
- "convert-source-map": "^1.7.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.1",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "funding": {
- "type": "opencollective",
- "url": "https://opencollective.com/babel"
- }
- },
- "node_modules/@babel/core/node_modules/debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "peer": true,
- "dependencies": {
- "ms": "2.1.2"
- },
- "engines": {
- "node": ">=6.0"
- },
- "peerDependenciesMeta": {
- "supports-color": {
- "optional": true
- }
- }
- },
- "node_modules/@babel/core/node_modules/ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "peer": true
- },
- "node_modules/@babel/core/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "peer": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"node_modules/@babel/generator": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz",
@@ -192,33 +99,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-compilation-targets": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz",
- "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==",
- "peer": true,
- "dependencies": {
- "@babel/compat-data": "^7.19.1",
- "@babel/helper-validator-option": "^7.18.6",
- "browserslist": "^4.21.3",
- "semver": "^6.3.0"
- },
- "engines": {
- "node": ">=6.9.0"
- },
- "peerDependencies": {
- "@babel/core": "^7.0.0"
- }
- },
- "node_modules/@babel/helper-compilation-targets/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "peer": true,
- "bin": {
- "semver": "bin/semver.js"
- }
- },
"node_modules/@babel/helper-environment-visitor": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
@@ -261,25 +141,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-module-transforms": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz",
- "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==",
- "peer": true,
- "dependencies": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-simple-access": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/helper-validator-identifier": "^7.18.6",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.0",
- "@babel/types": "^7.19.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-plugin-utils": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
@@ -288,18 +149,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-simple-access": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz",
- "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==",
- "peer": true,
- "dependencies": {
- "@babel/types": "^7.18.6"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/helper-split-export-declaration": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
@@ -327,29 +176,6 @@
"node": ">=6.9.0"
}
},
- "node_modules/@babel/helper-validator-option": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
- "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
- "peer": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
- "node_modules/@babel/helpers": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz",
- "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==",
- "peer": true,
- "dependencies": {
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.0",
- "@babel/types": "^7.19.0"
- },
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/@babel/highlight": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
@@ -1264,6 +1090,12 @@
"hoist-non-react-statics": "^3.3.0"
}
},
+ "node_modules/@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
"node_modules/@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -1336,6 +1168,12 @@
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
+ "node_modules/@types/semver": {
+ "version": "7.3.13",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
+ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+ "dev": true
+ },
"node_modules/@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
@@ -1351,15 +1189,71 @@
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
"integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw=="
},
- "node_modules/@typescript-eslint/parser": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.44.0.tgz",
- "integrity": "sha512-H7LCqbZnKqkkgQHaKLGC6KUjt3pjJDx8ETDqmwncyb6PuoigYajyAwBGz08VU/l86dZWZgI4zm5k2VaKqayYyA==",
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz",
+ "integrity": "sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.44.0",
- "@typescript-eslint/types": "5.44.0",
- "@typescript-eslint/typescript-estree": "5.44.0",
+ "@typescript-eslint/scope-manager": "5.45.0",
+ "@typescript-eslint/type-utils": "5.45.0",
+ "@typescript-eslint/utils": "5.45.0",
+ "debug": "^4.3.4",
+ "ignore": "^5.2.0",
+ "natural-compare-lite": "^1.4.0",
+ "regexpp": "^3.2.0",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^5.0.0",
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz",
+ "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "5.45.0",
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/typescript-estree": "5.45.0",
"debug": "^4.3.4"
},
"engines": {
@@ -1402,13 +1296,13 @@
"dev": true
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz",
- "integrity": "sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g==",
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz",
+ "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.44.0",
- "@typescript-eslint/visitor-keys": "5.44.0"
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/visitor-keys": "5.45.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1418,10 +1312,60 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz",
+ "integrity": "sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/typescript-estree": "5.45.0",
+ "@typescript-eslint/utils": "5.45.0",
+ "debug": "^4.3.4",
+ "tsutils": "^3.21.0"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "*"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils/node_modules/debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "dependencies": {
+ "ms": "2.1.2"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils/node_modules/ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ },
"node_modules/@typescript-eslint/types": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.44.0.tgz",
- "integrity": "sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ==",
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz",
+ "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1432,13 +1376,13 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz",
- "integrity": "sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw==",
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz",
+ "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.44.0",
- "@typescript-eslint/visitor-keys": "5.44.0",
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/visitor-keys": "5.45.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -1481,13 +1425,61 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
- "node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz",
- "integrity": "sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ==",
+ "node_modules/@typescript-eslint/utils": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.45.0.tgz",
+ "integrity": "sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.44.0",
+ "@types/json-schema": "^7.0.9",
+ "@types/semver": "^7.3.12",
+ "@typescript-eslint/scope-manager": "5.45.0",
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/typescript-estree": "5.45.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^3.0.0",
+ "semver": "^7.3.7"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ },
+ "engines": {
+ "node": ">=8.0.0"
+ }
+ },
+ "node_modules/@typescript-eslint/utils/node_modules/estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true,
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz",
+ "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==",
+ "dev": true,
+ "dependencies": {
+ "@typescript-eslint/types": "5.45.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -1890,6 +1882,7 @@
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
"integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -2479,7 +2472,8 @@
"node_modules/electron-to-chromium": {
"version": "1.4.206",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz",
- "integrity": "sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA=="
+ "integrity": "sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA==",
+ "dev": true
},
"node_modules/emoji-regex": {
"version": "9.2.2",
@@ -2601,6 +2595,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
"integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true,
"engines": {
"node": ">=6"
}
@@ -2614,9 +2609,9 @@
}
},
"node_modules/eslint": {
- "version": "8.28.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz",
- "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==",
+ "version": "8.29.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
+ "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.3.3",
@@ -2906,6 +2901,27 @@
"semver": "bin/semver.js"
}
},
+ "node_modules/eslint-plugin-prettier": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz",
+ "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==",
+ "dev": true,
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.28.0",
+ "prettier": ">=2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
"node_modules/eslint-plugin-react": {
"version": "7.31.11",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz",
@@ -3273,6 +3289,12 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
+ "node_modules/fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
"node_modules/fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
@@ -3501,15 +3523,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
- "node_modules/gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "peer": true,
- "engines": {
- "node": ">=6.9.0"
- }
- },
"node_modules/get-intrinsic": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
@@ -4240,18 +4253,6 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
- "node_modules/json5": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
- "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
- "peer": true,
- "bin": {
- "json5": "lib/cli.js"
- },
- "engines": {
- "node": ">=6"
- }
- },
"node_modules/jsonp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz",
@@ -5091,6 +5092,12 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "node_modules/natural-compare-lite": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+ "dev": true
+ },
"node_modules/next": {
"version": "12.3.1",
"resolved": "https://registry.npmjs.org/next/-/next-12.3.1.tgz",
@@ -5146,7 +5153,8 @@
"node_modules/node-releases": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
- "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
},
"node_modules/normalize-path": {
"version": "3.0.0",
@@ -5616,6 +5624,18 @@
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -7022,6 +7042,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz",
"integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==",
+ "dev": true,
"funding": [
{
"type": "opencollective",
@@ -7227,28 +7248,6 @@
}
},
"dependencies": {
- "@ampproject/remapping": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
- "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==",
- "peer": true,
- "requires": {
- "@jridgewell/gen-mapping": "^0.1.0",
- "@jridgewell/trace-mapping": "^0.3.9"
- },
- "dependencies": {
- "@jridgewell/gen-mapping": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz",
- "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==",
- "peer": true,
- "requires": {
- "@jridgewell/set-array": "^1.0.0",
- "@jridgewell/sourcemap-codec": "^1.4.10"
- }
- }
- }
- },
"@babel/code-frame": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz",
@@ -7257,58 +7256,6 @@
"@babel/highlight": "^7.18.6"
}
},
- "@babel/compat-data": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.1.tgz",
- "integrity": "sha512-72a9ghR0gnESIa7jBN53U32FOVCEoztyIlKaNoU05zRhEecduGK9L9c3ww7Mp06JiR+0ls0GBPFJQwwtjn9ksg==",
- "peer": true
- },
- "@babel/core": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.1.tgz",
- "integrity": "sha512-1H8VgqXme4UXCRv7/Wa1bq7RVymKOzC7znjyFM8KiEzwFqcKUKYNoQef4GhdklgNvoBXyW4gYhuBNCM5o1zImw==",
- "peer": true,
- "requires": {
- "@ampproject/remapping": "^2.1.0",
- "@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.19.0",
- "@babel/helper-compilation-targets": "^7.19.1",
- "@babel/helper-module-transforms": "^7.19.0",
- "@babel/helpers": "^7.19.0",
- "@babel/parser": "^7.19.1",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.1",
- "@babel/types": "^7.19.0",
- "convert-source-map": "^1.7.0",
- "debug": "^4.1.0",
- "gensync": "^1.0.0-beta.2",
- "json5": "^2.2.1",
- "semver": "^6.3.0"
- },
- "dependencies": {
- "debug": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
- "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
- "peer": true,
- "requires": {
- "ms": "2.1.2"
- }
- },
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
- "peer": true
- },
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "peer": true
- }
- }
- },
"@babel/generator": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.0.tgz",
@@ -7327,26 +7274,6 @@
"@babel/types": "^7.18.6"
}
},
- "@babel/helper-compilation-targets": {
- "version": "7.19.1",
- "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.1.tgz",
- "integrity": "sha512-LlLkkqhCMyz2lkQPvJNdIYU7O5YjWRgC2R4omjCTpZd8u8KMQzZvX4qce+/BluN1rcQiV7BoGUpmQ0LeHerbhg==",
- "peer": true,
- "requires": {
- "@babel/compat-data": "^7.19.1",
- "@babel/helper-validator-option": "^7.18.6",
- "browserslist": "^4.21.3",
- "semver": "^6.3.0"
- },
- "dependencies": {
- "semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
- "peer": true
- }
- }
- },
"@babel/helper-environment-visitor": {
"version": "7.18.9",
"resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz",
@@ -7377,36 +7304,11 @@
"@babel/types": "^7.18.6"
}
},
- "@babel/helper-module-transforms": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz",
- "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==",
- "peer": true,
- "requires": {
- "@babel/helper-environment-visitor": "^7.18.9",
- "@babel/helper-module-imports": "^7.18.6",
- "@babel/helper-simple-access": "^7.18.6",
- "@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/helper-validator-identifier": "^7.18.6",
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.0",
- "@babel/types": "^7.19.0"
- }
- },
"@babel/helper-plugin-utils": {
"version": "7.19.0",
"resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz",
"integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw=="
},
- "@babel/helper-simple-access": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz",
- "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==",
- "peer": true,
- "requires": {
- "@babel/types": "^7.18.6"
- }
- },
"@babel/helper-split-export-declaration": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz",
@@ -7425,23 +7327,6 @@
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
"integrity": "sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g=="
},
- "@babel/helper-validator-option": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz",
- "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==",
- "peer": true
- },
- "@babel/helpers": {
- "version": "7.19.0",
- "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz",
- "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==",
- "peer": true,
- "requires": {
- "@babel/template": "^7.18.10",
- "@babel/traverse": "^7.19.0",
- "@babel/types": "^7.19.0"
- }
- },
"@babel/highlight": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz",
@@ -7781,8 +7666,7 @@
"@headlessui/react": {
"version": "1.6.6",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-1.6.6.tgz",
- "integrity": "sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q==",
- "requires": {}
+ "integrity": "sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q=="
},
"@humanwhocodes/config-array": {
"version": "0.11.7",
@@ -8070,6 +7954,12 @@
"hoist-non-react-statics": "^3.3.0"
}
},
+ "@types/json-schema": {
+ "version": "7.0.11",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz",
+ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==",
+ "dev": true
+ },
"@types/json5": {
"version": "0.0.29",
"resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz",
@@ -8142,6 +8032,12 @@
"resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
"integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
},
+ "@types/semver": {
+ "version": "7.3.13",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz",
+ "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==",
+ "dev": true
+ },
"@types/unist": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz",
@@ -8157,15 +8053,49 @@
"resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-8.3.4.tgz",
"integrity": "sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw=="
},
- "@typescript-eslint/parser": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.44.0.tgz",
- "integrity": "sha512-H7LCqbZnKqkkgQHaKLGC6KUjt3pjJDx8ETDqmwncyb6PuoigYajyAwBGz08VU/l86dZWZgI4zm5k2VaKqayYyA==",
+ "@typescript-eslint/eslint-plugin": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.45.0.tgz",
+ "integrity": "sha512-CXXHNlf0oL+Yg021cxgOdMHNTXD17rHkq7iW6RFHoybdFgQBjU3yIXhhcPpGwr1CjZlo6ET8C6tzX5juQoXeGA==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.44.0",
- "@typescript-eslint/types": "5.44.0",
- "@typescript-eslint/typescript-estree": "5.44.0",
+ "@typescript-eslint/scope-manager": "5.45.0",
+ "@typescript-eslint/type-utils": "5.45.0",
+ "@typescript-eslint/utils": "5.45.0",
+ "debug": "^4.3.4",
+ "ignore": "^5.2.0",
+ "natural-compare-lite": "^1.4.0",
+ "regexpp": "^3.2.0",
+ "semver": "^7.3.7",
+ "tsutils": "^3.21.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
+ }
+ },
+ "@typescript-eslint/parser": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.45.0.tgz",
+ "integrity": "sha512-brvs/WSM4fKUmF5Ot/gEve6qYiCMjm6w4HkHPfS6ZNmxTS0m0iNN4yOChImaCkqc1hRwFGqUyanMXuGal6oyyQ==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/scope-manager": "5.45.0",
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/typescript-estree": "5.45.0",
"debug": "^4.3.4"
},
"dependencies": {
@@ -8187,29 +8117,58 @@
}
},
"@typescript-eslint/scope-manager": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.44.0.tgz",
- "integrity": "sha512-2pKml57KusI0LAhgLKae9kwWeITZ7IsZs77YxyNyIVOwQ1kToyXRaJLl+uDEXzMN5hnobKUOo2gKntK9H1YL8g==",
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.45.0.tgz",
+ "integrity": "sha512-noDMjr87Arp/PuVrtvN3dXiJstQR1+XlQ4R1EvzG+NMgXi8CuMCXpb8JqNtFHKceVSQ985BZhfRdowJzbv4yKw==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.44.0",
- "@typescript-eslint/visitor-keys": "5.44.0"
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/visitor-keys": "5.45.0"
+ }
+ },
+ "@typescript-eslint/type-utils": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.45.0.tgz",
+ "integrity": "sha512-DY7BXVFSIGRGFZ574hTEyLPRiQIvI/9oGcN8t1A7f6zIs6ftbrU0nhyV26ZW//6f85avkwrLag424n+fkuoJ1Q==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/typescript-estree": "5.45.0",
+ "@typescript-eslint/utils": "5.45.0",
+ "debug": "^4.3.4",
+ "tsutils": "^3.21.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "dev": true,
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+ "dev": true
+ }
}
},
"@typescript-eslint/types": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.44.0.tgz",
- "integrity": "sha512-Tp+zDnHmGk4qKR1l+Y1rBvpjpm5tGXX339eAlRBDg+kgZkz9Bw+pqi4dyseOZMsGuSH69fYfPJCBKBrbPCxYFQ==",
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.45.0.tgz",
+ "integrity": "sha512-QQij+u/vgskA66azc9dCmx+rev79PzX8uDHpsqSjEFtfF2gBUTRCpvYMh2gw2ghkJabNkPlSUCimsyBEQZd1DA==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.44.0.tgz",
- "integrity": "sha512-M6Jr+RM7M5zeRj2maSfsZK2660HKAJawv4Ud0xT+yauyvgrsHu276VtXlKDFnEmhG+nVEd0fYZNXGoAgxwDWJw==",
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.45.0.tgz",
+ "integrity": "sha512-maRhLGSzqUpFcZgXxg1qc/+H0bT36lHK4APhp0AEUVrpSwXiRAomm/JGjSG+kNUio5kAa3uekCYu/47cnGn5EQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.44.0",
- "@typescript-eslint/visitor-keys": "5.44.0",
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/visitor-keys": "5.45.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -8234,13 +8193,47 @@
}
}
},
- "@typescript-eslint/visitor-keys": {
- "version": "5.44.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.44.0.tgz",
- "integrity": "sha512-a48tLG8/4m62gPFbJ27FxwCOqPKxsb8KC3HkmYoq2As/4YyjQl1jDbRr1s63+g4FS/iIehjmN3L5UjmKva1HzQ==",
+ "@typescript-eslint/utils": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.45.0.tgz",
+ "integrity": "sha512-OUg2JvsVI1oIee/SwiejTot2OxwU8a7UfTFMOdlhD2y+Hl6memUSL4s98bpUTo8EpVEr0lmwlU7JSu/p2QpSvA==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.44.0",
+ "@types/json-schema": "^7.0.9",
+ "@types/semver": "^7.3.12",
+ "@typescript-eslint/scope-manager": "5.45.0",
+ "@typescript-eslint/types": "5.45.0",
+ "@typescript-eslint/typescript-estree": "5.45.0",
+ "eslint-scope": "^5.1.1",
+ "eslint-utils": "^3.0.0",
+ "semver": "^7.3.7"
+ },
+ "dependencies": {
+ "eslint-scope": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
+ "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "estraverse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
+ "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
+ "dev": true
+ }
+ }
+ },
+ "@typescript-eslint/visitor-keys": {
+ "version": "5.45.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.45.0.tgz",
+ "integrity": "sha512-jc6Eccbn2RtQPr1s7th6jJWQHBHI6GBVQkCHoJFQ5UreaKm59Vxw+ynQUPPY2u2Amquc+7tmEoC2G52ApsGNNg==",
+ "dev": true,
+ "requires": {
+ "@typescript-eslint/types": "5.45.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -8254,8 +8247,7 @@
"version": "5.3.2",
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
"integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"acorn-node": {
"version": "1.8.2",
@@ -8458,8 +8450,7 @@
"axios-auth-refresh": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/axios-auth-refresh/-/axios-auth-refresh-3.3.3.tgz",
- "integrity": "sha512-2IbDhJ/h6ddNBBnnzn1VFK/qx17pE9aVqiafB8rx5LVHsJ1HtFpUGkbXY7PzTG+8P9HJWcyA3fNZl9BikSuilg==",
- "requires": {}
+ "integrity": "sha512-2IbDhJ/h6ddNBBnnzn1VFK/qx17pE9aVqiafB8rx5LVHsJ1HtFpUGkbXY7PzTG+8P9HJWcyA3fNZl9BikSuilg=="
},
"axobject-query": {
"version": "2.2.0",
@@ -8540,6 +8531,7 @@
"version": "4.21.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
"integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
+ "dev": true,
"requires": {
"caniuse-lite": "^1.0.30001370",
"electron-to-chromium": "^1.4.202",
@@ -8988,7 +8980,8 @@
"electron-to-chromium": {
"version": "1.4.206",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.206.tgz",
- "integrity": "sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA=="
+ "integrity": "sha512-h+Fadt1gIaQ06JaIiyqPsBjJ08fV5Q7md+V8bUvQW/9OvXfL2LRICTz2EcnnCP7QzrFTS6/27MRV6Bl9Yn97zA==",
+ "dev": true
},
"emoji-regex": {
"version": "9.2.2",
@@ -9089,7 +9082,8 @@
"escalade": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
- "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
+ "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+ "dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
@@ -9097,9 +9091,9 @@
"integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg=="
},
"eslint": {
- "version": "8.28.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.28.0.tgz",
- "integrity": "sha512-S27Di+EVyMxcHiwDrFzk8dJYAaD+/5SoWKxL1ri/71CRHsnJnRDPNt2Kzj24+MT9FDupf4aqqyqPrvI8MvQ4VQ==",
+ "version": "8.29.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.29.0.tgz",
+ "integrity": "sha512-isQ4EEiyUjZFbEKvEGJKKGBwXtvXX+zJbkVKCgTuB9t/+jUBcy8avhkEwWJecI15BkRkOYmvIM5ynbhRjEkoeg==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.3.3",
@@ -9406,6 +9400,15 @@
}
}
},
+ "eslint-plugin-prettier": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz",
+ "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==",
+ "dev": true,
+ "requires": {
+ "prettier-linter-helpers": "^1.0.0"
+ }
+ },
"eslint-plugin-react": {
"version": "7.31.11",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz",
@@ -9461,15 +9464,13 @@
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz",
"integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"eslint-plugin-simple-import-sort": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-8.0.0.tgz",
"integrity": "sha512-bXgJQ+lqhtQBCuWY/FUWdB27j4+lqcvXv5rUARkzbeWLwea+S5eBZEQrhnO+WgX3ZoJHVj0cn943iyXwByHHQw==",
- "dev": true,
- "requires": {}
+ "dev": true
},
"eslint-scope": {
"version": "7.1.1",
@@ -9582,6 +9583,12 @@
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"dev": true
},
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
"fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
@@ -9748,12 +9755,6 @@
"integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==",
"dev": true
},
- "gensync": {
- "version": "1.0.0-beta.2",
- "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
- "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
- "peer": true
- },
"get-intrinsic": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
@@ -10268,12 +10269,6 @@
"integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
"dev": true
},
- "json5": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
- "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
- "peer": true
- },
"jsonp": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/jsonp/-/jsonp-0.2.1.tgz",
@@ -10824,6 +10819,12 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
+ "natural-compare-lite": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
+ "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
+ "dev": true
+ },
"next": {
"version": "12.3.1",
"resolved": "https://registry.npmjs.org/next/-/next-12.3.1.tgz",
@@ -10853,7 +10854,8 @@
"node-releases": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
- "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg=="
+ "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
+ "dev": true
},
"normalize-path": {
"version": "3.0.0",
@@ -11159,6 +11161,15 @@
"integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==",
"dev": true
},
+ "prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "requires": {
+ "fast-diff": "^1.1.2"
+ }
+ },
"process-nextick-args": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
@@ -11430,8 +11441,7 @@
"react-table": {
"version": "7.8.0",
"resolved": "https://registry.npmjs.org/react-table/-/react-table-7.8.0.tgz",
- "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA==",
- "requires": {}
+ "integrity": "sha512-hNaz4ygkZO4bESeFfnfOft73iBUj8K5oKi1EcSHPAibEydfsX2MyU6Z8KCr3mv3C9Kqqh71U+DhZkFvibbnPbA=="
},
"read-cache": {
"version": "1.0.0",
@@ -11472,8 +11482,7 @@
"redux-thunk": {
"version": "2.4.1",
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-2.4.1.tgz",
- "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q==",
- "requires": {}
+ "integrity": "sha512-OOYGNY5Jy2TWvTL1KgAlVy6dcx3siPJ1wTq741EPyUKfn6W6nChdICjZwCd0p8AZBs5kWpZlbkXW2nE/zjUa+Q=="
},
"regenerator-runtime": {
"version": "0.13.11",
@@ -11825,8 +11834,7 @@
"styled-jsx": {
"version": "5.0.7",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.0.7.tgz",
- "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA==",
- "requires": {}
+ "integrity": "sha512-b3sUzamS086YLRuvnaDigdAewz1/EFYlHpYBP5mZovKEdQQOIIYq8lApylub3HHZ6xFjV051kkGU7cudJmrXEA=="
},
"stylis": {
"version": "4.0.13",
@@ -12171,6 +12179,7 @@
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz",
"integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==",
+ "dev": true,
"requires": {
"escalade": "^3.1.1",
"picocolors": "^1.0.0"
@@ -12188,14 +12197,12 @@
"use-memo-one": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/use-memo-one/-/use-memo-one-1.1.3.tgz",
- "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ==",
- "requires": {}
+ "integrity": "sha512-g66/K7ZQGYrI6dy8GLpVcMsBp4s17xNkYJVSMvTEevGy3nDxHOfE6z8BVE22+5G5x7t3+bhzrlTDB7ObrEE0cQ=="
},
"use-sync-external-store": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",
- "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==",
- "requires": {}
+ "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA=="
},
"util-deprecate": {
"version": "1.0.2",
diff --git a/frontend/package.json b/frontend/package.json
index 7d6571da1..ebfdbfe3c 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -53,9 +53,12 @@
"devDependencies": {
"@tailwindcss/typography": "^0.5.4",
"@types/node": "18.11.9",
+ "@typescript-eslint/eslint-plugin": "^5.45.0",
+ "@typescript-eslint/parser": "^5.45.0",
"autoprefixer": "^10.4.7",
- "eslint": "^8.28.0",
+ "eslint": "^8.29.0",
"eslint-config-next": "^13.0.5",
+ "eslint-import-resolver-typescript": "^3.5.2",
"eslint-plugin-simple-import-sort": "^8.0.0",
"postcss": "^8.4.14",
"prettier": "2.7.1",
diff --git a/frontend/pages/api/auth/IssueBackupPrivateKey.js b/frontend/pages/api/auth/IssueBackupPrivateKey.js
index 43e9f64ee..9a31f7b00 100644
--- a/frontend/pages/api/auth/IssueBackupPrivateKey.js
+++ b/frontend/pages/api/auth/IssueBackupPrivateKey.js
@@ -31,8 +31,8 @@ const issueBackupPrivateKey = ({
if (res.status == 200) {
return res;
} else {
- return res;
console.log("Failed to issue the backup key");
+ return res;
}
});
};
diff --git a/frontend/pages/api/auth/Logout.js b/frontend/pages/api/auth/Logout.ts
similarity index 89%
rename from frontend/pages/api/auth/Logout.js
rename to frontend/pages/api/auth/Logout.ts
index 24c338a27..4dbcb7bca 100644
--- a/frontend/pages/api/auth/Logout.js
+++ b/frontend/pages/api/auth/Logout.ts
@@ -3,11 +3,8 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route logs the user out. Note: the user should authorized to do this.
* We first try to log out - if the authorization fails (response.status = 401), we refetch the new token, and then retry
- * @param {*} req
- * @param {*} res
- * @returns
*/
-const logout = async (req, res) => {
+const logout = async () => {
return SecurityClient.fetchCall("/api/v1/auth/logout", {
method: "POST",
headers: {
@@ -15,7 +12,7 @@ const logout = async (req, res) => {
},
credentials: "include",
}).then((res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
SecurityClient.setToken("");
// Delete the cookie by not setting a value; Alternatively clear the local storage
localStorage.setItem("publicKey", "");
diff --git a/frontend/pages/api/organization/GetOrg.js b/frontend/pages/api/organization/GetOrg.ts
similarity index 65%
rename from frontend/pages/api/organization/GetOrg.js
rename to frontend/pages/api/organization/GetOrg.ts
index 74782a564..ecb07bd2d 100644
--- a/frontend/pages/api/organization/GetOrg.js
+++ b/frontend/pages/api/organization/GetOrg.ts
@@ -2,18 +2,17 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get info about a certain org
- * @param {*} req
- * @param {*} res
+ * @param {string} orgId - the organization ID
* @returns
*/
-const getOrganization = (req, res) => {
- return SecurityClient.fetchCall("/api/v1/organization/" + req.orgId, {
+const getOrganization = ({ orgId }: { orgId: string; }) => {
+ return SecurityClient.fetchCall("/api/v1/organization/" + orgId, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).organization;
} else {
console.log("Failed to get org info");
diff --git a/frontend/pages/api/organization/GetOrgUsers.js b/frontend/pages/api/organization/GetOrgUsers.ts
similarity index 67%
rename from frontend/pages/api/organization/GetOrgUsers.js
rename to frontend/pages/api/organization/GetOrgUsers.ts
index feeb60477..53b9518cf 100644
--- a/frontend/pages/api/organization/GetOrgUsers.js
+++ b/frontend/pages/api/organization/GetOrgUsers.ts
@@ -2,13 +2,13 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get all the users in an org.
- * @param {*} req
- * @param {*} res
+ * @param {object} obj
+ * @param {string} obj.orgId - organization Id
* @returns
*/
-const getOrganizationUsers = (req, res) => {
+const getOrganizationUsers = ({ orgId }: { orgId: string; }) => {
return SecurityClient.fetchCall(
- "/api/v1/organization/" + req.orgId + "/users",
+ "/api/v1/organization/" + orgId + "/users",
{
method: "GET",
headers: {
@@ -16,7 +16,7 @@ const getOrganizationUsers = (req, res) => {
},
}
).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).users;
} else {
console.log("Failed to get org users");
diff --git a/frontend/pages/api/organization/getOrgs.js b/frontend/pages/api/organization/getOrgs.ts
similarity index 81%
rename from frontend/pages/api/organization/getOrgs.js
rename to frontend/pages/api/organization/getOrgs.ts
index 6720c22a9..cc655642f 100644
--- a/frontend/pages/api/organization/getOrgs.js
+++ b/frontend/pages/api/organization/getOrgs.ts
@@ -2,18 +2,16 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get the all the orgs of a certain user.
- * @param {*} req
- * @param {*} res
* @returns
*/
-const getOrganizations = (req, res) => {
+const getOrganizations = () => {
return SecurityClient.fetchCall("/api/v1/organization", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).organizations;
} else {
console.log("Failed to get orgs of a user");
diff --git a/frontend/pages/api/user/getUser.js b/frontend/pages/api/user/getUser.ts
similarity index 79%
rename from frontend/pages/api/user/getUser.js
rename to frontend/pages/api/user/getUser.ts
index 10ca0d5f8..4bfebc5fe 100644
--- a/frontend/pages/api/user/getUser.js
+++ b/frontend/pages/api/user/getUser.ts
@@ -2,18 +2,15 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route gets the information about a specific user.
- * @param {*} req
- * @param {*} res
- * @returns
*/
-const getUser = (req, res) => {
+const getUser = () => {
return SecurityClient.fetchCall("/api/v1/user", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).user;
} else {
console.log("Failed to get user info");
diff --git a/frontend/pages/api/workspace/createWorkspace.js b/frontend/pages/api/workspace/createWorkspace.ts
similarity index 61%
rename from frontend/pages/api/workspace/createWorkspace.js
rename to frontend/pages/api/workspace/createWorkspace.ts
index d5c44e2a6..0cedb0a57 100644
--- a/frontend/pages/api/workspace/createWorkspace.js
+++ b/frontend/pages/api/workspace/createWorkspace.ts
@@ -1,11 +1,12 @@
import SecurityClient from "~/utilities/SecurityClient";
/**
- * This route creates a new workspace for a user.
- * @param {*} workspaceName
+ * This route creates a new workspace for a user within a certain organization.
+ * @param {string} workspaceName - project Name
+ * @param {string} organizationId - org ID
* @returns
*/
-const createWorkspace = (workspaceName, organizationId) => {
+const createWorkspace = ( { workspaceName, organizationId }: { workspaceName: string; organizationId: string; }) => {
return SecurityClient.fetchCall("/api/v1/workspace", {
method: "POST",
headers: {
@@ -16,7 +17,7 @@ const createWorkspace = (workspaceName, organizationId) => {
organizationId: organizationId,
}),
}).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).workspace;
} else {
console.log("Failed to create a project");
diff --git a/frontend/pages/api/workspace/getLatestFileKey.js b/frontend/pages/api/workspace/getLatestFileKey.ts
similarity index 79%
rename from frontend/pages/api/workspace/getLatestFileKey.js
rename to frontend/pages/api/workspace/getLatestFileKey.ts
index a5b14520a..86ecb7456 100644
--- a/frontend/pages/api/workspace/getLatestFileKey.js
+++ b/frontend/pages/api/workspace/getLatestFileKey.ts
@@ -2,10 +2,10 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* Get the latest key pairs from a certain workspace
- * @param {*} workspaceId
+ * @param {string} workspaceId
* @returns
*/
-const getLatestFileKey = (workspaceId) => {
+const getLatestFileKey = ({ workspaceId } : { workspaceId: string; }) => {
return SecurityClient.fetchCall(
"/api/v1/key/" + workspaceId + "/latest",
{
@@ -15,7 +15,7 @@ const getLatestFileKey = (workspaceId) => {
},
}
).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return await res.json();
} else {
console.log("Failed to get the latest key pairs for a certain project");
diff --git a/frontend/pages/api/workspace/getWorkspaceInfo.js b/frontend/pages/api/workspace/getProjectInfo.ts
similarity index 62%
rename from frontend/pages/api/workspace/getWorkspaceInfo.js
rename to frontend/pages/api/workspace/getProjectInfo.ts
index 4266dbbaa..c6eef9dce 100644
--- a/frontend/pages/api/workspace/getWorkspaceInfo.js
+++ b/frontend/pages/api/workspace/getProjectInfo.ts
@@ -2,13 +2,12 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get the information of a certain project.
- * @param {*} req
- * @param {*} res
+ * @param {*} projectId - project ID (we renamed workspaces to projects in the app)
* @returns
*/
-const getWorkspaceInfo = (req, res) => {
+const getProjectInfo = ({ projectId }: { projectId: string; }) => {
return SecurityClient.fetchCall(
- "/api/v1/workspace/" + req.workspaceId,
+ "/api/v1/workspace/" + projectId,
{
method: "GET",
headers: {
@@ -16,7 +15,7 @@ const getWorkspaceInfo = (req, res) => {
},
}
).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).workspace;
} else {
console.log("Failed to get project info");
@@ -24,4 +23,4 @@ const getWorkspaceInfo = (req, res) => {
});
};
-export default getWorkspaceInfo;
+export default getProjectInfo;
diff --git a/frontend/pages/api/workspace/getWorkspaceKeys.js b/frontend/pages/api/workspace/getWorkspaceKeys.ts
similarity index 73%
rename from frontend/pages/api/workspace/getWorkspaceKeys.js
rename to frontend/pages/api/workspace/getWorkspaceKeys.ts
index 368d00fa0..09b468662 100644
--- a/frontend/pages/api/workspace/getWorkspaceKeys.js
+++ b/frontend/pages/api/workspace/getWorkspaceKeys.ts
@@ -2,13 +2,12 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get the public keys of everyone in your workspace.
- * @param {*} req
- * @param {*} res
+ * @param {string} workspaceId
* @returns
*/
-const getWorkspaceKeys = (req, res) => {
+const getWorkspaceKeys = ({ workspaceId }: { workspaceId: string; }) => {
return SecurityClient.fetchCall(
- "/api/v1/workspace/" + req.workspaceId + "/keys",
+ "/api/v1/workspace/" + workspaceId + "/keys",
{
method: "GET",
headers: {
@@ -16,7 +15,7 @@ const getWorkspaceKeys = (req, res) => {
},
}
).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).publicKeys;
} else {
console.log("Failed to get the public keys of everyone in the workspace");
diff --git a/frontend/pages/api/workspace/getWorkspaceUsers.js b/frontend/pages/api/workspace/getWorkspaceUsers.ts
similarity index 69%
rename from frontend/pages/api/workspace/getWorkspaceUsers.js
rename to frontend/pages/api/workspace/getWorkspaceUsers.ts
index 4d87836c7..9805c2695 100644
--- a/frontend/pages/api/workspace/getWorkspaceUsers.js
+++ b/frontend/pages/api/workspace/getWorkspaceUsers.ts
@@ -2,13 +2,12 @@ import SecurityClient from "~/utilities/SecurityClient";
/**
* This route lets us get all the users in the workspace.
- * @param {*} req
- * @param {*} res
+ * @param {string} workspaceId - workspace ID
* @returns
*/
-const getWorkspaceUsers = (req, res) => {
+const getWorkspaceUsers = ({ workspaceId }: { workspaceId: string; }) => {
return SecurityClient.fetchCall(
- "/api/v1/workspace/" + req.workspaceId + "/users",
+ "/api/v1/workspace/" + workspaceId + "/users",
{
method: "GET",
headers: {
@@ -16,7 +15,7 @@ const getWorkspaceUsers = (req, res) => {
},
}
).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).users;
} else {
console.log("Failed to get Project Users");
diff --git a/frontend/pages/api/workspace/getWorkspaces.js b/frontend/pages/api/workspace/getWorkspaces.ts
similarity index 69%
rename from frontend/pages/api/workspace/getWorkspaces.js
rename to frontend/pages/api/workspace/getWorkspaces.ts
index ccaf49e9b..9427c03d0 100644
--- a/frontend/pages/api/workspace/getWorkspaces.js
+++ b/frontend/pages/api/workspace/getWorkspaces.ts
@@ -1,19 +1,17 @@
import SecurityClient from "~/utilities/SecurityClient";
/**
- * This route lets us get the public keys of everyone in your workspace.
- * @param {*} req
- * @param {*} res
+ * This route lets us get the workspaces of a certain user
* @returns
*/
-const getWorkspaces = (req, res) => {
+const getWorkspaces = () => {
return SecurityClient.fetchCall("/api/v1/workspace", {
method: "GET",
headers: {
"Content-Type": "application/json",
},
}).then(async (res) => {
- if (res.status == 200) {
+ if (res?.status == 200) {
return (await res.json()).workspaces;
} else {
console.log("Failed to get projects");
diff --git a/frontend/pages/dashboard/[id].js b/frontend/pages/dashboard/[id].js
index 42abf24db..b2dfd70f4 100644
--- a/frontend/pages/dashboard/[id].js
+++ b/frontend/pages/dashboard/[id].js
@@ -378,9 +378,9 @@ export default function Dashboard() {
} else if (duplicatesExist) {
console.log("Remove the duplicated entries first!");
} else {
- // Once "Save changed is clicked", disable that button
+ // Once "Save changes is clicked", disable that button
setButtonReady(false);
- pushKeys(obj, router.query.id, env);
+ pushKeys({obj, workspaceId: router.query.id, env});
/**
* Check which integrations are active for this project and environment
diff --git a/frontend/pages/home/[id].tsx b/frontend/pages/home/[id].tsx
new file mode 100644
index 000000000..21f15fcc3
--- /dev/null
+++ b/frontend/pages/home/[id].tsx
@@ -0,0 +1,142 @@
+import React, { useEffect, useState } from "react";
+import Link from "next/link";
+import { useRouter } from "next/router";
+import { IconProp } from "@fortawesome/fontawesome-svg-core";
+import { faSlack } from "@fortawesome/free-brands-svg-icons";
+import { faCheckCircle, faHandPeace, faNetworkWired, faPlug, faPlus, faStar, faUserPlus } from "@fortawesome/free-solid-svg-icons";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+
+import getOrganizationUsers from "../api/organization/GetOrgUsers";
+import checkUserAction from "../api/userActions/checkUserAction";
+import registerUserAction from "../api/userActions/registerUserAction";
+
+type ItemProps = {
+ text: string;
+ subText: string;
+ complete: boolean;
+ icon: IconProp;
+ time: string;
+ userAction?: string;
+ link?: string;
+};
+
+const learningItem = ({ text, subText, complete, icon, time, userAction, link }: ItemProps): JSX.Element => {
+ if (link) {
+ return (
+
+
+ {
+ if (userAction) {
+ await registerUserAction({
+ action: userAction
+ })
+ }
+ }}
+ className="relative bg-bunker-700 hover:bg-bunker-500 shadow-xl duration-200 rounded-md border border-dashed border-bunker-400 pl-2 pr-6 py-2 h-[5.5rem] w-full flex items-center justify-between overflow-hidden my-1.5 cursor-pointer">
+
+
+ {complete &&
+
+
+
}
+
+
+
+ {complete ? "Complete!" : "About " + time}
+
+ {complete &&
}
+
+
+
+ );
+ } else {
+ return (
+
{
+ if (userAction) {
+ await registerUserAction({
+ action: userAction
+ })
+ }
+ }}
+ className="relative bg-bunker-700 hover:bg-bunker-500 shadow-xl duration-200 rounded-md border border-dashed border-bunker-400 pl-2 pr-6 py-2 h-[5.5rem] w-full flex items-center justify-between overflow-hidden my-1.5 cursor-pointer">
+
+
+ {complete &&
+
+
+
}
+
+
+
+ {complete ? "Complete!" : "About " + time}
+
+ {complete &&
}
+
+ );
+ }
+}
+
+/**
+ * This tab is called Home because in the future it will include some company news,
+ * updates, roadmap, relavant blogs, etc. Currently it only has the setup instruction
+ * for the new users
+ */
+export default function Home() {
+ const router = useRouter();
+ const [hasUserClickedSlack, setHasUserClickedSlack] = useState(false);
+ const [hasUserClickedIntro, setHasUserClickedIntro] = useState(false);
+ const [hasUserStarred, setHasUserStarred] = useState(false);
+ const [usersInOrg, setUsersInOrg] = useState(false);
+
+ useEffect(() => {
+ const checkUserActionsFunction = async () => {
+ const userActionSlack = await checkUserAction({
+ action: "slack_cta_clicked",
+ });
+ setHasUserClickedSlack(userActionSlack ? true : false);
+
+ const userActionIntro = await checkUserAction({
+ action: "intro_cta_clicked",
+ });
+ setHasUserClickedIntro(userActionIntro ? true : false);
+
+ const userActionStar = await checkUserAction({
+ action: "star_cta_clicked",
+ });
+ setHasUserStarred(userActionStar ? true : false);
+
+ const orgId = localStorage.getItem("orgData.id");
+ const orgUsers = await getOrganizationUsers({
+ orgId: orgId ? orgId : "",
+ });
+ setUsersInOrg(orgUsers.length > 1)
+ };
+ checkUserActionsFunction();
+ }, []);
+
+ return (
+
+
+
Your quick start guide
+
Click on the items below and follow the instructions.
+ {learningItem({ text: "Get to know Infisical", subText: "", complete: hasUserClickedIntro, icon: faHandPeace, time: "3 min", userAction: "intro_cta_clicked", link: "https://www.youtube.com/watch?v=JS3OKYU2078" })}
+ {learningItem({ text: "Add your secrets", subText: "Click to see example secrets, and add your own.", complete: false, icon: faPlus, time: "2 min", userAction: "first_time_secrets_pushed", link: "/dashboard/" + router.query.id })}
+ {learningItem({ text: "Inject secrets locally", subText: "Replace .env files with a more secure an efficient alternative.", complete: false, icon: faNetworkWired, time: "8 min", link: "https://infisical.com/docs/getting-started/quickstart" })}
+ {learningItem({ text: "Integrate Infisical with your infrastructure", subText: "Only a few integrations are currently available. Many more coming soon!", complete: false, icon: faPlug, time: "15 min", link: "https://infisical.com/docs/integrations/overview" })}
+ {learningItem({ text: "Invite your teammates", subText: "", complete: usersInOrg, icon: faUserPlus, time: "2 min", link: "/settings/org/" + router.query.id + "?invite" })}
+ {learningItem({ text: "Join Infisical Slack", subText: "Have any questions? Ask us!", complete: hasUserClickedSlack, icon: faSlack, time: "1 min", userAction: "slack_cta_clicked", link: "https://join.slack.com/t/infisical-users/shared_invite/zt-1kdbk07ro-RtoyEt_9E~fyzGo_xQYP6g" })}
+ {learningItem({ text: "Star Infisical on GitHub", subText: "Like what we're doing? You know what to do! :)", complete: hasUserStarred, icon: faStar, time: "1 min", userAction: "star_cta_clicked", link: "https://github.com/Infisical/infisical" })}
+
+
+ );
+}
+
+Home.requireAuth = true;
diff --git a/frontend/pages/signup.js b/frontend/pages/signup.js
index 14ae51dcf..77c3c7ef4 100644
--- a/frontend/pages/signup.js
+++ b/frontend/pages/signup.js
@@ -197,7 +197,7 @@ export default function SignUp() {
},
async () => {
client.createVerifier(async (err, result) => {
- const response = await completeAccountInformationSignup({
+ let response = await completeAccountInformationSignup({
email,
firstName,
lastName,
@@ -495,7 +495,9 @@ export default function SignUp() {
setBackupKeyError,
setBackupKeyIssued,
});
- router.push("/dashboard/");
+ const userWorkspaces = await getWorkspaces();
+ let userWorkspace = userWorkspaces[0]._id;
+ router.push("/home/" + userWorkspace);
}}
size="lg"
/>
diff --git a/frontend/pages/signupinvite.js b/frontend/pages/signupinvite.js
index 8e7f1d4a0..15c511739 100644
--- a/frontend/pages/signupinvite.js
+++ b/frontend/pages/signupinvite.js
@@ -92,7 +92,7 @@ export default function SignupInvite() {
},
async () => {
client.createVerifier(async (err, result) => {
- const response = await completeAccountInformationSignupInvite({
+ let response = await completeAccountInformationSignupInvite({
email,
firstName,
lastName,
@@ -291,7 +291,7 @@ export default function SignupInvite() {
)}
-
+
{
diff --git a/helm-charts/README.md b/helm-charts/README.md
new file mode 100644
index 000000000..ffcef1a65
--- /dev/null
+++ b/helm-charts/README.md
@@ -0,0 +1,22 @@
+## Usage
+
+[Helm](https://helm.sh) must be installed to use the charts. Please refer to
+Helm's [documentation](https://helm.sh/docs) to get started.
+
+Once Helm has been set up correctly, add the repo as follows:
+
+```
+ helm repo add https://infisical.github.io/helm-charts
+```
+
+If you had already added this repo earlier, run `helm repo update` to retrieve
+the latest versions of the packages. You can then run `helm search repo
+` to see the charts.
+
+To install the chart:
+
+ helm install my- /
+
+To uninstall the chart:
+
+ helm delete my-
diff --git a/helm-charts/infisical/.helmignore b/helm-charts/infisical/.helmignore
new file mode 100644
index 000000000..0e8a0eb36
--- /dev/null
+++ b/helm-charts/infisical/.helmignore
@@ -0,0 +1,23 @@
+# Patterns to ignore when building packages.
+# This supports shell glob matching, relative path matching, and
+# negation (prefixed with !). Only one pattern per line.
+.DS_Store
+# Common VCS dirs
+.git/
+.gitignore
+.bzr/
+.bzrignore
+.hg/
+.hgignore
+.svn/
+# Common backup files
+*.swp
+*.bak
+*.tmp
+*.orig
+*~
+# Various IDEs
+.project
+.idea/
+*.tmproj
+.vscode/
diff --git a/helm-charts/infisical/Chart.yaml b/helm-charts/infisical/Chart.yaml
new file mode 100644
index 000000000..ecef711f1
--- /dev/null
+++ b/helm-charts/infisical/Chart.yaml
@@ -0,0 +1,16 @@
+apiVersion: v2
+name: infisical
+description: A helm chart for a full Infisical application
+
+type: application
+
+# This is the chart version. This version number should be incremented each time you make changes
+# to the chart and its templates, including the app version.
+# Versions are expected to follow Semantic Versioning (https://semver.org/)
+version: 0.1.0
+
+# This is the version number of the application being deployed. This version number should be
+# incremented each time you make changes to the application. Versions are not expected to
+# follow Semantic Versioning. They should reflect the version the application is using.
+# It is recommended to use it with quotes.
+appVersion: "1.16.0"
diff --git a/helm-charts/infisical/templates/NOTES.txt b/helm-charts/infisical/templates/NOTES.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/helm-charts/infisical/templates/backend-deployment.yaml b/helm-charts/infisical/templates/backend-deployment.yaml
new file mode 100644
index 000000000..ca45c528b
--- /dev/null
+++ b/helm-charts/infisical/templates/backend-deployment.yaml
@@ -0,0 +1,45 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ .Release.Name }}-backend-deployment
+ labels:
+ app: backend
+ namespace: {{ .Values.namespace }}
+spec:
+ replicas: {{ .Values.backend.replicaCount }}
+ selector:
+ matchLabels:
+ app: backend
+ template:
+ metadata:
+ labels:
+ app: backend
+ spec:
+ containers:
+ - name: backend
+ image: infisical/backend
+ imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
+ ports:
+ - containerPort: 4000
+ env:
+ {{- range $key, $value := .Values.secrets }}
+ {{- if eq $value "MUST_REPLACE" }}
+ {{ fail "Environment variables are not set. Please set all environment variables to continue." }}
+ {{ end }}
+ - name: {{ $key }}
+ value: {{ $value }}
+ {{- end }}
+
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: infisical-backend-service
+ namespace: {{ .Values.namespace }}
+spec:
+ selector:
+ app: backend
+ ports:
+ - protocol: TCP
+ port: 4000
+ targetPort: 4000 # container port
diff --git a/helm-charts/infisical/templates/frontend-deployment.yaml b/helm-charts/infisical/templates/frontend-deployment.yaml
new file mode 100644
index 000000000..f19beaa3d
--- /dev/null
+++ b/helm-charts/infisical/templates/frontend-deployment.yaml
@@ -0,0 +1,36 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ .Release.Name }}-frontend-deployment
+ labels:
+ app: frontend
+ namespace: {{ .Values.namespace }}
+spec:
+ replicas: {{ .Values.frontend.replicaCount }}
+ selector:
+ matchLabels:
+ app: frontend
+ template:
+ metadata:
+ labels:
+ app: frontend
+ spec:
+ containers:
+ - name: frontend
+ image: infisical/frontend
+ imagePullPolicy: {{ .Values.frontend.image.pullPolicy }}
+ ports:
+ - containerPort: 4000
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: infisical-frontend-service
+ namespace: {{ .Values.namespace }}
+spec:
+ selector:
+ app: frontend
+ ports:
+ - protocol: TCP
+ port: 3000 # service
+ targetPort: 3000 # container port
diff --git a/helm-charts/infisical/templates/ingress.yaml b/helm-charts/infisical/templates/ingress.yaml
new file mode 100644
index 000000000..e8b0febb3
--- /dev/null
+++ b/helm-charts/infisical/templates/ingress.yaml
@@ -0,0 +1,40 @@
+{{ if .Values.ingress.enabled }}
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: infisical-ingress
+ namespace: {{ .Values.namespace }}
+ {{- with .Values.ingress.annotations }}
+ annotations:
+ {{- toYaml . | nindent 4 }}
+ {{- end }}
+spec:
+{{- if .Values.ingress.tls }}
+ tls:
+ {{- range .Values.ingress.tls }}
+ - hosts:
+ {{- range .hosts }}
+ - {{ . | quote }}
+ {{- end }}
+ secretName: {{ .secretName }}
+ {{- end }}
+{{- end }}
+ rules:
+ - host: {{ .Values.ingress.hostName}}
+ http:
+ paths:
+ - path: {{ .Values.ingress.frontend.path }}
+ pathType: {{ .Values.ingress.frontend.pathType }}
+ backend:
+ service:
+ name: infisical-frontend-service
+ port:
+ number: 3000
+ - path: {{ .Values.ingress.backend.path }}
+ pathType: {{ .Values.ingress.backend.pathType }}
+ backend:
+ service:
+ name: infisical-backend-service
+ port:
+ number: 4000
+{{ end }}
\ No newline at end of file
diff --git a/helm-charts/infisical/templates/mongodb-deployment.yaml b/helm-charts/infisical/templates/mongodb-deployment.yaml
new file mode 100644
index 000000000..02d380b1e
--- /dev/null
+++ b/helm-charts/infisical/templates/mongodb-deployment.yaml
@@ -0,0 +1,40 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: mongodb-deployment
+ namespace: {{ .Values.namespace }}
+ labels:
+ app: mongodb
+spec:
+ replicas: 1 # Cannot be scaled. To scale, you must set up Stateful Set
+ selector:
+ matchLabels:
+ app: mongodb
+ template:
+ metadata:
+ labels:
+ app: mongodb
+ spec:
+ containers:
+ - name: mongodb
+ image: mongo
+ ports:
+ - containerPort: 27017
+ env:
+ - name: MONGO_INITDB_ROOT_USERNAME
+ value: root
+ - name: MONGO_INITDB_ROOT_PASSWORD
+ value: root
+---
+apiVersion: v1
+kind: Service
+metadata:
+ name: mongodb-service
+ namespace: {{ .Values.namespace }}
+spec:
+ selector:
+ app: mongodb
+ ports:
+ - protocol: TCP
+ port: 27017
+ targetPort: 27017 # container port
diff --git a/helm-charts/infisical/templates/namespace.yaml b/helm-charts/infisical/templates/namespace.yaml
new file mode 100644
index 000000000..3f9c2c1ad
--- /dev/null
+++ b/helm-charts/infisical/templates/namespace.yaml
@@ -0,0 +1,4 @@
+apiVersion: v1
+kind: Namespace
+metadata:
+ name: infisical
\ No newline at end of file
diff --git a/helm-charts/infisical/values.yaml b/helm-charts/infisical/values.yaml
new file mode 100644
index 000000000..94bce75ef
--- /dev/null
+++ b/helm-charts/infisical/values.yaml
@@ -0,0 +1,76 @@
+#####
+# INFISICAL K8 DEFAULT VALUES FIL
+# PLEASE REPLACE VALUES/EDIT AS REQUIRED
+#####
+
+namespace: infisical
+
+frontend:
+ replicaCount: 1
+ image:
+ repository:
+ pullPolicy: IfNotPresent
+ tag: "latest"
+
+backend:
+ replicaCount: 1
+ image:
+ repository:
+ pullPolicy: IfNotPresent
+ tag: "latest"
+
+ingress:
+ enabled: true
+ annotations: {}
+ hostName: example.com
+ frontend:
+ path: /
+ pathType: Prefix
+ backend:
+ path: /api
+ pathType: Prefix
+ tls: []
+
+## Complete Ingress example
+# ingress:
+# enabled: true
+# annotations:
+# kubernetes.io/ingress.class: "nginx"
+# cert-manager.io/issuer: letsencrypt-nginx
+# hostName: example.com
+# frontend:
+# path: /
+# pathType: Prefix
+# backend:
+# path: /api
+# pathType: Prefix
+# tls:
+# hosts:
+# - k8.infisical.com
+# secretName: letsencrypt-nginx
+
+###
+### YOU MUST FILL IN ALL SECRETS BELOW
+###
+secrets:
+ # Required keys for platform encryption/decryption ops. Replace with nacl sk keys
+ PRIVATE_KEY: MUST_REPLACE
+ PUBLIC_KEY: MUST_REPLACE
+ ENCRYPTION_KEY: MUST_REPLACE
+
+ # JWT
+ # Required secrets to sign JWT tokens
+ JWT_SIGNUP_SECRET: MUST_REPLACE
+ JWT_REFRESH_SECRET: MUST_REPLACE
+ JWT_AUTH_SECRET: MUST_REPLACE
+
+ # Mail/SMTP
+ # Required to send emails
+ SMTP_HOST: MUST_REPLACE
+ SMTP_NAME: MUST_REPLACE
+ SMTP_USERNAME: MUST_REPLACE
+ SMTP_PASSWORD: MUST_REPLACE
+
+ # You may replace with Mongo Cloud URI
+ MONGO_URL: mongodb://root:root@mongodb-service:27017/
+
\ No newline at end of file