feat: fixed migration issues and resolved all routes in frontend

This commit is contained in:
=
2024-12-11 21:19:37 +05:30
parent 69bf9dc20f
commit a857375cc1
69 changed files with 547 additions and 265 deletions

View File

@@ -1,11 +1,12 @@
import slugify from "@sindresorhus/slugify";
import { Knex } from "knex";
import { v4 as uuidV4 } from "uuid";
import slugify from "@sindresorhus/slugify";
import { ProjectType, TableName } from "../schemas";
import { alphaNumericNanoId } from "@app/lib/nanoid";
/* eslint-disable no-await-in-loop,no-param-reassign,@typescript-eslint/ban-ts-comment */
import { ProjectType, TableName } from "../schemas";
/* eslint-disable no-await-in-loop,@typescript-eslint/ban-ts-comment */
const newProject = async (knex: Knex, projectId: string, projectType: ProjectType) => {
const newProjectId = uuidV4();
const project = await knex(TableName.Project).where("id", projectId).first();
@@ -24,10 +25,12 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
projectCustomRoles.map((el) => {
const id = uuidV4();
customRoleMapping[el.id] = id;
el.id = id;
el.projectId = newProjectId;
el.permissions = el.permissions ? JSON.stringify(el.permissions) : el.permissions;
return el;
return {
...el,
id,
projectId: newProjectId,
permissions: el.permissions ? JSON.stringify(el.permissions) : el.permissions
};
})
);
}
@@ -38,9 +41,7 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
groupMemberships.map((el) => {
const id = uuidV4();
groupMembershipMapping[el.id] = id;
el.id = id;
el.projectId = newProjectId;
return el;
return { ...el, id, projectId: newProjectId };
})
);
}
@@ -53,10 +54,9 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
await knex(TableName.GroupProjectMembershipRole).insert(
groupMembershipRoles.map((el) => {
const id = uuidV4();
el.id = id;
el.projectMembershipId = groupMembershipMapping[el.id];
el.customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId;
return el;
const projectMembershipId = groupMembershipMapping[el.id];
const customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId;
return { ...el, id, projectMembershipId, customRoleId };
})
);
}
@@ -68,9 +68,7 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
identities.map((el) => {
const id = uuidV4();
identityProjectMembershipMapping[el.id] = id;
el.id = id;
el.projectId = newProjectId;
return el;
return { ...el, id, projectId: newProjectId };
})
);
}
@@ -83,10 +81,9 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
await knex(TableName.IdentityProjectMembershipRole).insert(
identitiesRoles.map((el) => {
const id = uuidV4();
el.id = id;
el.projectMembershipId = identityProjectMembershipMapping[el.projectMembershipId];
el.customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId;
return el;
const projectMembershipId = identityProjectMembershipMapping[el.projectMembershipId];
const customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId;
return { ...el, id, projectMembershipId, customRoleId };
})
);
}
@@ -98,9 +95,7 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
projectUserMembers.map((el) => {
const id = uuidV4();
projectMembershipMapping[el.id] = id;
el.id = id;
el.projectId = newProjectId;
return el;
return { ...el, id, projectId: newProjectId };
})
);
}
@@ -112,10 +107,9 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
await knex(TableName.ProjectUserMembershipRole).insert(
membershipRoles.map((el) => {
const id = uuidV4();
el.id = id;
el.projectMembershipId = projectMembershipMapping[el.projectMembershipId];
el.customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId;
return el;
const projectMembershipId = projectMembershipMapping[el.projectMembershipId];
const customRoleId = el.customRoleId ? customRoleMapping[el.customRoleId] : el.customRoleId;
return { ...el, id, projectMembershipId, customRoleId };
})
);
}
@@ -125,10 +119,8 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
await knex(TableName.KmsKey).insert(
kmsKeys.map((el) => {
const id = uuidV4();
el.id = id;
el.projectId = newProjectId;
el.slug = slugify(alphaNumericNanoId(8).toLowerCase());
return el;
const slug = slugify(alphaNumericNanoId(8).toLowerCase());
return { ...el, id, slug, projectId: newProjectId };
})
);
}
@@ -143,9 +135,7 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
await knex(TableName.ProjectKeys).insert(
projectKeys.map((el) => {
const id = uuidV4();
el.id = id;
el.projectId = newProjectId;
return el;
return { ...el, id, projectId: newProjectId };
})
);
}
@@ -154,16 +144,14 @@ const newProject = async (knex: Knex, projectId: string, projectType: ProjectTyp
if (serviceTokens.length) {
await knex(TableName.ServiceToken).insert(
serviceTokens.map((el) => {
el.id = uuidV4();
el.projectId = projectId;
el.scopes = el.scopes ? JSON.stringify(el.scopes) : el.scopes;
return el;
const id = uuidV4();
const scopes = el.scopes ? JSON.stringify(el.scopes) : el.scopes;
return { ...el, id, scopes, projectId: newProjectId };
})
);
}
return newProjectId;
};
/* eslint-enable */
const BATCH_SIZE = 500;
export async function up(knex: Knex): Promise<void> {

View File

@@ -137,7 +137,7 @@ export const registerProjectRouter = async (server: FastifyZodProvider) => {
.enum(["true", "false"])
.default("false")
.transform((value) => value === "true"),
type: z.nativeEnum(ProjectType).optional()
type: z.enum([ProjectType.SecretManager, ProjectType.Cmek, ProjectType.CertificateManager, "all"]).optional()
}),
response: {
200: z.object({

View File

@@ -197,7 +197,7 @@ export const orgServiceFactory = ({
const findAllWorkspaces = async ({ actor, actorId, orgId, type }: TFindAllWorkspacesDTO) => {
if (actor === ActorType.USER) {
const workspaces = await projectDAL.findAllProjects(actorId, orgId, type);
const workspaces = await projectDAL.findAllProjects(actorId, orgId, type || "all");
return workspaces;
}

View File

@@ -19,7 +19,7 @@ export type TProjectDALFactory = ReturnType<typeof projectDALFactory>;
export const projectDALFactory = (db: TDbClient) => {
const projectOrm = ormify(db, TableName.Project);
const findAllProjects = async (userId: string, orgId: string, projectType?: ProjectType | null) => {
const findAllProjects = async (userId: string, orgId: string, projectType: ProjectType | "all") => {
try {
const workspaces = await db
.replicaNode()(TableName.ProjectMembership)
@@ -27,7 +27,7 @@ export const projectDALFactory = (db: TDbClient) => {
.join(TableName.Project, `${TableName.ProjectMembership}.projectId`, `${TableName.Project}.id`)
.where(`${TableName.Project}.orgId`, orgId)
.andWhere((qb) => {
if (projectType) {
if (projectType !== "all") {
void qb.where(`${TableName.Project}.type`, projectType);
}
})
@@ -130,7 +130,11 @@ export const projectDALFactory = (db: TDbClient) => {
.replicaNode()(TableName.IdentityProjectMembership)
.where({ identityId })
.join(TableName.Project, `${TableName.IdentityProjectMembership}.projectId`, `${TableName.Project}.id`)
.where(`${TableName.Project}.type`, projectType)
.andWhere((qb) => {
if (projectType) {
void qb.where(`${TableName.Project}.type`, projectType);
}
})
.leftJoin(TableName.Environment, `${TableName.Environment}.projectId`, `${TableName.Project}.id`)
.select(
selectAllTableCols(TableName.Project),

View File

@@ -431,7 +431,13 @@ export const projectServiceFactory = ({
return deletedProject;
};
const getProjects = async ({ actorId, includeRoles, actorAuthMethod, actorOrgId, type }: TListProjectsDTO) => {
const getProjects = async ({
actorId,
includeRoles,
actorAuthMethod,
actorOrgId,
type = ProjectType.SecretManager
}: TListProjectsDTO) => {
const workspaces = await projectDAL.findAllProjects(actorId, actorOrgId, type);
if (includeRoles) {

View File

@@ -85,7 +85,7 @@ export type TDeleteProjectDTO = {
export type TListProjectsDTO = {
includeRoles: boolean;
type?: ProjectType | null;
type?: ProjectType | "all";
} & Omit<TProjectPermission, "projectId">;
export type TUpgradeProjectDTO = {

View File

@@ -5,6 +5,8 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Menu, Transition } from "@headlessui/react";
import { Tag } from "public/data/frequentInterfaces";
import { ProjectType } from "@app/hooks/api/workspace/types";
/**
* This is the menu that is used to add more tags to a secret
* @param {object} obj
@@ -75,7 +77,7 @@ const AddTagsMenu = ({
<button
type="button"
className="w-full rounded-sm bg-mineshaft-800 px-2 py-0.5 text-left text-bunker-200 duration-200 hover:bg-primary hover:text-black"
onClick={() => router.push(`/project/${String(router.query.id)}/settings`)}
onClick={() => router.push(`/${ProjectType.SecretManager}/${String(router.query.id)}/settings`)}
>
<FontAwesomeIcon icon={faPlus} className="mr-2 text-xs" />
Add more tags

View File

@@ -1,5 +1,7 @@
import { useRouter } from "next/router";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { Button } from "../v2";
interface IProps {
@@ -20,7 +22,7 @@ export const NoEnvironmentsBanner = ({ projectId }: IProps) => {
</p>
</div>
<div className="my-2">
<Button onClick={() => router.push(`/project/${projectId}/settings#environments`)}>
<Button onClick={() => router.push(`/${ProjectType.SecretManager}/${projectId}/settings#environments`)}>
Add environments
</Button>
</div>

View File

@@ -148,7 +148,7 @@ const NewProjectForm = ({ onOpenChange, projectType }: NewProjectFormProps) => {
createNotification({ text: "Project created", type: "success" });
reset();
onOpenChange(false);
router.push(`/project/${newProjectId}/${projectType}/overview`);
router.push(`/${projectType}/${newProjectId}/${projectType}/overview`);
} catch (err) {
console.error(err);
createNotification({ text: "Failed to create project", type: "error" });

View File

@@ -3,7 +3,7 @@ import { useRouter } from "next/router";
import { createNotification } from "@app/components/notifications";
import { useGetUserWorkspaces } from "@app/hooks/api";
import { Workspace } from "@app/hooks/api/workspace/types";
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
type TWorkspaceContext = {
workspaces: Workspace[];
@@ -35,7 +35,7 @@ export const WorkspaceProvider = ({ children }: Props): JSX.Element => {
const shouldTriggerNoProjectAccess =
!value.isLoading &&
!value.currentWorkspace &&
router.pathname.startsWith("/project") &&
Object.values(ProjectType).some((el) => router.pathname.startsWith(`/${el}`)) &&
workspaceId;
// handle redirects for project-specific routes

View File

@@ -0,0 +1,12 @@
import { Workspace } from "@app/hooks/api/types";
import { ProjectType } from "@app/hooks/api/workspace/types";
export const getWorkspaceHomePage = (workspace: Workspace) => {
if (workspace.type === ProjectType.SecretManager) {
return `/${workspace.type}/${workspace.id}/secrets/overview`;
}
if (workspace.type === ProjectType.CertificateManager) {
return `/${workspace.type}/${workspace.id}/certificates`;
}
return `/${workspace.type}/${workspace.id}/kms`;
};

View File

@@ -103,7 +103,7 @@ export const useGetUpgradeProjectStatus = ({
});
};
const fetchUserWorkspaces = async (includeRoles?: boolean, type?: ProjectType) => {
const fetchUserWorkspaces = async (includeRoles?: boolean, type?: ProjectType | "all") => {
const { data } = await apiRequest.get<{ workspaces: Workspace[] }>("/api/v1/workspace", {
params: {
includeRoles,
@@ -143,10 +143,10 @@ export const useGetWorkspaceById = (
export const useGetUserWorkspaces = ({
includeRoles,
type
type = "all"
}: {
includeRoles?: boolean;
type?: ProjectType;
type?: ProjectType | "all";
} = {}) =>
useQuery(workspaceKeys.getAllUserWorkspace(type || ""), () =>
fetchUserWorkspaces(includeRoles, type)

View File

@@ -5,7 +5,7 @@
/* eslint-disable no-var */
/* eslint-disable func-names */
import { useEffect, useMemo, useState } from "react";
import { useEffect, useState } from "react";
import { useTranslation } from "react-i18next";
import Link from "next/link";
import { useRouter } from "next/router";
@@ -38,13 +38,7 @@ import {
} from "@app/components/v2";
import { useOrganization, useSubscription, useUser, useWorkspace } from "@app/context";
import { usePopUp, useToggle } from "@app/hooks";
import {
useGetAccessRequestsCount,
useGetOrgTrialUrl,
useGetSecretApprovalRequestCount,
useLogoutUser,
useSelectOrganization
} from "@app/hooks/api";
import { useGetOrgTrialUrl, useLogoutUser, useSelectOrganization } from "@app/hooks/api";
import { MfaMethod } from "@app/hooks/api/auth/types";
import { AuthMethod } from "@app/hooks/api/users/types";
import { InsecureConnectionBanner } from "@app/layouts/AppLayout/components/InsecureConnectionBanner";
@@ -53,6 +47,7 @@ import { navigateUserToOrg } from "@app/views/Login/Login.utils";
import { Mfa } from "@app/views/Login/Mfa";
import { CreateOrgModal } from "@app/views/Org/components";
import { ProjectSidebarItem } from "./components/ProjectSidebarItems";
import { WishForm } from "./components/WishForm/WishForm";
interface LayoutProps {
@@ -87,7 +82,7 @@ export const AppLayout = ({ children }: LayoutProps) => {
const { mutateAsync } = useGetOrgTrialUrl();
const { workspaces, currentWorkspace } = useWorkspace();
const { currentWorkspace } = useWorkspace();
const { orgs, currentOrg } = useOrganization();
const [shouldShowMfa, toggleShowMfa] = useToggle(false);
@@ -96,15 +91,6 @@ export const AppLayout = ({ children }: LayoutProps) => {
const { user } = useUser();
const { subscription } = useSubscription();
const workspaceId = currentWorkspace?.id || "";
const projectSlug = currentWorkspace?.slug || "";
const { data: secretApprovalReqCount } = useGetSecretApprovalRequestCount({ workspaceId });
const { data: accessApprovalRequestCount } = useGetAccessRequestsCount({ projectSlug });
const pendingRequestsCount = useMemo(() => {
return (secretApprovalReqCount?.open || 0) + (accessApprovalRequestCount?.pendingCount || 0);
}, [secretApprovalReqCount, accessApprovalRequestCount]);
const infisicalPlatformVersion = process.env.NEXT_PUBLIC_INFISICAL_PLATFORM_VERSION;
@@ -152,41 +138,6 @@ export const AppLayout = ({ children }: LayoutProps) => {
if (tempLocalStorage("orgData.id") === "" && orgs?.[0]?.id) {
localStorage.setItem("orgData.id", orgs?.[0]?.id);
}
if (
currentOrg &&
((workspaces?.length === 0 && router.asPath.includes("project")) ||
router.asPath.includes("/project/undefined") ||
(!orgs?.map((org) => org.id)?.includes(router.query.id as string) &&
!router.asPath.includes("project") &&
!router.asPath.includes("personal") &&
!router.asPath.includes("secret-scanning") &&
!router.asPath.includes("integration")))
) {
router.push(`/org/${currentOrg?.id}/secret-manager/overview`);
}
// else if (!router.asPath.includes("org") && !router.asPath.includes("project") && !router.asPath.includes("integrations") && !router.asPath.includes("personal-settings")) {
// const pathSegments = router.asPath.split("/").filter((segment) => segment.length > 0);
// let intendedWorkspaceId;
// if (pathSegments.length >= 2 && pathSegments[0] === "dashboard") {
// [, intendedWorkspaceId] = pathSegments;
// } else if (pathSegments.length >= 3 && pathSegments[0] === "settings") {
// [, , intendedWorkspaceId] = pathSegments;
// } else {
// const lastPathSegments = router.asPath.split("/").pop();
// if (lastPathSegments !== undefined) {
// [intendedWorkspaceId] = lastPathSegments.split("?");
// }
// }
// if (!intendedWorkspaceId) return;
// if (!["callback", "create", "authorize"].includes(intendedWorkspaceId)) {
// localStorage.setItem("projectData.id", intendedWorkspaceId);
// }
// }
};
putUserInOrg();
}, [router.query.id]);
@@ -214,8 +165,7 @@ export const AppLayout = ({ children }: LayoutProps) => {
<div>
{!router.asPath.includes("personal") && (
<div className="flex h-12 cursor-default items-center px-3 pt-6">
{(router.asPath.includes("project") ||
router.asPath.includes("integrations")) && (
{(currentWorkspace || router.asPath.includes("integrations")) && (
<Link href={`/org/${currentOrg?.id}/${currentWorkspace?.type}/overview`}>
<div className="pl-1 pr-2 text-mineshaft-400 duration-200 hover:text-mineshaft-100">
<FontAwesomeIcon icon={faArrowLeft} />
@@ -387,111 +337,8 @@ export const AppLayout = ({ children }: LayoutProps) => {
</Link>
))}
<div className={`px-1 ${!router.asPath.includes("personal") ? "block" : "hidden"}`}>
{(router.asPath.includes("project") || router.asPath.includes("integrations")) &&
currentWorkspace ? (
<Menu>
<Link href={`/project/${currentWorkspace?.id}/secrets/overview`} passHref>
<a>
<MenuItem
isSelected={router.asPath.includes(
`/project/${currentWorkspace?.id}/secrets`
)}
icon="system-outline-90-lock-closed"
>
{t("nav.menu.secrets")}
</MenuItem>
</a>
</Link>
<Link href={`/project/${currentWorkspace?.id}/certificates`} passHref>
<a>
<MenuItem
isSelected={
router.asPath === `/project/${currentWorkspace?.id}/certificates`
}
icon="system-outline-90-lock-closed"
>
Internal PKI
</MenuItem>
</a>
</Link>
<Link href={`/project/${currentWorkspace?.id}/kms`} passHref>
<a>
<MenuItem
isSelected={router.asPath === `/project/${currentWorkspace?.id}/kms`}
icon="system-outline-90-lock-closed"
>
Key Management
</MenuItem>
</a>
</Link>
<Link href={`/project/${currentWorkspace?.id}/members`} passHref>
<a>
<MenuItem
isSelected={
router.asPath === `/project/${currentWorkspace?.id}/members`
}
icon="system-outline-96-groups"
>
Access Control
</MenuItem>
</a>
</Link>
<Link href={`/integrations/${currentWorkspace?.id}`} passHref>
<a>
<MenuItem
isSelected={router.asPath.includes("/integrations")}
icon="system-outline-82-extension"
>
{t("nav.menu.integrations")}
</MenuItem>
</a>
</Link>
<Link href={`/project/${currentWorkspace?.id}/secret-rotation`} passHref>
<a className="relative">
<MenuItem
isSelected={
router.asPath === `/project/${currentWorkspace?.id}/secret-rotation`
}
icon="rotation"
>
Secret Rotation
</MenuItem>
</a>
</Link>
<Link href={`/project/${currentWorkspace?.id}/approval`} passHref>
<a className="relative">
<MenuItem
isSelected={
router.asPath === `/project/${currentWorkspace?.id}/approval`
}
icon="system-outline-189-domain-verification"
>
Approvals
{Boolean(
secretApprovalReqCount?.open ||
accessApprovalRequestCount?.pendingCount
) && (
<span className="ml-2 rounded border border-primary-400 bg-primary-600 py-0.5 px-1 text-xs font-semibold text-black">
{pendingRequestsCount}
</span>
)}
</MenuItem>
</a>
</Link>
<Link href={`/project/${currentWorkspace?.id}/settings`} passHref>
<a>
<MenuItem
isSelected={
router.asPath === `/project/${currentWorkspace?.id}/settings`
}
icon="system-outline-109-slider-toggle-settings"
>
{t("nav.menu.project-settings")}
</MenuItem>
</a>
</Link>
</Menu>
) : (
<ProjectSidebarItem />
{router.pathname.startsWith("/org") && (
<Menu className="mt-4">
<Link href={`/org/${currentOrg?.id}/secret-manager/overview`} passHref>
<a>

View File

@@ -16,6 +16,7 @@ import {
useSubscription,
useWorkspace
} from "@app/context";
import { getWorkspaceHomePage } from "@app/helpers/workspace";
import { usePopUp } from "@app/hooks";
import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation";
import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries";
@@ -190,7 +191,7 @@ export const ProjectSelect = () => {
// todo(akhi): this is not using react query because react query in overview is throwing error when envs are not exact same count
// to reproduce change this back to router.push and switch between two projects with different env count
// look into this on dashboard revamp
window.location.assign(`/project/${project.id}/secrets/overview`);
window.location.assign(getWorkspaceHomePage(project));
}}
options={options}
components={{

View File

@@ -0,0 +1,158 @@
import { useTranslation } from "react-i18next";
import Link from "next/link";
import { useRouter } from "next/router";
import { Menu, MenuItem } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { useGetAccessRequestsCount, useGetSecretApprovalRequestCount } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/workspace/types";
export const ProjectSidebarItem = () => {
const { currentWorkspace } = useWorkspace();
const router = useRouter();
const { t } = useTranslation();
const workspaceId = currentWorkspace?.id || "";
const projectSlug = currentWorkspace?.slug || "";
const { data: secretApprovalReqCount } = useGetSecretApprovalRequestCount({ workspaceId });
const { data: accessApprovalRequestCount } = useGetAccessRequestsCount({ projectSlug });
const pendingRequestsCount =
(secretApprovalReqCount?.open || 0) + (accessApprovalRequestCount?.pendingCount || 0);
if (
!currentWorkspace ||
router.asPath.startsWith("personal") ||
router.asPath.startsWith("integrations")
) {
return <div />;
}
const isSecretManager = currentWorkspace?.type === ProjectType.SecretManager;
const isCertManager = currentWorkspace?.type === ProjectType.CertificateManager;
const isCmek = currentWorkspace?.type === ProjectType.Cmek;
return (
<Menu>
{isSecretManager && (
<Link
href={`/${ProjectType.SecretManager}/${currentWorkspace?.id}/secrets/overview`}
passHref
>
<a>
<MenuItem
isSelected={router.asPath.includes(
`/${ProjectType.SecretManager}/${currentWorkspace?.id}/secrets`
)}
icon="system-outline-90-lock-closed"
>
{t("nav.menu.secrets")}
</MenuItem>
</a>
</Link>
)}
{isCertManager && (
<Link
href={`/${ProjectType.CertificateManager}/${currentWorkspace?.id}/certificates`}
passHref
>
<a>
<MenuItem
isSelected={
router.asPath ===
`/${ProjectType.CertificateManager}/${currentWorkspace?.id}/certificates`
}
icon="system-outline-90-lock-closed"
>
Internal PKI
</MenuItem>
</a>
</Link>
)}
{isCmek && (
<Link href={`/${ProjectType.Cmek}/${currentWorkspace?.id}/kms`} passHref>
<a>
<MenuItem
isSelected={router.asPath === `/${ProjectType.Cmek}/${currentWorkspace?.id}/kms`}
icon="system-outline-90-lock-closed"
>
Key Management
</MenuItem>
</a>
</Link>
)}
<Link href={`/${currentWorkspace.type}/${currentWorkspace?.id}/members`} passHref>
<a>
<MenuItem
isSelected={router.asPath.endsWith(`/${currentWorkspace?.id}/members`)}
icon="system-outline-96-groups"
>
Access Control
</MenuItem>
</a>
</Link>
{isSecretManager && (
<Link href={`/integrations/${currentWorkspace?.id}`} passHref>
<a>
<MenuItem
isSelected={router.asPath.includes("/integrations")}
icon="system-outline-82-extension"
>
{t("nav.menu.integrations")}
</MenuItem>
</a>
</Link>
)}
{isSecretManager && (
<Link
href={`/${ProjectType.SecretManager}/${currentWorkspace?.id}/secret-rotation`}
passHref
>
<a className="relative">
<MenuItem
isSelected={
router.asPath ===
`/${ProjectType.SecretManager}/${currentWorkspace?.id}/secret-rotation`
}
icon="rotation"
>
Secret Rotation
</MenuItem>
</a>
</Link>
)}
{isSecretManager && (
<Link href={`/secret-manager/${currentWorkspace?.id}/approval`} passHref>
<a className="relative">
<MenuItem
isSelected={
router.asPath === `/${ProjectType.SecretManager}/${currentWorkspace?.id}/approval`
}
icon="system-outline-189-domain-verification"
>
Approvals
{Boolean(
secretApprovalReqCount?.open || accessApprovalRequestCount?.pendingCount
) && (
<span className="ml-2 rounded border border-primary-400 bg-primary-600 py-0.5 px-1 text-xs font-semibold text-black">
{pendingRequestsCount}
</span>
)}
</MenuItem>
</a>
</Link>
)}
<Link href={`/${currentWorkspace.type}/${currentWorkspace?.id}/settings`} passHref>
<a>
<MenuItem
isSelected={router.asPath.endsWith(`/${currentWorkspace?.id}/settings`)}
icon="system-outline-109-slider-toggle-settings"
>
{t("nav.menu.project-settings")}
</MenuItem>
</a>
</Link>
</Menu>
);
};

View File

@@ -0,0 +1 @@
export { ProjectSidebarItem } from "./ProjectSidebarItems";

View File

@@ -0,0 +1,21 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { IPAllowlistPage } from "@app/views/Project/IPAllowListPage";
const ProjectAllowlist = () => {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<IPAllowlistPage />
</>
);
};
export default ProjectAllowlist;
ProjectAllowlist.requireAuth = true;

View File

@@ -0,0 +1,20 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { IdentityDetailsPage } from "@app/views/Project/IdentityDetailsPage";
export default function ProjectIdentityDetailsPage() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.members.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<IdentityDetailsPage />
</>
);
}
ProjectIdentityDetailsPage.requireAuth = true;

View File

@@ -0,0 +1,20 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { MemberDetailsPage } from "@app/views/Project/MemberDetailsPage";
export default function Page() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.members.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<MemberDetailsPage />
</>
);
}
Page.requireAuth = true;

View File

@@ -0,0 +1,21 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { MembersPage } from "@app/views/Project/MembersPage";
export default function WorkspaceMemberSettings() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.members.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<MembersPage />
</>
);
}
WorkspaceMemberSettings.requireAuth = true;

View File

@@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { RolePage } from "@app/views/Project/RolePage";
export default function Role() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: "Project Settings" })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<RolePage />
</>
);
}
Role.requireAuth = true;

View File

@@ -0,0 +1,22 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { ProjectSettingsPage } from "@app/views/Settings/ProjectSettingsPage";
const ProjectSettings = () => {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<ProjectSettingsPage />
</>
);
};
export default ProjectSettings;
ProjectSettings.requireAuth = true;

View File

@@ -1,4 +1,5 @@
import { ProjectType } from "@app/hooks/api/workspace/types";
import { ProductOverview } from "../secret-manager/overview";
const CertManagerOverviewPage = () => <ProductOverview type={ProjectType.CertificateManager} />;

View File

@@ -1,4 +1,5 @@
import { ProjectType } from "@app/hooks/api/workspace/types";
import { ProductOverview } from "../secret-manager/overview";
const CmekManagerOverviewPage = () => <ProductOverview type={ProjectType.Cmek} />;

View File

@@ -1,6 +1,7 @@
import { useOrganization } from "@app/context";
import { useRouter } from "next/router";
import { useEffect } from "react";
import { useRouter } from "next/router";
import { useOrganization } from "@app/context";
// #TODO: Update all the workspaceIds
const OrganizationPage = () => {

View File

@@ -51,6 +51,7 @@ import {
useSubscription,
useUser
} from "@app/context";
import { getWorkspaceHomePage } from "@app/helpers/workspace";
import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetUserWorkspaces, useRegisterUserAction } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types";
@@ -59,8 +60,8 @@ import { useFetchServerStatus } from "@app/hooks/api/serverDetails";
import { Workspace } from "@app/hooks/api/types";
import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation";
import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries";
import { usePopUp } from "@app/hooks/usePopUp";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { usePopUp } from "@app/hooks/usePopUp";
const features = [
{
@@ -603,7 +604,7 @@ export const ProductOverview = ({ type }: Props) => {
// eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
<div
onClick={() => {
router.push(`/project/${workspace.id}/secrets/overview`);
router.push(getWorkspaceHomePage(workspace));
localStorage.setItem("projectData.id", workspace.id);
}}
key={workspace.id}
@@ -667,7 +668,7 @@ export const ProductOverview = ({ type }: Props) => {
// eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
<div
onClick={() => {
router.push(`/project/${workspace.id}/secrets/overview`);
router.push(getWorkspaceHomePage(workspace));
localStorage.setItem("projectData.id", workspace.id);
}}
key={workspace.id}
@@ -1047,7 +1048,6 @@ export const ProductOverview = ({ type }: Props) => {
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text="You have exceeded the number of projects allowed on the free plan."
/>
{/* <DeleteUserDialog isOpen={isDeleteOpen} closeModal={closeDeleteModal} submitModal={deleteMembership} userIdToBeDeleted={userIdToBeDeleted}/> */}
</div>
);
};

View File

@@ -0,0 +1,21 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { IPAllowlistPage } from "@app/views/Project/IPAllowListPage";
const ProjectAllowlist = () => {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<IPAllowlistPage />
</>
);
};
export default ProjectAllowlist;
ProjectAllowlist.requireAuth = true;

View File

@@ -0,0 +1,20 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { IdentityDetailsPage } from "@app/views/Project/IdentityDetailsPage";
export default function ProjectIdentityDetailsPage() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.members.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<IdentityDetailsPage />
</>
);
}
ProjectIdentityDetailsPage.requireAuth = true;

View File

@@ -0,0 +1,20 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { MemberDetailsPage } from "@app/views/Project/MemberDetailsPage";
export default function Page() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.members.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<MemberDetailsPage />
</>
);
}
Page.requireAuth = true;

View File

@@ -0,0 +1,21 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { MembersPage } from "@app/views/Project/MembersPage";
export default function WorkspaceMemberSettings() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.members.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<MembersPage />
</>
);
}
WorkspaceMemberSettings.requireAuth = true;

View File

@@ -0,0 +1,20 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { RolePage } from "@app/views/Project/RolePage";
export default function Role() {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: "Project Settings" })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<RolePage />
</>
);
}
Role.requireAuth = true;

View File

@@ -0,0 +1,22 @@
import { useTranslation } from "react-i18next";
import Head from "next/head";
import { ProjectSettingsPage } from "@app/views/Settings/ProjectSettingsPage";
const ProjectSettings = () => {
const { t } = useTranslation();
return (
<>
<Head>
<title>{t("common.head-title", { title: t("settings.project.title") })}</title>
<link rel="icon" href="/infisical.ico" />
</Head>
<ProjectSettingsPage />
</>
);
};
export default ProjectSettings;
ProjectSettings.requireAuth = true;

View File

@@ -16,6 +16,7 @@ import { useServerConfig } from "@app/context";
import { useVerifySignupEmailVerificationCode } from "@app/hooks/api";
import { fetchOrganizations } from "@app/hooks/api/organization/queries";
import { useFetchServerStatus } from "@app/hooks/api/serverDetails";
import { ProjectType } from "@app/hooks/api/workspace/types";
/**
* @returns the signup page
@@ -47,7 +48,7 @@ export default function SignUp() {
const tryAuth = async () => {
try {
const userOrgs = await fetchOrganizations();
router.push(`/org/${userOrgs[0].id}/overview`);
router.push(`/org/${userOrgs[0].id}/${ProjectType.SecretManager}/overview`);
} catch (error) {
console.log("Error - Not logged in yet");
}
@@ -90,7 +91,7 @@ export default function SignUp() {
if (!serverDetails?.emailConfigured && step === 5) {
const userOrgs = await fetchOrganizations();
router.push(`/org/${userOrgs[0].id}/overview`);
router.push(`/org/${userOrgs[0].id}/${ProjectType.SecretManager}/overview`);
}
})();
}, [step]);

View File

@@ -31,6 +31,7 @@ import {
} from "@app/hooks/api/auth/queries";
import { MfaMethod } from "@app/hooks/api/auth/types";
import { fetchOrganizations } from "@app/hooks/api/organization/queries";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { navigateUserToOrg } from "@app/views/Login/Login.utils";
import { Mfa } from "@app/views/Login/Mfa";
@@ -386,7 +387,7 @@ export default function SignupInvite() {
setBackupKeyError,
setBackupKeyIssued
});
router.push(`/org/${organizationId}/overview`);
router.push(`/org/${organizationId}/${ProjectType.SecretManager}/overview`);
}}
size="lg"
/>

View File

@@ -3,6 +3,7 @@ import { NextRouter, useRouter } from "next/router";
import { useServerConfig } from "@app/context";
import { fetchOrganizations } from "@app/hooks/api/organization/queries";
import { userKeys } from "@app/hooks/api/users";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { queryClient } from "@app/reactQuery";
export const navigateUserToOrg = async (router: NextRouter, organizationId?: string) => {
@@ -20,7 +21,7 @@ export const navigateUserToOrg = async (router: NextRouter, organizationId?: str
// user is part of at least 1 non-auth enforced org
const userOrg = nonAuthEnforcedOrgs[0] && nonAuthEnforcedOrgs[0].id;
localStorage.setItem("orgData.id", userOrg);
router.push(`/org/${userOrg}/overview`);
router.push(`/org/${userOrg}/${ProjectType.SecretManager}/overview`);
} else {
// user is not part of any non-auth enforced orgs
localStorage.removeItem("orgData.id");

View File

@@ -33,7 +33,7 @@ export const IdentityProjectRow = ({
membership: { id, createdAt, identity, project, roles },
handlePopUpOpen
}: Props) => {
const { workspaces } = useWorkspace();
const { workspaces,currentWorkspace } = useWorkspace();
const router = useRouter();
const isAccessible = useMemo(() => {
@@ -52,7 +52,7 @@ export const IdentityProjectRow = ({
key={`identity-project-membership-${id}`}
onClick={() => {
if (isAccessible) {
router.push(`/project/${project.id}/members?selectedTab=${TabSections.Identities}`);
router.push(`/${currentWorkspace?.type}/${project.id}/members?selectedTab=${TabSections.Identities}`);
return;
}

View File

@@ -7,6 +7,7 @@ import z from "zod";
import { createNotification } from "@app/components/notifications";
import { Button, FormControl, Input, Modal, ModalContent } from "@app/components/v2";
import { useCreateOrg, useSelectOrganization } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/workspace/types";
const schema = z
.object({
@@ -57,8 +58,8 @@ export const CreateOrgModal: FC<CreateOrgModalProps> = ({ isOpen, onClose }) =>
type: "success"
});
if (router.isReady) router.push(`/org/${organization.id}/overview`);
else window.location.href = `/org/${organization.id}/overview`;
if (router.isReady) router.push(`/org/${organization.id}/${ProjectType.SecretManager}/overview`);
else window.location.href = `/org/${organization.id}/${ProjectType.SecretManager}/overview`;
localStorage.setItem("orgData.id", organization.id);

View File

@@ -52,16 +52,13 @@ export const OrgAdminProjects = withPermission(
const projectCount = data?.count || 0;
const isEmpty = !isProjectsLoading && projects.length === 0;
const handleAccessProject = async (projectId: string) => {
const handleAccessProject = async (type:string,projectId: string) => {
try {
await orgAdminAccessProject.mutateAsync({
projectId
});
await router.push({
pathname: "/project/[projectId]/secrets/overview",
query: {
projectId
}
pathname: `/${type}/${projectId}/secrets/overview`,
});
} catch {
createNotification({
@@ -103,7 +100,7 @@ export const OrgAdminProjects = withPermission(
<TBody>
{isProjectsLoading && <TableSkeleton columns={4} innerKey="projects" />}
{!isProjectsLoading &&
projects?.map(({ name, slug, createdAt, id }) => (
projects?.map(({ name, slug, createdAt,type, id }) => (
<Tr key={`project-${id}`} className="group w-full">
<Td>{name}</Td>
<Td>{slug}</Td>
@@ -124,7 +121,7 @@ export const OrgAdminProjects = withPermission(
onClick={(e) => {
e.stopPropagation();
e.preventDefault();
handleAccessProject(id);
handleAccessProject(type,id);
}}
icon={<FontAwesomeIcon icon={faSignIn} />}
disabled={

View File

@@ -18,6 +18,7 @@ import {
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { withProjectPermission } from "@app/hoc";
import { useDeleteCa, useGetCaById } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { CaModal } from "@app/views/Project/CertificatesPage/components/CaTab/components/CaModal";
@@ -60,7 +61,7 @@ export const CaPage = withProjectPermission(
});
handlePopUpClose("deleteCa");
router.push(`/project/${projectId}/certificates`);
router.push(`/${ProjectType.CertificateManager}/${projectId}/certificates`);
} catch (err) {
console.error(err);
createNotification({
@@ -78,7 +79,7 @@ export const CaPage = withProjectPermission(
variant="link"
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => router.push(`/project/${projectId}/certificates`)}
onClick={() => router.push(`/${ProjectType.CertificateManager}/${projectId}/certificates`)}
className="mb-4"
>
Certificate Authorities

View File

@@ -34,6 +34,7 @@ import {
caTypeToNameMap,
getCaStatusBadgeVariant
} from "@app/hooks/api/ca/constants";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
type Props = {
@@ -80,7 +81,7 @@ export const CaTable = ({ handlePopUpOpen }: Props) => {
<Tr
className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
key={`ca-${ca.id}`}
onClick={() => router.push(`/project/${currentWorkspace?.id}/ca/${ca.id}`)}
onClick={() => router.push(`/${ProjectType.CertificateManager}/${currentWorkspace?.id}/ca/${ca.id}`)}
>
<Td>{ca.friendlyName}</Td>
<Td>

View File

@@ -12,6 +12,7 @@ import {
useGetPkiCollectionById,
useUpdatePkiCollection
} from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
const schema = z.object({
@@ -81,7 +82,7 @@ export const PkiCollectionModal = ({ popUp, handlePopUpToggle }: Props) => {
projectId
});
router.push(`/project/${projectId}/pki-collections/${createdId}`);
router.push(`/${ProjectType.CertificateManager}/${projectId}/pki-collections/${createdId}`);
}
handlePopUpToggle("pkiCollection", false);

View File

@@ -21,6 +21,7 @@ import {
} from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { useListWorkspacePkiCollections } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
type Props = {
@@ -59,7 +60,7 @@ export const PkiCollectionTable = ({ handlePopUpOpen }: Props) => {
className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
key={`pki-collection-${pkiCollection.id}`}
onClick={() =>
router.push(`/project/${projectId}/pki-collections/${pkiCollection.id}`)
router.push(`/${ProjectType.CertificateManager}/${projectId}/pki-collections/${pkiCollection.id}`)
}
>
<Td>{pkiCollection.name}</Td>

View File

@@ -48,7 +48,7 @@ export const IdentityDetailsPage = withProjectPermission(
type: "success"
});
handlePopUpClose("deleteIdentity");
router.push(`/project/${workspaceId}/members?selectedTab=identities`);
router.push(`/${currentWorkspace?.type}/${workspaceId}/members?selectedTab=identities`);
} catch (err) {
console.error(err);
const error = err as any;
@@ -77,7 +77,7 @@ export const IdentityDetailsPage = withProjectPermission(
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
router.push(`/project/${workspaceId}/members?selectedTab=identities`);
router.push(`/${currentWorkspace?.type}/${workspaceId}/members?selectedTab=identities`);
}}
className="mb-4"
>

View File

@@ -58,7 +58,7 @@ export const MemberDetailsPage = withProjectPermission(
text: "Successfully removed user from project",
type: "success"
});
router.push(`/project/${currentWorkspace?.id}/members`);
router.push(`/${currentWorkspace.type}/${currentWorkspace?.id}/members`);
} catch (error) {
console.error(error);
createNotification({
@@ -85,7 +85,7 @@ export const MemberDetailsPage = withProjectPermission(
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
router.push(`/project/${workspaceId}/members`);
router.push(`/${currentWorkspace?.type}/${workspaceId}/members`);
}}
className="mb-4"
>

View File

@@ -244,10 +244,10 @@ export const IdentityTab = withProjectPermission(
tabIndex={0}
onKeyDown={(evt) => {
if (evt.key === "Enter") {
router.push(`/project/${workspaceId}/identities/${id}`);
router.push(`/${currentWorkspace?.type}/${workspaceId}/identities/${id}`);
}
}}
onClick={() => router.push(`/project/${workspaceId}/identities/${id}`)}
onClick={() => router.push(`/${currentWorkspace?.type}/${workspaceId}/identities/${id}`)}
>
<Td>{name}</Td>

View File

@@ -212,10 +212,10 @@ export const MembersTable = ({ handlePopUpOpen }: Props) => {
tabIndex={0}
onKeyDown={(evt) => {
if (evt.key === "Enter") {
router.push(`/project/${workspaceId}/members/${membershipId}`);
router.push(`/${currentWorkspace?.type}/${workspaceId}/members/${membershipId}`);
}
}}
onClick={() => router.push(`/project/${workspaceId}/members/${membershipId}`)}
onClick={() => router.push(`/${currentWorkspace?.type}/${workspaceId}/members/${membershipId}`)}
>
<Td>{name}</Td>
<Td>{email}</Td>

View File

@@ -92,7 +92,7 @@ export const ProjectRoleList = () => {
<Tr
key={`role-list-${id}`}
className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
onClick={() => router.push(`/project/${projectId}/roles/${slug}`)}
onClick={() => router.push(`/${currentWorkspace?.type}/${projectId}/roles/${slug}`)}
>
<Td>{name}</Td>
<Td>{slug}</Td>
@@ -115,7 +115,7 @@ export const ProjectRoleList = () => {
)}
onClick={(e) => {
e.stopPropagation();
router.push(`/project/${projectId}/roles/${slug}`);
router.push(`/${currentWorkspace?.type}/${projectId}/roles/${slug}`);
}}
disabled={!isAllowed}
>

View File

@@ -19,6 +19,7 @@ import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@a
import { withProjectPermission } from "@app/hoc";
import { useDeletePkiCollection, useGetPkiCollectionById } from "@app/hooks/api";
import { PkiItemType } from "@app/hooks/api/pkiCollections/constants";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { PkiCollectionModal } from "../CertificatesPage/components/PkiAlertsTab/components/PkiCollectionModal";
@@ -53,7 +54,7 @@ export const PkiCollectionPage = withProjectPermission(
type: "success"
});
handlePopUpClose("deletePkiCollection");
router.push(`/project/${projectId}/certificates`);
router.push(`/${ProjectType.CertificateManager}/${projectId}/certificates`);
} catch (err) {
console.error(err);
}
@@ -68,7 +69,7 @@ export const PkiCollectionPage = withProjectPermission(
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() => {
router.push(`/project/${projectId}/certificates`);
router.push(`/${ProjectType.CertificateManager}/${projectId}/certificates`);
}}
className="mb-4"
>

View File

@@ -53,7 +53,7 @@ export const RolePage = withProjectPermission(
type: "success"
});
handlePopUpClose("deleteRole");
router.push(`/project/${projectId}/members?selectedTab=${TabSections.Roles}`);
router.push(`/${currentWorkspace?.type}/${projectId}/members?selectedTab=${TabSections.Roles}`);
} catch (err) {
console.error(err);
const error = err as any;
@@ -77,7 +77,7 @@ export const RolePage = withProjectPermission(
type="submit"
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
onClick={() =>
router.push(`/project/${projectId}/members?selectedTab=${TabSections.Roles}`)
router.push(`/${currentWorkspace?.type}/${projectId}/members?selectedTab=${TabSections.Roles}`)
}
className="mb-4"
>

View File

@@ -99,7 +99,7 @@ export const RoleModal = ({ popUp, handlePopUpToggle }: Props) => {
permissions: []
});
router.push(`/project/${currentWorkspace?.id}/roles/${newRole.slug}`);
router.push(`/${currentWorkspace?.type}/${currentWorkspace?.id}/roles/${newRole.slug}`);
handlePopUpToggle("role", false);
}

View File

@@ -35,6 +35,7 @@ import {
import { useGetProjectSecretsDetails } from "@app/hooks/api/dashboard";
import { DashboardSecretsOrderBy } from "@app/hooks/api/dashboard/types";
import { OrderByDirection } from "@app/hooks/api/generic/types";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { DynamicSecretListView } from "@app/views/SecretMainPage/components/DynamicSecretListView";
import { FolderListView } from "@app/views/SecretMainPage/components/FolderListView";
import { SecretImportListView } from "@app/views/SecretMainPage/components/SecretImportListView";
@@ -142,7 +143,7 @@ const SecretMainPageContent = () => {
!currentWorkspace?.environments.find((env) => env.slug === environment) &&
router.isReady
) {
router.push(`/project/${workspaceId}/secrets/overview`);
router.push(`/${ProjectType.SecretManager}/${workspaceId}/secrets/overview`);
createNotification({
text: "No environment found with given slug",
type: "error"

View File

@@ -68,7 +68,7 @@ import { OrderByDirection } from "@app/hooks/api/generic/types";
import { useUpdateFolderBatch } from "@app/hooks/api/secretFolders/queries";
import { TUpdateFolderBatchDTO } from "@app/hooks/api/secretFolders/types";
import { SecretType, SecretV3RawSanitized, TSecretFolder } from "@app/hooks/api/types";
import { ProjectVersion } from "@app/hooks/api/workspace/types";
import { ProjectType, ProjectVersion } from "@app/hooks/api/workspace/types";
import { useDynamicSecretOverview, useFolderOverview, useSecretOverview } from "@app/hooks/utils";
import { SecretOverviewDynamicSecretRow } from "@app/views/SecretOverviewPage/components/SecretOverviewDynamicSecretRow";
import {
@@ -170,7 +170,7 @@ export const SecretOverviewPage = () => {
useEffect(() => {
if (!isWorkspaceLoading && !workspaceId && router.isReady) {
router.push(`/org/${currentOrg?.id}/overview`);
router.push(`/org/${currentOrg?.id}/${ProjectType.SecretManager}/overview`);
}
}, [isWorkspaceLoading, workspaceId, router.isReady]);
@@ -508,7 +508,7 @@ export const SecretOverviewPage = () => {
const envIndex = visibleEnvs.findIndex((el) => slug === el.slug);
if (envIndex !== -1) {
router.push({
pathname: "/project/[id]/secrets/[env]",
pathname: `/${ProjectType.SecretManager}/[id]/secrets/[env]`,
query
});
}

View File

@@ -14,6 +14,7 @@ import {
} from "@app/context";
import { useToggle } from "@app/hooks";
import { useDeleteWorkspace, useGetWorkspaceUsers, useLeaveProject } from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { usePopUp } from "@app/hooks/usePopUp";
export const DeleteProjectSection = () => {
@@ -63,7 +64,7 @@ export const DeleteProjectSection = () => {
type: "success"
});
router.push(`/org/${orgId}/overview`);
router.push(`/org/${orgId}/${ProjectType.SecretManager}/overview`);
handlePopUpClose("deleteWorkspace");
} catch (err) {
console.error(err);
@@ -120,7 +121,7 @@ export const DeleteProjectSection = () => {
workspaceId: currentWorkspace.id
});
router.push(`/org/${currentOrg.id}/overview`);
router.push(`/org/${currentOrg.id}/${ProjectType.SecretManager}/overview`);
} catch (err) {
console.error(err);
createNotification({

View File

@@ -5,6 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import issueBackupKey from "@app/components/utilities/cryptography/issueBackupKey";
import { Button } from "@app/components/v2";
import { ProjectType } from "@app/hooks/api/workspace/types";
interface DownloadBackupPDFStepProps {
email: string;
@@ -49,7 +50,7 @@ export const BackupPDFStep = ({ email, password, name }: DownloadBackupPDFStepPr
setBackupKeyIssued: () => {}
});
router.push(`/org/${localStorage.getItem("orgData.id")}/overview`);
router.push(`/org/${localStorage.getItem("orgData.id")}/${ProjectType.SecretManager}/overview`);
}}
size="sm"
isFullWidth

View File

@@ -27,6 +27,7 @@ import {
useGetServerRootKmsEncryptionDetails,
useUpdateServerConfig
} from "@app/hooks/api";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { AuthPanel } from "./AuthPanel";
import { EncryptionPanel } from "./EncryptionPanel";
@@ -98,7 +99,7 @@ export const AdminDashboardPage = () => {
if (isNotAllowed && !isUserLoading) {
if (orgs?.length) {
localStorage.setItem("orgData.id", orgs?.[0]?.id);
router.push(`/org/${orgs?.[0]?.id}/overview`);
router.push(`/org/${orgs?.[0]?.id}/${ProjectType.SecretManager}/overview`);
}
}
}, [isNotAllowed, isUserLoading]);