Acme stuff

This commit is contained in:
Fang-Pen Lin
2025-11-07 09:17:48 -08:00
parent a3c3ab10d1
commit 4875add711
4 changed files with 47 additions and 18 deletions
@@ -11,7 +11,7 @@ export const GetAcmeDirectoryResponseSchema = z.object({
newNonce: z.string(),
newAccount: z.string(),
newOrder: z.string(),
revokeCert: z.string()
revokeCert: z.string().optional()
});
// New Nonce endpoint
@@ -1,3 +1,4 @@
import { getConfig } from "@app/lib/config/env";
import { NotFoundError } from "@app/lib/errors";
import { TCertificateProfileDALFactory } from "@app/services/certificate-profile/certificate-profile-dal";
@@ -21,20 +22,24 @@ type TPkiAcmeServiceFactoryDep = {
};
export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
const appCfg = getConfig();
const getAcmeDirectory = async (profileId: string): Promise<TGetAcmeDirectoryResponse> => {
// FIXME: Implement ACME directory endpoint
// Validate profile exists and is for ACME enrollment
const profile = await certificateProfileDAL.findById(profileId);
if (!profile) {
throw new NotFoundError({ message: "Certificate profile not found" });
}
// const profile = await certificateProfileDAL.findById(profileId);
// if (!profile) {
// throw new NotFoundError({ message: "Certificate profile not found" });
// }
// FIXME: Validate profile is configured for ACME enrollment
// Return absolute URLs using SITE_URL
const baseUrl = appCfg.SITE_URL ?? "";
return {
newNonce: `/api/v1/pki/acme/profiles/${profileId}/new-nonce`,
newAccount: `/api/v1/pki/acme/profiles/${profileId}/new-account`,
newOrder: `/api/v1/pki/acme/profiles/${profileId}/new-order`,
revokeCert: `/api/v1/pki/acme/profiles/${profileId}/revoke-cert`
newNonce: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/new-nonce`,
newAccount: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/new-account`,
newOrder: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/new-order`
};
};
@@ -48,23 +53,26 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
// FIXME: Implement ACME new account registration
// Use EAB authentication to find corresponding Infisical machine identity
// Check permissions and return account information
const baseUrl = appCfg.SITE_URL || "";
const accountId = "FIXME-account-id";
return {
status: "valid",
accountUrl: `/api/v1/pki/acme/profiles/${profileId}/accounts/FIXME-account-id`,
accountUrl: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/accounts/${accountId}`,
contact: [],
orders: `/api/v1/pki/acme/profiles/${profileId}/accounts/FIXME-account-id/orders`
orders: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/accounts/${accountId}/orders`
};
};
const createAcmeOrder = async (profileId: string, body: unknown): Promise<TCreateAcmeOrderResponse> => {
// FIXME: Implement ACME new order creation
const orderId = "FIXME-order-id";
const baseUrl = appCfg.SITE_URL || "";
return {
status: "pending",
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
identifiers: [],
authorizations: [],
finalize: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
finalize: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
};
};
@@ -87,12 +95,13 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
const getAcmeOrder = async (profileId: string, orderId: string): Promise<TGetAcmeOrderResponse> => {
// FIXME: Implement ACME get order
const baseUrl = appCfg.SITE_URL || "";
return {
status: "pending",
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
identifiers: [],
authorizations: [],
finalize: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
finalize: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
};
};
@@ -102,13 +111,14 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
csr: string
): Promise<TFinalizeAcmeOrderResponse> => {
// FIXME: Implement ACME finalize order
const baseUrl = appCfg.SITE_URL || "";
return {
status: "processing",
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
identifiers: [],
authorizations: [],
finalize: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`,
certificate: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/certificate`
finalize: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`,
certificate: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/certificate`
};
};
@@ -120,6 +130,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
const getAcmeAuthorization = async (profileId: string, authzId: string): Promise<TGetAcmeAuthorizationResponse> => {
// FIXME: Implement ACME authorization retrieval
const baseUrl = appCfg.SITE_URL || "";
return {
status: "pending",
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
@@ -130,7 +141,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
challenges: [
{
type: "http-01",
url: `/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
url: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
status: "pending",
token: "FIXME-challenge-token"
}
@@ -144,9 +155,10 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
): Promise<TRespondToAcmeChallengeResponse> => {
// FIXME: Implement ACME challenge response
// Trigger verification process
const baseUrl = appCfg.SITE_URL || "";
return {
type: "http-01",
url: `/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
url: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
status: "pending",
token: "FIXME-challenge-token"
};