Add challenge

This commit is contained in:
Fang-Pen Lin
2025-11-07 09:19:06 -08:00
parent b50d7157b9
commit 7b15dee2e6
5 changed files with 47 additions and 20 deletions
@@ -0,0 +1,13 @@
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { ormify } from "@app/lib/knex";
export type TPkiAcmeChallengeDALFactory = ReturnType<typeof pkiAcmeChallengeDALFactory>;
export const pkiAcmeChallengeDALFactory = (db: TDbClient) => {
const pkiAcmeChallengeOrm = ormify(db, TableName.PkiAcmeChallenge);
return {
...pkiAcmeChallengeOrm
};
};
@@ -21,6 +21,12 @@ export enum AcmeAuthStatus {
Revoked = "revoked"
}
export enum AcmeChallengeType {
HTTP_01 = "http-01",
DNS_01 = "dns-01",
TLS_ALPN_01 = "tls-alpn-01"
}
export const ProtectedHeaderSchema = z
.object({
alg: z.string(),
@@ -136,7 +142,7 @@ export const GetAcmeAuthorizationResponseSchema = z.object({
}),
challenges: z.array(
z.object({
type: z.string(),
type: z.enum(Object.values(AcmeChallengeType) as [string, ...string[]]),
url: z.string(),
status: z.string(),
token: z.string(),
@@ -146,7 +152,7 @@ export const GetAcmeAuthorizationResponseSchema = z.object({
});
export const RespondToAcmeChallengeResponseSchema = z.object({
type: z.string(),
type: z.enum(Object.values(AcmeChallengeType) as [string, ...string[]]),
url: z.string(),
status: z.string(),
token: z.string(),
@@ -15,6 +15,7 @@ import { errors, flattenedVerify, FlattenedVerifyResult, importJWK, JWSHeaderPar
import { z, ZodError } from "zod";
import { TPkiAcmeAccountDALFactory } from "./pki-acme-account-dal";
import { TPkiAcmeAuthDALFactory } from "./pki-acme-auth-dal";
import { TPkiAcmeChallengeDALFactory } from "./pki-acme-challenge-dal";
import {
AcmeAccountDoesNotExistError,
AcmeBadPublicKeyError,
@@ -28,6 +29,7 @@ import { TPkiAcmeOrderAuthDALFactory } from "./pki-acme-order-auth-dal";
import { TPkiAcmeOrderDALFactory } from "./pki-acme-order-dal";
import {
AcmeAuthStatus,
AcmeChallengeType,
AcmeIdentifierType,
AcmeOrderStatus,
CreateAcmeAccountBodySchema,
@@ -58,6 +60,7 @@ type TPkiAcmeServiceFactoryDep = {
acmeOrderDAL: Pick<TPkiAcmeOrderDALFactory, "create" | "transaction" | "findByAccountAndOrderIdWithAuthorizations">;
acmeAuthDAL: Pick<TPkiAcmeAuthDALFactory, "create" | "findByAccountIdAndAuthIdWithChallenges">;
acmeOrderAuthDAL: Pick<TPkiAcmeOrderAuthDALFactory, "insertMany">;
acmeChallengeDAL: Pick<TPkiAcmeChallengeDALFactory, "create">;
};
export const pkiAcmeServiceFactory = ({
@@ -65,7 +68,8 @@ export const pkiAcmeServiceFactory = ({
acmeAccountDAL,
acmeOrderDAL,
acmeAuthDAL,
acmeOrderAuthDAL
acmeOrderAuthDAL,
acmeChallengeDAL
}: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
const validateAcmeProfile = async (profileId: string): Promise<TCertificateProfileWithConfigs> => {
const profile = await certificateProfileDAL.findById(profileId);
@@ -376,7 +380,7 @@ export const pkiAcmeServiceFactory = ({
payload.identifiers.map(async (identifier) => {
if (identifier.type === AcmeIdentifierType.DNS) {
// TODO: reuse existing authorizations for this identifier if they exist
return await acmeAuthDAL.create(
const auth = await acmeAuthDAL.create(
{
accountId: account.id,
status: AcmeAuthStatus.Pending,
@@ -391,6 +395,15 @@ export const pkiAcmeServiceFactory = ({
},
tx
);
// TODO: support other challenge types here. Currently only HTTP-01 is supported.
await acmeChallengeDAL.create(
{
authId: auth.id,
type: AcmeChallengeType.HTTP_01
},
tx
);
return auth;
} else {
throw new AcmeUnsupportedIdentifierError({ detail: "Only DNS identifiers are supported" });
}