Resolve PR issues

This commit is contained in:
Tuan Dang
2024-06-12 13:11:21 -07:00
parent 868d0345d6
commit f5322abe85
26 changed files with 244 additions and 243 deletions
+7 -7
View File
@@ -44,9 +44,9 @@ import {
TCertificateAuthoritySecret,
TCertificateAuthoritySecretInsert,
TCertificateAuthoritySecretUpdate,
TCertificateCerts,
TCertificateCertsInsert,
TCertificateCertsUpdate,
TCertificateBodies,
TCertificateBodiesInsert,
TCertificateBodiesUpdate,
TCertificates,
TCertificateSecrets,
TCertificateSecretsInsert,
@@ -299,10 +299,10 @@ declare module "knex/types/tables" {
TCertificateAuthorityCrlUpdate
>;
[TableName.Certificate]: Knex.CompositeTableType<TCertificates, TCertificatesInsert, TCertificatesUpdate>;
[TableName.CertificateCert]: Knex.CompositeTableType<
TCertificateCerts,
TCertificateCertsInsert,
TCertificateCertsUpdate
[TableName.CertificateBody]: Knex.CompositeTableType<
TCertificateBodies,
TCertificateBodiesInsert,
TCertificateBodiesUpdate
>;
[TableName.CertificateSecret]: Knex.CompositeTableType<
TCertificateSecrets,
@@ -24,6 +24,7 @@ export async function up(knex: Knex): Promise<void> {
t.foreign("projectId").references("id").inTable(TableName.Project).onDelete("CASCADE");
t.string("type").notNullable(); // root / intermediate
t.string("status").notNullable(); // active / pending-certificate
t.string("friendlyName").notNullable();
t.string("organization").notNullable();
t.string("ou").notNullable();
t.string("country").notNullable();
@@ -31,7 +32,6 @@ export async function up(knex: Knex): Promise<void> {
t.string("locality").notNullable();
t.string("commonName").notNullable();
t.string("dn").notNullable();
t.unique(["dn", "projectId"]);
t.string("serialNumber").nullable().unique();
t.integer("maxPathLength").nullable();
t.string("keyAlgorithm").notNullable();
@@ -80,6 +80,7 @@ export async function up(knex: Knex): Promise<void> {
t.foreign("caId").references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE");
t.string("status").notNullable(); // active / pending-certificate
t.string("serialNumber").notNullable().unique();
t.string("friendlyName").notNullable();
t.string("commonName").notNullable();
t.datetime("notBefore").notNullable();
t.datetime("notAfter").notNullable();
@@ -88,8 +89,8 @@ export async function up(knex: Knex): Promise<void> {
});
}
if (!(await knex.schema.hasTable(TableName.CertificateCert))) {
await knex.schema.createTable(TableName.CertificateCert, (t) => {
if (!(await knex.schema.hasTable(TableName.CertificateBody))) {
await knex.schema.createTable(TableName.CertificateBody, (t) => {
t.uuid("id", { primaryKey: true }).defaultTo(knex.fn.uuid());
t.timestamps(true, true, true);
t.uuid("certId").notNullable().unique();
@@ -102,7 +103,7 @@ export async function up(knex: Knex): Promise<void> {
await createOnUpdateTrigger(knex, TableName.CertificateAuthorityCert);
await createOnUpdateTrigger(knex, TableName.CertificateAuthoritySecret);
await createOnUpdateTrigger(knex, TableName.Certificate);
await createOnUpdateTrigger(knex, TableName.CertificateCert);
await createOnUpdateTrigger(knex, TableName.CertificateBody);
}
export async function down(knex: Knex): Promise<void> {
@@ -115,8 +116,8 @@ export async function down(knex: Knex): Promise<void> {
}
// certificates
await knex.schema.dropTableIfExists(TableName.CertificateCert);
await dropOnUpdateTrigger(knex, TableName.CertificateCert);
await knex.schema.dropTableIfExists(TableName.CertificateBody);
await dropOnUpdateTrigger(knex, TableName.CertificateBody);
await knex.schema.dropTableIfExists(TableName.Certificate);
await dropOnUpdateTrigger(knex, TableName.Certificate);
@@ -15,6 +15,7 @@ export const CertificateAuthoritiesSchema = z.object({
projectId: z.string(),
type: z.string(),
status: z.string(),
friendlyName: z.string(),
organization: z.string(),
ou: z.string(),
country: z.string(),
@@ -9,7 +9,7 @@ import { zodBuffer } from "@app/lib/zod";
import { TImmutableDBKeys } from "./models";
export const CertificateCertsSchema = z.object({
export const CertificateBodiesSchema = z.object({
id: z.string().uuid(),
createdAt: z.date(),
updatedAt: z.date(),
@@ -17,6 +17,6 @@ export const CertificateCertsSchema = z.object({
encryptedCertificate: zodBuffer
});
export type TCertificateCerts = z.infer<typeof CertificateCertsSchema>;
export type TCertificateCertsInsert = Omit<z.input<typeof CertificateCertsSchema>, TImmutableDBKeys>;
export type TCertificateCertsUpdate = Partial<Omit<z.input<typeof CertificateCertsSchema>, TImmutableDBKeys>>;
export type TCertificateBodies = z.infer<typeof CertificateBodiesSchema>;
export type TCertificateBodiesInsert = Omit<z.input<typeof CertificateBodiesSchema>, TImmutableDBKeys>;
export type TCertificateBodiesUpdate = Partial<Omit<z.input<typeof CertificateBodiesSchema>, TImmutableDBKeys>>;
+1
View File
@@ -14,6 +14,7 @@ export const CertificatesSchema = z.object({
caId: z.string().uuid(),
status: z.string(),
serialNumber: z.string(),
friendlyName: z.string(),
commonName: z.string(),
notBefore: z.date(),
notAfter: z.date(),
+1 -1
View File
@@ -12,7 +12,7 @@ export * from "./certificate-authorities";
export * from "./certificate-authority-certs";
export * from "./certificate-authority-crl";
export * from "./certificate-authority-secret";
export * from "./certificate-certs";
export * from "./certificate-bodies";
export * from "./certificate-secrets";
export * from "./certificates";
export * from "./dynamic-secret-leases";
+1 -1
View File
@@ -7,7 +7,7 @@ export enum TableName {
CertificateAuthoritySecret = "certificate_authority_secret",
CertificateAuthorityCrl = "certificate_authority_crl",
Certificate = "certificates",
CertificateCert = "certificate_certs",
CertificateBody = "certificate_bodies",
CertificateSecret = "certificate_secrets",
Groups = "groups",
GroupProjectMembership = "group_project_memberships",
+4 -4
View File
@@ -71,7 +71,7 @@ import { authPaswordServiceFactory } from "@app/services/auth/auth-password-serv
import { authSignupServiceFactory } from "@app/services/auth/auth-signup-service";
import { tokenDALFactory } from "@app/services/auth-token/auth-token-dal";
import { tokenServiceFactory } from "@app/services/auth-token/auth-token-service";
import { certificateCertDALFactory } from "@app/services/certificate/certificate-cert-dal";
import { certificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
import { certificateDALFactory } from "@app/services/certificate/certificate-dal";
import { certificateServiceFactory } from "@app/services/certificate/certificate-service";
import { certificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
@@ -521,11 +521,11 @@ export const registerRoutes = async (
const certificateAuthorityCrlDAL = certificateAuthorityCrlDALFactory(db);
const certificateDAL = certificateDALFactory(db);
const certificateCertDAL = certificateCertDALFactory(db);
const certificateBodyDAL = certificateBodyDALFactory(db);
const certificateService = certificateServiceFactory({
certificateDAL,
certificateCertDAL,
certificateBodyDAL,
certificateAuthorityDAL,
certificateAuthorityCertDAL,
certificateAuthorityCrlDAL,
@@ -552,7 +552,7 @@ export const registerRoutes = async (
certificateAuthorityCrlDAL,
certificateAuthorityQueue,
certificateDAL,
certificateCertDAL,
certificateBodyDAL,
projectDAL,
kmsService,
permissionService
@@ -1,3 +1,4 @@
import ms from "ms";
import { z } from "zod";
import { CertificateAuthoritiesSchema } from "@app/db/schemas";
@@ -21,7 +22,8 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
body: z
.object({
projectSlug: z.string().trim(),
type: z.enum([CaType.ROOT, CaType.INTERMEDIATE]),
type: z.nativeEnum(CaType),
friendlyName: z.string().optional(),
commonName: z.string().trim(),
organization: z.string().trim(),
ou: z.string().trim(),
@@ -32,14 +34,7 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
notBefore: validateCaDateField.optional(),
notAfter: validateCaDateField.optional(),
maxPathLength: z.number().min(-1).default(-1),
keyAlgorithm: z
.enum([
CertKeyAlgorithm.RSA_2048,
CertKeyAlgorithm.RSA_4096,
CertKeyAlgorithm.ECDSA_P256,
CertKeyAlgorithm.ECDSA_P384
])
.default(CertKeyAlgorithm.RSA_2048)
keyAlgorithm: z.nativeEnum(CertKeyAlgorithm).default(CertKeyAlgorithm.RSA_2048)
})
.refine(
(data) => {
@@ -342,8 +337,9 @@ export const registerCaRouter = async (server: FastifyZodProvider) => {
}),
body: z
.object({
friendlyName: z.string().optional(),
commonName: z.string().trim().min(1),
ttl: z.number().int().min(0).optional(),
ttl: z.string().refine((val) => ms(val) > 0, "TTL must be a positive number"),
notBefore: validateCaDateField.optional(),
notAfter: validateCaDateField.optional()
})
@@ -52,17 +52,7 @@ export const registerCertRouter = async (server: FastifyZodProvider) => {
serialNumber: z.string().trim()
}),
body: z.object({
revocationReason: z.enum([
CrlReason.UNSPECIFIED,
CrlReason.KEY_COMPROMISE,
CrlReason.CA_COMPROMISE,
CrlReason.AFFILIATION_CHANGED,
CrlReason.SUPERSEDED,
CrlReason.CESSATION_OF_OPERATION,
CrlReason.CERTIFICATE_HOLD,
CrlReason.PRIVILEGE_WITHDRAWN,
CrlReason.A_A_COMPROMISE
])
revocationReason: z.nativeEnum(CrlReason)
}),
response: {
200: z.object({
@@ -2,11 +2,12 @@
import { ForbiddenError } from "@casl/ability";
import * as x509 from "@peculiar/x509";
import crypto, { KeyObject } from "crypto";
import ms from "ms";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { BadRequestError } from "@app/lib/errors";
import { TCertificateCertDALFactory } from "@app/services/certificate/certificate-cert-dal";
import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
import { TKmsServiceFactory } from "@app/services/kms/kms-service";
import { TProjectDALFactory } from "@app/services/project/project-dal";
@@ -50,7 +51,7 @@ type TCertificateAuthorityServiceFactoryDep = {
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "create" | "findOne" | "update">;
certificateAuthorityQueue: TCertificateAuthorityQueueFactory; // TODO: Pick
certificateDAL: Pick<TCertificateDALFactory, "transaction" | "create" | "find">;
certificateCertDAL: Pick<TCertificateCertDALFactory, "create">;
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "create">;
projectDAL: Pick<TProjectDALFactory, "findProjectBySlug" | "findOne" | "updateById" | "findById" | "transaction">;
kmsService: Pick<TKmsServiceFactory, "generateKmsKey" | "encrypt" | "decrypt">;
permissionService: Pick<TPermissionServiceFactory, "getProjectPermission">;
@@ -64,7 +65,7 @@ export const certificateAuthorityServiceFactory = ({
certificateAuthoritySecretDAL,
certificateAuthorityCrlDAL,
certificateDAL,
certificateCertDAL,
certificateBodyDAL,
projectDAL,
kmsService,
permissionService
@@ -75,6 +76,7 @@ export const certificateAuthorityServiceFactory = ({
const createCa = async ({
projectSlug,
type,
friendlyName,
commonName,
organization,
ou,
@@ -127,6 +129,7 @@ export const certificateAuthorityServiceFactory = ({
: new Date(new Date().setFullYear(new Date().getFullYear() + 10));
const serialNumber = crypto.randomBytes(32).toString("hex");
const ca = await certificateAuthorityDAL.create(
{
projectId: project.id,
@@ -136,6 +139,7 @@ export const certificateAuthorityServiceFactory = ({
country,
province,
locality,
friendlyName: friendlyName || dn,
commonName,
status: type === CaType.ROOT ? CaStatus.ACTIVE : CaStatus.PENDING_CERTIFICATE,
dn,
@@ -642,6 +646,7 @@ export const certificateAuthorityServiceFactory = ({
*/
const issueCertFromCa = async ({
caId,
friendlyName,
commonName,
ttl,
notBefore,
@@ -688,8 +693,7 @@ export const certificateAuthorityServiceFactory = ({
if (notAfter) {
notAfterDate = new Date(notAfter);
} else if (ttl) {
// ttl in seconds
notAfterDate = new Date(new Date().getTime() + ttl * 1000);
notAfterDate = new Date(new Date().getTime() + ms(ttl));
}
const caCertNotBeforeDate = new Date(caCertObj.notBefore);
@@ -760,6 +764,7 @@ export const certificateAuthorityServiceFactory = ({
{
caId: ca.id,
status: CertStatus.ACTIVE,
friendlyName: friendlyName || commonName,
commonName,
serialNumber,
notBefore: notBeforeDate,
@@ -768,7 +773,7 @@ export const certificateAuthorityServiceFactory = ({
tx
);
await certificateCertDAL.create(
await certificateBodyDAL.create(
{
certId: cert.id,
encryptedCertificate
@@ -23,6 +23,7 @@ export enum CaStatus {
export type TCreateCaDTO = {
projectSlug: string;
type: CaType;
friendlyName?: string;
commonName: string;
organization: string;
ou: string;
@@ -72,8 +73,9 @@ export type TImportCertToCaDTO = {
export type TIssueCertFromCaDTO = {
caId: string;
friendlyName?: string;
commonName: string;
ttl?: number;
ttl: string;
notBefore?: string;
notAfter?: string;
} & Omit<TProjectPermission, "projectId">;
@@ -0,0 +1,10 @@
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { ormify } from "@app/lib/knex";
export type TCertificateBodyDALFactory = ReturnType<typeof certificateBodyDALFactory>;
export const certificateBodyDALFactory = (db: TDbClient) => {
const certificateBodyOrm = ormify(db, TableName.CertificateBody);
return certificateBodyOrm;
};
@@ -1,10 +0,0 @@
import { TDbClient } from "@app/db";
import { TableName } from "@app/db/schemas";
import { ormify } from "@app/lib/knex";
export type TCertificateCertDALFactory = ReturnType<typeof certificateCertDALFactory>;
export const certificateCertDALFactory = (db: TDbClient) => {
const certificateCertOrm = ormify(db, TableName.CertificateCert);
return certificateCertOrm;
};
@@ -3,7 +3,7 @@ import * as x509 from "@peculiar/x509";
import { TPermissionServiceFactory } from "@app/ee/services/permission/permission-service";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/ee/services/permission/project-permission";
import { TCertificateCertDALFactory } from "@app/services/certificate/certificate-cert-dal";
import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
import { TCertificateAuthorityCertDALFactory } from "@app/services/certificate-authority/certificate-authority-cert-dal";
import { TCertificateAuthorityCrlDALFactory } from "@app/services/certificate-authority/certificate-authority-crl-dal";
@@ -19,7 +19,7 @@ import { CertStatus, TDeleteCertDTO, TGetCertCertDTO, TGetCertDTO, TRevokeCertDT
type TCertificateServiceFactoryDep = {
certificateDAL: Pick<TCertificateDALFactory, "findOne" | "deleteById" | "update" | "find">;
certificateCertDAL: Pick<TCertificateCertDALFactory, "findOne">;
certificateBodyDAL: Pick<TCertificateBodyDALFactory, "findOne">;
certificateAuthorityDAL: Pick<TCertificateAuthorityDALFactory, "findById">;
certificateAuthorityCertDAL: Pick<TCertificateAuthorityCertDALFactory, "findOne">;
certificateAuthorityCrlDAL: Pick<TCertificateAuthorityCrlDALFactory, "update">;
@@ -33,7 +33,7 @@ export type TCertificateServiceFactory = ReturnType<typeof certificateServiceFac
export const certificateServiceFactory = ({
certificateDAL,
certificateCertDAL,
certificateBodyDAL,
certificateAuthorityDAL,
certificateAuthorityCertDAL,
certificateAuthorityCrlDAL,
@@ -155,7 +155,7 @@ export const certificateServiceFactory = ({
ForbiddenError.from(permission).throwUnlessCan(ProjectPermissionActions.Read, ProjectPermissionSub.Certificates);
const certCert = await certificateCertDAL.findOne({ certId: cert.id });
const certCert = await certificateBodyDAL.findOne({ certId: cert.id });
const keyId = await getProjectKmsCertificateKeyId({
projectId: ca.projectId,