Add acme order table

This commit is contained in:
Fang-Pen Lin
2025-10-29 16:13:51 -07:00
parent d880c4c6c9
commit 76505939f3
8 changed files with 96 additions and 3 deletions

View File

@@ -728,6 +728,11 @@ declare module "knex/types/tables" {
TPkiAcmeOrdersUpdate
>;
[TableName.PkiAcmeAuth]: KnexOriginal.CompositeTableType<TPkiAcmeAuths, TPkiAcmeAuthsInsert, TPkiAcmeAuthsUpdate>;
[TableName.PkiAcmeOrderAuth]: KnexOriginal.CompositeTableType<
TPkiAcmeOrderAuths,
TPkiAcmeOrderAuthsInsert,
TPkiAcmeOrderAuthsUpdate
>;
[TableName.PkiAcmeChallenge]: KnexOriginal.CompositeTableType<
TPkiAcmeChallenges,
TPkiAcmeChallengesInsert,

View File

@@ -116,6 +116,25 @@ export async function up(knex: Knex): Promise<void> {
await createOnUpdateTrigger(knex, TableName.PkiAcmeAuth);
}
// Create PkiAcmeOrderAuth table
if (!(await knex.schema.hasTable(TableName.PkiAcmeOrderAuth))) {
await knex.schema.createTable(TableName.PkiAcmeOrderAuth, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
// Foreign key to PkiAcmeOrder
t.uuid("orderId").notNullable();
t.foreign("orderId").references("id").inTable(TableName.PkiAcmeOrder).onDelete("CASCADE");
// Foreign key to PkiAcmeAuth
t.uuid("authId").notNullable();
t.foreign("authId").references("id").inTable(TableName.PkiAcmeAuth).onDelete("CASCADE");
t.timestamps(true, true, true);
});
await createOnUpdateTrigger(knex, TableName.PkiAcmeOrderAuth);
}
// Create PkiAcmeChallenge table
if (!(await knex.schema.hasTable(TableName.PkiAcmeChallenge))) {
await knex.schema.createTable(TableName.PkiAcmeChallenge, (t) => {
@@ -150,6 +169,12 @@ export async function down(knex: Knex): Promise<void> {
await dropOnUpdateTrigger(knex, TableName.PkiAcmeChallenge);
}
// Drop PkiAcmeOrderAuth (depends on PkiAcmeOrder and PkiAcmeAuth)
if (await knex.schema.hasTable(TableName.PkiAcmeOrderAuth)) {
await knex.schema.dropTable(TableName.PkiAcmeOrderAuth);
await dropOnUpdateTrigger(knex, TableName.PkiAcmeOrderAuth);
}
// Drop PkiAcmeAuth (depends on PkiAcmeAccount and Certificate)
if (await knex.schema.hasTable(TableName.PkiAcmeAuth)) {
await knex.schema.dropTable(TableName.PkiAcmeAuth);

View File

@@ -97,6 +97,7 @@ export * from "./pki-acme-auths";
export * from "./pki-acme-challenges";
export * from "./pki-acme-enrollment-configs";
export * from "./pki-acme-orders";
export * from "./pki-acme-order-auths";
export * from "./pki-alerts";
export * from "./pki-api-enrollment-configs";
export * from "./pki-certificate-profiles";

View File

@@ -30,6 +30,7 @@ export enum TableName {
PkiAcmeEnrollmentConfig = "pki_acme_enrollment_configs",
PkiAcmeAccount = "pki_acme_accounts",
PkiAcmeOrder = "pki_acme_orders",
PkiAcmeOrderAuth = "pki_acme_order_auths",
PkiAcmeAuth = "pki_acme_auths",
PkiAcmeChallenge = "pki_acme_challenges",
PkiSubscriber = "pki_subscribers",

View File

@@ -0,0 +1,20 @@
// Code generated by automation script, DO NOT EDIT.
// Automated by pulling database and generating zod schema
// To update. Just run npm run generate:schema
// Written by akhilmhdh.
import { z } from "zod";
import { TImmutableDBKeys } from "./models";
export const PkiAcmeOrderAuthsSchema = z.object({
id: z.string().uuid(),
orderId: z.string().uuid(),
authId: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date()
});
export type TPkiAcmeOrderAuths = z.infer<typeof PkiAcmeOrderAuthsSchema>;
export type TPkiAcmeOrderAuthsInsert = Omit<z.input<typeof PkiAcmeOrderAuthsSchema>, TImmutableDBKeys>;
export type TPkiAcmeOrderAuthsUpdate = Partial<Omit<z.input<typeof PkiAcmeOrderAuthsSchema>, TImmutableDBKeys>>;

View File

@@ -0,0 +1,27 @@
import { Knex } from "knex";
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { TPkiAcmeOrderAuthsInsert } from "@app/db/schemas/pki-acme-order-auths";
import { DatabaseError } from "@app/lib/errors";
import { ormify } from "@app/lib/knex";
export type TPkiAcmeOrderAuthDALFactory = ReturnType<typeof pkiAcmeOrderAuthDALFactory>;
export const pkiAcmeOrderAuthDALFactory = (db: TDbClient) => {
const pkiAcmeOrderAuthOrm = ormify(db, TableName.PkiAcmeOrderAuth);
const insertMany = async (rows: TPkiAcmeOrderAuthsInsert[], tx?: Knex) => {
try {
const result = await (tx || db)(TableName.PkiAcmeOrderAuth).insert(rows).returning("*");
return result;
} catch (error) {
throw new DatabaseError({ error, name: "Insert many PKI ACME order auths" });
}
};
return {
...pkiAcmeOrderAuthOrm,
insertMany
};
};

View File

@@ -11,6 +11,7 @@ import {
} from "./pki-acme-errors";
import { TPkiAcmeAccounts } from "@app/db/schemas/pki-acme-accounts";
import { TPkiAcmeAuths } from "@app/db/schemas/pki-acme-auths";
import { logger } from "@app/lib/logger";
import {
EnrollmentType,
@@ -21,6 +22,7 @@ import { z, ZodError } from "zod";
import { TPkiAcmeAccountDALFactory } from "./pki-acme-account-dal";
import { TPkiAcmeAuthDALFactory } from "./pki-acme-auth-dal";
import { TPkiAcmeOrderDALFactory } from "./pki-acme-order-dal";
import { TPkiAcmeOrderAuthDALFactory } from "./pki-acme-order-auth-dal";
import {
AcmeAuthStatus,
AcmeIdentifierType,
@@ -54,13 +56,15 @@ type TPkiAcmeServiceFactoryDep = {
acmeAccountDAL: Pick<TPkiAcmeAccountDALFactory, "findById" | "findByPublicKey" | "create">;
acmeOrderDAL: Pick<TPkiAcmeOrderDALFactory, "create">;
acmeAuthDAL: Pick<TPkiAcmeAuthDALFactory, "create">;
acmeOrderAuthDAL: Pick<TPkiAcmeOrderAuthDALFactory, "insertMany">;
};
export const pkiAcmeServiceFactory = ({
certificateProfileDAL,
acmeAccountDAL,
acmeOrderDAL,
acmeAuthDAL
acmeAuthDAL,
acmeOrderAuthDAL
}: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
const validateAcmeProfile = async (profileId: string): Promise<TCertificateProfileWithConfigs> => {
const profile = await certificateProfileDAL.findById(profileId);
@@ -260,7 +264,7 @@ export const pkiAcmeServiceFactory = ({
accountId: account.id,
status: AcmeOrderStatus.Pending
});
const authorizations = await Promise.all(
const authorizations: TPkiAcmeAuths[] = await Promise.all(
payload.identifiers.map(async (identifier) => {
if (identifier.type === AcmeIdentifierType.DNS) {
// TODO: reuse existing authorizations for this identifier if they exist
@@ -278,6 +282,13 @@ export const pkiAcmeServiceFactory = ({
})
);
await acmeOrderAuthDAL.insertMany(
authorizations.map((auth) => ({
orderId: order.id,
authId: auth.id
}))
);
// FIXME: Implement ACME new order creation
const orderId = "FIXME-order-id";
return {

View File

@@ -76,6 +76,7 @@ import { permissionServiceFactory } from "@app/ee/services/permission/permission
import { pitServiceFactory } from "@app/ee/services/pit/pit-service";
import { pkiAcmeAuthDALFactory } from "@app/ee/services/pki-acme/pki-acme-auth-dal";
import { pkiAcmeServiceFactory } from "@app/ee/services/pki-acme/pki-acme-service";
import { pkiAcmeOrderAuthDALFactory } from "@app/ee/services/pki-acme/pki-acme-order-auth-dal";
import { projectTemplateDALFactory } from "@app/ee/services/project-template/project-template-dal";
import { projectTemplateServiceFactory } from "@app/ee/services/project-template/project-template-service";
import { rateLimitDALFactory } from "@app/ee/services/rate-limit/rate-limit-dal";
@@ -1070,6 +1071,7 @@ export const registerRoutes = async (
const acmeAccountDAL = pkiAcmeAccountDALFactory(db);
const acmeOrderDAL = pkiAcmeOrderDALFactory(db);
const acmeAuthDAL = pkiAcmeAuthDALFactory(db);
const acmeOrderAuthDAL = pkiAcmeOrderAuthDALFactory(db);
const certificateDAL = certificateDALFactory(db);
const certificateBodyDAL = certificateBodyDALFactory(db);
const certificateSecretDAL = certificateSecretDALFactory(db);
@@ -1174,7 +1176,8 @@ export const registerRoutes = async (
certificateProfileDAL,
acmeAccountDAL,
acmeOrderDAL,
acmeAuthDAL
acmeAuthDAL,
acmeOrderAuthDAL
});
const pkiAlertService = pkiAlertServiceFactory({