-
-
+
+
{syntaxHighlight(value, isVisible || isSecretFocused, isImport)}
diff --git a/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx b/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx
index bbe63bc6e0..c28b179272 100644
--- a/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx
+++ b/frontend/src/components/v2/SecretPathInput/SecretPathInput.tsx
@@ -39,7 +39,7 @@ export const SecretPathInput = ({
const workspaceId = currentWorkspace?.id || "";
const { folderNames: folders } = useGetFoldersByEnv({
path: secretPath,
- environments: [environment || currentWorkspace?.environments?.[0].slug!],
+ environments: [environment || currentWorkspace?.environments?.[0].slug || ""],
projectId: workspaceId
});
@@ -141,7 +141,7 @@ export const SecretPathInput = ({
maxHeight: "var(--radix-select-content-available-height)"
}}
>
-
+
{suggestions.map((suggestion, i) => (
= {
- title: "Components/Select",
- component: Select,
- tags: ["v2"],
- argTypes: {
- placeholder: {
- defaultValue: "Type something..."
- }
- }
-};
-
-export default meta;
-type Story = StoryObj
;
-
-export const Basic: Story = {
- render: (args) => (
-
-
-
- )
-};
-
-const Controlled = (args: SelectProps) => {
- const [isOpen, setIsOpen] = useState(false);
- const [selected, setSelected] = useState("");
-
- return (
-
-
-
- );
-};
-
-export const Control: Story = {
- render: (args) =>
-};
-
-export const Disabled: Story = {
- render: (args) => (
-
-
-
- )
-};
-
-export const Loading: Story = {
- render: (args) => (
-
-
-
- )
-};
-
-const AsyncSelectOptions = () => {
- const [isLoading, setIsLoading] = useState(true);
-
- useEffect(() => {
- // eslint-disable-next-line no-new
- new Promise((resolve): void => {
- setTimeout(() => {
- setIsLoading(false);
- resolve();
- }, 1000);
- });
- }, []);
-
- return (
-
-
-
- );
-};
-
-export const Async: Story = {
- render: (args) =>
-};
diff --git a/frontend/src/components/v2/Select/Select.tsx b/frontend/src/components/v2/Select/Select.tsx
index cfc70450b1..7259c81579 100644
--- a/frontend/src/components/v2/Select/Select.tsx
+++ b/frontend/src/components/v2/Select/Select.tsx
@@ -52,8 +52,7 @@ export const Select = forwardRef(
(
(
onSelect={() => onClear()}
onClick={() => onClear()}
className={twMerge(
- `relative mb-0.5 flex
- cursor-pointer select-none items-center rounded-md py-2 pl-10 pr-4 text-sm
- outline-none transition-all hover:bg-mineshaft-500 data-[highlighted]:bg-mineshaft-700/80`,
+ "relative mb-0.5 flex cursor-pointer select-none items-center rounded-md py-2 pl-10 pr-4 text-sm outline-none transition-all hover:bg-mineshaft-500 data-[highlighted]:bg-mineshaft-700/80",
isSelected && "bg-primary",
isDisabled &&
"cursor-not-allowed text-gray-600 hover:bg-transparent hover:text-mineshaft-600",
diff --git a/frontend/src/components/v2/Skeleton/Skeleton.stories.tsx b/frontend/src/components/v2/Skeleton/Skeleton.stories.tsx
deleted file mode 100644
index 8af7fb0de0..0000000000
--- a/frontend/src/components/v2/Skeleton/Skeleton.stories.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-
-import { Skeleton } from "./Skeleton";
-
-const meta: Meta = {
- title: "Components/Skeleton",
- component: Skeleton,
- tags: ["v2"],
- argTypes: {}
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Basic: Story = {
- render: (args) =>
-};
diff --git a/frontend/src/components/v2/Switch/Switch.stories.tsx b/frontend/src/components/v2/Switch/Switch.stories.tsx
deleted file mode 100644
index e4ae2e6df4..0000000000
--- a/frontend/src/components/v2/Switch/Switch.stories.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-
-import { Switch } from "./Switch";
-
-const meta: Meta = {
- title: "Components/Switch",
- component: Switch,
- tags: ["v2"],
- argTypes: {}
-};
-
-export default meta;
-type Story = StoryObj;
-
-// More on writing stories with args: https://storybook.js.org/docs/7.0/react/writing-stories/args
-export const Simple: Story = {
- args: {
- children: "Dark mode"
- }
-};
-
-export const Disabled: Story = {
- args: {
- children: "Dark mode",
- isDisabled: true
- }
-};
-
-export const Required: Story = {
- args: {
- children: "Dark mode",
- isRequired: true
- }
-};
diff --git a/frontend/src/components/v2/Table/Table.stories.tsx b/frontend/src/components/v2/Table/Table.stories.tsx
deleted file mode 100644
index 95be1bb055..0000000000
--- a/frontend/src/components/v2/Table/Table.stories.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-
-import { Table, TableContainer, TableSkeleton, TBody, Td, Th, THead, Tr } from "./Table";
-
-const meta: Meta = {
- title: "Components/Table",
- component: Table,
- tags: ["v2"],
- argTypes: {}
-};
-
-export default meta;
-type Story = StoryObj;
-
-export const Basic: Story = {
- render: (args) => (
-
-
-
-
- Head#1 |
- Head#2 |
- Head#3 |
-
-
-
-
- Row#1 |
- Row#2 |
- Row#3 |
-
-
- Row#1 |
- Row#2 |
- Row#3 |
-
-
-
-
- )
-};
-
-export const Loading: Story = {
- render: (args) => (
-
-
-
-
- Head#1 |
- Head#2 |
- Head#3 |
-
-
-
-
-
-
-
- )
-};
diff --git a/frontend/src/components/v2/Table/Table.tsx b/frontend/src/components/v2/Table/Table.tsx
index 065efab1ef..1d5a9c394d 100644
--- a/frontend/src/components/v2/Table/Table.tsx
+++ b/frontend/src/components/v2/Table/Table.tsx
@@ -101,7 +101,7 @@ export type ThProps = {
export const Th = ({ children, className }: ThProps): JSX.Element => (
diff --git a/frontend/src/components/v2/Tabs/Tabs.tsx b/frontend/src/components/v2/Tabs/Tabs.tsx
index ca5c22dcb4..a4e897a422 100644
--- a/frontend/src/components/v2/Tabs/Tabs.tsx
+++ b/frontend/src/components/v2/Tabs/Tabs.tsx
@@ -13,7 +13,7 @@ export type TabListProps = TabsPrimitive.TabsListProps;
export const TabList = ({ className, children, ...props }: TabListProps) => (
{children}
diff --git a/frontend/src/components/v2/TextArea/TextArea.stories.tsx b/frontend/src/components/v2/TextArea/TextArea.stories.tsx
deleted file mode 100644
index 866a6ff598..0000000000
--- a/frontend/src/components/v2/TextArea/TextArea.stories.tsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-
-import { TextArea } from "./TextArea";
-
-const meta: Meta = {
- title: "Components/TextArea",
- component: TextArea,
- tags: ["v2"],
- argTypes: {
- placeholder: {
- defaultValue: "Type anything",
- type: "string"
- }
- }
-};
-
-export default meta;
-type Story = StoryObj;
-
-// More on writing stories with args: https://storybook.js.org/docs/7.0/react/writing-stories/args
-export const Filled: Story = {
- args: {}
-};
-
-export const Outline: Story = {
- args: {
- variant: "outline"
- }
-};
-
-export const Plain: Story = {
- args: {
- variant: "plain"
- }
-};
-
-export const Error: Story = {
- args: {
- isError: true
- }
-};
-
-export const AutoWidth: Story = {
- args: {
- isFullWidth: false,
- className: "w-auto"
- }
-};
diff --git a/frontend/src/components/v2/Tooltip/Tooltip.stories.tsx b/frontend/src/components/v2/Tooltip/Tooltip.stories.tsx
deleted file mode 100644
index b35c5fb1d3..0000000000
--- a/frontend/src/components/v2/Tooltip/Tooltip.stories.tsx
+++ /dev/null
@@ -1,28 +0,0 @@
-import type { Meta, StoryObj } from "@storybook/react";
-
-import { Tooltip, TooltipProps, TooltipProvider } from "./Tooltip";
-
-const meta: Meta = {
- title: "Components/Tooltip",
- component: Tooltip,
- tags: ["v2"],
- args: {
- content: "Hi"
- }
-};
-
-export default meta;
-type Story = StoryObj;
-
-const Template = (args: TooltipProps) => (
-
-
- Hello infisical
-
-
-);
-
-// More on writing stories with args: https://storybook.js.org/docs/7.0/react/writing-stories/args
-export const Primary: Story = {
- render: (args) =>
-};
diff --git a/frontend/src/components/v2/Tooltip/Tooltip.tsx b/frontend/src/components/v2/Tooltip/Tooltip.tsx
index abfebc5b49..3c9dcf1cb2 100644
--- a/frontend/src/components/v2/Tooltip/Tooltip.tsx
+++ b/frontend/src/components/v2/Tooltip/Tooltip.tsx
@@ -45,16 +45,11 @@ export const Tooltip = ({
sideOffset={5}
{...props}
className={twMerge(
- `z-50 max-w-[15rem] select-none border border-mineshaft-600 bg-mineshaft-800 font-light text-bunker-200 shadow-md
- data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade
- data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade
- data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade
- data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade
- `,
+ "z-50 max-w-[15rem] select-none border border-mineshaft-600 bg-mineshaft-800 font-light text-bunker-200 shadow-md data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade",
isDisabled && "!hidden",
center && "text-center",
- size === "sm" && "rounded-sm py-1 px-2 text-xs",
- size === "md" && "rounded-md py-2 px-4 text-sm",
+ size === "sm" && "rounded-sm px-2 py-1 text-xs",
+ size === "md" && "rounded-md px-4 py-2 text-sm",
className
)}
>
diff --git a/frontend/src/components/v2/index.tsx b/frontend/src/components/v2/index.tsx
index 725a27ed33..8e195102b3 100644
--- a/frontend/src/components/v2/index.tsx
+++ b/frontend/src/components/v2/index.tsx
@@ -1,3 +1,4 @@
+/* eslint-disable react-refresh/only-export-components */
export * from "./Accordion";
export * from "./Alert";
export * from "./Badge";
@@ -33,4 +34,3 @@ export * from "./Tabs";
export * from "./Tag";
export * from "./TextArea";
export * from "./Tooltip";
-export * from "./UpgradePlanModal";
diff --git a/frontend/src/config/env.ts b/frontend/src/config/env.ts
new file mode 100644
index 0000000000..296c6a87d2
--- /dev/null
+++ b/frontend/src/config/env.ts
@@ -0,0 +1,32 @@
+// akhilmhdh: These are runtime environment variables loaded from server
+// The window body is filled with value from the server
+// We add a script in index.html to load it from server before react loads
+/* eslint-disable no-underscore-dangle */
+export const envConfig = {
+ ENV: import.meta.env.MODE,
+ get CAPTCHA_SITE_KEY() {
+ return (
+ window?.__INFISICAL_RUNTIME_ENV__?.CAPTCHA_SITE_KEY || import.meta.env.VITE_CAPTCHA_SITE_KEY
+ );
+ },
+ get INTERCOM_ID() {
+ return window?.__INFISICAL_RUNTIME_ENV__?.INTERCOM_ID || import.meta.env.VITE_INTERCOM_ID;
+ },
+ get POSTHOG_API_KEY() {
+ return (
+ window?.__INFISICAL_RUNTIME_ENV__?.POSTHOG_API_KEY || import.meta.env.VITE_POSTHOG_API_KEY
+ );
+ },
+ get POSTHOG_HOST() {
+ return import.meta.env.VITE_POSTHOG_HOST! || "https://app.posthog.com";
+ },
+ get TELEMETRY_CAPTURING_ENABLED() {
+ return (
+ window?.__INFISICAL_RUNTIME_ENV__?.TELEMETRY_CAPTURING_ENABLED ||
+ import.meta.env.VITE_TELEMETRY_CAPTURING_ENABLED === true
+ );
+ },
+ get PLATFORM_VERSION() {
+ return import.meta.env.VITE_INFISICAL_PLATFORM_VERSION;
+ }
+};
diff --git a/frontend/src/config/request.ts b/frontend/src/config/request.ts
index b29f19f5e7..9a06296196 100644
--- a/frontend/src/config/request.ts
+++ b/frontend/src/config/request.ts
@@ -1,7 +1,7 @@
import axios from "axios";
import SecurityClient from "@app/components/utilities/SecurityClient";
-import { getAuthToken, getMfaTempToken, getSignupTempToken } from "@app/reactQuery";
+import { getAuthToken, getMfaTempToken, getSignupTempToken } from "@app/hooks/api/reactQuery";
export const apiRequest = axios.create({
baseURL: "/",
diff --git a/frontend/src/const/routes.ts b/frontend/src/const/routes.ts
new file mode 100644
index 0000000000..221917b94a
--- /dev/null
+++ b/frontend/src/const/routes.ts
@@ -0,0 +1,277 @@
+import { FileRouteTypes } from "@app/routeTree.gen";
+
+const setRoute = (
+ path: TFull,
+ id: TId
+) => ({ path, id }) as const;
+
+export const ROUTE_PATHS = Object.freeze({
+ Auth: {
+ LoginSSO: setRoute("/login/sso", "/_restrict-login-signup/login/sso"),
+ ProviderSuccessPage: setRoute(
+ "/login/provider/success",
+ "/_restrict-login-signup/login/provider/success"
+ ),
+ SignUpSsoPage: setRoute("/signup/sso", "/_restrict-login-signup/signup/sso"),
+ PasswordResetPage: setRoute("/password-reset", "/_restrict-login-signup/password-reset")
+ },
+ Organization: {
+ SecretScanning: setRoute(
+ "/organization/secret-scanning",
+ "/_authenticate/_inject-org-details/organization/_layout/secret-scanning"
+ ),
+ SettingsPage: setRoute(
+ "/organization/settings",
+ "/_authenticate/_inject-org-details/organization/_layout/settings"
+ ),
+ GroupDetailsByIDPage: setRoute(
+ "/organization/groups/$groupId",
+ "/_authenticate/_inject-org-details/organization/_layout/groups/$groupId"
+ ),
+ IdentityDetailsByIDPage: setRoute(
+ "/organization/identities/$identityId",
+ "/_authenticate/_inject-org-details/organization/_layout/identities/$identityId"
+ ),
+ UserDetailsByIDPage: setRoute(
+ "/organization/members/$membershipId",
+ "/_authenticate/_inject-org-details/organization/_layout/members/$membershipId"
+ ),
+ AccessControlPage: setRoute(
+ "/organization/access-management",
+ "/_authenticate/_inject-org-details/organization/_layout/access-management"
+ ),
+ RoleByIDPage: setRoute(
+ "/organization/roles/$roleId",
+ "/_authenticate/_inject-org-details/organization/_layout/roles/$roleId"
+ ),
+ AppConnections: {
+ GithubOauthCallbackPage: setRoute(
+ "/organization/app-connections/github/oauth/callback",
+ "/_authenticate/_inject-org-details/organization/_layout/app-connections/github/oauth/callback"
+ )
+ }
+ },
+ SecretManager: {
+ ApprovalPage: setRoute(
+ "/secret-manager/$projectId/approval",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/approval"
+ ),
+ SecretDashboardPage: setRoute(
+ "/secret-manager/$projectId/secrets/$envSlug",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/secrets/$envSlug"
+ ),
+ OverviewPage: setRoute(
+ "/secret-manager/$projectId/overview",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/overview"
+ ),
+ IntegrationDetailsByIDPage: setRoute(
+ "/secret-manager/$projectId/integrations/$integrationId",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/$integrationId"
+ ),
+ Integratons: {
+ SelectIntegrationAuth: setRoute(
+ "/secret-manager/$projectId/integrations/select-integration-auth",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/select-integration-auth"
+ ),
+ HerokuOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/heroku/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/heroku/oauth2/callback"
+ ),
+ HerokuConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/heroku/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/heroku/create"
+ ),
+ AwsParameterStoreConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/aws-parameter-store/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/aws-parameter-store/create"
+ ),
+ AwsSecretManagerConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/aws-secret-manager/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/aws-secret-manager/create"
+ ),
+ AzureAppConfigurationsOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/azure-app-configuration/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-app-configuration/oauth2/callback"
+ ),
+ AzureAppConfigurationsConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/azure-app-configuration/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-app-configuration/create"
+ ),
+ AzureDevopsConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/azure-devops/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-devops/create"
+ ),
+ AzureKeyVaultOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/azure-key-vault/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/oauth2/callback"
+ ),
+ AzureKeyVaultConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/azure-key-vault/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/azure-key-vault/create"
+ ),
+ BitbucketOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/bitbucket/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/bitbucket/oauth2/callback"
+ ),
+ BitbucketConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/bitbucket/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/bitbucket/create"
+ ),
+ ChecklyConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/checkly/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/checkly/create"
+ ),
+ CircleConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/circleci/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/circleci/create"
+ ),
+ CloudflarePagesConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/cloudflare-pages/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/cloudflare-pages/create"
+ ),
+ DigitalOceanAppPlatformConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/digital-ocean-app-platform/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/digital-ocean-app-platform/create"
+ ),
+ CloudflareWorkersConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/cloudflare-workers/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/cloudflare-workers/create"
+ ),
+ CodefreshConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/codefresh/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/codefresh/create"
+ ),
+ GcpSecretManagerConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/gcp-secret-manager/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/create"
+ ),
+ GcpSecretManagerOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/gcp-secret-manager/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/gcp-secret-manager/oauth2/callback"
+ ),
+ GithubConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/github/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/github/create"
+ ),
+ GithubOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/github/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/github/oauth2/callback"
+ ),
+ GitlabConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/gitlab/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/gitlab/create"
+ ),
+ GitlabOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/gitlab/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/gitlab/oauth2/callback"
+ ),
+ VercelOauthCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/vercel/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/vercel/oauth2/callback"
+ ),
+ VercelConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/vercel/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/vercel/create"
+ ),
+ FlyioConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/flyio/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/flyio/create"
+ ),
+ HashicorpVaultConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/hashicorp-vault/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/hashicorp-vault/create"
+ ),
+ HasuraCloudConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/hasura-cloud/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/hasura-cloud/create"
+ ),
+ LaravelForgeConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/laravel-forge/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/laravel-forge/create"
+ ),
+ NorthflankConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/northflank/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/northflank/create"
+ ),
+ RailwayConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/railway/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/railway/create"
+ ),
+ RenderConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/render/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/render/create"
+ ),
+ RundeckConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/rundeck/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/rundeck/create"
+ ),
+ WindmillConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/windmill/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/windmill/create"
+ ),
+ TravisCIConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/travisci/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/travisci/create"
+ ),
+ TerraformCloudConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/terraform-cloud/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/terraform-cloud/create"
+ ),
+ TeamcityConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/teamcity/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/teamcity/create"
+ ),
+ SupabaseConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/supabase/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/supabase/create"
+ ),
+ OctopusDeployCloudConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/octopus-deploy/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/octopus-deploy/create"
+ ),
+ DatabricksConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/databricks/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/databricks/create"
+ ),
+ QoveryConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/qovery/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/qovery/create"
+ ),
+ Cloud66ConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/cloud-66/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/cloud-66/create"
+ ),
+ NetlifyConfigurePage: setRoute(
+ "/secret-manager/$projectId/integrations/netlify/create",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/netlify/create"
+ ),
+ NetlifyOuathCallbackPage: setRoute(
+ "/secret-manager/$projectId/integrations/netlify/oauth2/callback",
+ "/_authenticate/_inject-org-details/secret-manager/$projectId/_secret-manager-layout/integrations/netlify/oauth2/callback"
+ )
+ }
+ },
+ CertManager: {
+ CertAuthDetailsByIDPage: setRoute(
+ "/cert-manager/$projectId/ca/$caId",
+ "/_authenticate/_inject-org-details/cert-manager/$projectId/_cert-manager-layout/ca/$caId"
+ ),
+ OverviewPage: setRoute(
+ "/cert-manager/$projectId/overview",
+ "/_authenticate/_inject-org-details/cert-manager/$projectId/_cert-manager-layout/overview"
+ ),
+ PkiCollectionDetailsByIDPage: setRoute(
+ "/cert-manager/$projectId/pki-collections/$collectionId",
+ "/_authenticate/_inject-org-details/cert-manager/$projectId/_cert-manager-layout/pki-collections/$collectionId"
+ )
+ },
+ Ssh: {
+ SshCaByIDPage: setRoute(
+ "/ssh/$projectId/ca/$caId",
+ "/_authenticate/_inject-org-details/ssh/$projectId/_ssh-layout/ca/$caId"
+ )
+ },
+ Public: {
+ ViewSharedSecretByIDPage: setRoute("/shared/secret/$secretId", "/shared/secret/$secretId")
+ }
+});
diff --git a/frontend/src/context/AuthContext/AuthContext.tsx b/frontend/src/context/AuthContext/AuthContext.tsx
deleted file mode 100644
index 2950b5cc5a..0000000000
--- a/frontend/src/context/AuthContext/AuthContext.tsx
+++ /dev/null
@@ -1,54 +0,0 @@
-import { ReactNode, useEffect } from "react";
-import { useRouter } from "next/router";
-
-import { publicPaths } from "@app/const";
-import { useToggle } from "@app/hooks";
-import { useGetAuthToken } from "@app/hooks/api";
-import { isLoggedIn } from "@app/reactQuery";
-
-type Props = {
- children: ReactNode;
-};
-
-// TODO(akhilmhdh): Using react-simple-animate from hard dom offloading
-// smoother dom offloading needs to be done
-
-// Authentication controller
-// Does route checking
-// Provide a context for whole app to notify user is authorized or not
-export const AuthProvider = ({ children }: Props): JSX.Element => {
- const { isLoading } = useGetAuthToken();
- const { pathname, push, asPath } = useRouter();
- const [isReady, setIsReady] = useToggle(false);
-
- useEffect(() => {
- // check if loading of auth is done
- if (!isLoading) {
- // not a public path and not authenticated kick to login page
- if (!publicPaths.includes(pathname) && !isLoggedIn()) {
- push({ pathname: "/login", query: { redirect: asPath } }).then(() => {
- setIsReady.on();
- });
- } else {
- // else good to go
- setIsReady.on();
- }
- }
- }, [pathname, isLoading]);
-
- // wait for app to load the auth state
- if (isLoading || !isReady) {
- return (
-
- ![infisical loading indicator](/images/loading/loading.gif)
-
- );
- }
-
- return children as JSX.Element;
-};
diff --git a/frontend/src/context/AuthContext/index.tsx b/frontend/src/context/AuthContext/index.tsx
deleted file mode 100644
index f4b4117942..0000000000
--- a/frontend/src/context/AuthContext/index.tsx
+++ /dev/null
@@ -1 +0,0 @@
-export { AuthProvider } from "./AuthContext";
diff --git a/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx b/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx
index 36422b7223..dbbc4a8062 100644
--- a/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx
+++ b/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx
@@ -1,58 +1,32 @@
-import { createContext, ReactNode, useContext } from "react";
+import { createMongoAbility, MongoAbility, RawRuleOf } from "@casl/ability";
+import { unpackRules } from "@casl/ability/extra";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import { useRouteContext } from "@tanstack/react-router";
-import { useGetUserOrgPermissions } from "@app/hooks/api";
-import { OrgUser } from "@app/hooks/api/types";
+import {
+ conditionsMatcher,
+ fetchUserOrgPermissions,
+ roleQueryKeys
+} from "@app/hooks/api/roles/queries";
-import { useOrganization } from "../OrganizationContext";
-import { TOrgPermission } from "./types";
-
-type Props = {
- children: ReactNode;
-};
-
-const OrgPermissionContext = createContext(null);
-
-export const OrgPermissionProvider = ({ children }: Props): JSX.Element => {
- const { currentOrg } = useOrganization();
- const orgId = currentOrg?.id || "";
- const { data: permission, isLoading } = useGetUserOrgPermissions({ orgId });
-
- if (isLoading) {
- return (
-
- ![infisical loading indicator](/images/loading/loading.gif)
-
- );
- }
-
- if (!permission) {
- return (
-
- Failed to load user permissions
-
- );
- }
-
- return (
- {children}
- );
-};
+import { OrgPermissionSet } from "./types";
export const useOrgPermission = () => {
- const ctx = useContext(OrgPermissionContext);
- if (!ctx) {
- throw new Error("useOrgPermission to be used within ");
- }
-
- return ctx;
+ const organizationId = useRouteContext({
+ from: "/_authenticate/_inject-org-details",
+ select: (el) => el.organizationId
+ });
+
+ const { data } = useSuspenseQuery({
+ queryKey: roleQueryKeys.getUserOrgPermissions({ orgId: organizationId }),
+ queryFn: () => fetchUserOrgPermissions({ orgId: organizationId }),
+ select: (res) => {
+ const rule = unpackRules>>(res.permissions);
+ const ability = createMongoAbility(rule, { conditionsMatcher });
+ return { permission: ability, membership: res.membership };
+ },
+ staleTime: Infinity
+ });
+
+ return data;
};
diff --git a/frontend/src/context/OrgPermissionContext/index.tsx b/frontend/src/context/OrgPermissionContext/index.tsx
index 730fe55b1c..300f05904b 100644
--- a/frontend/src/context/OrgPermissionContext/index.tsx
+++ b/frontend/src/context/OrgPermissionContext/index.tsx
@@ -1,3 +1,3 @@
-export { OrgPermissionProvider, useOrgPermission } from "./OrgPermissionContext";
+export { useOrgPermission } from "./OrgPermissionContext";
export type { TOrgPermission } from "./types";
export { OrgPermissionActions, OrgPermissionSubjects } from "./types";
diff --git a/frontend/src/context/OrganizationContext/OrganizationContext.tsx b/frontend/src/context/OrganizationContext/OrganizationContext.tsx
index e73578d135..26865b5bff 100644
--- a/frontend/src/context/OrganizationContext/OrganizationContext.tsx
+++ b/frontend/src/context/OrganizationContext/OrganizationContext.tsx
@@ -1,44 +1,19 @@
-import { createContext, ReactNode, useContext, useMemo } from "react";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import { useRouteContext } from "@tanstack/react-router";
-import { useGetOrganizations } from "@app/hooks/api";
-import { Organization } from "@app/hooks/api/types";
-
-type TOrgContext = {
- orgs?: Organization[];
- currentOrg?: Organization;
- isLoading: boolean;
-};
-
-const OrgContext = createContext(null);
-
-type Props = {
- children: ReactNode;
-};
-
-export const OrgProvider = ({ children }: Props): JSX.Element => {
- const { data: userOrgs, isLoading } = useGetOrganizations();
-
- // const currentWsOrgID = currentWorkspace?.organization;
- const currentWsOrgID = localStorage.getItem("orgData.id");
-
- // memorize the workspace details for the context
- const value = useMemo(
- () => ({
- orgs: userOrgs,
- currentOrg: (userOrgs || []).find(({ id }) => id === currentWsOrgID),
- isLoading
- }),
- [currentWsOrgID, userOrgs, isLoading]
- );
-
- return {children};
-};
+import { fetchOrganizationById, organizationKeys } from "@app/hooks/api/organization/queries";
export const useOrganization = () => {
- const ctx = useContext(OrgContext);
- if (!ctx) {
- throw new Error("useOrganization to be used within ");
- }
-
- return ctx;
+ const organizationId = useRouteContext({
+ from: "/_authenticate/_inject-org-details",
+ select: (el) => el.organizationId
+ });
+
+ const { data: currentOrg } = useSuspenseQuery({
+ queryKey: organizationKeys.getOrgById(organizationId),
+ queryFn: () => fetchOrganizationById(organizationId),
+ staleTime: Infinity
+ });
+
+ return { currentOrg };
};
diff --git a/frontend/src/context/OrganizationContext/index.tsx b/frontend/src/context/OrganizationContext/index.tsx
index 65aba8ca4f..ba97abd12d 100644
--- a/frontend/src/context/OrganizationContext/index.tsx
+++ b/frontend/src/context/OrganizationContext/index.tsx
@@ -1 +1 @@
-export { OrgProvider, useOrganization } from "./OrganizationContext";
+export { useOrganization } from "./OrganizationContext";
diff --git a/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx b/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx
index b0ee59960d..63a3c63b8b 100644
--- a/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx
+++ b/frontend/src/context/ProjectPermissionContext/ProjectPermissionContext.tsx
@@ -1,62 +1,77 @@
-import { createContext, ReactNode, useContext } from "react";
+import { useCallback } from "react";
+import { createMongoAbility, MongoAbility, RawRuleOf } from "@casl/ability";
+import { unpackRules } from "@casl/ability/extra";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import { useParams } from "@tanstack/react-router";
-import { useGetUserProjectPermissions } from "@app/hooks/api";
-import { TProjectMembership } from "@app/hooks/api/users/types";
+import {
+ conditionsMatcher,
+ fetchUserProjectPermissions,
+ roleQueryKeys
+} from "@app/hooks/api/roles/queries";
+import { groupBy } from "@app/lib/fn/array";
+import { omit } from "@app/lib/fn/object";
-import { useWorkspace } from "../WorkspaceContext";
-import { TProjectPermission } from "./types";
+import { ProjectPermissionSet } from "./types";
-type Props = {
- children: ReactNode;
-};
-
-const ProjectPermissionContext = createContext(null);
-
-export const ProjectPermissionProvider = ({ children }: Props): JSX.Element => {
- const { currentWorkspace, isLoading: isWsLoading } = useWorkspace();
- const workspaceId = currentWorkspace?.id || "";
- const { data: permission, isLoading } = useGetUserProjectPermissions({ workspaceId });
-
- if ((isLoading && currentWorkspace) || isWsLoading) {
- return (
-
- ![infisical loading indicator](/images/loading/loading.gif)
-
- );
+export const useProjectPermission = () => {
+ const projectId = useParams({
+ strict: false,
+ select: (el) => el?.projectId
+ });
+ if (!projectId) {
+ throw new Error("useProjectPermission to be used within ");
}
- if (!permission && currentWorkspace) {
- return (
-
- Failed to load user permissions
-
- );
- }
+ const {
+ data: { permission, membership }
+ } = useSuspenseQuery({
+ queryKey: roleQueryKeys.getUserProjectPermissions({ workspaceId: projectId }),
+ queryFn: () => fetchUserProjectPermissions({ workspaceId: projectId }),
+ staleTime: Infinity,
+ select: (data) => {
+ const rule = unpackRules>>(data.permissions);
+ const negatedRules = groupBy(
+ rule.filter((i) => i.inverted && i.conditions),
+ (i) => `${i.subject}-${JSON.stringify(i.conditions)}`
+ );
+ const ability = createMongoAbility(rule, {
+ // this allows in frontend to skip some rules using *
+ conditionsMatcher: (rules) => {
+ return (entity) => {
+ // skip validation if its negated rules
+ const isNegatedRule =
+ // eslint-disable-next-line no-underscore-dangle
+ negatedRules?.[`${entity.__caslSubjectType__}-${JSON.stringify(rules)}`];
+ if (isNegatedRule) {
+ const baseMatcher = conditionsMatcher(rules);
+ return baseMatcher(entity);
+ }
- return (
-
- {children}
-
- );
-};
+ const rulesStrippedOfWildcard = omit(
+ rules,
+ Object.keys(entity).filter((el) => entity[el]?.includes("*"))
+ );
+ const baseMatcher = conditionsMatcher(rulesStrippedOfWildcard);
+ return baseMatcher(entity);
+ };
+ }
+ });
-export const useProjectPermission = () => {
- const ctx = useContext(ProjectPermissionContext);
- if (!ctx) {
- throw new Error("useProjectPermission to be used within ");
- }
+ return {
+ permission: ability,
+ membership: {
+ ...data.membership,
+ roles: data.membership.roles.map(({ role }) => role)
+ }
+ };
+ }
+ });
- const hasProjectRole = (role: string) => ctx?.membership?.roles?.includes(role) || false;
+ const hasProjectRole = useCallback(
+ (role: string) => membership?.roles?.includes(role) || false,
+ []
+ );
- return { ...ctx, hasProjectRole };
+ return { permission, membership, hasProjectRole };
};
diff --git a/frontend/src/context/ProjectPermissionContext/index.tsx b/frontend/src/context/ProjectPermissionContext/index.tsx
index 4b04f5cb84..009bc9451b 100644
--- a/frontend/src/context/ProjectPermissionContext/index.tsx
+++ b/frontend/src/context/ProjectPermissionContext/index.tsx
@@ -1,4 +1,4 @@
-export { ProjectPermissionProvider, useProjectPermission } from "./ProjectPermissionContext";
+export { useProjectPermission } from "./ProjectPermissionContext";
export type { ProjectPermissionSet, TProjectPermission } from "./types";
export {
ProjectPermissionActions,
diff --git a/frontend/src/context/ServerConfigContext/ServerConfigContext.tsx b/frontend/src/context/ServerConfigContext/ServerConfigContext.tsx
index 659cff9687..acc63118b9 100644
--- a/frontend/src/context/ServerConfigContext/ServerConfigContext.tsx
+++ b/frontend/src/context/ServerConfigContext/ServerConfigContext.tsx
@@ -1,89 +1,13 @@
-import { createContext, ReactNode, useContext, useEffect, useMemo } from "react";
-import Head from "next/head";
-import { useRouter } from "next/router";
+import { useSuspenseQuery } from "@tanstack/react-query";
-import { ContentLoader } from "@app/components/v2/ContentLoader";
-import { useGetServerConfig } from "@app/hooks/api";
-import { TServerConfig } from "@app/hooks/api/admin/types";
-
-type TServerConfigContext = {
- config: TServerConfig;
-};
-
-const ServerConfigContext = createContext(null);
-
-type Props = {
- children: ReactNode;
-};
-
-export const ServerConfigProvider = ({ children }: Props): JSX.Element => {
- const router = useRouter();
- const { data, isLoading } = useGetServerConfig();
-
- // memorize the workspace details for the context
- const value = useMemo(() => {
- return {
- config: data!
- };
- }, [data]);
-
- useEffect(() => {
- if (!isLoading && data && !data.initialized && !data.isMigrationModeOn) {
- router.push("/admin/signup");
- }
- }, [isLoading, data]);
-
- if (!isLoading && data?.isMigrationModeOn) {
- return (
-
-
- Infisical Maintenance Mode
-
-
- ![maintenance mode](/images/maintenance.png)
-
- Scheduled Maintenance
-
-
- Infisical is undergoing planned maintenance. No action is required on your end —
- your applications will continue to fetch secrets.
- If you have questions, please{" "}
-
- join our Slack community
-
- .
-
-
- );
- }
-
- if (isLoading || (!data?.initialized && router.pathname !== "/admin/signup")) {
- return (
-
-
-
- );
- }
-
- return {children};
-};
+import { adminQueryKeys, fetchServerConfig } from "@app/hooks/api/admin/queries";
export const useServerConfig = () => {
- const ctx = useContext(ServerConfigContext);
- if (!ctx) {
- throw new Error("useServerConfig has to be used within ");
- }
+ const { data: config } = useSuspenseQuery({
+ queryKey: adminQueryKeys.serverConfig(),
+ queryFn: fetchServerConfig,
+ staleTime: Infinity
+ });
- return ctx;
+ return { config };
};
diff --git a/frontend/src/context/ServerConfigContext/index.tsx b/frontend/src/context/ServerConfigContext/index.tsx
index 856eb5c77a..41c2a5f263 100644
--- a/frontend/src/context/ServerConfigContext/index.tsx
+++ b/frontend/src/context/ServerConfigContext/index.tsx
@@ -1 +1 @@
-export { ServerConfigProvider, useServerConfig } from "./ServerConfigContext";
+export { useServerConfig } from "./ServerConfigContext";
diff --git a/frontend/src/context/SubscriptionContext/SubscriptionContext.tsx b/frontend/src/context/SubscriptionContext/SubscriptionContext.tsx
index 9c50e425f6..de52e5f183 100644
--- a/frontend/src/context/SubscriptionContext/SubscriptionContext.tsx
+++ b/frontend/src/context/SubscriptionContext/SubscriptionContext.tsx
@@ -1,45 +1,19 @@
-import { createContext, ReactNode, useContext, useMemo } from "react";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import { useRouteContext } from "@tanstack/react-router";
-import { useGetOrgSubscription } from "@app/hooks/api";
-import { SubscriptionPlan } from "@app/hooks/api/types";
+import { fetchOrgSubscription, subscriptionQueryKeys } from "@app/hooks/api/subscriptions/queries";
-import { useOrganization } from "../OrganizationContext";
-
-type TSubscriptionContext = {
- subscription?: SubscriptionPlan;
- isLoading: boolean;
-};
-
-const SubscriptionContext = createContext(null);
-
-type Props = {
- children: ReactNode;
-};
-
-export const SubscriptionProvider = ({ children }: Props): JSX.Element => {
- const { currentOrg } = useOrganization();
-
- const { data, isLoading } = useGetOrgSubscription({
- orgID: currentOrg?.id || ""
+export const useSubscription = () => {
+ const organizationId = useRouteContext({
+ from: "/_authenticate/_inject-org-details",
+ select: (el) => el.organizationId
});
- // memorize the workspace details for the context
- const value = useMemo(
- () => ({
- subscription: data,
- isLoading
- }),
- [data, isLoading]
- );
-
- return {children};
-};
-
-export const useSubscription = () => {
- const ctx = useContext(SubscriptionContext);
- if (!ctx) {
- throw new Error("useSubscription has to be used within ");
- }
+ const { data: subscription } = useSuspenseQuery({
+ queryKey: subscriptionQueryKeys.getOrgSubsription(organizationId),
+ queryFn: () => fetchOrgSubscription(organizationId),
+ staleTime: Infinity
+ });
- return ctx;
+ return { subscription };
};
diff --git a/frontend/src/context/SubscriptionContext/index.tsx b/frontend/src/context/SubscriptionContext/index.tsx
index 50a97eeb28..0c5a895522 100644
--- a/frontend/src/context/SubscriptionContext/index.tsx
+++ b/frontend/src/context/SubscriptionContext/index.tsx
@@ -1 +1 @@
-export { SubscriptionProvider, useSubscription } from "./SubscriptionContext";
+export { useSubscription } from "./SubscriptionContext";
diff --git a/frontend/src/context/UserContext/UserContext.tsx b/frontend/src/context/UserContext/UserContext.tsx
index 0e23ccb7cf..eafde94657 100644
--- a/frontend/src/context/UserContext/UserContext.tsx
+++ b/frontend/src/context/UserContext/UserContext.tsx
@@ -1,53 +1,14 @@
-import { createContext, ReactNode, useContext, useMemo } from "react";
+import { useSuspenseQuery } from "@tanstack/react-query";
-import { useGetUser } from "@app/hooks/api";
-import { User, UserEnc } from "@app/hooks/api/types";
-
-type TUserContext = {
- user: User & UserEnc;
- isLoading: boolean;
-};
-
-const UserContext = createContext(null);
-
-type Props = {
- children: ReactNode;
-};
-
-export const UserProvider = ({ children }: Props): JSX.Element => {
- const { data, isLoading } = useGetUser();
-
- // memorize the workspace details for the context
- const value = useMemo(() => {
- return {
- user: data!,
- isLoading
- };
- }, [data, isLoading]);
-
- if (isLoading) {
- return (
-
- ![infisical loading indicator](/images/loading/loading.gif)
-
- );
- }
-
- return {children};
-};
+import { userKeys } from "@app/hooks/api";
+import { fetchUserDetails } from "@app/hooks/api/users/queries";
export const useUser = () => {
- const ctx = useContext(UserContext);
- if (!ctx) {
- throw new Error("useUser has to be used within ");
- }
+ const { data: user } = useSuspenseQuery({
+ queryKey: userKeys.getUser,
+ queryFn: fetchUserDetails,
+ staleTime: Infinity
+ });
- return ctx;
+ return { user };
};
diff --git a/frontend/src/context/UserContext/index.tsx b/frontend/src/context/UserContext/index.tsx
index b4f6056ddf..c425b80739 100644
--- a/frontend/src/context/UserContext/index.tsx
+++ b/frontend/src/context/UserContext/index.tsx
@@ -1 +1 @@
-export { UserProvider, useUser } from "./UserContext";
+export { useUser } from "./UserContext";
diff --git a/frontend/src/context/WorkspaceContext/WorkspaceContext.tsx b/frontend/src/context/WorkspaceContext/WorkspaceContext.tsx
index e4d7612ecb..8bef13b314 100644
--- a/frontend/src/context/WorkspaceContext/WorkspaceContext.tsx
+++ b/frontend/src/context/WorkspaceContext/WorkspaceContext.tsx
@@ -1,73 +1,22 @@
-import { createContext, ReactNode, useContext, useEffect, useMemo } from "react";
-import { useRouter } from "next/router";
+import { useSuspenseQuery } from "@tanstack/react-query";
+import { useParams } from "@tanstack/react-router";
-import { createNotification } from "@app/components/notifications";
-import { useGetUserWorkspaces } from "@app/hooks/api";
-import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
-
-type TWorkspaceContext = {
- workspaces: Workspace[];
- currentWorkspace?: Workspace;
- isLoading: boolean;
-};
-
-const WorkspaceContext = createContext(null);
-
-type Props = {
- children: ReactNode;
-};
-
-export const WorkspaceProvider = ({ children }: Props): JSX.Element => {
- const { data: ws, isLoading } = useGetUserWorkspaces();
- const router = useRouter();
- const workspaceId = router.query.id;
-
- // memorize the workspace details for the context
- const value = useMemo(() => {
- const wsId = workspaceId || localStorage.getItem("projectData.id");
- return {
- workspaces: ws || [],
- currentWorkspace: (ws || []).find(({ id }) => id === wsId),
- isLoading
- };
- }, [ws, workspaceId, isLoading]);
-
- const shouldTriggerNoProjectAccess =
- !value.isLoading &&
- !value.currentWorkspace &&
- Object.values(ProjectType).some((el) => router.pathname.startsWith(`/${el}`)) &&
- workspaceId;
-
- // handle redirects for project-specific routes
- useEffect(() => {
- if (shouldTriggerNoProjectAccess) {
- createNotification({
- text: "You are not a member of this project.",
- type: "info"
- });
-
- setTimeout(() => {
- router.push("/");
- }, 5000);
- }
- }, [shouldTriggerNoProjectAccess, router]);
-
- if (shouldTriggerNoProjectAccess) {
- return (
-
- You do not have sufficient access to this project.
-
- );
- }
-
- return {children};
-};
+import { workspaceKeys } from "@app/hooks/api";
+import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries";
export const useWorkspace = () => {
- const ctx = useContext(WorkspaceContext);
- if (!ctx) {
- throw new Error("useWorkspace has to be used within ");
+ const params = useParams({
+ strict: false
+ });
+ if (!params.projectId) {
+ throw new Error("Missing project id");
}
- return ctx;
+ const { data: currentWorkspace } = useSuspenseQuery({
+ queryKey: workspaceKeys.getWorkspaceById(params.projectId),
+ queryFn: () => fetchWorkspaceById(params.projectId as string),
+ staleTime: Infinity
+ });
+
+ return { currentWorkspace };
};
diff --git a/frontend/src/context/WorkspaceContext/index.tsx b/frontend/src/context/WorkspaceContext/index.tsx
index 0ae8cb4c58..b0c25d4dab 100644
--- a/frontend/src/context/WorkspaceContext/index.tsx
+++ b/frontend/src/context/WorkspaceContext/index.tsx
@@ -1 +1 @@
-export { useWorkspace, WorkspaceProvider } from "./WorkspaceContext";
+export { useWorkspace } from "./WorkspaceContext";
diff --git a/frontend/src/context/index.tsx b/frontend/src/context/index.tsx
index 91dae5d2d2..70d00dd744 100644
--- a/frontend/src/context/index.tsx
+++ b/frontend/src/context/index.tsx
@@ -1,9 +1,7 @@
-export { AuthProvider } from "./AuthContext";
-export { OrgProvider, useOrganization } from "./OrganizationContext";
+export { useOrganization } from "./OrganizationContext";
export type { TOrgPermission } from "./OrgPermissionContext";
export {
OrgPermissionActions,
- OrgPermissionProvider,
OrgPermissionSubjects,
useOrgPermission
} from "./OrgPermissionContext";
@@ -12,11 +10,10 @@ export {
ProjectPermissionActions,
ProjectPermissionCmekActions,
ProjectPermissionDynamicSecretActions,
- ProjectPermissionProvider,
ProjectPermissionSub,
useProjectPermission
} from "./ProjectPermissionContext";
-export { ServerConfigProvider, useServerConfig } from "./ServerConfigContext";
-export { SubscriptionProvider, useSubscription } from "./SubscriptionContext";
-export { UserProvider, useUser } from "./UserContext";
-export { useWorkspace, WorkspaceProvider } from "./WorkspaceContext";
+export { useServerConfig } from "./ServerConfigContext";
+export { useSubscription } from "./SubscriptionContext";
+export { useUser } from "./UserContext";
+export { useWorkspace } from "./WorkspaceContext";
diff --git a/frontend/src/ee/api/memberships/UpdateUserProjectPermission.ts b/frontend/src/ee/api/memberships/UpdateUserProjectPermission.ts
deleted file mode 100644
index d508053113..0000000000
--- a/frontend/src/ee/api/memberships/UpdateUserProjectPermission.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import SecurityClient from "@app/components/utilities/SecurityClient";
-
-/**
- * This function updates user permissions for a certain environment in a project
- * @param {object} obj
- * @param {string} obj.membershipId - membershipId of a certain user in a project
- * @param {*[]} obj.denials - permissions that we are prohibitting users to do
- * @returns
- */
-const updateUserProjectPermission = async ({
- membershipId,
- denials
-}: {
- membershipId: string;
- denials: {
- ability: string;
- environmentSlug: string;
- }[];
-}) =>
- SecurityClient.fetchCall(`/api/v1/membership/${membershipId}/deny-permissions`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- permissions: denials
- })
- }).then(async (res) => {
- // console.log({
- // permissions: denials
- // }, res)
- if (res && res.status === 200) {
- return res.json();
- }
- console.log("Failed to update user permissions for a certain environment in a project");
- return undefined;
- });
-
-export default updateUserProjectPermission;
diff --git a/frontend/src/ee/api/secrets/GetActionData.ts b/frontend/src/ee/api/secrets/GetActionData.ts
deleted file mode 100644
index b491414310..0000000000
--- a/frontend/src/ee/api/secrets/GetActionData.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import SecurityClient from "@app/components/utilities/SecurityClient";
-
-interface WorkspaceProps {
- actionId: string;
-}
-
-/**
- * This function fetches the data for a certain action performed by a user
- * @param {object} obj
- * @param {string} obj.actionId - id of an action for which we are trying to get data
- * @returns
- */
-const getActionData = async ({ actionId }: WorkspaceProps) =>
- SecurityClient.fetchCall(`/api/v1/action/${actionId}`, {
- method: "GET",
- headers: {
- "Content-Type": "application/json"
- }
- }).then(async (res) => {
- if (res && res.status === 200) {
- return (await res.json()).action;
- }
- console.log("Failed to get the info about an action");
- return undefined;
- });
-
-export default getActionData;
diff --git a/frontend/src/ee/api/secrets/GetProjectSercetShanpshots.ts b/frontend/src/ee/api/secrets/GetProjectSercetShanpshots.ts
deleted file mode 100644
index ff29e7d5b1..0000000000
--- a/frontend/src/ee/api/secrets/GetProjectSercetShanpshots.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import SecurityClient from "@app/components/utilities/SecurityClient";
-
-interface WorkspaceProps {
- workspaceId: string;
- offset: number;
- limit: number;
-}
-
-/**
- * This function fetches the secret snapshots for a certain project
- * @param {object} obj
- * @param {string} obj.workspaceId - project id for which we are trying to get project secret snapshots
- * @param {object} obj.offset - teh starting point of snapshots that we want to pull
- * @param {object} obj.limit - how many snapshots will we output
- * @returns
- */
-const getProjectSecretShanpshots = async ({ workspaceId, offset, limit }: WorkspaceProps) =>
- SecurityClient.fetchCall(
- `/api/v1/workspace/${workspaceId}/secret-snapshots?${new URLSearchParams({
- offset: String(offset),
- limit: String(limit)
- })}`,
- {
- method: "GET",
- headers: {
- "Content-Type": "application/json"
- }
- }
- ).then(async (res) => {
- if (res && res.status === 200) {
- return (await res.json()).secretSnapshots;
- }
- console.log("Failed to get project secret snapshots");
- return undefined;
- });
-
-export default getProjectSecretShanpshots;
diff --git a/frontend/src/ee/api/secrets/GetProjectSercetSnapshotsCount.ts b/frontend/src/ee/api/secrets/GetProjectSercetSnapshotsCount.ts
deleted file mode 100644
index e7c3292abd..0000000000
--- a/frontend/src/ee/api/secrets/GetProjectSercetSnapshotsCount.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import SecurityClient from "@app/components/utilities/SecurityClient";
-
-interface WorkspaceProps {
- workspaceId: string;
-}
-
-/**
- * This function fetches the count of secret snapshots for a certain project
- * @param {object} obj
- * @param {string} obj.workspaceId - project id for which we are trying to get project secret snapshots
- * @returns
- */
-const getProjectSercetSnapshotsCount = async ({ workspaceId }: WorkspaceProps) =>
- SecurityClient.fetchCall(`/api/v1/workspace/${workspaceId}/secret-snapshots/count`, {
- method: "GET",
- headers: {
- "Content-Type": "application/json"
- }
- }).then(async (res) => {
- if (res && res.status === 200) {
- return (await res.json()).count;
- }
- console.log("Failed to get the count of project secret snapshots");
- return undefined;
- });
-
-export default getProjectSercetSnapshotsCount;
diff --git a/frontend/src/ee/api/secrets/GetSecretSnapshotData.ts b/frontend/src/ee/api/secrets/GetSecretSnapshotData.ts
deleted file mode 100644
index ff1d16791e..0000000000
--- a/frontend/src/ee/api/secrets/GetSecretSnapshotData.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import SecurityClient from "@app/components/utilities/SecurityClient";
-
-interface SnapshotProps {
- secretSnapshotId: string;
-}
-
-/**
- * This function fetches the secrets for a certain secret snapshot
- * @param {object} obj
- * @param {string} obj.secretSnapshotId - snapshot id for which we are trying to get secrets
- * @returns
- */
-const getSecretSnapshotData = async ({ secretSnapshotId }: SnapshotProps) =>
- SecurityClient.fetchCall(`/api/v1/secret-snapshot/${secretSnapshotId}`, {
- method: "GET",
- headers: {
- "Content-Type": "application/json"
- }
- }).then(async (res) => {
- if (res && res.status === 200) {
- return (await res.json()).secretSnapshot;
- }
- console.log("Failed to get the secrets of a certain snapshot");
- return undefined;
- });
-
-export default getSecretSnapshotData;
diff --git a/frontend/src/ee/api/secrets/GetSecretVersions.ts b/frontend/src/ee/api/secrets/GetSecretVersions.ts
deleted file mode 100644
index f6a380cb32..0000000000
--- a/frontend/src/ee/api/secrets/GetSecretVersions.ts
+++ /dev/null
@@ -1,37 +0,0 @@
-import SecurityClient from "@app/components/utilities/SecurityClient";
-
-interface SecretVersionProps {
- secretId: string;
- offset: number;
- limit: number;
-}
-
-/**
- * This function fetches the versions of a specific secret
- * @param {object} obj
- * @param {string} obj.secretId - the id of a secret for which we are fetching the version history
- * @param {number} obj.offset - the start of our query
- * @param {number} obj.limit - how far our query goes
- * @returns
- */
-const getSecretVersions = async ({ secretId, offset, limit }: SecretVersionProps) =>
- SecurityClient.fetchCall(
- `/api/v1/secret/${secretId}/secret-versions?${new URLSearchParams({
- offset: String(offset),
- limit: String(limit)
- })}`,
- {
- method: "GET",
- headers: {
- "Content-Type": "application/json"
- }
- }
- ).then(async (res) => {
- if (res && res.status === 200) {
- return res.json();
- }
- console.log("Failed to get secret version history");
- return undefined;
- });
-
-export default getSecretVersions;
diff --git a/frontend/src/ee/api/secrets/PerformSecretRollback.ts b/frontend/src/ee/api/secrets/PerformSecretRollback.ts
deleted file mode 100644
index 7464a8fc78..0000000000
--- a/frontend/src/ee/api/secrets/PerformSecretRollback.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import SecurityClient from "@app/components/utilities/SecurityClient";
-
-/**
- * This function performs a rollback of secrets in a certain project
- * @param {object} obj
- * @param {string} obj.workspaceId - id of the project for which we are rolling back data
- * @param {number} obj.version - version to which we are rolling back
- * @returns
- */
-const performSecretRollback = async ({
- workspaceId,
- version
-}: {
- workspaceId: string;
- version: number;
-}) =>
- SecurityClient.fetchCall(`/api/v1/workspace/${workspaceId}/secret-snapshots/rollback`, {
- method: "POST",
- headers: {
- "Content-Type": "application/json"
- },
- body: JSON.stringify({
- version
- })
- }).then(async (res) => {
- if (res && res.status === 200) {
- return res.json();
- }
- console.log("Failed to perform the secret rollback");
- return undefined;
- });
-
-export default performSecretRollback;
diff --git a/frontend/src/ee/utilities/findTextDifferences.ts b/frontend/src/ee/utilities/findTextDifferences.ts
deleted file mode 100644
index c15bb4b058..0000000000
--- a/frontend/src/ee/utilities/findTextDifferences.ts
+++ /dev/null
@@ -1,356 +0,0 @@
-/* eslint-disable */
-// TODO(akhilmhdh): Danger. This file functions needs to simplified.
-// Disabled eslinting as below algos uses unnary operator and need to be careful on handling it
-// Will revisit this and change to simplier non-recursive to dynamic programming with space allocation strategy
-/**
- *
- * @param textOld - old secret
- * @param textNew - new (updated) secret
- * @param diffPlusFlag - a flag for whether we want to detect moving segments
- * - doesn't work in some examples (e.g., when we have a full reverse ordering of the text)
- * @returns
- */
-function patienceDiff(textOld: string[], textNew: string[], diffPlusFlag?: boolean) {
- /**
- * findUnique finds all unique values in arr[lo..hi], inclusive. This
- * function is used in preparation for determining the longest common
- * subsequence. Specifically, it first reduces the array range in question
- * to unique values.
- * @param chars - an array of characters
- * @param lo
- * @param hi
- * @returns - an ordered Map, with the arr[i] value as the Map key and the
- * array index i as the Map value.
- */
- function findUnique(chars: string[], lo: number, hi: number) {
- const characterMap = new Map();
-
- for (let i = lo; i <= hi; i += 1) {
- const character = chars[i];
-
- if (characterMap.has(character)) {
- characterMap.get(character).count += 1;
- characterMap.get(character).index = i;
- } else {
- characterMap.set(character, { count: 1, index: i });
- }
- }
-
- characterMap.forEach((val, key, map) => {
- if (val.count !== 1) {
- map.delete(key);
- } else {
- map.set(key, val.index);
- }
- });
-
- return characterMap;
- }
-
- /**
- * @param aArray
- * @param aLo
- * @param aHi
- * @param bArray
- * @param bLo
- * @param bHi
- * @returns an ordered Map, with the Map key as the common line between aArray
- * and bArray, with the Map value as an object containing the array indexes of
- * the matching unique lines.
- *
- */
- function uniqueCommon(
- aArray: string[],
- aLo: number,
- aHi: number,
- bArray: string[],
- bLo: number,
- bHi: number
- ) {
- const ma = findUnique(aArray, aLo, aHi);
- const mb = findUnique(bArray, bLo, bHi);
-
- ma.forEach((val, key, map) => {
- if (mb.has(key)) {
- map.set(key, {
- indexA: val,
- indexB: mb.get(key)
- });
- } else {
- map.delete(key);
- }
- });
-
- return ma;
- }
-
- /**
- * longestCommonSubsequence takes an ordered Map from the function uniqueCommon
- * and determines the Longest Common Subsequence (LCS).
- * @param abMap
- * @returns an ordered array of objects containing the array indexes of the
- * matching lines for a LCS.
- */
- function longestCommonSubsequence(
- abMap: Map
- ) {
- const ja: any = [];
-
- // First, walk the list creating the jagged array.
- abMap.forEach((val, key, map) => {
- let i = 0;
-
- while (ja[i] && ja[i][ja[i].length - 1].indexB < val.indexB) {
- i += 1;
- }
-
- if (!ja[i]) {
- ja[i] = [];
- }
-
- if (i > 0) {
- val.prev = ja[i - 1][ja[i - 1].length - 1];
- }
- ja[i].push(val);
- });
-
- // Now, pull out the longest common subsequence.
- let lcs: any[] = [];
-
- if (ja.length > 0) {
- const n = ja.length - 1;
- lcs = [ja[n][ja[n].length - 1]];
-
- while (lcs[lcs.length - 1].prev) {
- lcs.push(lcs[lcs.length - 1].prev);
- }
- }
-
- return lcs.reverse();
- }
-
- // "result" is the array used to accumulate the textOld that are deleted, the
- // lines that are shared between textOld and textNew, and the textNew that were
- // inserted.
-
- const result: any[] = [];
- let deleted = 0;
- let inserted = 0;
-
- // aMove and bMove will contain the lines that don't match, and will be returned
- // for possible searching of lines that moved.
-
- const aMove: any[] = [];
- const aMoveIndex: any[] = [];
- const bMove: any[] = [];
- const bMoveIndex: any[] = [];
-
- /**
- * addToResult simply pushes the latest value onto the "result" array. This
- * array captures the diff of the line, aIndex, and bIndex from the textOld
- * and textNew array.
- * @param aIndex
- * @param bIndex
- */
- function addToResult(aIndex: number, bIndex: number) {
- if (bIndex < 0) {
- aMove.push(textOld[aIndex]);
- aMoveIndex.push(result.length);
- deleted += 1;
- } else if (aIndex < 0) {
- bMove.push(textNew[bIndex]);
- bMoveIndex.push(result.length);
- inserted += 1;
- }
-
- result.push({
- line: aIndex >= 0 ? textOld[aIndex] : textNew[bIndex],
- aIndex,
- bIndex
- });
- }
-
- /**
- * addSubMatch handles the lines between a pair of entries in the LCS. Thus,
- * this function might recursively call recurseLCS to further match the lines
- * between textOld and textNew.
- * @param aLo
- * @param aHi
- * @param bLo
- * @param bHi
- */
- function addSubMatch(aLo: number, aHi: number, bLo: number, bHi: number) {
- // Match any lines at the beginning of textOld and textNew.
- while (aLo <= aHi && bLo <= bHi && textOld[aLo] === textNew[bLo]) {
- addToResult(aLo++, bLo++);
- }
-
- // Match any lines at the end of textOld and textNew, but don't place them
- // in the "result" array just yet, as the lines between these matches at
- // the beginning and the end need to be analyzed first.
-
- const aHiTemp = aHi;
- while (aLo <= aHi && bLo <= bHi && textOld[aHi] === textNew[bHi]) {
- aHi -= 1;
- bHi -= 1;
- }
-
- // Now, check to determine with the remaining lines in the subsequence
- // whether there are any unique common lines between textOld and textNew.
- //
- // If not, add the subsequence to the result (all textOld having been
- // deleted, and all textNew having been inserted).
- //
- // If there are unique common lines between textOld and textNew, then let's
- // recursively perform the patience diff on the subsequence.
-
- const uniqueCommonMap = uniqueCommon(textOld, aLo, aHi, textNew, bLo, bHi);
-
- if (uniqueCommonMap.size === 0) {
- while (aLo <= aHi) {
- addToResult(aLo++, -1);
- }
-
- while (bLo <= bHi) {
- addToResult(-1, bLo++);
- }
- } else {
- recurseLCS(aLo, aHi, bLo, bHi, uniqueCommonMap);
- }
-
- // Finally, let's add the matches at the end to the result.
- while (aHi < aHiTemp) {
- addToResult(++aHi, ++bHi);
- }
- }
-
- /**
- * recurseLCS finds the longest common subsequence (LCS) between the arrays
- * textOld[aLo..aHi] and textNew[bLo..bHi] inclusive. Then for each subsequence
- * recursively performs another LCS search (via addSubMatch), until there are
- * none found, at which point the subsequence is dumped to the result.
- * @param aLo
- * @param aHi
- * @param bLo
- * @param bHi
- * @param uniqueCommonMap
- */
- function recurseLCS(aLo: number, aHi: number, bLo: number, bHi: number, uniqueCommonMap?: any) {
- const x = longestCommonSubsequence(
- uniqueCommonMap || uniqueCommon(textOld, aLo, aHi, textNew, bLo, bHi)
- );
-
- if (x.length === 0) {
- addSubMatch(aLo, aHi, bLo, bHi);
- } else {
- if (aLo < x[0].indexA || bLo < x[0].indexB) {
- addSubMatch(aLo, x[0].indexA - 1, bLo, x[0].indexB - 1);
- }
-
- let i;
- for (i = 0; i < x.length - 1; i += 1) {
- addSubMatch(x[i].indexA, x[i + 1].indexA - 1, x[i].indexB, x[i + 1].indexB - 1);
- }
-
- if (x[i].indexA <= aHi || x[i].indexB <= bHi) {
- addSubMatch(x[i].indexA, aHi, x[i].indexB, bHi);
- }
- }
- }
-
- recurseLCS(0, textOld.length - 1, 0, textNew.length - 1);
-
- if (diffPlusFlag) {
- return {
- lines: result,
- lineCountDeleted: deleted,
- lineCountInserted: inserted,
- lineCountMoved: 0,
- aMove,
- aMoveIndex,
- bMove,
- bMoveIndex
- };
- }
-
- return {
- lines: result,
- lineCountDeleted: deleted,
- lineCountInserted: inserted,
- lineCountMoved: 0
- };
-}
-
-/**
- * use: patienceDiffPlus( textOld[], textNew[] )
- *
- * where:
- * textOld[] contains the original text lines.
- * textNew[] contains the new text lines.
- *
- * returns an object with the following properties:
- * lines[] with properties of:
- * line containing the line of text from textOld or textNew.
- * aIndex referencing the index in aLine[].
- * bIndex referencing the index in textNew[].
- * (Note: The line is text from either textOld or textNew, with aIndex and bIndex
- * referencing the original index. If aIndex === -1 then the line is new from textNew,
- * and if bIndex === -1 then the line is old from textOld.)
- * moved is true if the line was moved from elsewhere in textOld[] or textNew[].
- * lineCountDeleted is the number of lines from textOld[] not appearing in textNew[].
- * lineCountInserted is the number of lines from textNew[] not appearing in textOld[].
- * lineCountMoved is the number of lines that moved.
- */
-
-function patienceDiffPlus(textOld: string[], textNew: string[]) {
- const difference = patienceDiff(textOld, textNew, true);
-
- let aMoveNext = difference.aMove;
- let aMoveIndexNext = difference.aMoveIndex;
- let bMoveNext = difference.bMove;
- let bMoveIndexNext = difference.bMoveIndex;
-
- delete difference.aMove;
- delete difference.aMoveIndex;
- delete difference.bMove;
- delete difference.bMoveIndex;
-
- let lastLineCountMoved;
-
- do {
- const aMove = aMoveNext;
- const aMoveIndex = aMoveIndexNext;
- const bMove = bMoveNext;
- const bMoveIndex = bMoveIndexNext;
-
- aMoveNext = [];
- aMoveIndexNext = [];
- bMoveNext = [];
- bMoveIndexNext = [];
-
- const subDiff = patienceDiff(aMove!, bMove!);
-
- lastLineCountMoved = difference.lineCountMoved;
-
- subDiff.lines.forEach((v, i) => {
- if (v.aIndex >= 0 && v.bIndex >= 0) {
- difference.lines[aMoveIndex![v.aIndex]].moved = true;
- difference.lines[bMoveIndex![v.bIndex]].aIndex = aMoveIndex![v.aIndex];
- difference.lines[bMoveIndex![v.bIndex]].moved = true;
- difference.lineCountInserted -= 1;
- difference.lineCountDeleted -= 1;
- difference.lineCountMoved += 1;
- } else if (v.bIndex < 0) {
- aMoveNext!.push(aMove![v.aIndex]);
- aMoveIndexNext!.push(aMoveIndex![v.aIndex]);
- } else {
- bMoveNext!.push(bMove![v.bIndex]);
- bMoveIndexNext!.push(bMoveIndex![v.bIndex]);
- }
- });
- } while (difference.lineCountMoved - lastLineCountMoved > 0);
-
- return difference;
-}
-
-export default patienceDiff;
diff --git a/frontend/src/ee/utilities/timeSince.ts b/frontend/src/ee/utilities/timeSince.ts
deleted file mode 100644
index a70ae19059..0000000000
--- a/frontend/src/ee/utilities/timeSince.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Time since a certain date
- * @param {Date} date - the timestamp got which we want to understand how long ago it happened
- * @returns {String} text - how much time has passed since a certain timestamp
- */
-function timeSince(date: Date) {
- const seconds = Math.floor(((new Date() as any) - (date as any)) / 1000) as number;
-
- let interval = seconds / 31536000;
-
- if (interval > 1) {
- return `${Math.floor(interval)} years ago`;
- }
- interval = seconds / 2592000;
- if (interval > 1) {
- return `${Math.floor(interval)} months ago`;
- }
- interval = seconds / 86400;
- if (interval > 1) {
- return `${Math.floor(interval)} days ago`;
- }
- interval = seconds / 3600;
- if (interval > 1) {
- return `${Math.floor(interval)} hours ago`;
- }
- interval = seconds / 60;
- if (interval > 1) {
- return `${Math.floor(interval)} minutes ago`;
- }
- return `${Math.floor(seconds)} seconds ago`;
-}
-
-export default timeSince;
diff --git a/frontend/src/global.d.ts b/frontend/src/global.d.ts
new file mode 100644
index 0000000000..30b80cb706
--- /dev/null
+++ b/frontend/src/global.d.ts
@@ -0,0 +1,12 @@
+export {};
+
+declare global {
+ interface Window {
+ __INFISICAL_RUNTIME_ENV__?: {
+ CAPTCHA_SITE_KEY?: string;
+ POSTHOG_API_KEY?: string;
+ INTERCOM_ID?: string;
+ TELEMETRY_CAPTURING_ENABLED: string;
+ };
+ }
+}
diff --git a/frontend/src/helpers/key.ts b/frontend/src/helpers/key.ts
index 9301bb77b9..c516826f16 100644
--- a/frontend/src/helpers/key.ts
+++ b/frontend/src/helpers/key.ts
@@ -74,7 +74,7 @@ const decryptPrivateKeyHelper = async ({
} else {
throw new Error("Insufficient details to decrypt private key");
}
- } catch (err) {
+ } catch {
throw new Error("Failed to decrypt private key");
}
diff --git a/frontend/src/helpers/localStorage.ts b/frontend/src/helpers/localStorage.ts
new file mode 100644
index 0000000000..7a265d18e4
--- /dev/null
+++ b/frontend/src/helpers/localStorage.ts
@@ -0,0 +1,9 @@
+const INTEGRATION_PROJECT_ID = "integration_project_id";
+export const localStorageService = {
+ getIintegrationProjectId() {
+ return localStorage.getItem(INTEGRATION_PROJECT_ID);
+ },
+ setIntegrationProjectId(projectId: string) {
+ return localStorage.setItem(INTEGRATION_PROJECT_ID, projectId);
+ }
+};
diff --git a/frontend/src/helpers/parseEnvVar.ts b/frontend/src/helpers/parseEnvVar.ts
index 8bde050844..6c3221e3b1 100644
--- a/frontend/src/helpers/parseEnvVar.ts
+++ b/frontend/src/helpers/parseEnvVar.ts
@@ -1,31 +1,31 @@
-/** Extracts the key and value from a passed in env string based on the provided delimiters. */
-export const getKeyValue = (pastedContent: string, delimiters: string[]) => {
- if (!pastedContent) {
- return { key: "", value: "" };
- }
-
- let firstDelimiterIndex = -1;
- let foundDelimiter = "";
-
- delimiters.forEach((delimiter) => {
- const index = pastedContent.indexOf(delimiter);
- if (index !== -1 && (firstDelimiterIndex === -1 || index < firstDelimiterIndex)) {
- firstDelimiterIndex = index;
- foundDelimiter = delimiter;
- }
- });
-
- const hasValueAfterDelimiter = pastedContent.length > firstDelimiterIndex + foundDelimiter.length;
-
- if (firstDelimiterIndex === -1 || !hasValueAfterDelimiter) {
- return { key: pastedContent.trim(), value: "" };
- }
-
- const key = pastedContent.substring(0, firstDelimiterIndex);
- const value = pastedContent.substring(firstDelimiterIndex + foundDelimiter.length);
-
- return {
- key: key.trim(),
- value: value.trim()
- };
-};
+/** Extracts the key and value from a passed in env string based on the provided delimiters. */
+export const getKeyValue = (pastedContent: string, delimiters: string[]) => {
+ if (!pastedContent) {
+ return { key: "", value: "" };
+ }
+
+ let firstDelimiterIndex = -1;
+ let foundDelimiter = "";
+
+ delimiters.forEach((delimiter) => {
+ const index = pastedContent.indexOf(delimiter);
+ if (index !== -1 && (firstDelimiterIndex === -1 || index < firstDelimiterIndex)) {
+ firstDelimiterIndex = index;
+ foundDelimiter = delimiter;
+ }
+ });
+
+ const hasValueAfterDelimiter = pastedContent.length > firstDelimiterIndex + foundDelimiter.length;
+
+ if (firstDelimiterIndex === -1 || !hasValueAfterDelimiter) {
+ return { key: pastedContent.trim(), value: "" };
+ }
+
+ const key = pastedContent.substring(0, firstDelimiterIndex);
+ const value = pastedContent.substring(firstDelimiterIndex + foundDelimiter.length);
+
+ return {
+ key: key.trim(),
+ value: value.trim()
+ };
+};
diff --git a/frontend/src/helpers/policies.ts b/frontend/src/helpers/policies.ts
index c6d7c935ae..7828807dc5 100644
--- a/frontend/src/helpers/policies.ts
+++ b/frontend/src/helpers/policies.ts
@@ -9,4 +9,4 @@ export const policyDetails: Record {
- if (workspace.type === ProjectType.SecretManager) {
- return `/${workspace.type}/${workspace.id}/secrets/overview`;
- }
- if (workspace.type === ProjectType.CertificateManager) {
- return `/${workspace.type}/${workspace.id}/certificates`;
- }
-
- if (workspace.type === ProjectType.KMS) {
- return `/${workspace.type}/${workspace.id}/kms`;
- }
-
- return `/${workspace.type}/${workspace.id}/ssh`;
+ return `/${workspace.type}/$projectId/overview` as const;
};
export const getProjectTitle = (type: ProjectType) => {
diff --git a/frontend/src/helpers/string.ts b/frontend/src/helpers/string.ts
index bd97d8a3c5..109b51d494 100644
--- a/frontend/src/helpers/string.ts
+++ b/frontend/src/helpers/string.ts
@@ -11,4 +11,4 @@ export const isValidPath = (val: string): boolean => {
// Check for valid characters and no consecutive slashes
const validPathRegex = /^[a-zA-Z0-9-_.:]+(?:\/[a-zA-Z0-9-_.:]+)*$/;
return validPathRegex.test(val);
-}
\ No newline at end of file
+};
diff --git a/frontend/src/hoc/withPermission/withPermission.tsx b/frontend/src/hoc/withPermission/withPermission.tsx
index 0fe2d9f4fb..ef814d9583 100644
--- a/frontend/src/hoc/withPermission/withPermission.tsx
+++ b/frontend/src/hoc/withPermission/withPermission.tsx
@@ -16,7 +16,7 @@ type Props = (T extends AbilityTuple
subject: string;
}) & { className?: string; containerClassName?: string };
-export const withPermission = (
+export const withPermission = (
Component: ComponentType,
{ action, subject, className, containerClassName }: Props["abilities"]>
) => {
diff --git a/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx b/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx
index 22c91ab52e..564d44adcc 100644
--- a/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx
+++ b/frontend/src/hoc/withProjectPermission/withProjectPermission.tsx
@@ -14,7 +14,7 @@ type Props = {
subject: T[1];
};
-export const withProjectPermission = (
+export const withProjectPermission = (
Component: ComponentType, "action" | "subject"> & T>,
{ action, subject, className, containerClassName }: Props
) => {
diff --git a/frontend/src/hooks/api/accessApproval/mutation.tsx b/frontend/src/hooks/api/accessApproval/mutation.tsx
index 9c3199a996..115b731868 100644
--- a/frontend/src/hooks/api/accessApproval/mutation.tsx
+++ b/frontend/src/hooks/api/accessApproval/mutation.tsx
@@ -15,7 +15,7 @@ import {
export const useCreateAccessApprovalPolicy = () => {
const queryClient = useQueryClient();
- return useMutation<{}, {}, TCreateAccessPolicyDTO>({
+ return useMutation |