This commit is contained in:
Fang-Pen Lin
2025-11-07 09:18:33 -08:00
parent dd5bd35ad4
commit ea4b36b0ae
4 changed files with 32 additions and 15 deletions
@@ -26,7 +26,7 @@ export const pkiAcmeAccountDALFactory = (db: TDbClient) => {
} }
}; };
const findById = async (profileId: string, id: string, tx?: Knex) => { const findByProjectIdAndAccountId = async (profileId: string, id: string, tx?: Knex) => {
try { try {
const account = await (tx || db)(TableName.PkiAcmeAccount).where({ profileId, id }).first(); const account = await (tx || db)(TableName.PkiAcmeAccount).where({ profileId, id }).first();
@@ -49,7 +49,7 @@ export const pkiAcmeAccountDALFactory = (db: TDbClient) => {
return { return {
...pkiAcmeAccountOrm, ...pkiAcmeAccountOrm,
create, create,
findById, findByProjectIdAndAccountId,
findByPublicKey findByPublicKey
}; };
}; };
@@ -114,6 +114,8 @@ export const DeactivateAcmeAccountResponseSchema = z.object({
}); });
// List Orders endpoint // List Orders endpoint
export const ListAcmeOrdersPayloadSchema = z.object({}).strict();
export const ListAcmeOrdersResponseSchema = z.object({ export const ListAcmeOrdersResponseSchema = z.object({
orders: z.array(z.string()) orders: z.array(z.string())
}); });
@@ -53,7 +53,7 @@ import {
type TPkiAcmeServiceFactoryDep = { type TPkiAcmeServiceFactoryDep = {
certificateProfileDAL: Pick<TCertificateProfileDALFactory, "findById">; certificateProfileDAL: Pick<TCertificateProfileDALFactory, "findById">;
acmeAccountDAL: Pick<TPkiAcmeAccountDALFactory, "findById" | "findByPublicKey" | "create">; acmeAccountDAL: Pick<TPkiAcmeAccountDALFactory, "findByProjectIdAndAccountId" | "findByPublicKey" | "create">;
acmeOrderDAL: Pick<TPkiAcmeOrderDALFactory, "create" | "transaction">; acmeOrderDAL: Pick<TPkiAcmeOrderDALFactory, "create" | "transaction">;
acmeAuthDAL: Pick<TPkiAcmeAuthDALFactory, "create">; acmeAuthDAL: Pick<TPkiAcmeAuthDALFactory, "create">;
acmeOrderAuthDAL: Pick<TPkiAcmeOrderAuthDALFactory, "insertMany">; acmeOrderAuthDAL: Pick<TPkiAcmeOrderAuthDALFactory, "insertMany">;
@@ -150,11 +150,17 @@ export const pkiAcmeServiceFactory = ({
); );
}; };
const validateExistingAccountJwsPayload = async <T>( const validateExistingAccountJwsPayload = async <T>({
profileId: string, profileId,
rawJwsPayload: TRawJwsPayload, rawJwsPayload,
schema: z.ZodSchema<T> schema,
): Promise<TAuthenciatedJwsPayload<T>> => { expectedAccountId
}: {
profileId: string;
rawJwsPayload: TRawJwsPayload;
schema: z.ZodSchema<T>;
expectedAccountId?: string;
}): Promise<TAuthenciatedJwsPayload<T>> => {
const profile = await validateAcmeProfile(profileId); const profile = await validateAcmeProfile(profileId);
const result = await validateJwsPayload( const result = await validateJwsPayload(
rawJwsPayload, rawJwsPayload,
@@ -163,7 +169,10 @@ export const pkiAcmeServiceFactory = ({
throw new AcmeMalformedError({ detail: "KID is required in the protected header" }); throw new AcmeMalformedError({ detail: "KID is required in the protected header" });
} }
const accountId = extractAccountIdFromKid(protectedHeader.kid, profileId); const accountId = extractAccountIdFromKid(protectedHeader.kid, profileId);
const account = await acmeAccountDAL.findById(profile.id, accountId); if (expectedAccountId && accountId !== expectedAccountId) {
throw new AcmeAccountDoesNotExistError({ message: "ACME account ID mismatch" });
}
const account = await acmeAccountDAL.findByProjectIdAndAccountId(profile.id, accountId);
if (!account) { if (!account) {
throw new AcmeAccountDoesNotExistError({ message: "ACME account not found" }); throw new AcmeAccountDoesNotExistError({ message: "ACME account not found" });
} }
@@ -261,7 +270,7 @@ export const pkiAcmeServiceFactory = ({
// if we do, return the existing order // if we do, return the existing order
const order = await acmeOrderDAL.transaction(async (tx) => { const order = await acmeOrderDAL.transaction(async (tx) => {
const account = await acmeAccountDAL.findById(profileId, accountId)!; const account = await acmeAccountDAL.findByProjectIdAndAccountId(profileId, accountId)!;
const createdOrder = await acmeOrderDAL.create( const createdOrder = await acmeOrderDAL.create(
{ {
accountId: account.id, accountId: account.id,
@@ -58,11 +58,17 @@ export type TPkiAcmeServiceFactory = {
schema: z.ZodSchema<T> schema: z.ZodSchema<T>
) => Promise<TJwsPayload<T>>; ) => Promise<TJwsPayload<T>>;
validateNewAccountJwsPayload: (rawJwsPayload: TRawJwsPayload) => Promise<TJwsPayload<TCreateAcmeAccountPayload>>; validateNewAccountJwsPayload: (rawJwsPayload: TRawJwsPayload) => Promise<TJwsPayload<TCreateAcmeAccountPayload>>;
validateExistingAccountJwsPayload: <T>( validateExistingAccountJwsPayload: <T>({
profileId: string, profileId,
rawJwsPayload: TRawJwsPayload, rawJwsPayload,
schema: z.ZodSchema<T> schema,
) => Promise<TAuthenciatedJwsPayload<T>>; expectedAccountId
}: {
profileId: string;
rawJwsPayload: TRawJwsPayload;
schema: z.ZodSchema<T>;
expectedAccountId?: string;
}) => Promise<TAuthenciatedJwsPayload<T>>;
getAcmeDirectory: (profileId: string) => Promise<TGetAcmeDirectoryResponse>; getAcmeDirectory: (profileId: string) => Promise<TGetAcmeDirectoryResponse>;
getAcmeNewNonce: (profileId: string) => Promise<string>; getAcmeNewNonce: (profileId: string) => Promise<string>;
createAcmeAccount: ({ createAcmeAccount: ({