mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-14 22:51:53 +00:00
Move ssh back to project level
This commit is contained in:
@@ -23,10 +23,7 @@ export enum OrgPermissionSubjects {
|
||||
Kms = "kms",
|
||||
AdminConsole = "organization-admin-console",
|
||||
AuditLogs = "audit-logs",
|
||||
ProjectTemplates = "project-templates",
|
||||
SshCertificateAuthorities = "ssh-certificate-authorities",
|
||||
SshCertificateTemplates = "ssh-certificate-templates",
|
||||
SshCertificates = "ssh-certificates"
|
||||
ProjectTemplates = "project-templates"
|
||||
}
|
||||
|
||||
export enum OrgPermissionAdminConsoleAction {
|
||||
@@ -50,9 +47,6 @@ export type OrgPermissionSet =
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.Kms]
|
||||
| [OrgPermissionAdminConsoleAction, OrgPermissionSubjects.AdminConsole]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.AuditLogs]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.ProjectTemplates]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.SshCertificateAuthorities]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.SshCertificates]
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.SshCertificateTemplates];
|
||||
| [OrgPermissionActions, OrgPermissionSubjects.ProjectTemplates];
|
||||
|
||||
export type TOrgPermission = MongoAbility<OrgPermissionSet>;
|
||||
|
||||
@@ -81,6 +81,9 @@ export enum ProjectPermissionSub {
|
||||
CertificateAuthorities = "certificate-authorities",
|
||||
Certificates = "certificates",
|
||||
CertificateTemplates = "certificate-templates",
|
||||
SshCertificateAuthorities = "ssh-certificate-authorities",
|
||||
SshCertificateTemplates = "ssh-certificate-templates",
|
||||
SshCertificates = "ssh-certificates",
|
||||
PkiAlerts = "pki-alerts",
|
||||
PkiCollections = "pki-collections",
|
||||
Kms = "kms",
|
||||
@@ -155,6 +158,9 @@ export type ProjectPermissionSet =
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificateAuthorities]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.Certificates]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.CertificateTemplates]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateAuthorities]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificateTemplates]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.SshCertificates]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.PkiAlerts]
|
||||
| [ProjectPermissionActions, ProjectPermissionSub.PkiCollections]
|
||||
| [ProjectPermissionActions.Delete, ProjectPermissionSub.Project]
|
||||
|
||||
@@ -19,8 +19,6 @@ export {
|
||||
useGetOrgPmtMethods,
|
||||
useGetOrgTaxIds,
|
||||
useGetOrgTrialUrl,
|
||||
useListOrgSshCas,
|
||||
useListOrgSshCertificates,
|
||||
useListOrgSshCertificateTemplates,
|
||||
useUpdateOrg,
|
||||
useUpdateOrgBillingDetails} from "./queries";
|
||||
useUpdateOrgBillingDetails
|
||||
} from "./queries";
|
||||
|
||||
@@ -4,8 +4,6 @@ import { apiRequest } from "@app/config/request";
|
||||
import { OrderByDirection } from "@app/hooks/api/generic/types";
|
||||
|
||||
import { TGroupOrgMembership } from "../groups/types";
|
||||
import { TSshCertificate,TSshCertificateAuthority } from "../ssh-ca/types";
|
||||
import { TSshCertificateTemplate } from "../sshCertificateTemplates/types";
|
||||
import { IntegrationAuth } from "../types";
|
||||
import {
|
||||
BillingDetails,
|
||||
@@ -43,12 +41,7 @@ export const organizationKeys = {
|
||||
}: TListOrgIdentitiesDTO) =>
|
||||
[...organizationKeys.getOrgIdentityMemberships(orgId), params] as const,
|
||||
getOrgGroups: (orgId: string) => [{ orgId }, "organization-groups"] as const,
|
||||
getOrgIntegrationAuths: (orgId: string) => [{ orgId }, "integration-auths"] as const,
|
||||
getOrgSshCas: ({ orgId }: { orgId: string }) => [{ orgId }, "org-ssh-cas"] as const,
|
||||
allOrgSshCertificates: () => ["org-ssh-certificates"] as const,
|
||||
specificOrgSshCertificates: ({ offset, limit }: { offset: number; limit: number }) =>
|
||||
[...organizationKeys.allOrgSshCertificates(), { offset, limit }] as const,
|
||||
getOrgSshCertificateTemplates: () => ["org-ssh-certificate-templates"] as const
|
||||
getOrgIntegrationAuths: (orgId: string) => [{ orgId }, "integration-auths"] as const
|
||||
};
|
||||
|
||||
export const fetchOrganizations = async () => {
|
||||
@@ -502,63 +495,3 @@ export const useGetOrgIntegrationAuths = <TData = IntegrationAuth[],>(
|
||||
select
|
||||
});
|
||||
};
|
||||
|
||||
export const useListOrgSshCas = ({ orgId }: { orgId: string }) => {
|
||||
return useQuery({
|
||||
queryKey: organizationKeys.getOrgSshCas({ orgId }),
|
||||
queryFn: async () => {
|
||||
const {
|
||||
data: { cas }
|
||||
} = await apiRequest.get<{ cas: Omit<TSshCertificateAuthority, "publicKey">[] }>(
|
||||
`/api/v1/organization/${orgId}/ssh-cas`
|
||||
);
|
||||
return cas;
|
||||
},
|
||||
enabled: Boolean(orgId)
|
||||
});
|
||||
};
|
||||
|
||||
export const useListOrgSshCertificates = ({
|
||||
orgId,
|
||||
offset,
|
||||
limit
|
||||
}: {
|
||||
orgId: string;
|
||||
offset: number;
|
||||
limit: number;
|
||||
}) => {
|
||||
return useQuery({
|
||||
queryKey: organizationKeys.specificOrgSshCertificates({
|
||||
offset,
|
||||
limit
|
||||
}),
|
||||
queryFn: async () => {
|
||||
const params = new URLSearchParams({
|
||||
offset: String(offset),
|
||||
limit: String(limit)
|
||||
});
|
||||
|
||||
const { data } = await apiRequest.get<{
|
||||
certificates: TSshCertificate[];
|
||||
totalCount: number;
|
||||
}>(`/api/v1/organization/${orgId}/ssh-certificates`, {
|
||||
params
|
||||
});
|
||||
return data;
|
||||
},
|
||||
enabled: Boolean(orgId)
|
||||
});
|
||||
};
|
||||
|
||||
export const useListOrgSshCertificateTemplates = ({ orgId }: { orgId: string }) => {
|
||||
return useQuery({
|
||||
queryKey: organizationKeys.getOrgSshCertificateTemplates(),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<{ certificateTemplates: TSshCertificateTemplate[] }>(
|
||||
`/api/v1/organization/${orgId}/ssh-certificate-templates`
|
||||
);
|
||||
return data;
|
||||
},
|
||||
enabled: Boolean(orgId)
|
||||
});
|
||||
};
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
|
||||
import { apiRequest } from "@app/config/request";
|
||||
|
||||
import { organizationKeys } from "../organization/queries";
|
||||
import { workspaceKeys } from "../workspace/query-keys";
|
||||
import {
|
||||
TCreateSshCaDTO,
|
||||
TDeleteSshCaDTO,
|
||||
@@ -27,8 +27,8 @@ export const useCreateSshCa = () => {
|
||||
} = await apiRequest.post<{ ca: TSshCertificateAuthority }>("/api/v1/ssh/ca/", body);
|
||||
return ca;
|
||||
},
|
||||
onSuccess: ({ orgId }) => {
|
||||
queryClient.invalidateQueries(organizationKeys.getOrgSshCas({ orgId }));
|
||||
onSuccess: ({ projectId }) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getWorkspaceSshCas(projectId));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -42,8 +42,8 @@ export const useUpdateSshCa = () => {
|
||||
} = await apiRequest.patch<{ ca: TSshCertificateAuthority }>(`/api/v1/ssh/ca/${caId}`, body);
|
||||
return ca;
|
||||
},
|
||||
onSuccess: ({ orgId }, { caId }) => {
|
||||
queryClient.invalidateQueries(organizationKeys.getOrgSshCas({ orgId }));
|
||||
onSuccess: ({ projectId }, { caId }) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getWorkspaceSshCas(projectId));
|
||||
queryClient.invalidateQueries(sshCaKeys.getSshCaById(caId));
|
||||
}
|
||||
});
|
||||
@@ -58,8 +58,8 @@ export const useDeleteSshCa = () => {
|
||||
} = await apiRequest.delete<{ ca: TSshCertificateAuthority }>(`/api/v1/ssh/ca/${caId}`);
|
||||
return ca;
|
||||
},
|
||||
onSuccess: ({ orgId }) => {
|
||||
queryClient.invalidateQueries(organizationKeys.getOrgSshCas({ orgId }));
|
||||
onSuccess: ({ projectId }) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.getWorkspaceSshCas(projectId));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -71,8 +71,8 @@ export const useSignSshKey = () => {
|
||||
const { data } = await apiRequest.post<TSignSshKeyResponse>("/api/v1/ssh/sign", body);
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(organizationKeys.allOrgSshCertificates());
|
||||
onSuccess: (_, { projectId }) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.allWorkspaceSshCertificates(projectId));
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -84,8 +84,8 @@ export const useIssueSshCreds = () => {
|
||||
const { data } = await apiRequest.post<TIssueSshCredsResponse>("/api/v1/ssh/issue", body);
|
||||
return data;
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries(organizationKeys.allOrgSshCertificates());
|
||||
onSuccess: (_, { projectId }) => {
|
||||
queryClient.invalidateQueries(workspaceKeys.allWorkspaceSshCertificates(projectId));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -7,7 +7,6 @@ export type TSshCertificate = {
|
||||
sshCertificateTemplateId: string;
|
||||
serialNumber: string;
|
||||
certType: SshCertType;
|
||||
publicKey: string;
|
||||
principals: string[];
|
||||
keyId: string;
|
||||
notBefore: string;
|
||||
@@ -16,7 +15,7 @@ export type TSshCertificate = {
|
||||
|
||||
export type TSshCertificateAuthority = {
|
||||
id: string;
|
||||
orgId: string;
|
||||
projectId: string;
|
||||
status: SshCaStatus;
|
||||
friendlyName: string;
|
||||
keyAlgorithm: CertKeyAlgorithm;
|
||||
@@ -26,6 +25,7 @@ export type TSshCertificateAuthority = {
|
||||
};
|
||||
|
||||
export type TCreateSshCaDTO = {
|
||||
projectId: string;
|
||||
friendlyName?: string;
|
||||
keyAlgorithm: CertKeyAlgorithm;
|
||||
};
|
||||
@@ -41,6 +41,7 @@ export type TDeleteSshCaDTO = {
|
||||
};
|
||||
|
||||
export type TSignSshKeyDTO = {
|
||||
projectId: string;
|
||||
templateName: string;
|
||||
publicKey?: string;
|
||||
certType: SshCertType;
|
||||
@@ -55,6 +56,7 @@ export type TSignSshKeyResponse = {
|
||||
};
|
||||
|
||||
export type TIssueSshCredsDTO = {
|
||||
projectId: string;
|
||||
templateName: string;
|
||||
keyAlgorithm: CertKeyAlgorithm;
|
||||
certType: SshCertType;
|
||||
|
||||
@@ -32,6 +32,9 @@ export {
|
||||
useListWorkspaceGroups,
|
||||
useListWorkspacePkiAlerts,
|
||||
useListWorkspacePkiCollections,
|
||||
useListWorkspaceSshCas,
|
||||
useListWorkspaceSshCertificates,
|
||||
useListWorkspaceSshCertificateTemplates,
|
||||
useNameWorkspaceSecrets,
|
||||
useToggleAutoCapitalization,
|
||||
useUpdateIdentityWorkspaceRole,
|
||||
|
||||
@@ -15,6 +15,8 @@ import { TIntegration } from "../integrations/types";
|
||||
import { TPkiAlert } from "../pkiAlerts/types";
|
||||
import { TPkiCollection } from "../pkiCollections/types";
|
||||
import { EncryptedSecret } from "../secrets/types";
|
||||
import { TSshCertificate, TSshCertificateAuthority } from "../ssh-ca/types";
|
||||
import { TSshCertificateTemplate } from "../sshCertificateTemplates/types";
|
||||
import { userKeys } from "../users/query-keys";
|
||||
import { TWorkspaceUser } from "../users/types";
|
||||
import { ProjectSlackConfig } from "../workflowIntegrations/types";
|
||||
@@ -713,6 +715,67 @@ export const useListWorkspaceCertificateTemplates = ({ workspaceId }: { workspac
|
||||
});
|
||||
};
|
||||
|
||||
export const useListWorkspaceSshCertificates = ({
|
||||
offset,
|
||||
limit,
|
||||
projectId
|
||||
}: {
|
||||
offset: number;
|
||||
limit: number;
|
||||
projectId: string;
|
||||
}) => {
|
||||
return useQuery({
|
||||
queryKey: workspaceKeys.specificWorkspaceSshCertificates({
|
||||
offset,
|
||||
limit,
|
||||
projectId
|
||||
}),
|
||||
queryFn: async () => {
|
||||
const params = new URLSearchParams({
|
||||
offset: String(offset),
|
||||
limit: String(limit)
|
||||
});
|
||||
|
||||
const { data } = await apiRequest.get<{
|
||||
certificates: TSshCertificate[];
|
||||
totalCount: number;
|
||||
}>(`/api/v2/workspace/${projectId}/ssh-certificates`, {
|
||||
params
|
||||
});
|
||||
return data;
|
||||
},
|
||||
enabled: Boolean(projectId)
|
||||
});
|
||||
};
|
||||
|
||||
export const useListWorkspaceSshCas = (projectId: string) => {
|
||||
return useQuery({
|
||||
queryKey: workspaceKeys.getWorkspaceSshCas(projectId),
|
||||
queryFn: async () => {
|
||||
const {
|
||||
data: { cas }
|
||||
} = await apiRequest.get<{ cas: Omit<TSshCertificateAuthority, "publicKey">[] }>(
|
||||
`/api/v2/workspace/${projectId}/ssh-cas`
|
||||
);
|
||||
return cas;
|
||||
},
|
||||
enabled: Boolean(projectId)
|
||||
});
|
||||
};
|
||||
|
||||
export const useListWorkspaceSshCertificateTemplates = (projectId: string) => {
|
||||
return useQuery({
|
||||
queryKey: workspaceKeys.getWorkspaceSshCertificateTemplates(projectId),
|
||||
queryFn: async () => {
|
||||
const { data } = await apiRequest.get<{ certificateTemplates: TSshCertificateTemplate[] }>(
|
||||
`/api/v2/workspace/${projectId}/ssh-certificate-templates`
|
||||
);
|
||||
return data;
|
||||
},
|
||||
enabled: Boolean(projectId)
|
||||
});
|
||||
};
|
||||
|
||||
export const useGetWorkspaceSlackConfig = ({ workspaceId }: { workspaceId: string }) => {
|
||||
return useQuery({
|
||||
queryKey: workspaceKeys.getWorkspaceSlackConfig(workspaceId),
|
||||
|
||||
@@ -52,5 +52,19 @@ export const workspaceKeys = {
|
||||
getWorkspaceCertificateTemplates: (workspaceId: string) =>
|
||||
[{ workspaceId }, "workspace-certificate-templates"] as const,
|
||||
getWorkspaceSlackConfig: (workspaceId: string) =>
|
||||
[{ workspaceId }, "workspace-slack-config"] as const
|
||||
[{ workspaceId }, "workspace-slack-config"] as const,
|
||||
getWorkspaceSshCas: (projectId: string) => [{ projectId }, "workspace-ssh-cas"] as const,
|
||||
allWorkspaceSshCertificates: (projectId: string) =>
|
||||
[{ projectId }, "workspace-ssh-certificates"] as const,
|
||||
specificWorkspaceSshCertificates: ({
|
||||
offset,
|
||||
limit,
|
||||
projectId
|
||||
}: {
|
||||
offset: number;
|
||||
limit: number;
|
||||
projectId: string;
|
||||
}) => [...workspaceKeys.allWorkspaceSshCertificates(projectId), { offset, limit }] as const,
|
||||
getWorkspaceSshCertificateTemplates: (projectId: string) =>
|
||||
[{ projectId }, "workspace-ssh-certificate-templates"] as const
|
||||
};
|
||||
|
||||
@@ -424,6 +424,16 @@ export const AppLayout = ({ children }: LayoutProps) => {
|
||||
</MenuItem>
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/project/${currentWorkspace?.id}/ssh`} passHref>
|
||||
<a>
|
||||
<MenuItem
|
||||
isSelected={router.asPath === `/project/${currentWorkspace?.id}/ssh`}
|
||||
icon="system-outline-90-lock-closed"
|
||||
>
|
||||
SSH
|
||||
</MenuItem>
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/project/${currentWorkspace?.id}/members`} passHref>
|
||||
<a>
|
||||
<MenuItem
|
||||
@@ -513,16 +523,6 @@ export const AppLayout = ({ children }: LayoutProps) => {
|
||||
</MenuItem>
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/org/${currentOrg?.id}/ssh`} passHref>
|
||||
<a>
|
||||
<MenuItem
|
||||
isSelected={router.asPath === `/org/${currentOrg?.id}/ssh`}
|
||||
icon="system-outline-90-lock-closed"
|
||||
>
|
||||
SSH
|
||||
</MenuItem>
|
||||
</a>
|
||||
</Link>
|
||||
<Link href={`/org/${currentOrg?.id}/secret-scanning`} passHref>
|
||||
<a>
|
||||
<MenuItem
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Head from "next/head";
|
||||
|
||||
import { SshPage } from "@app/views/Org/SshPage";
|
||||
|
||||
const Ssh = () => {
|
||||
const { t } = useTranslation();
|
||||
return (
|
||||
<>
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: t("approval.title") })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
<meta property="og:title" content={String(t("approval.og-title"))} />
|
||||
<meta name="og:description" content={String(t("approval.og-description"))} />
|
||||
</Head>
|
||||
<div className="h-full">
|
||||
<SshPage />
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default Ssh;
|
||||
|
||||
Ssh.requireAuth = true;
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import Head from "next/head";
|
||||
|
||||
import { SshCaPage } from "@app/views/Org/SshCaPage";
|
||||
import { SshCaPage } from "@app/views/Project/SshCaPage";
|
||||
|
||||
export default function SshCa() {
|
||||
return (
|
||||
@@ -0,0 +1,23 @@
|
||||
import { useTranslation } from "react-i18next";
|
||||
import Head from "next/head";
|
||||
|
||||
import { SshPage } from "@app/views/Project/SshPage";
|
||||
|
||||
const Ssh = () => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
<div className="h-full bg-bunker-800">
|
||||
<Head>
|
||||
<title>{t("common.head-title", { title: "Certificates" })}</title>
|
||||
<link rel="icon" href="/infisical.ico" />
|
||||
<meta property="og:image" content="/images/message.png" />
|
||||
</Head>
|
||||
<SshPage />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Ssh;
|
||||
|
||||
Ssh.requireAuth = true;
|
||||
@@ -49,10 +49,7 @@ export const formSchema = z.object({
|
||||
identity: generalPermissionSchema,
|
||||
"organization-admin-console": adminConsolePermissionSchmea,
|
||||
[OrgPermissionSubjects.Kms]: generalPermissionSchema,
|
||||
[OrgPermissionSubjects.ProjectTemplates]: generalPermissionSchema,
|
||||
[OrgPermissionSubjects.SshCertificateAuthorities]: generalPermissionSchema,
|
||||
[OrgPermissionSubjects.SshCertificates]: generalPermissionSchema,
|
||||
[OrgPermissionSubjects.SshCertificateTemplates]: generalPermissionSchema
|
||||
[OrgPermissionSubjects.ProjectTemplates]: generalPermissionSchema
|
||||
})
|
||||
.optional()
|
||||
});
|
||||
|
||||
+1
-13
@@ -69,19 +69,7 @@ const SIMPLE_PERMISSION_OPTIONS = [
|
||||
title: "External KMS",
|
||||
formName: OrgPermissionSubjects.Kms
|
||||
},
|
||||
{ title: "Project Templates", formName: OrgPermissionSubjects.ProjectTemplates },
|
||||
{
|
||||
title: "SSH Certificate Authorities",
|
||||
formName: OrgPermissionSubjects.SshCertificateAuthorities
|
||||
},
|
||||
{
|
||||
title: "SSH Certificates",
|
||||
formName: OrgPermissionSubjects.SshCertificates
|
||||
},
|
||||
{
|
||||
title: "SSH Certificate Templates",
|
||||
formName: OrgPermissionSubjects.SshCertificateTemplates
|
||||
}
|
||||
{ title: "Project Templates", formName: OrgPermissionSubjects.ProjectTemplates }
|
||||
] as const;
|
||||
|
||||
type Props = {
|
||||
|
||||
+35
@@ -121,6 +121,11 @@ export const projectRoleFormSchema = z.object({
|
||||
[ProjectPermissionSub.PkiAlerts]: GeneralPolicyActionSchema.array().default([]),
|
||||
[ProjectPermissionSub.PkiCollections]: GeneralPolicyActionSchema.array().default([]),
|
||||
[ProjectPermissionSub.CertificateTemplates]: GeneralPolicyActionSchema.array().default([]),
|
||||
[ProjectPermissionSub.SshCertificateAuthorities]: GeneralPolicyActionSchema.array().default(
|
||||
[]
|
||||
),
|
||||
[ProjectPermissionSub.SshCertificates]: GeneralPolicyActionSchema.array().default([]),
|
||||
[ProjectPermissionSub.SshCertificateTemplates]: GeneralPolicyActionSchema.array().default([]),
|
||||
[ProjectPermissionSub.SecretApproval]: GeneralPolicyActionSchema.array().default([]),
|
||||
[ProjectPermissionSub.SecretRollback]: SecretRollbackPolicyActionSchema.array().default([]),
|
||||
[ProjectPermissionSub.Project]: WorkspacePolicyActionSchema.array().default([]),
|
||||
@@ -203,6 +208,9 @@ export const rolePermission2Form = (permissions: TProjectPermission[] = []) => {
|
||||
ProjectPermissionSub.PkiAlerts,
|
||||
ProjectPermissionSub.PkiCollections,
|
||||
ProjectPermissionSub.CertificateTemplates,
|
||||
ProjectPermissionSub.SshCertificateAuthorities,
|
||||
ProjectPermissionSub.SshCertificates,
|
||||
ProjectPermissionSub.SshCertificateTemplates,
|
||||
ProjectPermissionSub.SecretApproval,
|
||||
ProjectPermissionSub.Tags,
|
||||
ProjectPermissionSub.SecretRotation,
|
||||
@@ -589,6 +597,33 @@ export const PROJECT_PERMISSION_OBJECT: TProjectPermissionObject = {
|
||||
{ label: "Remove", value: "delete" }
|
||||
]
|
||||
},
|
||||
[ProjectPermissionSub.SshCertificateAuthorities]: {
|
||||
title: "SSH Certificate Authorities",
|
||||
actions: [
|
||||
{ label: "Read", value: "read" },
|
||||
{ label: "Create", value: "create" },
|
||||
{ label: "Modify", value: "edit" },
|
||||
{ label: "Remove", value: "delete" }
|
||||
]
|
||||
},
|
||||
[ProjectPermissionSub.SshCertificates]: {
|
||||
title: "SSH Certificates",
|
||||
actions: [
|
||||
{ label: "Read", value: "read" },
|
||||
{ label: "Create", value: "create" },
|
||||
{ label: "Modify", value: "edit" },
|
||||
{ label: "Remove", value: "delete" }
|
||||
]
|
||||
},
|
||||
[ProjectPermissionSub.SshCertificateTemplates]: {
|
||||
title: "SSH Certificate Templates",
|
||||
actions: [
|
||||
{ label: "Read", value: "read" },
|
||||
{ label: "Create", value: "create" },
|
||||
{ label: "Modify", value: "edit" },
|
||||
{ label: "Remove", value: "delete" }
|
||||
]
|
||||
},
|
||||
[ProjectPermissionSub.PkiCollections]: {
|
||||
title: "PKI Collections",
|
||||
actions: [
|
||||
|
||||
+14
-13
@@ -5,7 +5,7 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Button,
|
||||
DeleteActionModal,
|
||||
@@ -15,17 +15,18 @@ import {
|
||||
DropdownMenuTrigger,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||
import { withPermission } from "@app/hoc";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
|
||||
import { withProjectPermission } from "@app/hoc";
|
||||
import { useDeleteSshCa, useGetSshCaById } from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
|
||||
import { SshCaModal } from "../SshPage/components/SshCaModal";
|
||||
import { SshCaDetailsSection, SshCertificateTemplatesSection } from "./components";
|
||||
|
||||
export const SshCaPage = withPermission(
|
||||
export const SshCaPage = withProjectPermission(
|
||||
() => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const projectId = currentWorkspace?.id || "";
|
||||
const router = useRouter();
|
||||
const caId = router.query.caId as string;
|
||||
const { data } = useGetSshCaById(caId);
|
||||
@@ -39,7 +40,7 @@ export const SshCaPage = withPermission(
|
||||
|
||||
const onRemoveCaSubmit = async (caIdToDelete: string) => {
|
||||
try {
|
||||
if (!currentOrg?.id) return;
|
||||
if (!projectId) return;
|
||||
|
||||
await deleteSshCa({ caId: caIdToDelete });
|
||||
|
||||
@@ -49,7 +50,7 @@ export const SshCaPage = withPermission(
|
||||
});
|
||||
|
||||
handlePopUpClose("deleteSshCa");
|
||||
router.push(`/org/${currentOrg.id}/ssh`);
|
||||
router.push(`/project/${projectId}/ssh`);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
createNotification({
|
||||
@@ -67,7 +68,7 @@ export const SshCaPage = withPermission(
|
||||
variant="link"
|
||||
type="submit"
|
||||
leftIcon={<FontAwesomeIcon icon={faChevronLeft} />}
|
||||
onClick={() => router.push(`/org/${currentOrg?.id}/ssh`)}
|
||||
onClick={() => router.push(`/project/${projectId}/ssh`)}
|
||||
className="mb-4"
|
||||
>
|
||||
SSH Certificate Authorities
|
||||
@@ -83,9 +84,9 @@ export const SshCaPage = withPermission(
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="p-1">
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Delete}
|
||||
a={OrgPermissionSubjects.SshCertificateAuthorities}
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={ProjectPermissionSub.SshCertificateAuthorities}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
@@ -104,7 +105,7 @@ export const SshCaPage = withPermission(
|
||||
Delete SSH CA
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
@@ -131,5 +132,5 @@ export const SshCaPage = withPermission(
|
||||
</div>
|
||||
);
|
||||
},
|
||||
{ action: OrgPermissionActions.Read, subject: OrgPermissionSubjects.SshCertificateAuthorities }
|
||||
{ action: ProjectPermissionActions.Read, subject: ProjectPermissionSub.SshCertificateAuthorities }
|
||||
);
|
||||
+7
-7
@@ -1,10 +1,10 @@
|
||||
import { faCheck, faCopy, faDownload,faPencil } from "@fortawesome/free-solid-svg-icons";
|
||||
import { faCheck, faCopy, faDownload, faPencil } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import FileSaver from "file-saver";
|
||||
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { IconButton, Tooltip } from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { useTimedReset } from "@app/hooks";
|
||||
import { useGetSshCaById } from "@app/hooks/api";
|
||||
import { caStatusToNameMap } from "@app/hooks/api/ca/constants";
|
||||
@@ -35,9 +35,9 @@ export const SshCaDetailsSection = ({ caId, handlePopUpOpen }: Props) => {
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
||||
<h3 className="text-lg font-semibold text-mineshaft-100">SSH CA Details</h3>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.SshCertificateAuthorities}
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={ProjectPermissionSub.SshCertificateAuthorities}
|
||||
>
|
||||
{(isAllowed) => {
|
||||
return (
|
||||
@@ -59,7 +59,7 @@ export const SshCaDetailsSection = ({ caId, handlePopUpOpen }: Props) => {
|
||||
</Tooltip>
|
||||
);
|
||||
}}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
</div>
|
||||
<div className="pt-4">
|
||||
<div className="mb-4">
|
||||
+10
-7
@@ -13,13 +13,14 @@ import {
|
||||
Select,
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { useOrganization } from "@app/context";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import {
|
||||
SshCertTemplateStatus,
|
||||
useGetSshCertTemplate,
|
||||
useIssueSshCreds,
|
||||
useListOrgSshCertificateTemplates,
|
||||
useSignSshKey} from "@app/hooks/api";
|
||||
useListWorkspaceSshCertificateTemplates,
|
||||
useSignSshKey
|
||||
} from "@app/hooks/api";
|
||||
import { certKeyAlgorithms } from "@app/hooks/api/certificates/constants";
|
||||
import { CertKeyAlgorithm } from "@app/hooks/api/certificates/enums";
|
||||
import { SshCertType } from "@app/hooks/api/ssh-ca/constants";
|
||||
@@ -62,7 +63,8 @@ enum SshCertificateOperation {
|
||||
}
|
||||
|
||||
export const SshCertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const projectId = currentWorkspace?.id || "";
|
||||
const [operation, setOperation] = useState<SshCertificateOperation>(
|
||||
SshCertificateOperation.SIGN_SSH_KEY
|
||||
);
|
||||
@@ -77,9 +79,7 @@ export const SshCertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
templateId: string;
|
||||
};
|
||||
|
||||
const { data: templatesData } = useListOrgSshCertificateTemplates({
|
||||
orgId: currentOrg?.id || ""
|
||||
});
|
||||
const { data: templatesData } = useListWorkspaceSshCertificateTemplates(projectId);
|
||||
|
||||
const {
|
||||
control,
|
||||
@@ -117,10 +117,12 @@ export const SshCertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
}: FormData) => {
|
||||
try {
|
||||
if (!templateData) return;
|
||||
if (!projectId) return;
|
||||
|
||||
switch (operation) {
|
||||
case SshCertificateOperation.SIGN_SSH_KEY: {
|
||||
const { serialNumber, signedKey } = await signSshKey({
|
||||
projectId: currentWorkspace?.id || "",
|
||||
templateName: templateData.name,
|
||||
publicKey: existingPublicKey,
|
||||
certType,
|
||||
@@ -137,6 +139,7 @@ export const SshCertificateModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
}
|
||||
case SshCertificateOperation.ISSUE_SSH_CREDS: {
|
||||
const { serialNumber, publicKey, privateKey, signedKey } = await issueSshCreds({
|
||||
projectId,
|
||||
templateName: templateData.name,
|
||||
keyAlgorithm,
|
||||
certType,
|
||||
+4
-6
@@ -14,12 +14,12 @@ import {
|
||||
SelectItem,
|
||||
Switch
|
||||
} from "@app/components/v2";
|
||||
import { useOrganization } from "@app/context";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import {
|
||||
useCreateSshCertTemplate,
|
||||
useGetSshCaById,
|
||||
useGetSshCertTemplate,
|
||||
useListOrgSshCas,
|
||||
useListWorkspaceSshCas,
|
||||
useUpdateSshCertTemplate
|
||||
} from "@app/hooks/api";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
@@ -48,7 +48,7 @@ type Props = {
|
||||
};
|
||||
|
||||
export const SshCertificateTemplateModal = ({ popUp, handlePopUpToggle, sshCaId }: Props) => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
|
||||
const { data: ca } = useGetSshCaById(sshCaId);
|
||||
|
||||
@@ -56,9 +56,7 @@ export const SshCertificateTemplateModal = ({ popUp, handlePopUpToggle, sshCaId
|
||||
(popUp?.sshCertificateTemplate?.data as { id: string })?.id || ""
|
||||
);
|
||||
|
||||
const { data: cas } = useListOrgSshCas({
|
||||
orgId: currentOrg?.id ?? ""
|
||||
});
|
||||
const { data: cas } = useListWorkspaceSshCas(currentWorkspace?.id || "");
|
||||
|
||||
const { mutateAsync: createSshCertTemplate } = useCreateSshCertTemplate();
|
||||
const { mutateAsync: updateSshCertTemplate } = useUpdateSshCertTemplate();
|
||||
+8
-7
@@ -2,14 +2,15 @@ import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { DeleteActionModal, IconButton } from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks";
|
||||
import {
|
||||
SshCertTemplateStatus,
|
||||
useDeleteSshCertTemplate,
|
||||
useUpdateSshCertTemplate} from "@app/hooks/api";
|
||||
useUpdateSshCertTemplate
|
||||
} from "@app/hooks/api";
|
||||
|
||||
import { SshCertificateModal } from "./SshCertificateModal";
|
||||
import { SshCertificateTemplateModal } from "./SshCertificateTemplateModal";
|
||||
@@ -85,9 +86,9 @@ export const SshCertificateTemplatesSection = ({ caId }: Props) => {
|
||||
<div className="h-full rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="flex items-center justify-between border-b border-mineshaft-400 pb-4">
|
||||
<h3 className="text-lg font-semibold text-mineshaft-100">Certificate Templates</h3>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Create}
|
||||
a={OrgPermissionSubjects.SshCertificateTemplates}
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={ProjectPermissionSub.SshCertificateTemplates}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<IconButton
|
||||
@@ -100,7 +101,7 @@ export const SshCertificateTemplatesSection = ({ caId }: Props) => {
|
||||
<FontAwesomeIcon icon={faPlus} />
|
||||
</IconButton>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
</div>
|
||||
<div className="py-4">
|
||||
<SshCertificateTemplatesTable handlePopUpOpen={handlePopUpOpen} sshCaId={caId} />
|
||||
+19
-19
@@ -8,7 +8,7 @@ import {
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
@@ -26,8 +26,8 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { SshCertTemplateStatus,useGetSshCaCertTemplates } from "@app/hooks/api";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { SshCertTemplateStatus, useGetSshCaCertTemplates } from "@app/hooks/api";
|
||||
import { caStatusToNameMap, getCaStatusBadgeVariant } from "@app/hooks/api/ca/constants";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
@@ -89,9 +89,9 @@ export const SshCertificateTemplatesTable = ({ handlePopUpOpen, sshCaId }: Props
|
||||
</div>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start" className="p-1">
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.SshCertificateTemplates}
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={ProjectPermissionSub.SshCertificateTemplates}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
@@ -118,10 +118,10 @@ export const SshCertificateTemplatesTable = ({ handlePopUpOpen, sshCaId }: Props
|
||||
} Template`}
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.SshCertificateTemplates}
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={ProjectPermissionSub.SshCertificateTemplates}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() => {
|
||||
@@ -136,10 +136,10 @@ export const SshCertificateTemplatesTable = ({ handlePopUpOpen, sshCaId }: Props
|
||||
>
|
||||
Issue Certificate
|
||||
</DropdownMenuItem>
|
||||
</OrgPermissionCan>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.SshCertificateTemplates}
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={ProjectPermissionSub.SshCertificateTemplates}
|
||||
>
|
||||
<DropdownMenuItem
|
||||
onClick={() =>
|
||||
@@ -151,10 +151,10 @@ export const SshCertificateTemplatesTable = ({ handlePopUpOpen, sshCaId }: Props
|
||||
>
|
||||
Edit Template
|
||||
</DropdownMenuItem>
|
||||
</OrgPermissionCan>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Delete}
|
||||
a={OrgPermissionSubjects.SshCertificateTemplates}
|
||||
</ProjectPermissionCan>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={ProjectPermissionSub.SshCertificateTemplates}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
@@ -173,7 +173,7 @@ export const SshCertificateTemplatesTable = ({ handlePopUpOpen, sshCaId }: Props
|
||||
Delete Template
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</Td>
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
import { Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { withPermission } from "@app/hoc";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { withProjectPermission } from "@app/hoc";
|
||||
|
||||
import { SshCaSection, SshCertificatesSection } from "./components";
|
||||
|
||||
@@ -11,7 +11,7 @@ enum TabSections {
|
||||
SshCertificates = "ssh-certificates"
|
||||
}
|
||||
|
||||
export const SshPage = withPermission(
|
||||
export const SshPage = withProjectPermission(
|
||||
() => {
|
||||
return (
|
||||
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
||||
@@ -49,5 +49,5 @@ export const SshPage = withPermission(
|
||||
</div>
|
||||
);
|
||||
},
|
||||
{ action: OrgPermissionActions.Read, subject: OrgPermissionSubjects.SshCertificateAuthorities }
|
||||
{ action: ProjectPermissionActions.Read, subject: ProjectPermissionSub.SshCertificateAuthorities }
|
||||
);
|
||||
+6
@@ -13,6 +13,7 @@ import {
|
||||
Select,
|
||||
SelectItem
|
||||
} from "@app/components/v2";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useCreateSshCa, useGetSshCaById, useUpdateSshCa } from "@app/hooks/api";
|
||||
import { certKeyAlgorithms } from "@app/hooks/api/certificates/constants";
|
||||
import { CertKeyAlgorithm } from "@app/hooks/api/certificates/enums";
|
||||
@@ -38,6 +39,8 @@ const schema = z
|
||||
export type FormData = z.infer<typeof schema>;
|
||||
|
||||
export const SshCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const projectId = currentWorkspace?.id || "";
|
||||
const { data: ca } = useGetSshCaById((popUp?.sshCa?.data as { caId: string })?.caId || "");
|
||||
|
||||
const { mutateAsync: createMutateAsync } = useCreateSshCa();
|
||||
@@ -72,6 +75,8 @@ export const SshCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
|
||||
const onFormSubmit = async ({ friendlyName, keyAlgorithm }: FormData) => {
|
||||
try {
|
||||
if (!projectId) return;
|
||||
|
||||
if (ca) {
|
||||
await updateMutateAsync({
|
||||
caId: ca.id,
|
||||
@@ -79,6 +84,7 @@ export const SshCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||
});
|
||||
} else {
|
||||
await createMutateAsync({
|
||||
projectId,
|
||||
friendlyName,
|
||||
keyAlgorithm
|
||||
});
|
||||
+6
-6
@@ -2,9 +2,9 @@ import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button, DeleteActionModal } from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { SshCaStatus, useDeleteSshCa, useUpdateSshCa } from "@app/hooks/api";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
|
||||
@@ -64,9 +64,9 @@ export const SshCaSection = () => {
|
||||
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex justify-between">
|
||||
<p className="text-xl font-semibold text-mineshaft-100">Certificate Authorities</p>
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Create}
|
||||
a={OrgPermissionSubjects.SshCertificateAuthorities}
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={ProjectPermissionSub.SshCertificateAuthorities}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
@@ -79,7 +79,7 @@ export const SshCaSection = () => {
|
||||
Create SSH CA
|
||||
</Button>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
</div>
|
||||
<SshCaTable handlePopUpOpen={handlePopUpOpen} />
|
||||
<SshCaModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
||||
+14
-16
@@ -3,7 +3,7 @@ import { faBan, faCertificate, faEllipsis, faTrash } from "@fortawesome/free-sol
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import {
|
||||
Badge,
|
||||
DropdownMenu,
|
||||
@@ -21,8 +21,8 @@ import {
|
||||
Tooltip,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
|
||||
import { SshCaStatus , useListOrgSshCas } from "@app/hooks/api";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub,useWorkspace } from "@app/context";
|
||||
import { SshCaStatus, useListWorkspaceSshCas } from "@app/hooks/api";
|
||||
import { caStatusToNameMap, getCaStatusBadgeVariant } from "@app/hooks/api/ca/constants";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
@@ -35,10 +35,8 @@ type Props = {
|
||||
|
||||
export const SshCaTable = ({ handlePopUpOpen }: Props) => {
|
||||
const router = useRouter();
|
||||
const { currentOrg } = useOrganization();
|
||||
const { data, isLoading } = useListOrgSshCas({
|
||||
orgId: currentOrg?.id ?? ""
|
||||
});
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const { data, isLoading } = useListWorkspaceSshCas(currentWorkspace?.id || "");
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -61,7 +59,7 @@ export const SshCaTable = ({ handlePopUpOpen }: Props) => {
|
||||
<Tr
|
||||
className="h-10 cursor-pointer transition-colors duration-100 hover:bg-mineshaft-700"
|
||||
key={`ca-${ca.id}`}
|
||||
onClick={() => router.push(`/org/${currentOrg?.id}/ssh/ca/${ca.id}`)}
|
||||
onClick={() => router.push(`/project/${currentWorkspace?.id}/ssh/ca/${ca.id}`)}
|
||||
>
|
||||
<Td>{ca.friendlyName}</Td>
|
||||
<Td>
|
||||
@@ -81,9 +79,9 @@ export const SshCaTable = ({ handlePopUpOpen }: Props) => {
|
||||
<DropdownMenuContent align="start" className="p-1">
|
||||
{(ca.status === SshCaStatus.ACTIVE ||
|
||||
ca.status === SshCaStatus.DISABLED) && (
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Edit}
|
||||
a={OrgPermissionSubjects.SshCertificateAuthorities}
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Edit}
|
||||
a={ProjectPermissionSub.SshCertificateAuthorities}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
@@ -109,11 +107,11 @@ export const SshCaTable = ({ handlePopUpOpen }: Props) => {
|
||||
} SSH CA`}
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
)}
|
||||
<OrgPermissionCan
|
||||
I={OrgPermissionActions.Delete}
|
||||
a={OrgPermissionSubjects.SshCertificateAuthorities}
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Delete}
|
||||
a={ProjectPermissionSub.SshCertificateAuthorities}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<DropdownMenuItem
|
||||
@@ -132,7 +130,7 @@ export const SshCaTable = ({ handlePopUpOpen }: Props) => {
|
||||
Delete SSH CA
|
||||
</DropdownMenuItem>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</Td>
|
||||
+7
-4
@@ -1,9 +1,9 @@
|
||||
import { faPlus } from "@fortawesome/free-solid-svg-icons";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { OrgPermissionCan } from "@app/components/permissions";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button } from "@app/components/v2";
|
||||
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
|
||||
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
|
||||
import { usePopUp } from "@app/hooks/usePopUp";
|
||||
|
||||
import { SshCertificateModal } from "../../SshCaPage/components/SshCertificateModal";
|
||||
@@ -15,7 +15,10 @@ export const SshCertificatesSection = () => {
|
||||
<div className="rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
|
||||
<div className="mb-4 flex justify-between">
|
||||
<p className="text-xl font-semibold text-mineshaft-100">Certificates</p>
|
||||
<OrgPermissionCan I={OrgPermissionActions.Create} a={OrgPermissionSubjects.SshCertificates}>
|
||||
<ProjectPermissionCan
|
||||
I={ProjectPermissionActions.Create}
|
||||
a={ProjectPermissionSub.SshCertificates}
|
||||
>
|
||||
{(isAllowed) => (
|
||||
<Button
|
||||
colorSchema="primary"
|
||||
@@ -27,7 +30,7 @@ export const SshCertificatesSection = () => {
|
||||
Request
|
||||
</Button>
|
||||
)}
|
||||
</OrgPermissionCan>
|
||||
</ProjectPermissionCan>
|
||||
</div>
|
||||
<SshCertificatesTable />
|
||||
<SshCertificateModal popUp={popUp} handlePopUpToggle={handlePopUpToggle} />
|
||||
+5
-5
@@ -15,20 +15,20 @@ import {
|
||||
THead,
|
||||
Tr
|
||||
} from "@app/components/v2";
|
||||
import { useOrganization } from "@app/context";
|
||||
import { useListOrgSshCertificates } from "@app/hooks/api";
|
||||
import { useWorkspace } from "@app/context";
|
||||
import { useListWorkspaceSshCertificates } from "@app/hooks/api";
|
||||
|
||||
import { getSshCertStatusBadgeDetails } from "./SshCertificatesTable.utils";
|
||||
|
||||
const PER_PAGE_INIT = 25;
|
||||
|
||||
export const SshCertificatesTable = () => {
|
||||
const { currentOrg } = useOrganization();
|
||||
const { currentWorkspace } = useWorkspace();
|
||||
const [page, setPage] = useState(1);
|
||||
const [perPage, setPerPage] = useState(PER_PAGE_INIT);
|
||||
|
||||
const { data, isLoading } = useListOrgSshCertificates({
|
||||
orgId: currentOrg?.id ?? "",
|
||||
const { data, isLoading } = useListWorkspaceSshCertificates({
|
||||
projectId: currentWorkspace?.id || "",
|
||||
offset: (page - 1) * perPage,
|
||||
limit: perPage
|
||||
});
|
||||
Reference in New Issue
Block a user