This commit is contained in:
Fang-Pen Lin
2025-11-07 09:20:17 -08:00
parent 393fa01570
commit 59ce408ec1
4 changed files with 46 additions and 5 deletions
@@ -129,7 +129,8 @@ export enum ProjectPermissionCertificateProfileActions {
Create = "create", Create = "create",
Edit = "edit", Edit = "edit",
Delete = "delete", Delete = "delete",
IssueCert = "issue-cert" IssueCert = "issue-cert",
RevealAcmeEabSecret = "reveal-acme-eab-secret"
} }
export enum ProjectPermissionSecretRotationActions { export enum ProjectPermissionSecretRotationActions {
@@ -23,6 +23,8 @@ export const CertificateProfilesTab = () => {
const [isCreateModalOpen, setIsCreateModalOpen] = useState(false); const [isCreateModalOpen, setIsCreateModalOpen] = useState(false);
const [isEditModalOpen, setIsEditModalOpen] = useState(false); const [isEditModalOpen, setIsEditModalOpen] = useState(false);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [isRevealProfileAcmeEabSecretModalOpen, setIsRevealProfileAcmeEabSecretModalOpen] =
useState(false);
const [selectedProfile, setSelectedProfile] = useState<TCertificateProfileWithDetails | null>( const [selectedProfile, setSelectedProfile] = useState<TCertificateProfileWithDetails | null>(
null null
); );
@@ -43,6 +45,11 @@ export const CertificateProfilesTab = () => {
setIsEditModalOpen(true); setIsEditModalOpen(true);
}; };
const handleRevealProfileAcmeEabSecret = (profile: TCertificateProfileWithDetails) => {
setSelectedProfile(profile);
setIsRevealProfileAcmeEabSecretModalOpen(true);
};
const handleDeleteProfile = (profile: TCertificateProfileWithDetails) => { const handleDeleteProfile = (profile: TCertificateProfileWithDetails) => {
setSelectedProfile(profile); setSelectedProfile(profile);
setIsDeleteModalOpen(true); setIsDeleteModalOpen(true);
@@ -85,7 +92,11 @@ export const CertificateProfilesTab = () => {
)} )}
</div> </div>
<ProfileList onEditProfile={handleEditProfile} onDeleteProfile={handleDeleteProfile} /> <ProfileList
onEditProfile={handleEditProfile}
onRevealProfileAcmeEabSecret={handleRevealProfileAcmeEabSecret}
onDeleteProfile={handleDeleteProfile}
/>
<CreateProfileModal isOpen={isCreateModalOpen} onClose={() => setIsCreateModalOpen(false)} /> <CreateProfileModal isOpen={isCreateModalOpen} onClose={() => setIsCreateModalOpen(false)} />
@@ -20,9 +20,14 @@ import { ProfileRow } from "./ProfileRow";
interface Props { interface Props {
onEditProfile: (profile: TCertificateProfileWithDetails) => void; onEditProfile: (profile: TCertificateProfileWithDetails) => void;
onDeleteProfile: (profile: TCertificateProfileWithDetails) => void; onDeleteProfile: (profile: TCertificateProfileWithDetails) => void;
onRevealProfileAcmeEabSecret: (profile: TCertificateProfileWithDetails) => void;
} }
export const ProfileList = ({ onEditProfile, onDeleteProfile }: Props) => { export const ProfileList = ({
onEditProfile,
onRevealProfileAcmeEabSecret,
onDeleteProfile
}: Props) => {
const { currentProject } = useProject(); const { currentProject } = useProject();
const { data, isLoading } = useListCertificateProfiles({ const { data, isLoading } = useListCertificateProfiles({
@@ -88,6 +93,7 @@ export const ProfileList = ({ onEditProfile, onDeleteProfile }: Props) => {
key={profile.id} key={profile.id}
profile={profile} profile={profile}
onEditProfile={onEditProfile} onEditProfile={onEditProfile}
onRevealProfileAcmeEabSecret={onRevealProfileAcmeEabSecret}
onDeleteProfile={onDeleteProfile} onDeleteProfile={onDeleteProfile}
/> />
))} ))}
@@ -1,14 +1,15 @@
import { useCallback } from "react";
import { import {
faCheck, faCheck,
faCircleInfo, faCircleInfo,
faCopy, faCopy,
faEdit, faEdit,
faEllipsis, faEllipsis,
faEye,
faPlus, faPlus,
faTrash faTrash
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useCallback } from "react";
import { createNotification } from "@app/components/notifications"; import { createNotification } from "@app/components/notifications";
import { import {
@@ -36,10 +37,16 @@ import { CertificateIssuanceModal } from "@app/pages/cert-manager/CertificatesPa
interface Props { interface Props {
profile: TCertificateProfile; profile: TCertificateProfile;
onEditProfile: (profile: TCertificateProfile) => void; onEditProfile: (profile: TCertificateProfile) => void;
onRevealProfileAcmeEabSecret: (profile: TCertificateProfile) => void;
onDeleteProfile: (profile: TCertificateProfile) => void; onDeleteProfile: (profile: TCertificateProfile) => void;
} }
export const ProfileRow = ({ profile, onEditProfile, onDeleteProfile }: Props) => { export const ProfileRow = ({
profile,
onEditProfile,
onRevealProfileAcmeEabSecret,
onDeleteProfile
}: Props) => {
const { permission } = useProjectPermission(); const { permission } = useProjectPermission();
const { data: caData } = useGetCaById(profile.caId); const { data: caData } = useGetCaById(profile.caId);
@@ -69,6 +76,11 @@ export const ProfileRow = ({ profile, onEditProfile, onDeleteProfile }: Props) =
ProjectPermissionSub.CertificateAuthorities ProjectPermissionSub.CertificateAuthorities
); );
const canRevealProfileAcmeEabSecret = permission.can(
ProjectPermissionCertificateProfileActions.RevealAcmeEabSecret,
ProjectPermissionSub.CertificateProfiles
);
const canIssueCertificate = permission.can( const canIssueCertificate = permission.can(
ProjectPermissionCertificateProfileActions.IssueCert, ProjectPermissionCertificateProfileActions.IssueCert,
ProjectPermissionSub.CertificateProfiles ProjectPermissionSub.CertificateProfiles
@@ -144,6 +156,17 @@ export const ProfileRow = ({ profile, onEditProfile, onDeleteProfile }: Props) =
Edit Profile Edit Profile
</DropdownMenuItem> </DropdownMenuItem>
)} )}
{canRevealProfileAcmeEabSecret && profile.enrollmentType === "acme" && (
<DropdownMenuItem
onClick={(e) => {
e.stopPropagation();
onRevealProfileAcmeEabSecret(profile);
}}
icon={<FontAwesomeIcon icon={faEye} />}
>
Reveal ACME EAB Secret
</DropdownMenuItem>
)}
{canIssueCertificate && profile.enrollmentType === "api" && ( {canIssueCertificate && profile.enrollmentType === "api" && (
<DropdownMenuItem <DropdownMenuItem
onClick={(e) => { onClick={(e) => {