mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
misc: add indicators for errors
This commit is contained in:
@@ -88,6 +88,9 @@ export async function up(knex: Knex): Promise<void> {
|
||||
if (await knex.schema.hasTable(TableName.PkiSubscriber)) {
|
||||
await knex.schema.alterTable(TableName.PkiSubscriber, (t) => {
|
||||
t.string("ttl").nullable().alter();
|
||||
t.string("lastOperationStatus");
|
||||
t.text("lastOperationMessage");
|
||||
t.string("lastOperationAt");
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -164,4 +167,12 @@ export async function down(knex: Knex): Promise<void> {
|
||||
if (hasExternalCATable) {
|
||||
await knex.schema.dropTable(TableName.ExternalCertificateAuthority);
|
||||
}
|
||||
|
||||
if (await knex.schema.hasTable(TableName.PkiSubscriber)) {
|
||||
await knex.schema.alterTable(TableName.PkiSubscriber, (t) => {
|
||||
t.dropColumn("lastOperationStatus");
|
||||
t.dropColumn("lastOperationMessage");
|
||||
t.dropColumn("lastOperationAt");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,10 @@ export const PkiSubscribersSchema = z.object({
|
||||
ttl: z.string().nullable().optional(),
|
||||
keyUsages: z.string().array(),
|
||||
extendedKeyUsages: z.string().array(),
|
||||
status: z.string()
|
||||
status: z.string(),
|
||||
lastOperationStatus: z.string().nullable().optional(),
|
||||
lastOperationMessage: z.string().nullable().optional(),
|
||||
lastOperationAt: z.string().nullable().optional()
|
||||
});
|
||||
|
||||
export type TPkiSubscribers = z.infer<typeof PkiSubscribersSchema>;
|
||||
|
||||
@@ -180,7 +180,7 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
|
||||
ttl: z
|
||||
.string()
|
||||
.trim()
|
||||
.refine((val) => ms(val) > 0, "TTL must be a positive number")
|
||||
.refine((val) => !val || ms(val) > 0, "TTL must be a positive number")
|
||||
.optional()
|
||||
.describe(PKI_SUBSCRIBERS.UPDATE.ttl),
|
||||
keyUsages: z
|
||||
|
||||
@@ -86,8 +86,8 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
||||
serialNumber: result.internalSerialNumber,
|
||||
maxPathLength: result.internalMaxPathLength,
|
||||
keyAlgorithm: result.internalKeyAlgorithm,
|
||||
notBefore: result.internalNotBefore,
|
||||
notAfter: result.internalNotAfter,
|
||||
notBefore: result.internalNotBefore?.toISOString(),
|
||||
notAfter: result.internalNotAfter?.toISOString(),
|
||||
activeCaCertId: result.internalActiveCaCertId,
|
||||
certificateAuthorityId: result.internalCertificateAuthorityId
|
||||
}
|
||||
@@ -232,8 +232,8 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
||||
serialNumber: ca.internalSerialNumber,
|
||||
maxPathLength: ca.internalMaxPathLength,
|
||||
keyAlgorithm: ca.internalKeyAlgorithm,
|
||||
notBefore: ca.internalNotBefore,
|
||||
notAfter: ca.internalNotAfter,
|
||||
notBefore: ca.internalNotBefore?.toISOString(),
|
||||
notAfter: ca.internalNotAfter?.toISOString(),
|
||||
activeCaCertId: ca.internalActiveCaCertId,
|
||||
certificateAuthorityId: ca.internalCertificateAuthorityId
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import { TAppConnectionServiceFactory } from "../app-connection/app-connection-s
|
||||
import { TCertificateBodyDALFactory } from "../certificate/certificate-body-dal";
|
||||
import { TCertificateSecretDALFactory } from "../certificate/certificate-secret-dal";
|
||||
import { TPkiSubscriberDALFactory } from "../pki-subscriber/pki-subscriber-dal";
|
||||
import { SubscriberOperationStatus } from "../pki-subscriber/pki-subscriber-types";
|
||||
import { AcmeCertificateAuthorityFns } from "./acme/acme-certificate-authority-fns";
|
||||
import { TCertificateAuthorityDALFactory } from "./certificate-authority-dal";
|
||||
import { CaType } from "./certificate-authority-enums";
|
||||
@@ -47,7 +48,7 @@ type TCertificateAuthorityQueueFactoryDep = {
|
||||
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
|
||||
certificateSecretDAL: Pick<TCertificateSecretDALFactory, "create">;
|
||||
queueService: TQueueServiceFactory;
|
||||
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById">;
|
||||
pkiSubscriberDAL: Pick<TPkiSubscriberDALFactory, "findById" | "updateById">;
|
||||
};
|
||||
|
||||
export type TCertificateAuthorityQueueFactory = ReturnType<typeof certificateAuthorityQueueFactory>;
|
||||
@@ -152,8 +153,20 @@ export const certificateAuthorityQueueFactory = ({
|
||||
try {
|
||||
if (caType === CaType.ACME) {
|
||||
await acmeFns.orderSubscriberCertificate(subscriberId);
|
||||
await pkiSubscriberDAL.updateById(subscriberId, {
|
||||
lastOperationStatus: SubscriberOperationStatus.SUCCESS,
|
||||
lastOperationMessage: "Certificate ordered successfully",
|
||||
lastOperationAt: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
if (e instanceof Error) {
|
||||
await pkiSubscriberDAL.updateById(subscriberId, {
|
||||
lastOperationStatus: SubscriberOperationStatus.FAILED,
|
||||
lastOperationMessage: e.message,
|
||||
lastOperationAt: new Date().toISOString()
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
logger.error(e, `CaOrderCertificate Failed [subscriberId=${subscriberId}] [job=${job.name}]`);
|
||||
} finally {
|
||||
await lock.release();
|
||||
|
||||
@@ -18,7 +18,7 @@ const InternalCertificateAuthorityConfigurationSchema = z
|
||||
organization: z.string().trim(),
|
||||
ou: z.string().trim(),
|
||||
dn: z.string().trim(),
|
||||
parentCaId: z.string().uuid().optional(),
|
||||
parentCaId: z.string().uuid().nullish(),
|
||||
serialNumber: z.string().trim().optional(),
|
||||
activeCaCertId: z.string().uuid().optional(),
|
||||
country: z.string().trim(),
|
||||
|
||||
@@ -12,7 +12,10 @@ export const sanitizedPkiSubscriber = PkiSubscribersSchema.pick({
|
||||
subjectAlternativeNames: true,
|
||||
ttl: true,
|
||||
keyUsages: true,
|
||||
extendedKeyUsages: true
|
||||
extendedKeyUsages: true,
|
||||
lastOperationStatus: true,
|
||||
lastOperationMessage: true,
|
||||
lastOperationAt: true
|
||||
}).extend({
|
||||
supportsImmediateCertIssuance: z.boolean().optional()
|
||||
});
|
||||
|
||||
@@ -56,3 +56,8 @@ export type TListPkiSubscriberCertsDTO = {
|
||||
offset: number;
|
||||
limit: number;
|
||||
} & TProjectPermission;
|
||||
|
||||
export enum SubscriberOperationStatus {
|
||||
SUCCESS = "success",
|
||||
FAILED = "failed"
|
||||
}
|
||||
|
||||
@@ -39,13 +39,16 @@ export const pkiSubscriberKeys = {
|
||||
] as const
|
||||
};
|
||||
|
||||
export const useGetPkiSubscriber = ({
|
||||
subscriberName,
|
||||
projectId
|
||||
}: {
|
||||
subscriberName: string;
|
||||
projectId: string;
|
||||
}) => {
|
||||
export const useGetPkiSubscriber = (
|
||||
{
|
||||
subscriberName,
|
||||
projectId
|
||||
}: {
|
||||
subscriberName: string;
|
||||
projectId: string;
|
||||
},
|
||||
options?: TReactQueryOptions["options"]
|
||||
) => {
|
||||
return useQuery({
|
||||
queryKey: pkiSubscriberKeys.getPkiSubscriber({ subscriberName, projectId }),
|
||||
queryFn: async () => {
|
||||
@@ -59,7 +62,8 @@ export const useGetPkiSubscriber = ({
|
||||
);
|
||||
return pkiSubscriber;
|
||||
},
|
||||
enabled: Boolean(subscriberName) && Boolean(projectId)
|
||||
enabled: Boolean(subscriberName) && Boolean(projectId),
|
||||
...options
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -5,6 +5,11 @@ export enum PkiSubscriberStatus {
|
||||
DISABLED = "disabled"
|
||||
}
|
||||
|
||||
export enum SubscriberOperationStatus {
|
||||
SUCCESS = "success",
|
||||
FAILED = "failed"
|
||||
}
|
||||
|
||||
export type TPkiSubscriber = {
|
||||
id: string;
|
||||
projectId: string;
|
||||
@@ -17,6 +22,9 @@ export type TPkiSubscriber = {
|
||||
keyUsages: CertKeyUsage[];
|
||||
extendedKeyUsages: CertExtendedKeyUsage[];
|
||||
supportsImmediateCertIssuance?: boolean;
|
||||
lastOperationStatus?: SubscriberOperationStatus;
|
||||
lastOperationMessage?: string;
|
||||
lastOperationAt?: string;
|
||||
};
|
||||
|
||||
export type TCreatePkiSubscriberDTO = {
|
||||
|
||||
@@ -56,7 +56,7 @@ export const PkiSubscriberCertificatesTable = ({ subscriberName, handlePopUpOpen
|
||||
limit: perPage
|
||||
},
|
||||
{
|
||||
refetchInterval: 10 * 1000 // 10 seconds
|
||||
refetchInterval: 5000
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -5,7 +5,14 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
|
||||
import { createNotification } from "@app/components/notifications";
|
||||
import { ProjectPermissionCan } from "@app/components/permissions";
|
||||
import { Button, IconButton, Modal, ModalContent, Tooltip } from "@app/components/v2";
|
||||
import {
|
||||
Button,
|
||||
GenericFieldLabel,
|
||||
IconButton,
|
||||
Modal,
|
||||
ModalContent,
|
||||
Tooltip
|
||||
} from "@app/components/v2";
|
||||
import {
|
||||
ProjectPermissionPkiSubscriberActions,
|
||||
ProjectPermissionSub,
|
||||
@@ -19,6 +26,7 @@ import {
|
||||
useOrderPkiSubscriberCert
|
||||
} from "@app/hooks/api";
|
||||
import { pkiSubscriberStatusToNameMap } from "@app/hooks/api/pkiSubscriber/constants";
|
||||
import { SubscriberOperationStatus } from "@app/hooks/api/pkiSubscriber/types";
|
||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||
|
||||
import { CertificateContent } from "../../CertificatesPage/components/CertificateContent";
|
||||
@@ -45,10 +53,15 @@ export const PkiSubscriberDetailsSection = ({ subscriberName, handlePopUpOpen }:
|
||||
initialState: "Copy ID to clipboard"
|
||||
});
|
||||
|
||||
const { data: pkiSubscriber } = useGetPkiSubscriber({
|
||||
subscriberName,
|
||||
projectId
|
||||
});
|
||||
const { data: pkiSubscriber } = useGetPkiSubscriber(
|
||||
{
|
||||
subscriberName,
|
||||
projectId
|
||||
},
|
||||
{
|
||||
refetchInterval: 5000
|
||||
}
|
||||
);
|
||||
|
||||
const { mutateAsync: issuePkiSubscriberCert, isPending: isIssuingCert } =
|
||||
useIssuePkiSubscriberCert();
|
||||
@@ -163,9 +176,26 @@ export const PkiSubscriberDetailsSection = ({ subscriberName, handlePopUpOpen }:
|
||||
<p className="text-sm font-semibold text-mineshaft-300">Common Name</p>
|
||||
<p className="text-sm text-mineshaft-300">{pkiSubscriber.commonName}</p>
|
||||
</div>
|
||||
{pkiSubscriber.lastOperationAt && (
|
||||
<div className="mb-4">
|
||||
<p className="text-sm font-semibold text-mineshaft-300">Last Operation (Local Time)</p>
|
||||
<p className="text-sm text-mineshaft-300">
|
||||
{new Date(pkiSubscriber.lastOperationAt).toLocaleString()}
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
{pkiSubscriber.lastOperationStatus === SubscriberOperationStatus.FAILED && (
|
||||
<div className="mb-4">
|
||||
<GenericFieldLabel labelClassName="text-red" label="Last Operation Status">
|
||||
<p className="break-words rounded bg-mineshaft-600 p-2 text-xs">
|
||||
{pkiSubscriber.lastOperationMessage}
|
||||
</p>
|
||||
</GenericFieldLabel>
|
||||
</div>
|
||||
)}
|
||||
{canIssuePkiSubscriberCert && (
|
||||
<Button
|
||||
className="mt-4 w-full"
|
||||
className="mt-2 w-full"
|
||||
colorSchema="primary"
|
||||
type="button"
|
||||
isLoading={isIssuingCert}
|
||||
|
||||
Reference in New Issue
Block a user