From acb22cdf3658c88d1ad65138eb661bd5570a1773 Mon Sep 17 00:00:00 2001 From: carlosmonastyrski Date: Tue, 11 Mar 2025 12:58:09 -0300 Subject: [PATCH] Added new option to enable/disable option to share secrets with anyone --- ...hare-to-anyone-setting-to-organizations.ts | 26 ++++ backend/src/db/schemas/organizations.ts | 3 +- .../server/routes/v1/organization-router.ts | 3 +- backend/src/services/org/org-service.ts | 14 +- backend/src/services/org/org-types.ts | 1 + frontend/src/const/routes.ts | 4 + .../src/hooks/api/organization/queries.tsx | 6 +- frontend/src/hooks/api/organization/types.ts | 2 + .../OrganizationLayout/OrganizationLayout.tsx | 87 ++++------- .../ProductsSideBar/DefaultSideBar.tsx | 58 ++++++++ .../ProductsSideBar/SecretSharingSideBar.tsx | 34 +++++ .../ProductsSideBar/index.ts | 2 + .../SecretSharingSettingsPage.tsx | 35 +++++ .../SecretSharingAllowShareToAnyone.tsx | 58 ++++++++ .../SecretSharingAllowShareToAnyone/index.tsx | 1 + .../SecretSharingSettingsGeneralTab.tsx | 9 ++ .../SecretSharingSettingsGeneralTab/index.tsx | 1 + .../SecretSharingSettingsTabGroup.tsx | 39 +++++ .../SecretSharingSettingsTabGroup/index.tsx | 1 + .../components/index.tsx | 1 + .../SecretSharingSettingsPage/route.tsx | 37 +++++ .../components/ShareSecretForm.tsx | 26 +++- frontend/src/routeTree.gen.ts | 135 ++++++++++++++---- frontend/src/routes.ts | 5 +- 24 files changed, 486 insertions(+), 102 deletions(-) create mode 100644 backend/src/db/migrations/20250311105617_add-share-to-anyone-setting-to-organizations.ts create mode 100644 frontend/src/layouts/OrganizationLayout/ProductsSideBar/DefaultSideBar.tsx create mode 100644 frontend/src/layouts/OrganizationLayout/ProductsSideBar/SecretSharingSideBar.tsx create mode 100644 frontend/src/layouts/OrganizationLayout/ProductsSideBar/index.ts create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/SecretSharingAllowShareToAnyone.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/index.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/SecretSharingSettingsGeneralTab.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/index.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/SecretSharingSettingsTabGroup.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/index.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/components/index.tsx create mode 100644 frontend/src/pages/organization/SecretSharingSettingsPage/route.tsx diff --git a/backend/src/db/migrations/20250311105617_add-share-to-anyone-setting-to-organizations.ts b/backend/src/db/migrations/20250311105617_add-share-to-anyone-setting-to-organizations.ts new file mode 100644 index 000000000..71c3b736f --- /dev/null +++ b/backend/src/db/migrations/20250311105617_add-share-to-anyone-setting-to-organizations.ts @@ -0,0 +1,26 @@ +import { Knex } from "knex"; + +import { TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + if (await knex.schema.hasTable(TableName.Organization)) { + const hasSecretShareToAnyoneCol = await knex.schema.hasColumn(TableName.Organization, "secretShareToAnyone"); + + if (!hasSecretShareToAnyoneCol) { + await knex.schema.alterTable(TableName.Organization, (t) => { + t.boolean("secretShareSendToAnyone").defaultTo(true); + }); + } + } +} + +export async function down(knex: Knex): Promise { + if (await knex.schema.hasTable(TableName.Organization)) { + const hasSecretShareToAnyoneCol = await knex.schema.hasColumn(TableName.Organization, "secretShareToAnyone"); + if (hasSecretShareToAnyoneCol) { + await knex.schema.alterTable(TableName.Organization, (t) => { + t.dropColumn("secretShareSendToAnyone"); + }); + } + } +} diff --git a/backend/src/db/schemas/organizations.ts b/backend/src/db/schemas/organizations.ts index 3f40447ad..284ad8d58 100644 --- a/backend/src/db/schemas/organizations.ts +++ b/backend/src/db/schemas/organizations.ts @@ -22,7 +22,8 @@ export const OrganizationsSchema = z.object({ kmsEncryptedDataKey: zodBuffer.nullable().optional(), defaultMembershipRole: z.string().default("member"), enforceMfa: z.boolean().default(false), - selectedMfaMethod: z.string().nullable().optional() + selectedMfaMethod: z.string().nullable().optional(), + secretShareSendToAnyone: z.boolean().default(true).nullable().optional() }); export type TOrganizations = z.infer; diff --git a/backend/src/server/routes/v1/organization-router.ts b/backend/src/server/routes/v1/organization-router.ts index db0008ebe..0b6f7c2e1 100644 --- a/backend/src/server/routes/v1/organization-router.ts +++ b/backend/src/server/routes/v1/organization-router.ts @@ -257,7 +257,8 @@ export const registerOrgRouter = async (server: FastifyZodProvider) => { scimEnabled: z.boolean().optional(), defaultMembershipRoleSlug: slugSchema({ max: 64, field: "Default Membership Role" }).optional(), enforceMfa: z.boolean().optional(), - selectedMfaMethod: z.nativeEnum(MfaMethod).optional() + selectedMfaMethod: z.nativeEnum(MfaMethod).optional(), + secretShareSendToAnyone: z.boolean().optional() }), response: { 200: z.object({ diff --git a/backend/src/services/org/org-service.ts b/backend/src/services/org/org-service.ts index b0e5c1f67..12b5a7505 100644 --- a/backend/src/services/org/org-service.ts +++ b/backend/src/services/org/org-service.ts @@ -286,7 +286,16 @@ export const orgServiceFactory = ({ actorOrgId, actorAuthMethod, orgId, - data: { name, slug, authEnforced, scimEnabled, defaultMembershipRoleSlug, enforceMfa, selectedMfaMethod } + data: { + name, + slug, + authEnforced, + scimEnabled, + defaultMembershipRoleSlug, + enforceMfa, + selectedMfaMethod, + secretShareSendToAnyone + } }: TUpdateOrgDTO) => { const appCfg = getConfig(); const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId); @@ -358,7 +367,8 @@ export const orgServiceFactory = ({ scimEnabled, defaultMembershipRole, enforceMfa, - selectedMfaMethod + selectedMfaMethod, + secretShareSendToAnyone }); if (!org) throw new NotFoundError({ message: `Organization with ID '${orgId}' not found` }); return org; diff --git a/backend/src/services/org/org-types.ts b/backend/src/services/org/org-types.ts index b9228377b..b6dabe121 100644 --- a/backend/src/services/org/org-types.ts +++ b/backend/src/services/org/org-types.ts @@ -72,6 +72,7 @@ export type TUpdateOrgDTO = { defaultMembershipRoleSlug: string; enforceMfa: boolean; selectedMfaMethod: MfaMethod; + secretShareSendToAnyone: boolean; }>; } & TOrgPermission; diff --git a/frontend/src/const/routes.ts b/frontend/src/const/routes.ts index c36264f5c..e0de3da44 100644 --- a/frontend/src/const/routes.ts +++ b/frontend/src/const/routes.ts @@ -25,6 +25,10 @@ export const ROUTE_PATHS = Object.freeze({ "/organization/secret-sharing", "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing" ), + SecretSharingSettings: setRoute( + "/organization/secret-sharing/settings", + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings" + ), SettingsPage: setRoute( "/organization/settings", "/_authenticate/_inject-org-details/_org-layout/organization/settings" diff --git a/frontend/src/hooks/api/organization/queries.tsx b/frontend/src/hooks/api/organization/queries.tsx index b5637f049..64f8f2eb1 100644 --- a/frontend/src/hooks/api/organization/queries.tsx +++ b/frontend/src/hooks/api/organization/queries.tsx @@ -109,7 +109,8 @@ export const useUpdateOrg = () => { orgId, defaultMembershipRoleSlug, enforceMfa, - selectedMfaMethod + selectedMfaMethod, + secretShareSendToAnyone }) => { return apiRequest.patch(`/api/v1/organization/${orgId}`, { name, @@ -118,7 +119,8 @@ export const useUpdateOrg = () => { slug, defaultMembershipRoleSlug, enforceMfa, - selectedMfaMethod + selectedMfaMethod, + secretShareSendToAnyone }); }, onSuccess: () => { diff --git a/frontend/src/hooks/api/organization/types.ts b/frontend/src/hooks/api/organization/types.ts index 629c4a330..6ef32ff7e 100644 --- a/frontend/src/hooks/api/organization/types.ts +++ b/frontend/src/hooks/api/organization/types.ts @@ -15,6 +15,7 @@ export type Organization = { defaultMembershipRole: string; enforceMfa: boolean; selectedMfaMethod?: MfaMethod; + secretShareSendToAnyone?: boolean; }; export type UpdateOrgDTO = { @@ -26,6 +27,7 @@ export type UpdateOrgDTO = { defaultMembershipRoleSlug?: string; enforceMfa?: boolean; selectedMfaMethod?: MfaMethod; + secretShareSendToAnyone?: boolean; }; export type BillingDetails = { diff --git a/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx b/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx index 0e71c7bb6..583beed9a 100644 --- a/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx +++ b/frontend/src/layouts/OrganizationLayout/OrganizationLayout.tsx @@ -1,30 +1,37 @@ import { useTranslation } from "react-i18next"; import { faMobile } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { Link, linkOptions, Outlet, useLocation, useRouterState } from "@tanstack/react-router"; +import { linkOptions, Outlet, useLocation, useRouterState } from "@tanstack/react-router"; import { AnimatePresence, motion } from "framer-motion"; import { twMerge } from "tailwind-merge"; import { CreateOrgModal } from "@app/components/organization/CreateOrgModal"; import { Banner } from "@app/components/page-frames/Banner"; +import { BreadcrumbContainer, TBreadcrumbFormat } from "@app/components/v2"; import { - BreadcrumbContainer, - Menu, - MenuGroup, - MenuItem, - TBreadcrumbFormat -} from "@app/components/v2"; -import { useServerConfig } from "@app/context"; + OrgPermissionActions, + OrgPermissionSubjects, + useOrgPermission, + useServerConfig +} from "@app/context"; import { usePopUp } from "@app/hooks"; import { InsecureConnectionBanner } from "./components/InsecureConnectionBanner"; import { MinimizedOrgSidebar } from "./components/MinimizedOrgSidebar"; import { SidebarHeader } from "./components/SidebarHeader"; +import { DefaultSideBar, SecretSharingSideBar } from "./ProductsSideBar"; export const OrganizationLayout = () => { const matches = useRouterState({ select: (s) => s.matches.at(-1)?.context }); const location = useLocation(); const { config } = useServerConfig(); + const { permission } = useOrgPermission(); + + const shouldShowProductsSidebar = permission.can( + OrgPermissionActions.Edit, + OrgPermissionSubjects.Settings + ); + const isOrganizationSpecificPage = location.pathname.startsWith("/organization"); const breadcrumbs = isOrganizationSpecificPage && matches && "breadcrumbs" in matches @@ -35,16 +42,23 @@ export const OrganizationLayout = () => { const { t } = useTranslation(); + const isSecretSharingPage = ( + [ + linkOptions({ to: "/organization/secret-sharing" }).to, + linkOptions({ to: "/organization/secret-sharing/settings" }).to + ] as string[] + ).includes(location.pathname); + const shouldShowOrgSidebar = location.pathname.startsWith("/organization") && + (!isSecretSharingPage || shouldShowProductsSidebar) && !( [ linkOptions({ to: "/organization/secret-manager/overview" }).to, linkOptions({ to: "/organization/cert-manager/overview" }).to, linkOptions({ to: "/organization/ssh/overview" }).to, linkOptions({ to: "/organization/kms/overview" }).to, - linkOptions({ to: "/organization/secret-scanning" }).to, - linkOptions({ to: "/organization/secret-sharing" }).to + linkOptions({ to: "/organization/secret-scanning" }).to ] as string[] ).includes(location.pathname); @@ -73,58 +87,7 @@ export const OrganizationLayout = () => {
- - - - {({ isActive }) => ( - - Audit Logs - - )} - - {(window.location.origin.includes("https://app.infisical.com") || - window.location.origin.includes("https://eu.infisical.com") || - window.location.origin.includes("https://gamma.infisical.com")) && ( - - {({ isActive }) => ( - - Usage & Billing - - )} - - )} - - - - {({ isActive }) => ( - - Access Control - - )} - - - {({ isActive }) => ( - - App Connections - - )} - - - {({ isActive }) => ( - - Gateways - - )} - - - {({ isActive }) => ( - - Organization Settings - - )} - - - + {isSecretSharingPage ? : } )} diff --git a/frontend/src/layouts/OrganizationLayout/ProductsSideBar/DefaultSideBar.tsx b/frontend/src/layouts/OrganizationLayout/ProductsSideBar/DefaultSideBar.tsx new file mode 100644 index 000000000..e78d86703 --- /dev/null +++ b/frontend/src/layouts/OrganizationLayout/ProductsSideBar/DefaultSideBar.tsx @@ -0,0 +1,58 @@ +import { Link } from "@tanstack/react-router"; + +import { Menu, MenuGroup, MenuItem } from "@app/components/v2"; + +export const DefaultSideBar = () => ( + + + + {({ isActive }) => ( + + Audit Logs + + )} + + {(window.location.origin.includes("https://app.infisical.com") || + window.location.origin.includes("https://eu.infisical.com") || + window.location.origin.includes("https://gamma.infisical.com")) && ( + + {({ isActive }) => ( + + Usage & Billing + + )} + + )} + + + + {({ isActive }) => ( + + Access Control + + )} + + + {({ isActive }) => ( + + App Connections + + )} + + + {({ isActive }) => ( + + Gateways + + )} + + + {({ isActive }) => ( + + Organization Settings + + )} + + + +); diff --git a/frontend/src/layouts/OrganizationLayout/ProductsSideBar/SecretSharingSideBar.tsx b/frontend/src/layouts/OrganizationLayout/ProductsSideBar/SecretSharingSideBar.tsx new file mode 100644 index 000000000..fbfc018c0 --- /dev/null +++ b/frontend/src/layouts/OrganizationLayout/ProductsSideBar/SecretSharingSideBar.tsx @@ -0,0 +1,34 @@ +import { Link, useMatchRoute } from "@tanstack/react-router"; + +import { Menu, MenuGroup, MenuItem } from "@app/components/v2"; + +export const SecretSharingSideBar = () => { + const matchRoute = useMatchRoute(); + const isOverviewActive = !!matchRoute({ + to: "/organization/secret-sharing", + fuzzy: false + }); + + return ( + + + + {() => ( + + Secret Sharing + + )} + + + + + {({ isActive }) => ( + + Settings + + )} + + + + ); +}; diff --git a/frontend/src/layouts/OrganizationLayout/ProductsSideBar/index.ts b/frontend/src/layouts/OrganizationLayout/ProductsSideBar/index.ts new file mode 100644 index 000000000..b2c79d873 --- /dev/null +++ b/frontend/src/layouts/OrganizationLayout/ProductsSideBar/index.ts @@ -0,0 +1,2 @@ +export * from "./DefaultSideBar"; +export * from "./SecretSharingSideBar"; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx new file mode 100644 index 000000000..0a9752242 --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/SecretSharingSettingsPage.tsx @@ -0,0 +1,35 @@ +import { Helmet } from "react-helmet"; +import { useTranslation } from "react-i18next"; + +import { PageHeader } from "@app/components/v2"; +import { + OrgPermissionAppConnectionActions, + OrgPermissionSubjects +} from "@app/context/OrgPermissionContext/types"; +import { withPermission } from "@app/hoc"; + +import { SecretSharingSettingsTabGroup } from "./components"; + +export const SecretSharingSettingsPage = withPermission( + () => { + const { t } = useTranslation(); + + return ( + <> + + {t("common.head-title", { title: t("settings.org.title") })} + +
+
+ + +
+
+ + ); + }, + { + action: OrgPermissionAppConnectionActions.Edit, + subject: OrgPermissionSubjects.Settings + } +); diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/SecretSharingAllowShareToAnyone.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/SecretSharingAllowShareToAnyone.tsx new file mode 100644 index 000000000..71fa8fa77 --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/SecretSharingAllowShareToAnyone.tsx @@ -0,0 +1,58 @@ +import { createNotification } from "@app/components/notifications"; +import { OrgPermissionCan } from "@app/components/permissions"; +import { Switch } from "@app/components/v2"; +import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context"; +import { useUpdateOrg } from "@app/hooks/api"; + +export const SecretSharingAllowShareToAnyone = () => { + const { currentOrg } = useOrganization(); + const { mutateAsync } = useUpdateOrg(); + + const handleSecretSharingToggle = async (value: boolean) => { + try { + if (!currentOrg?.id) return; + + await mutateAsync({ + orgId: currentOrg.id, + secretShareSendToAnyone: value + }); + + createNotification({ + text: `Successfully ${value ? "enabled" : "disabled"} secret sharing to members outside of this organization`, + type: "success" + }); + } catch (err) { + console.error(err); + createNotification({ + text: (err as { response: { data: { message: string } } }).response.data.message, + type: "error" + }); + } + }; + + return ( +
+
+
+

+ Allow sharing secrets to members outside of this organization +

+ + {(isAllowed) => ( + handleSecretSharingToggle(value)} + isChecked={currentOrg?.secretShareSendToAnyone ?? false} + isDisabled={!isAllowed} + /> + )} + +
+

+ If enabled, team members will be able to share secrets to members outside of this + organization +

+
+
+ ); +}; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/index.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/index.tsx new file mode 100644 index 000000000..d02460498 --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingAllowShareToAnyone/index.tsx @@ -0,0 +1 @@ +export { SecretSharingAllowShareToAnyone } from "./SecretSharingAllowShareToAnyone"; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/SecretSharingSettingsGeneralTab.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/SecretSharingSettingsGeneralTab.tsx new file mode 100644 index 000000000..ede3d9fc8 --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/SecretSharingSettingsGeneralTab.tsx @@ -0,0 +1,9 @@ +import { SecretSharingAllowShareToAnyone } from "../SecretSharingAllowShareToAnyone"; + +export const SecretSharingSettingsGeneralTab = () => { + return ( +
+ +
+ ); +}; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/index.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/index.tsx new file mode 100644 index 000000000..306109025 --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsGeneralTab/index.tsx @@ -0,0 +1 @@ +export { SecretSharingSettingsGeneralTab } from "./SecretSharingSettingsGeneralTab"; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/SecretSharingSettingsTabGroup.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/SecretSharingSettingsTabGroup.tsx new file mode 100644 index 000000000..594df474f --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/SecretSharingSettingsTabGroup.tsx @@ -0,0 +1,39 @@ +import { useState } from "react"; +import { useSearch } from "@tanstack/react-router"; + +import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2"; +import { ROUTE_PATHS } from "@app/const/routes"; + +import { SecretSharingSettingsGeneralTab } from "../SecretSharingSettingsGeneralTab"; + +export const SecretSharingSettingsTabGroup = () => { + const search = useSearch({ + from: ROUTE_PATHS.Organization.SecretSharingSettings.id + }); + const tabs = [ + { + name: "General", + key: "tab-secret-sharing-general", + component: SecretSharingSettingsGeneralTab + } + ]; + + const [selectedTab, setSelectedTab] = useState(search.selectedTab || tabs[0].key); + + return ( + + + {tabs.map((tab) => ( + + {tab.name} + + ))} + + {tabs.map(({ key, component: Component }) => ( + + + + ))} + + ); +}; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/index.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/index.tsx new file mode 100644 index 000000000..2c60c7e20 --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/components/SecretSharingSettingsTabGroup/index.tsx @@ -0,0 +1 @@ +export { SecretSharingSettingsTabGroup } from "./SecretSharingSettingsTabGroup"; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/components/index.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/components/index.tsx new file mode 100644 index 000000000..2c60c7e20 --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/components/index.tsx @@ -0,0 +1 @@ +export { SecretSharingSettingsTabGroup } from "./SecretSharingSettingsTabGroup"; diff --git a/frontend/src/pages/organization/SecretSharingSettingsPage/route.tsx b/frontend/src/pages/organization/SecretSharingSettingsPage/route.tsx new file mode 100644 index 000000000..b7a9e128d --- /dev/null +++ b/frontend/src/pages/organization/SecretSharingSettingsPage/route.tsx @@ -0,0 +1,37 @@ +import { faHome } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { createFileRoute, linkOptions, stripSearchParams } from "@tanstack/react-router"; +import { zodValidator } from "@tanstack/zod-adapter"; +import { z } from "zod"; + +import { SecretSharingSettingsPage } from "./SecretSharingSettingsPage"; + +const SettingsPageQueryParams = z.object({ + selectedTab: z.string().catch("") +}); + +export const Route = createFileRoute( + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings" +)({ + component: SecretSharingSettingsPage, + validateSearch: zodValidator(SettingsPageQueryParams), + search: { + middlewares: [stripSearchParams({ selectedTab: "" })] + }, + context: () => ({ + breadcrumbs: [ + { + label: "Home", + icon: () => , + link: linkOptions({ to: "/" }) + }, + { + label: "Secret Sharing", + link: linkOptions({ to: "/organization/secret-sharing" }) + }, + { + label: "Settings" + } + ] + }) +}); diff --git a/frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx b/frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx index 25866778e..8357c5db1 100644 --- a/frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx +++ b/frontend/src/pages/public/ShareSecretPage/components/ShareSecretForm.tsx @@ -7,6 +7,7 @@ import { z } from "zod"; import { createNotification } from "@app/components/notifications"; import { Button, FormControl, IconButton, Input, Select, SelectItem } from "@app/components/v2"; +import { useOrganization } from "@app/context"; import { useTimedReset } from "@app/hooks"; import { useCreatePublicSharedSecret, useCreateSharedSecret } from "@app/hooks/api"; import { SecretSharingAccessType } from "@app/hooks/api/secretSharing"; @@ -45,6 +46,7 @@ type Props = { export const ShareSecretForm = ({ isPublic, value }: Props) => { const [secretLink, setSecretLink] = useState(""); + const { currentOrg } = useOrganization(); const [, isCopyingSecret, setCopyTextSecret] = useTimedReset({ initialState: "Copy to clipboard" }); @@ -120,7 +122,14 @@ export const ShareSecretForm = ({ isPublic, value }: Props) => { isError={Boolean(error)} errorText={error?.message} > - + )} /> @@ -155,7 +164,16 @@ export const ShareSecretForm = ({ isPublic, value }: Props) => { errorText={error?.message} isOptional > - + )} /> @@ -214,7 +232,9 @@ export const ShareSecretForm = ({ isPublic, value }: Props) => { onValueChange={(e) => onChange(e)} className="w-full" > - Anyone + {currentOrg?.secretShareSendToAnyone && ( + Anyone + )} People within your organization diff --git a/frontend/src/routeTree.gen.ts b/frontend/src/routeTree.gen.ts index e6bd0c8ee..ef31a5a33 100644 --- a/frontend/src/routeTree.gen.ts +++ b/frontend/src/routeTree.gen.ts @@ -42,7 +42,6 @@ import { Route as authProviderSuccessPageRouteImport } from './pages/auth/Provid import { Route as authProviderErrorPageRouteImport } from './pages/auth/ProviderErrorPage/route' import { Route as userPersonalSettingsPageRouteImport } from './pages/user/PersonalSettingsPage/route' import { Route as organizationSettingsPageRouteImport } from './pages/organization/SettingsPage/route' -import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route' import { Route as organizationSecretScanningPageRouteImport } from './pages/organization/SecretScanningPage/route' import { Route as organizationBillingPageRouteImport } from './pages/organization/BillingPage/route' import { Route as organizationAuditLogsPageRouteImport } from './pages/organization/AuditLogsPage/route' @@ -54,6 +53,7 @@ import { Route as secretManagerLayoutImport } from './pages/secret-manager/layou import { Route as kmsLayoutImport } from './pages/kms/layout' import { Route as certManagerLayoutImport } from './pages/cert-manager/layout' import { Route as organizationSshOverviewPageRouteImport } from './pages/organization/SshOverviewPage/route' +import { Route as organizationSecretSharingSettingsPageRouteImport } from './pages/organization/SecretSharingSettingsPage/route' import { Route as organizationSecretManagerOverviewPageRouteImport } from './pages/organization/SecretManagerOverviewPage/route' import { Route as organizationRoleByIDPageRouteImport } from './pages/organization/RoleByIDPage/route' import { Route as organizationUserDetailsByIDPageRouteImport } from './pages/organization/UserDetailsByIDPage/route' @@ -61,6 +61,7 @@ import { Route as organizationKmsOverviewPageRouteImport } from './pages/organiz import { Route as organizationIdentityDetailsByIDPageRouteImport } from './pages/organization/IdentityDetailsByIDPage/route' import { Route as organizationGroupDetailsByIDPageRouteImport } from './pages/organization/GroupDetailsByIDPage/route' import { Route as organizationCertManagerOverviewPageRouteImport } from './pages/organization/CertManagerOverviewPage/route' +import { Route as organizationSecretSharingPageRouteImport } from './pages/organization/SecretSharingPage/route' import { Route as organizationGatewaysGatewayListPageRouteImport } from './pages/organization/Gateways/GatewayListPage/route' import { Route as organizationAppConnectionsAppConnectionsPageRouteImport } from './pages/organization/AppConnections/AppConnectionsPage/route' import { Route as projectAccessControlPageRouteSshImport } from './pages/project/AccessControlPage/route-ssh' @@ -211,6 +212,10 @@ const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId', )() +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport = + createFileRoute( + '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing', + )() const AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport = createFileRoute( '/_authenticate/_inject-org-details/_org-layout/organization/gateways', @@ -467,6 +472,14 @@ const AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRoute = getParentRoute: () => organizationLayoutRoute, } as any) +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport.update({ + id: '/secret-sharing', + path: '/secret-sharing', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, + } as any) + const AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport.update({ id: '/gateways', @@ -505,14 +518,6 @@ const organizationSettingsPageRouteRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, } as any) -const organizationSecretSharingPageRouteRoute = - organizationSecretSharingPageRouteImport.update({ - id: '/secret-sharing', - path: '/secret-sharing', - getParentRoute: () => - AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, - } as any) - const organizationSecretScanningPageRouteRoute = organizationSecretScanningPageRouteImport.update({ id: '/secret-scanning', @@ -590,6 +595,14 @@ const organizationSshOverviewPageRouteRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, } as any) +const organizationSecretSharingSettingsPageRouteRoute = + organizationSecretSharingSettingsPageRouteImport.update({ + id: '/settings', + path: '/settings', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute, + } as any) + const organizationSecretManagerOverviewPageRouteRoute = organizationSecretManagerOverviewPageRouteImport.update({ id: '/secret-manager/overview', @@ -646,6 +659,14 @@ const organizationCertManagerOverviewPageRouteRoute = AuthenticateInjectOrgDetailsOrgLayoutOrganizationRoute, } as any) +const organizationSecretSharingPageRouteRoute = + organizationSecretSharingPageRouteImport.update({ + id: '/', + path: '/', + getParentRoute: () => + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute, + } as any) + const organizationGatewaysGatewayListPageRouteRoute = organizationGatewaysGatewayListPageRouteImport.update({ id: '/', @@ -1887,13 +1908,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof organizationSecretScanningPageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport } - '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': { - id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing' - path: '/secret-sharing' - fullPath: '/organization/secret-sharing' - preLoaderRoute: typeof organizationSecretSharingPageRouteImport - parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport - } '/_authenticate/_inject-org-details/_org-layout/organization/settings': { id: '/_authenticate/_inject-org-details/_org-layout/organization/settings' path: '/settings' @@ -1929,6 +1943,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport } + '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': { + id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing' + path: '/secret-sharing' + fullPath: '/organization/secret-sharing' + preLoaderRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport + } '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': { id: '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId' path: '/secret-manager/$projectId' @@ -1957,6 +1978,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof organizationGatewaysGatewayListPageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysImport } + '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': { + id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/' + path: '/' + fullPath: '/organization/secret-sharing/' + preLoaderRoute: typeof organizationSecretSharingPageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport + } '/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview': { id: '/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview' path: '/cert-manager/overview' @@ -2006,6 +2034,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof organizationSecretManagerOverviewPageRouteImport parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationImport } + '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings': { + id: '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings' + path: '/settings' + fullPath: '/organization/secret-sharing/settings' + preLoaderRoute: typeof organizationSecretSharingSettingsPageRouteImport + parentRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingImport + } '/_authenticate/_inject-org-details/_org-layout/organization/ssh/overview': { id: '/_authenticate/_inject-org-details/_org-layout/organization/ssh/overview' path: '/ssh/overview' @@ -2965,16 +3000,34 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteChildren, ) +interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren { + organizationSecretSharingPageRouteRoute: typeof organizationSecretSharingPageRouteRoute + organizationSecretSharingSettingsPageRouteRoute: typeof organizationSecretSharingSettingsPageRouteRoute +} + +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren: AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren = + { + organizationSecretSharingPageRouteRoute: + organizationSecretSharingPageRouteRoute, + organizationSecretSharingSettingsPageRouteRoute: + organizationSecretSharingSettingsPageRouteRoute, + } + +const AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren = + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute._addFileChildren( + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteChildren, + ) + interface AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren { organizationAccessManagementPageRouteRoute: typeof organizationAccessManagementPageRouteRoute organizationAdminPageRouteRoute: typeof organizationAdminPageRouteRoute organizationAuditLogsPageRouteRoute: typeof organizationAuditLogsPageRouteRoute organizationBillingPageRouteRoute: typeof organizationBillingPageRouteRoute organizationSecretScanningPageRouteRoute: typeof organizationSecretScanningPageRouteRoute - organizationSecretSharingPageRouteRoute: typeof organizationSecretSharingPageRouteRoute organizationSettingsPageRouteRoute: typeof organizationSettingsPageRouteRoute AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute: typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren organizationCertManagerOverviewPageRouteRoute: typeof organizationCertManagerOverviewPageRouteRoute organizationGroupDetailsByIDPageRouteRoute: typeof organizationGroupDetailsByIDPageRouteRoute organizationIdentityDetailsByIDPageRouteRoute: typeof organizationIdentityDetailsByIDPageRouteRoute @@ -2994,13 +3047,13 @@ const AuthenticateInjectOrgDetailsOrgLayoutOrganizationRouteChildren: Authentica organizationBillingPageRouteRoute: organizationBillingPageRouteRoute, organizationSecretScanningPageRouteRoute: organizationSecretScanningPageRouteRoute, - organizationSecretSharingPageRouteRoute: - organizationSecretSharingPageRouteRoute, organizationSettingsPageRouteRoute: organizationSettingsPageRouteRoute, AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren, AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRoute: AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren, + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRoute: + AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren, organizationCertManagerOverviewPageRouteRoute: organizationCertManagerOverviewPageRouteRoute, organizationGroupDetailsByIDPageRouteRoute: @@ -3672,16 +3725,17 @@ export interface FileRoutesByFullPath { '/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute '/organization/billing': typeof organizationBillingPageRouteRoute '/organization/secret-scanning': typeof organizationSecretScanningPageRouteRoute - '/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute '/organization/settings': typeof organizationSettingsPageRouteRoute '/cert-manager/$projectId': typeof certManagerLayoutRouteWithChildren '/kms/$projectId': typeof kmsLayoutRouteWithChildren '/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren '/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren + '/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren '/secret-manager/$projectId': typeof secretManagerLayoutRouteWithChildren '/ssh/$projectId': typeof sshLayoutRouteWithChildren '/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute '/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute + '/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute '/organization/cert-manager/overview': typeof organizationCertManagerOverviewPageRouteRoute '/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute '/organization/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute @@ -3689,6 +3743,7 @@ export interface FileRoutesByFullPath { '/organization/members/$membershipId': typeof organizationUserDetailsByIDPageRouteRoute '/organization/roles/$roleId': typeof organizationRoleByIDPageRouteRoute '/organization/secret-manager/overview': typeof organizationSecretManagerOverviewPageRouteRoute + '/organization/secret-sharing/settings': typeof organizationSecretSharingSettingsPageRouteRoute '/organization/ssh/overview': typeof organizationSshOverviewPageRouteRoute '/cert-manager/$projectId/overview': typeof certManagerCertificatesPageRouteRoute '/cert-manager/$projectId/settings': typeof certManagerSettingsPageRouteRoute @@ -3845,7 +3900,6 @@ export interface FileRoutesByTo { '/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute '/organization/billing': typeof organizationBillingPageRouteRoute '/organization/secret-scanning': typeof organizationSecretScanningPageRouteRoute - '/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute '/organization/settings': typeof organizationSettingsPageRouteRoute '/cert-manager/$projectId': typeof certManagerLayoutRouteWithChildren '/kms/$projectId': typeof kmsLayoutRouteWithChildren @@ -3853,6 +3907,7 @@ export interface FileRoutesByTo { '/ssh/$projectId': typeof sshLayoutRouteWithChildren '/organization/app-connections': typeof organizationAppConnectionsAppConnectionsPageRouteRoute '/organization/gateways': typeof organizationGatewaysGatewayListPageRouteRoute + '/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute '/organization/cert-manager/overview': typeof organizationCertManagerOverviewPageRouteRoute '/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute '/organization/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute @@ -3860,6 +3915,7 @@ export interface FileRoutesByTo { '/organization/members/$membershipId': typeof organizationUserDetailsByIDPageRouteRoute '/organization/roles/$roleId': typeof organizationRoleByIDPageRouteRoute '/organization/secret-manager/overview': typeof organizationSecretManagerOverviewPageRouteRoute + '/organization/secret-sharing/settings': typeof organizationSecretSharingSettingsPageRouteRoute '/organization/ssh/overview': typeof organizationSshOverviewPageRouteRoute '/cert-manager/$projectId/overview': typeof certManagerCertificatesPageRouteRoute '/cert-manager/$projectId/settings': typeof certManagerSettingsPageRouteRoute @@ -4025,16 +4081,17 @@ export interface FileRoutesById { '/_authenticate/_inject-org-details/_org-layout/organization/audit-logs': typeof organizationAuditLogsPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/billing': typeof organizationBillingPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning': typeof organizationSecretScanningPageRouteRoute - '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': typeof organizationSecretSharingPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/settings': typeof organizationSettingsPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutCertManagerProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/kms/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutKmsProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/app-connections': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationAppConnectionsRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/gateways': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationGatewaysRouteWithChildren + '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing': typeof AuthenticateInjectOrgDetailsOrgLayoutOrganizationSecretSharingRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSecretManagerProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/ssh/$projectId': typeof AuthenticateInjectOrgDetailsOrgLayoutSshProjectIdRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/': typeof organizationAppConnectionsAppConnectionsPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/gateways/': typeof organizationGatewaysGatewayListPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/': typeof organizationSecretSharingPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview': typeof organizationCertManagerOverviewPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId': typeof organizationGroupDetailsByIDPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/identities/$identityId': typeof organizationIdentityDetailsByIDPageRouteRoute @@ -4042,6 +4099,7 @@ export interface FileRoutesById { '/_authenticate/_inject-org-details/_org-layout/organization/members/$membershipId': typeof organizationUserDetailsByIDPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/roles/$roleId': typeof organizationRoleByIDPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/secret-manager/overview': typeof organizationSecretManagerOverviewPageRouteRoute + '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings': typeof organizationSecretSharingSettingsPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/organization/ssh/overview': typeof organizationSshOverviewPageRouteRoute '/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId/_cert-manager-layout': typeof certManagerLayoutRouteWithChildren '/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout': typeof kmsLayoutRouteWithChildren @@ -4208,16 +4266,17 @@ export interface FileRouteTypes { | '/organization/audit-logs' | '/organization/billing' | '/organization/secret-scanning' - | '/organization/secret-sharing' | '/organization/settings' | '/cert-manager/$projectId' | '/kms/$projectId' | '/organization/app-connections' | '/organization/gateways' + | '/organization/secret-sharing' | '/secret-manager/$projectId' | '/ssh/$projectId' | '/organization/app-connections/' | '/organization/gateways/' + | '/organization/secret-sharing/' | '/organization/cert-manager/overview' | '/organization/groups/$groupId' | '/organization/identities/$identityId' @@ -4225,6 +4284,7 @@ export interface FileRouteTypes { | '/organization/members/$membershipId' | '/organization/roles/$roleId' | '/organization/secret-manager/overview' + | '/organization/secret-sharing/settings' | '/organization/ssh/overview' | '/cert-manager/$projectId/overview' | '/cert-manager/$projectId/settings' @@ -4380,7 +4440,6 @@ export interface FileRouteTypes { | '/organization/audit-logs' | '/organization/billing' | '/organization/secret-scanning' - | '/organization/secret-sharing' | '/organization/settings' | '/cert-manager/$projectId' | '/kms/$projectId' @@ -4388,6 +4447,7 @@ export interface FileRouteTypes { | '/ssh/$projectId' | '/organization/app-connections' | '/organization/gateways' + | '/organization/secret-sharing' | '/organization/cert-manager/overview' | '/organization/groups/$groupId' | '/organization/identities/$identityId' @@ -4395,6 +4455,7 @@ export interface FileRouteTypes { | '/organization/members/$membershipId' | '/organization/roles/$roleId' | '/organization/secret-manager/overview' + | '/organization/secret-sharing/settings' | '/organization/ssh/overview' | '/cert-manager/$projectId/overview' | '/cert-manager/$projectId/settings' @@ -4558,16 +4619,17 @@ export interface FileRouteTypes { | '/_authenticate/_inject-org-details/_org-layout/organization/audit-logs' | '/_authenticate/_inject-org-details/_org-layout/organization/billing' | '/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning' - | '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing' | '/_authenticate/_inject-org-details/_org-layout/organization/settings' | '/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId' | '/_authenticate/_inject-org-details/_org-layout/kms/$projectId' | '/_authenticate/_inject-org-details/_org-layout/organization/app-connections' | '/_authenticate/_inject-org-details/_org-layout/organization/gateways' + | '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing' | '/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId' | '/_authenticate/_inject-org-details/_org-layout/ssh/$projectId' | '/_authenticate/_inject-org-details/_org-layout/organization/app-connections/' | '/_authenticate/_inject-org-details/_org-layout/organization/gateways/' + | '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/' | '/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview' | '/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId' | '/_authenticate/_inject-org-details/_org-layout/organization/identities/$identityId' @@ -4575,6 +4637,7 @@ export interface FileRouteTypes { | '/_authenticate/_inject-org-details/_org-layout/organization/members/$membershipId' | '/_authenticate/_inject-org-details/_org-layout/organization/roles/$roleId' | '/_authenticate/_inject-org-details/_org-layout/organization/secret-manager/overview' + | '/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings' | '/_authenticate/_inject-org-details/_org-layout/organization/ssh/overview' | '/_authenticate/_inject-org-details/_org-layout/cert-manager/$projectId/_cert-manager-layout' | '/_authenticate/_inject-org-details/_org-layout/kms/$projectId/_kms-layout' @@ -4936,10 +4999,10 @@ export const routeTree = rootRoute "/_authenticate/_inject-org-details/_org-layout/organization/audit-logs", "/_authenticate/_inject-org-details/_org-layout/organization/billing", "/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning", - "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing", "/_authenticate/_inject-org-details/_org-layout/organization/settings", "/_authenticate/_inject-org-details/_org-layout/organization/app-connections", "/_authenticate/_inject-org-details/_org-layout/organization/gateways", + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing", "/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview", "/_authenticate/_inject-org-details/_org-layout/organization/groups/$groupId", "/_authenticate/_inject-org-details/_org-layout/organization/identities/$identityId", @@ -4981,10 +5044,6 @@ export const routeTree = rootRoute "filePath": "organization/SecretScanningPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization" }, - "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing": { - "filePath": "organization/SecretSharingPage/route.tsx", - "parent": "/_authenticate/_inject-org-details/_org-layout/organization" - }, "/_authenticate/_inject-org-details/_org-layout/organization/settings": { "filePath": "organization/SettingsPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization" @@ -5018,6 +5077,14 @@ export const routeTree = rootRoute "/_authenticate/_inject-org-details/_org-layout/organization/gateways/" ] }, + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing": { + "filePath": "", + "parent": "/_authenticate/_inject-org-details/_org-layout/organization", + "children": [ + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/", + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings" + ] + }, "/_authenticate/_inject-org-details/_org-layout/secret-manager/$projectId": { "filePath": "", "parent": "/_authenticate/_inject-org-details/_org-layout", @@ -5040,6 +5107,10 @@ export const routeTree = rootRoute "filePath": "organization/Gateways/GatewayListPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization/gateways" }, + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/": { + "filePath": "organization/SecretSharingPage/route.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing" + }, "/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview": { "filePath": "organization/CertManagerOverviewPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization" @@ -5068,6 +5139,10 @@ export const routeTree = rootRoute "filePath": "organization/SecretManagerOverviewPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization" }, + "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing/settings": { + "filePath": "organization/SecretSharingSettingsPage/route.tsx", + "parent": "/_authenticate/_inject-org-details/_org-layout/organization/secret-sharing" + }, "/_authenticate/_inject-org-details/_org-layout/organization/ssh/overview": { "filePath": "organization/SshOverviewPage/route.tsx", "parent": "/_authenticate/_inject-org-details/_org-layout/organization" diff --git a/frontend/src/routes.ts b/frontend/src/routes.ts index 983129e33..19cf8fc62 100644 --- a/frontend/src/routes.ts +++ b/frontend/src/routes.ts @@ -16,7 +16,10 @@ const organizationRoutes = route("/organization", [ route("/admin", "organization/AdminPage/route.tsx"), route("/audit-logs", "organization/AuditLogsPage/route.tsx"), route("/billing", "organization/BillingPage/route.tsx"), - route("/secret-sharing", "organization/SecretSharingPage/route.tsx"), + route("/secret-sharing", [ + index("organization/SecretSharingPage/route.tsx"), + route("/settings", "organization/SecretSharingSettingsPage/route.tsx") + ]), route("/settings", "organization/SettingsPage/route.tsx"), route("/secret-scanning", "organization/SecretScanningPage/route.tsx"), route("/groups/$groupId", "organization/GroupDetailsByIDPage/route.tsx"),