mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 21:27:10 +00:00
misc: addressed first set of review comments
This commit is contained in:
@@ -24,6 +24,7 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
t.dropColumn("requireTemplateForIssuance");
|
t.dropColumn("requireTemplateForIssuance");
|
||||||
t.dropColumn("createdAt");
|
t.dropColumn("createdAt");
|
||||||
t.dropColumn("updatedAt");
|
t.dropColumn("updatedAt");
|
||||||
|
t.dropColumn("status");
|
||||||
t.uuid("parentCaId")
|
t.uuid("parentCaId")
|
||||||
.nullable()
|
.nullable()
|
||||||
.references("id")
|
.references("id")
|
||||||
@@ -44,22 +45,18 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
await Promise.all(
|
await Promise.all(
|
||||||
cas.map((ca) => {
|
cas.map((ca) => {
|
||||||
const slugifiedName = ca.friendlyName
|
const slugifiedName = ca.friendlyName
|
||||||
? slugify(`${ca.friendlyName}-${alphaNumericNanoId(8)}`)
|
? slugify(`${ca.friendlyName.slice(0, 16)}-${alphaNumericNanoId(8)}`)
|
||||||
: slugify(alphaNumericNanoId(12));
|
: slugify(alphaNumericNanoId(12));
|
||||||
|
|
||||||
return (
|
return knex(TableName.CertificateAuthority)
|
||||||
knex(TableName.CertificateAuthority)
|
.where({ id: ca.id })
|
||||||
.where({ id: ca.id })
|
.update({ name: slugifiedName, enableDirectIssuance: !ca.enableDirectIssuance });
|
||||||
// @ts-expect-error intentional: migration
|
|
||||||
.update({ name: slugifiedName, enableDirectIssuance: !ca.enableDirectIssuance })
|
|
||||||
);
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
|
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
|
||||||
t.dropColumn("parentCaId");
|
t.dropColumn("parentCaId");
|
||||||
t.dropColumn("type");
|
t.dropColumn("type");
|
||||||
t.dropColumn("status");
|
|
||||||
t.dropColumn("friendlyName");
|
t.dropColumn("friendlyName");
|
||||||
t.dropColumn("organization");
|
t.dropColumn("organization");
|
||||||
t.dropColumn("ou");
|
t.dropColumn("ou");
|
||||||
@@ -74,6 +71,7 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
t.dropColumn("notBefore");
|
t.dropColumn("notBefore");
|
||||||
t.dropColumn("notAfter");
|
t.dropColumn("notAfter");
|
||||||
t.dropColumn("activeCaCertId");
|
t.dropColumn("activeCaCertId");
|
||||||
|
t.boolean("enableDirectIssuance").notNullable().defaultTo(true).alter();
|
||||||
t.string("name").notNullable().alter();
|
t.string("name").notNullable().alter();
|
||||||
t.unique(["name", "projectId"]);
|
t.unique(["name", "projectId"]);
|
||||||
});
|
});
|
||||||
@@ -90,7 +88,6 @@ export async function up(knex: Knex): Promise<void> {
|
|||||||
t.uuid("caId").notNullable().references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE");
|
t.uuid("caId").notNullable().references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE");
|
||||||
t.binary("credentials");
|
t.binary("credentials");
|
||||||
t.json("configuration");
|
t.json("configuration");
|
||||||
t.string("status").notNullable();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +111,6 @@ export async function down(knex: Knex): Promise<void> {
|
|||||||
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
|
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
|
||||||
t.uuid("parentCaId").nullable().references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE");
|
t.uuid("parentCaId").nullable().references("id").inTable(TableName.CertificateAuthority).onDelete("CASCADE");
|
||||||
t.string("type").nullable();
|
t.string("type").nullable();
|
||||||
t.string("status").nullable();
|
|
||||||
t.string("friendlyName").nullable();
|
t.string("friendlyName").nullable();
|
||||||
t.string("organization").nullable();
|
t.string("organization").nullable();
|
||||||
t.string("ou").nullable();
|
t.string("ou").nullable();
|
||||||
@@ -150,7 +146,6 @@ export async function down(knex: Knex): Promise<void> {
|
|||||||
UPDATE ${TableName.CertificateAuthority} ca
|
UPDATE ${TableName.CertificateAuthority} ca
|
||||||
SET
|
SET
|
||||||
type = ica.type,
|
type = ica.type,
|
||||||
status = ica.status,
|
|
||||||
"friendlyName" = ica."friendlyName",
|
"friendlyName" = ica."friendlyName",
|
||||||
organization = ica.organization,
|
organization = ica.organization,
|
||||||
ou = ica.ou,
|
ou = ica.ou,
|
||||||
@@ -172,7 +167,6 @@ export async function down(knex: Knex): Promise<void> {
|
|||||||
|
|
||||||
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
|
await knex.schema.alterTable(TableName.CertificateAuthority, (t) => {
|
||||||
t.string("type").notNullable().alter();
|
t.string("type").notNullable().alter();
|
||||||
t.string("status").notNullable().alter();
|
|
||||||
t.string("friendlyName").notNullable().alter();
|
t.string("friendlyName").notNullable().alter();
|
||||||
t.string("organization").notNullable().alter();
|
t.string("organization").notNullable().alter();
|
||||||
t.string("ou").notNullable().alter();
|
t.string("ou").notNullable().alter();
|
||||||
@@ -182,6 +176,7 @@ export async function down(knex: Knex): Promise<void> {
|
|||||||
t.string("commonName").notNullable().alter();
|
t.string("commonName").notNullable().alter();
|
||||||
t.string("dn").notNullable().alter();
|
t.string("dn").notNullable().alter();
|
||||||
t.string("keyAlgorithm").notNullable().alter();
|
t.string("keyAlgorithm").notNullable().alter();
|
||||||
|
t.boolean("requireTemplateForIssuance").notNullable().defaultTo(false).alter();
|
||||||
});
|
});
|
||||||
|
|
||||||
await knex.schema.dropTable(TableName.InternalCertificateAuthority);
|
await knex.schema.dropTable(TableName.InternalCertificateAuthority);
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ export const CertificateAuthoritiesSchema = z.object({
|
|||||||
createdAt: z.date(),
|
createdAt: z.date(),
|
||||||
updatedAt: z.date(),
|
updatedAt: z.date(),
|
||||||
projectId: z.string(),
|
projectId: z.string(),
|
||||||
disableDirectIssuance: z.boolean().default(false)
|
enableDirectIssuance: z.boolean().default(true),
|
||||||
|
status: z.string(),
|
||||||
|
name: z.string()
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TCertificateAuthorities = z.infer<typeof CertificateAuthoritiesSchema>;
|
export type TCertificateAuthorities = z.infer<typeof CertificateAuthoritiesSchema>;
|
||||||
|
|||||||
@@ -12,14 +12,11 @@ import { TImmutableDBKeys } from "./models";
|
|||||||
export const ExternalCertificateAuthoritiesSchema = z.object({
|
export const ExternalCertificateAuthoritiesSchema = z.object({
|
||||||
id: z.string().uuid(),
|
id: z.string().uuid(),
|
||||||
type: z.string(),
|
type: z.string(),
|
||||||
name: z.string(),
|
|
||||||
projectId: z.string(),
|
|
||||||
appConnectionId: z.string().uuid().nullable().optional(),
|
appConnectionId: z.string().uuid().nullable().optional(),
|
||||||
dnsAppConnectionId: z.string().uuid().nullable().optional(),
|
dnsAppConnectionId: z.string().uuid().nullable().optional(),
|
||||||
certificateAuthorityId: z.string().uuid(),
|
caId: z.string().uuid(),
|
||||||
credentials: zodBuffer.nullable().optional(),
|
credentials: zodBuffer.nullable().optional(),
|
||||||
configuration: z.unknown().nullable().optional(),
|
configuration: z.unknown().nullable().optional()
|
||||||
status: z.string()
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TExternalCertificateAuthorities = z.infer<typeof ExternalCertificateAuthoritiesSchema>;
|
export type TExternalCertificateAuthorities = z.infer<typeof ExternalCertificateAuthoritiesSchema>;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ export const InternalCertificateAuthoritiesSchema = z.object({
|
|||||||
id: z.string().uuid(),
|
id: z.string().uuid(),
|
||||||
parentCaId: z.string().uuid().nullable().optional(),
|
parentCaId: z.string().uuid().nullable().optional(),
|
||||||
type: z.string(),
|
type: z.string(),
|
||||||
status: z.string(),
|
|
||||||
friendlyName: z.string(),
|
friendlyName: z.string(),
|
||||||
organization: z.string(),
|
organization: z.string(),
|
||||||
ou: z.string(),
|
ou: z.string(),
|
||||||
@@ -26,7 +25,7 @@ export const InternalCertificateAuthoritiesSchema = z.object({
|
|||||||
notBefore: z.date().nullable().optional(),
|
notBefore: z.date().nullable().optional(),
|
||||||
notAfter: z.date().nullable().optional(),
|
notAfter: z.date().nullable().optional(),
|
||||||
activeCaCertId: z.string().uuid().nullable().optional(),
|
activeCaCertId: z.string().uuid().nullable().optional(),
|
||||||
certificateAuthorityId: z.string().uuid()
|
caId: z.string().uuid()
|
||||||
});
|
});
|
||||||
|
|
||||||
export type TInternalCertificateAuthorities = z.infer<typeof InternalCertificateAuthoritiesSchema>;
|
export type TInternalCertificateAuthorities = z.infer<typeof InternalCertificateAuthoritiesSchema>;
|
||||||
|
|||||||
@@ -1793,7 +1793,7 @@ export const PKI_SUBSCRIBERS = {
|
|||||||
subscriberName: "The name of the PKI subscriber to get.",
|
subscriberName: "The name of the PKI subscriber to get.",
|
||||||
projectId: "The ID of the project to get the PKI subscriber for."
|
projectId: "The ID of the project to get the PKI subscriber for."
|
||||||
},
|
},
|
||||||
GET_ACTIVE_CERT_BUNDLE: {
|
GET_LATEST_CERT_BUNDLE: {
|
||||||
subscriberName: "The name of the PKI subscriber to get the active certificate bundle for.",
|
subscriberName: "The name of the PKI subscriber to get the active certificate bundle for.",
|
||||||
projectId: "The ID of the project to get the active certificate bundle for.",
|
projectId: "The ID of the project to get the active certificate bundle for.",
|
||||||
certificate: "The active certificate for the subscriber.",
|
certificate: "The active certificate for the subscriber.",
|
||||||
@@ -2018,13 +2018,14 @@ export const CertificateAuthorities = {
|
|||||||
CREATE: (type: CaType) => ({
|
CREATE: (type: CaType) => ({
|
||||||
name: `The name of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority to create. Must be slug-friendly.`,
|
name: `The name of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority to create. Must be slug-friendly.`,
|
||||||
projectId: `The ID of the project to create the Certificate Authority in.`,
|
projectId: `The ID of the project to create the Certificate Authority in.`,
|
||||||
disableDirectIssuance: `Whether or not to disable direct issuance of certificates for the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`,
|
enableDirectIssuance: `Whether or not to enable direct issuance of certificates for the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`,
|
||||||
status: `The status of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`
|
status: `The status of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`
|
||||||
}),
|
}),
|
||||||
UPDATE: (type: CaType) => ({
|
UPDATE: (type: CaType) => ({
|
||||||
caId: `The ID of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority to update.`,
|
caId: `The ID of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority to update.`,
|
||||||
|
projectId: `The ID of the project to update the Certificate Authority in.`,
|
||||||
name: `The updated name of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority. Must be slug-friendly.`,
|
name: `The updated name of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority. Must be slug-friendly.`,
|
||||||
disableDirectIssuance: `Whether or not to disable direct issuance of certificates for the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`,
|
enableDirectIssuance: `Whether or not to enable direct issuance of certificates for the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`,
|
||||||
status: `The updated status of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`
|
status: `The updated status of the ${CERTIFICATE_AUTHORITIES_TYPE_MAP[type]} Certificate Authority.`
|
||||||
}),
|
}),
|
||||||
CONFIGURATIONS: {
|
CONFIGURATIONS: {
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ export const SanitizedTagSchema = SecretTagsSchema.pick({
|
|||||||
|
|
||||||
export const InternalCertificateAuthorityResponseSchema = CertificateAuthoritiesSchema.merge(
|
export const InternalCertificateAuthorityResponseSchema = CertificateAuthoritiesSchema.merge(
|
||||||
InternalCertificateAuthoritiesSchema.omit({
|
InternalCertificateAuthoritiesSchema.omit({
|
||||||
|
caId: true,
|
||||||
notAfter: true,
|
notAfter: true,
|
||||||
notBefore: true
|
notBefore: true
|
||||||
})
|
})
|
||||||
|
|||||||
+38
-28
@@ -28,13 +28,14 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
projectId: string;
|
projectId: string;
|
||||||
status: CaStatus;
|
status: CaStatus;
|
||||||
configuration: I["configuration"];
|
configuration: I["configuration"];
|
||||||
disableDirectIssuance: boolean;
|
enableDirectIssuance: boolean;
|
||||||
}>;
|
}>;
|
||||||
updateSchema: z.ZodType<{
|
updateSchema: z.ZodType<{
|
||||||
|
projectId: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
status?: CaStatus;
|
status?: CaStatus;
|
||||||
configuration?: I["configuration"];
|
configuration?: I["configuration"];
|
||||||
disableDirectIssuance?: boolean;
|
enableDirectIssuance?: boolean;
|
||||||
}>;
|
}>;
|
||||||
responseSchema: z.ZodTypeAny;
|
responseSchema: z.ZodTypeAny;
|
||||||
}) => {
|
}) => {
|
||||||
@@ -51,7 +52,7 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
projectId: z.string().trim().min(1, "Project ID required")
|
projectId: z.string().trim().min(1, "Project ID required")
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({ certificateAuthorities: responseSchema.array() })
|
200: responseSchema.array()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
@@ -76,13 +77,13 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return { certificateAuthorities };
|
return certificateAuthorities;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: "/:certificateAuthorityId",
|
url: "/:caName",
|
||||||
config: {
|
config: {
|
||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
@@ -90,20 +91,25 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
hide: false,
|
hide: false,
|
||||||
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
||||||
params: z.object({
|
params: z.object({
|
||||||
certificateAuthorityId: z.string().uuid()
|
caName: z.string()
|
||||||
|
}),
|
||||||
|
querystring: z.object({
|
||||||
|
projectId: z.string().uuid()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({ certificateAuthority: responseSchema })
|
200: responseSchema
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { certificateAuthorityId } = req.params;
|
const { caName } = req.params;
|
||||||
|
const { projectId } = req.query;
|
||||||
|
|
||||||
const certificateAuthority = (await server.services.certificateAuthority.findCertificateAuthorityById(
|
const certificateAuthority =
|
||||||
{ certificateAuthorityId, type: caType },
|
(await server.services.certificateAuthority.findCertificateAuthorityByNameAndProjectId(
|
||||||
req.permission
|
{ caName, type: caType, projectId },
|
||||||
)) as T;
|
req.permission
|
||||||
|
)) as T;
|
||||||
|
|
||||||
await server.services.auditLog.createAuditLog({
|
await server.services.auditLog.createAuditLog({
|
||||||
...req.auditLogInfo,
|
...req.auditLogInfo,
|
||||||
@@ -116,7 +122,7 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return { certificateAuthority };
|
return certificateAuthority;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -131,7 +137,7 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
||||||
body: createSchema,
|
body: createSchema,
|
||||||
response: {
|
response: {
|
||||||
200: z.object({ certificateAuthority: responseSchema })
|
200: responseSchema
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
@@ -152,13 +158,13 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return { certificateAuthority };
|
return certificateAuthority;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "PATCH",
|
method: "PATCH",
|
||||||
url: "/:certificateAuthorityId",
|
url: "/:caName",
|
||||||
config: {
|
config: {
|
||||||
rateLimit: writeLimit
|
rateLimit: writeLimit
|
||||||
},
|
},
|
||||||
@@ -166,22 +172,22 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
hide: false,
|
hide: false,
|
||||||
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
||||||
params: z.object({
|
params: z.object({
|
||||||
certificateAuthorityId: z.string().uuid()
|
caName: z.string()
|
||||||
}),
|
}),
|
||||||
body: updateSchema,
|
body: updateSchema,
|
||||||
response: {
|
response: {
|
||||||
200: z.object({ certificateAuthority: responseSchema })
|
200: responseSchema
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { certificateAuthorityId } = req.params;
|
const { caName } = req.params;
|
||||||
|
|
||||||
const certificateAuthority = (await server.services.certificateAuthority.updateCertificateAuthority(
|
const certificateAuthority = (await server.services.certificateAuthority.updateCertificateAuthority(
|
||||||
{
|
{
|
||||||
...req.body,
|
...req.body,
|
||||||
id: certificateAuthorityId,
|
type: caType,
|
||||||
type: caType
|
caName
|
||||||
},
|
},
|
||||||
req.permission
|
req.permission
|
||||||
)) as T;
|
)) as T;
|
||||||
@@ -198,13 +204,13 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return { certificateAuthority };
|
return certificateAuthority;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
url: "/:certificateAuthorityId",
|
url: "/:caName",
|
||||||
config: {
|
config: {
|
||||||
rateLimit: writeLimit
|
rateLimit: writeLimit
|
||||||
},
|
},
|
||||||
@@ -212,18 +218,22 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
hide: false,
|
hide: false,
|
||||||
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
tags: [ApiDocsTags.PkiCertificateAuthorities],
|
||||||
params: z.object({
|
params: z.object({
|
||||||
certificateAuthorityId: z.string().uuid()
|
caName: z.string()
|
||||||
|
}),
|
||||||
|
body: z.object({
|
||||||
|
projectId: z.string().uuid()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({ certificateAuthority: responseSchema })
|
200: responseSchema
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
onRequest: verifyAuth([AuthMode.JWT, AuthMode.IDENTITY_ACCESS_TOKEN]),
|
||||||
handler: async (req) => {
|
handler: async (req) => {
|
||||||
const { certificateAuthorityId } = req.params;
|
const { caName } = req.params;
|
||||||
|
const { projectId } = req.body;
|
||||||
|
|
||||||
const certificateAuthority = (await server.services.certificateAuthority.deleteCertificateAuthority(
|
const certificateAuthority = (await server.services.certificateAuthority.deleteCertificateAuthority(
|
||||||
{ id: certificateAuthorityId, type: caType },
|
{ caName, type: caType, projectId },
|
||||||
req.permission
|
req.permission
|
||||||
)) as T;
|
)) as T;
|
||||||
|
|
||||||
@@ -238,7 +248,7 @@ export const registerCertificateAuthorityEndpoints = <
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return { certificateAuthority };
|
return certificateAuthority;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -485,30 +485,30 @@ export const registerPkiSubscriberRouter = async (server: FastifyZodProvider) =>
|
|||||||
|
|
||||||
server.route({
|
server.route({
|
||||||
method: "GET",
|
method: "GET",
|
||||||
url: "/:subscriberName/active-certificate/bundle",
|
url: "/:subscriberName/latest-certificate-bundle",
|
||||||
config: {
|
config: {
|
||||||
rateLimit: readLimit
|
rateLimit: readLimit
|
||||||
},
|
},
|
||||||
schema: {
|
schema: {
|
||||||
hide: false,
|
hide: false,
|
||||||
tags: [ApiDocsTags.PkiSubscribers],
|
tags: [ApiDocsTags.PkiSubscribers],
|
||||||
description: "Get active certificate bundle of a subscriber",
|
description: "Get latest certificate bundle of a subscriber",
|
||||||
params: z.object({
|
params: z.object({
|
||||||
subscriberName: z.string().describe(PKI_SUBSCRIBERS.GET_ACTIVE_CERT_BUNDLE.subscriberName)
|
subscriberName: z.string().describe(PKI_SUBSCRIBERS.GET_LATEST_CERT_BUNDLE.subscriberName)
|
||||||
}),
|
}),
|
||||||
querystring: z.object({
|
querystring: z.object({
|
||||||
projectId: z.string().trim().describe(PKI_SUBSCRIBERS.GET_ACTIVE_CERT_BUNDLE.projectId)
|
projectId: z.string().trim().describe(PKI_SUBSCRIBERS.GET_LATEST_CERT_BUNDLE.projectId)
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: z.object({
|
200: z.object({
|
||||||
certificate: z.string().trim().describe(PKI_SUBSCRIBERS.GET_ACTIVE_CERT_BUNDLE.certificate),
|
certificate: z.string().trim().describe(PKI_SUBSCRIBERS.GET_LATEST_CERT_BUNDLE.certificate),
|
||||||
certificateChain: z
|
certificateChain: z
|
||||||
.string()
|
.string()
|
||||||
.trim()
|
.trim()
|
||||||
.nullable()
|
.nullable()
|
||||||
.describe(PKI_SUBSCRIBERS.GET_ACTIVE_CERT_BUNDLE.certificateChain),
|
.describe(PKI_SUBSCRIBERS.GET_LATEST_CERT_BUNDLE.certificateChain),
|
||||||
privateKey: z.string().trim().describe(PKI_SUBSCRIBERS.GET_ACTIVE_CERT_BUNDLE.privateKey),
|
privateKey: z.string().trim().describe(PKI_SUBSCRIBERS.GET_LATEST_CERT_BUNDLE.privateKey),
|
||||||
serialNumber: z.string().trim().describe(PKI_SUBSCRIBERS.GET_ACTIVE_CERT_BUNDLE.serialNumber)
|
serialNumber: z.string().trim().describe(PKI_SUBSCRIBERS.GET_LATEST_CERT_BUNDLE.serialNumber)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -77,8 +77,8 @@ export const castDbEntryToAcmeCertificateAuthority = (
|
|||||||
return {
|
return {
|
||||||
id: ca.id,
|
id: ca.id,
|
||||||
type: CaType.ACME,
|
type: CaType.ACME,
|
||||||
disableDirectIssuance: ca.disableDirectIssuance,
|
enableDirectIssuance: ca.enableDirectIssuance,
|
||||||
name: ca.externalCa.name,
|
name: ca.name,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
credentials: ca.externalCa.credentials,
|
credentials: ca.externalCa.credentials,
|
||||||
configuration: {
|
configuration: {
|
||||||
@@ -90,7 +90,7 @@ export const castDbEntryToAcmeCertificateAuthority = (
|
|||||||
directoryUrl: dbConfigurationCol.directoryUrl,
|
directoryUrl: dbConfigurationCol.directoryUrl,
|
||||||
accountEmail: dbConfigurationCol.accountEmail
|
accountEmail: dbConfigurationCol.accountEmail
|
||||||
},
|
},
|
||||||
status: ca.externalCa.status as CaStatus
|
status: ca.status as CaStatus
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ export const AcmeCertificateAuthorityFns = ({
|
|||||||
name,
|
name,
|
||||||
projectId,
|
projectId,
|
||||||
configuration,
|
configuration,
|
||||||
disableDirectIssuance,
|
enableDirectIssuance,
|
||||||
actor,
|
actor,
|
||||||
status
|
status
|
||||||
}: {
|
}: {
|
||||||
@@ -184,7 +184,7 @@ export const AcmeCertificateAuthorityFns = ({
|
|||||||
name: string;
|
name: string;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
configuration: TCreateAcmeCertificateAuthorityDTO["configuration"];
|
configuration: TCreateAcmeCertificateAuthorityDTO["configuration"];
|
||||||
disableDirectIssuance: boolean;
|
enableDirectIssuance: boolean;
|
||||||
actor: OrgServiceActor;
|
actor: OrgServiceActor;
|
||||||
}) => {
|
}) => {
|
||||||
const { dnsAppConnectionId, directoryUrl, accountEmail, dnsProviderConfig } = configuration;
|
const { dnsAppConnectionId, directoryUrl, accountEmail, dnsProviderConfig } = configuration;
|
||||||
@@ -208,25 +208,24 @@ export const AcmeCertificateAuthorityFns = ({
|
|||||||
const ca = await certificateAuthorityDAL.create(
|
const ca = await certificateAuthorityDAL.create(
|
||||||
{
|
{
|
||||||
projectId,
|
projectId,
|
||||||
disableDirectIssuance
|
enableDirectIssuance,
|
||||||
|
name,
|
||||||
|
status
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
|
||||||
await externalCertificateAuthorityDAL.create(
|
await externalCertificateAuthorityDAL.create(
|
||||||
{
|
{
|
||||||
certificateAuthorityId: ca.id,
|
caId: ca.id,
|
||||||
dnsAppConnectionId,
|
dnsAppConnectionId,
|
||||||
type: CaType.ACME,
|
type: CaType.ACME,
|
||||||
name,
|
|
||||||
projectId,
|
|
||||||
configuration: {
|
configuration: {
|
||||||
directoryUrl,
|
directoryUrl,
|
||||||
accountEmail,
|
accountEmail,
|
||||||
dnsProvider: dnsProviderConfig.provider,
|
dnsProvider: dnsProviderConfig.provider,
|
||||||
hostedZoneId: dnsProviderConfig.hostedZoneId
|
hostedZoneId: dnsProviderConfig.hostedZoneId
|
||||||
},
|
}
|
||||||
status
|
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
@@ -255,14 +254,14 @@ export const AcmeCertificateAuthorityFns = ({
|
|||||||
id,
|
id,
|
||||||
status,
|
status,
|
||||||
configuration,
|
configuration,
|
||||||
disableDirectIssuance,
|
enableDirectIssuance,
|
||||||
actor,
|
actor,
|
||||||
name
|
name
|
||||||
}: {
|
}: {
|
||||||
id: string;
|
id: string;
|
||||||
status?: CaStatus;
|
status?: CaStatus;
|
||||||
configuration: TUpdateAcmeCertificateAuthorityDTO["configuration"];
|
configuration: TUpdateAcmeCertificateAuthorityDTO["configuration"];
|
||||||
disableDirectIssuance?: boolean;
|
enableDirectIssuance?: boolean;
|
||||||
actor: OrgServiceActor;
|
actor: OrgServiceActor;
|
||||||
name?: string;
|
name?: string;
|
||||||
}) => {
|
}) => {
|
||||||
@@ -290,7 +289,7 @@ export const AcmeCertificateAuthorityFns = ({
|
|||||||
|
|
||||||
await externalCertificateAuthorityDAL.update(
|
await externalCertificateAuthorityDAL.update(
|
||||||
{
|
{
|
||||||
certificateAuthorityId: id,
|
caId: id,
|
||||||
type: CaType.ACME
|
type: CaType.ACME
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -306,23 +305,13 @@ export const AcmeCertificateAuthorityFns = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await externalCertificateAuthorityDAL.update(
|
if (name || status || enableDirectIssuance) {
|
||||||
{
|
|
||||||
certificateAuthorityId: id,
|
|
||||||
type: CaType.ACME
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name,
|
|
||||||
status
|
|
||||||
},
|
|
||||||
tx
|
|
||||||
);
|
|
||||||
|
|
||||||
if (disableDirectIssuance !== undefined) {
|
|
||||||
await certificateAuthorityDAL.updateById(
|
await certificateAuthorityDAL.updateById(
|
||||||
id,
|
id,
|
||||||
{
|
{
|
||||||
disableDirectIssuance
|
name,
|
||||||
|
status,
|
||||||
|
enableDirectIssuance
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
@@ -399,7 +388,7 @@ export const AcmeCertificateAuthorityFns = ({
|
|||||||
});
|
});
|
||||||
await externalCertificateAuthorityDAL.update(
|
await externalCertificateAuthorityDAL.update(
|
||||||
{
|
{
|
||||||
certificateAuthorityId: acmeCa.id
|
caId: acmeCa.id
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
credentials: encryptedNewCredentials
|
credentials: encryptedNewCredentials
|
||||||
|
|||||||
@@ -14,25 +14,25 @@ export type TCertificateAuthorityWithAssociatedCa = Awaited<
|
|||||||
export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
||||||
const caOrm = ormify(db, TableName.CertificateAuthority);
|
const caOrm = ormify(db, TableName.CertificateAuthority);
|
||||||
|
|
||||||
const findByIdWithAssociatedCa = async (caId: string, tx?: Knex) => {
|
const findByNameAndProjectIdWithAssociatedCa = async (caName: string, projectId: string, tx?: Knex) => {
|
||||||
const result = await (tx || db.replicaNode())(TableName.CertificateAuthority)
|
const result = await (tx || db.replicaNode())(TableName.CertificateAuthority)
|
||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.InternalCertificateAuthority,
|
TableName.InternalCertificateAuthority,
|
||||||
`${TableName.CertificateAuthority}.id`,
|
`${TableName.CertificateAuthority}.id`,
|
||||||
`${TableName.InternalCertificateAuthority}.certificateAuthorityId`
|
`${TableName.InternalCertificateAuthority}.caId`
|
||||||
)
|
)
|
||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.ExternalCertificateAuthority,
|
TableName.ExternalCertificateAuthority,
|
||||||
`${TableName.CertificateAuthority}.id`,
|
`${TableName.CertificateAuthority}.id`,
|
||||||
`${TableName.ExternalCertificateAuthority}.certificateAuthorityId`
|
`${TableName.ExternalCertificateAuthority}.caId`
|
||||||
)
|
)
|
||||||
.where(`${TableName.CertificateAuthority}.id`, caId)
|
.where(`${TableName.CertificateAuthority}.name`, caName)
|
||||||
|
.where(`${TableName.CertificateAuthority}.projectId`, projectId)
|
||||||
.select(selectAllTableCols(TableName.CertificateAuthority))
|
.select(selectAllTableCols(TableName.CertificateAuthority))
|
||||||
.select(
|
.select(
|
||||||
db.ref("id").withSchema(TableName.InternalCertificateAuthority).as("internalCaId"),
|
db.ref("id").withSchema(TableName.InternalCertificateAuthority).as("internalCaId"),
|
||||||
db.ref("parentCaId").withSchema(TableName.InternalCertificateAuthority).as("internalParentCaId"),
|
db.ref("parentCaId").withSchema(TableName.InternalCertificateAuthority).as("internalParentCaId"),
|
||||||
db.ref("type").withSchema(TableName.InternalCertificateAuthority).as("internalType"),
|
db.ref("type").withSchema(TableName.InternalCertificateAuthority).as("internalType"),
|
||||||
db.ref("status").withSchema(TableName.InternalCertificateAuthority).as("internalStatus"),
|
|
||||||
db.ref("friendlyName").withSchema(TableName.InternalCertificateAuthority).as("internalFriendlyName"),
|
db.ref("friendlyName").withSchema(TableName.InternalCertificateAuthority).as("internalFriendlyName"),
|
||||||
db.ref("organization").withSchema(TableName.InternalCertificateAuthority).as("internalOrganization"),
|
db.ref("organization").withSchema(TableName.InternalCertificateAuthority).as("internalOrganization"),
|
||||||
db.ref("ou").withSchema(TableName.InternalCertificateAuthority).as("internalOu"),
|
db.ref("ou").withSchema(TableName.InternalCertificateAuthority).as("internalOu"),
|
||||||
@@ -46,17 +46,11 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("keyAlgorithm").withSchema(TableName.InternalCertificateAuthority).as("internalKeyAlgorithm"),
|
db.ref("keyAlgorithm").withSchema(TableName.InternalCertificateAuthority).as("internalKeyAlgorithm"),
|
||||||
db.ref("notBefore").withSchema(TableName.InternalCertificateAuthority).as("internalNotBefore"),
|
db.ref("notBefore").withSchema(TableName.InternalCertificateAuthority).as("internalNotBefore"),
|
||||||
db.ref("notAfter").withSchema(TableName.InternalCertificateAuthority).as("internalNotAfter"),
|
db.ref("notAfter").withSchema(TableName.InternalCertificateAuthority).as("internalNotAfter"),
|
||||||
db.ref("activeCaCertId").withSchema(TableName.InternalCertificateAuthority).as("internalActiveCaCertId"),
|
db.ref("activeCaCertId").withSchema(TableName.InternalCertificateAuthority).as("internalActiveCaCertId")
|
||||||
db
|
|
||||||
.ref("certificateAuthorityId")
|
|
||||||
.withSchema(TableName.InternalCertificateAuthority)
|
|
||||||
.as("internalCertificateAuthorityId")
|
|
||||||
)
|
)
|
||||||
.select(
|
.select(
|
||||||
db.ref("id").withSchema(TableName.ExternalCertificateAuthority).as("externalCaId"),
|
db.ref("id").withSchema(TableName.ExternalCertificateAuthority).as("externalCaId"),
|
||||||
db.ref("name").withSchema(TableName.ExternalCertificateAuthority).as("externalName"),
|
|
||||||
db.ref("type").withSchema(TableName.ExternalCertificateAuthority).as("externalType"),
|
db.ref("type").withSchema(TableName.ExternalCertificateAuthority).as("externalType"),
|
||||||
db.ref("status").withSchema(TableName.ExternalCertificateAuthority).as("externalStatus"),
|
|
||||||
db.ref("configuration").withSchema(TableName.ExternalCertificateAuthority).as("externalConfiguration"),
|
db.ref("configuration").withSchema(TableName.ExternalCertificateAuthority).as("externalConfiguration"),
|
||||||
db.ref("credentials").withSchema(TableName.ExternalCertificateAuthority).as("externalCredentials"),
|
db.ref("credentials").withSchema(TableName.ExternalCertificateAuthority).as("externalCredentials"),
|
||||||
db
|
db
|
||||||
@@ -74,7 +68,6 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
id: result.internalCaId,
|
id: result.internalCaId,
|
||||||
parentCaId: result.internalParentCaId,
|
parentCaId: result.internalParentCaId,
|
||||||
type: result.internalType,
|
type: result.internalType,
|
||||||
status: result.internalStatus,
|
|
||||||
friendlyName: result.internalFriendlyName,
|
friendlyName: result.internalFriendlyName,
|
||||||
organization: result.internalOrganization,
|
organization: result.internalOrganization,
|
||||||
ou: result.internalOu,
|
ou: result.internalOu,
|
||||||
@@ -88,16 +81,97 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
keyAlgorithm: result.internalKeyAlgorithm,
|
keyAlgorithm: result.internalKeyAlgorithm,
|
||||||
notBefore: result.internalNotBefore?.toISOString(),
|
notBefore: result.internalNotBefore?.toISOString(),
|
||||||
notAfter: result.internalNotAfter?.toISOString(),
|
notAfter: result.internalNotAfter?.toISOString(),
|
||||||
activeCaCertId: result.internalActiveCaCertId,
|
activeCaCertId: result.internalActiveCaCertId
|
||||||
certificateAuthorityId: result.internalCertificateAuthorityId
|
}
|
||||||
|
: undefined,
|
||||||
|
externalCa: result
|
||||||
|
? {
|
||||||
|
id: result.externalCaId,
|
||||||
|
type: result.externalType,
|
||||||
|
configuration: result.externalConfiguration,
|
||||||
|
dnsAppConnectionId: result.externalDnsAppConnectionId,
|
||||||
|
appConnectionId: result.externalAppConnectionId,
|
||||||
|
credentials: result.externalCredentials
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
return data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const findByIdWithAssociatedCa = async (caId: string, tx?: Knex) => {
|
||||||
|
const result = await (tx || db.replicaNode())(TableName.CertificateAuthority)
|
||||||
|
.leftJoin(
|
||||||
|
TableName.InternalCertificateAuthority,
|
||||||
|
`${TableName.CertificateAuthority}.id`,
|
||||||
|
`${TableName.InternalCertificateAuthority}.caId`
|
||||||
|
)
|
||||||
|
.leftJoin(
|
||||||
|
TableName.ExternalCertificateAuthority,
|
||||||
|
`${TableName.CertificateAuthority}.id`,
|
||||||
|
`${TableName.ExternalCertificateAuthority}.caId`
|
||||||
|
)
|
||||||
|
.where(`${TableName.CertificateAuthority}.id`, caId)
|
||||||
|
.select(selectAllTableCols(TableName.CertificateAuthority))
|
||||||
|
.select(
|
||||||
|
db.ref("id").withSchema(TableName.InternalCertificateAuthority).as("internalCaId"),
|
||||||
|
db.ref("parentCaId").withSchema(TableName.InternalCertificateAuthority).as("internalParentCaId"),
|
||||||
|
db.ref("type").withSchema(TableName.InternalCertificateAuthority).as("internalType"),
|
||||||
|
db.ref("friendlyName").withSchema(TableName.InternalCertificateAuthority).as("internalFriendlyName"),
|
||||||
|
db.ref("organization").withSchema(TableName.InternalCertificateAuthority).as("internalOrganization"),
|
||||||
|
db.ref("ou").withSchema(TableName.InternalCertificateAuthority).as("internalOu"),
|
||||||
|
db.ref("country").withSchema(TableName.InternalCertificateAuthority).as("internalCountry"),
|
||||||
|
db.ref("province").withSchema(TableName.InternalCertificateAuthority).as("internalProvince"),
|
||||||
|
db.ref("locality").withSchema(TableName.InternalCertificateAuthority).as("internalLocality"),
|
||||||
|
db.ref("commonName").withSchema(TableName.InternalCertificateAuthority).as("internalCommonName"),
|
||||||
|
db.ref("dn").withSchema(TableName.InternalCertificateAuthority).as("internalDn"),
|
||||||
|
db.ref("serialNumber").withSchema(TableName.InternalCertificateAuthority).as("internalSerialNumber"),
|
||||||
|
db.ref("maxPathLength").withSchema(TableName.InternalCertificateAuthority).as("internalMaxPathLength"),
|
||||||
|
db.ref("keyAlgorithm").withSchema(TableName.InternalCertificateAuthority).as("internalKeyAlgorithm"),
|
||||||
|
db.ref("notBefore").withSchema(TableName.InternalCertificateAuthority).as("internalNotBefore"),
|
||||||
|
db.ref("notAfter").withSchema(TableName.InternalCertificateAuthority).as("internalNotAfter"),
|
||||||
|
db.ref("activeCaCertId").withSchema(TableName.InternalCertificateAuthority).as("internalActiveCaCertId")
|
||||||
|
)
|
||||||
|
.select(
|
||||||
|
db.ref("id").withSchema(TableName.ExternalCertificateAuthority).as("externalCaId"),
|
||||||
|
db.ref("type").withSchema(TableName.ExternalCertificateAuthority).as("externalType"),
|
||||||
|
db.ref("configuration").withSchema(TableName.ExternalCertificateAuthority).as("externalConfiguration"),
|
||||||
|
db.ref("credentials").withSchema(TableName.ExternalCertificateAuthority).as("externalCredentials"),
|
||||||
|
db
|
||||||
|
.ref("dnsAppConnectionId")
|
||||||
|
.withSchema(TableName.ExternalCertificateAuthority)
|
||||||
|
.as("externalDnsAppConnectionId"),
|
||||||
|
db.ref("appConnectionId").withSchema(TableName.ExternalCertificateAuthority).as("externalAppConnectionId")
|
||||||
|
)
|
||||||
|
.first();
|
||||||
|
|
||||||
|
const data = {
|
||||||
|
...CertificateAuthoritiesSchema.parse(result),
|
||||||
|
internalCa: result
|
||||||
|
? {
|
||||||
|
id: result.internalCaId,
|
||||||
|
parentCaId: result.internalParentCaId,
|
||||||
|
type: result.internalType,
|
||||||
|
friendlyName: result.internalFriendlyName,
|
||||||
|
organization: result.internalOrganization,
|
||||||
|
ou: result.internalOu,
|
||||||
|
country: result.internalCountry,
|
||||||
|
province: result.internalProvince,
|
||||||
|
locality: result.internalLocality,
|
||||||
|
commonName: result.internalCommonName,
|
||||||
|
dn: result.internalDn,
|
||||||
|
serialNumber: result.internalSerialNumber,
|
||||||
|
maxPathLength: result.internalMaxPathLength,
|
||||||
|
keyAlgorithm: result.internalKeyAlgorithm,
|
||||||
|
notBefore: result.internalNotBefore?.toISOString(),
|
||||||
|
notAfter: result.internalNotAfter?.toISOString(),
|
||||||
|
activeCaCertId: result.internalActiveCaCertId
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
externalCa: result
|
externalCa: result
|
||||||
? {
|
? {
|
||||||
id: result.externalCaId,
|
id: result.externalCaId,
|
||||||
name: result.externalName,
|
|
||||||
type: result.externalType,
|
type: result.externalType,
|
||||||
status: result.externalStatus,
|
|
||||||
configuration: result.externalConfiguration,
|
configuration: result.externalConfiguration,
|
||||||
dnsAppConnectionId: result.externalDnsAppConnectionId,
|
dnsAppConnectionId: result.externalDnsAppConnectionId,
|
||||||
appConnectionId: result.externalAppConnectionId,
|
appConnectionId: result.externalAppConnectionId,
|
||||||
@@ -153,12 +227,12 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.InternalCertificateAuthority,
|
TableName.InternalCertificateAuthority,
|
||||||
`${TableName.CertificateAuthority}.id`,
|
`${TableName.CertificateAuthority}.id`,
|
||||||
`${TableName.InternalCertificateAuthority}.certificateAuthorityId`
|
`${TableName.InternalCertificateAuthority}.caId`
|
||||||
)
|
)
|
||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.ExternalCertificateAuthority,
|
TableName.ExternalCertificateAuthority,
|
||||||
`${TableName.CertificateAuthority}.id`,
|
`${TableName.CertificateAuthority}.id`,
|
||||||
`${TableName.ExternalCertificateAuthority}.certificateAuthorityId`
|
`${TableName.ExternalCertificateAuthority}.caId`
|
||||||
)
|
)
|
||||||
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
// eslint-disable-next-line @typescript-eslint/no-misused-promises
|
||||||
.where(buildFindFilter(filter))
|
.where(buildFindFilter(filter))
|
||||||
@@ -167,7 +241,6 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("id").withSchema(TableName.InternalCertificateAuthority).as("internalCaId"),
|
db.ref("id").withSchema(TableName.InternalCertificateAuthority).as("internalCaId"),
|
||||||
db.ref("parentCaId").withSchema(TableName.InternalCertificateAuthority).as("internalParentCaId"),
|
db.ref("parentCaId").withSchema(TableName.InternalCertificateAuthority).as("internalParentCaId"),
|
||||||
db.ref("type").withSchema(TableName.InternalCertificateAuthority).as("internalType"),
|
db.ref("type").withSchema(TableName.InternalCertificateAuthority).as("internalType"),
|
||||||
db.ref("status").withSchema(TableName.InternalCertificateAuthority).as("internalStatus"),
|
|
||||||
db.ref("friendlyName").withSchema(TableName.InternalCertificateAuthority).as("internalFriendlyName"),
|
db.ref("friendlyName").withSchema(TableName.InternalCertificateAuthority).as("internalFriendlyName"),
|
||||||
db.ref("organization").withSchema(TableName.InternalCertificateAuthority).as("internalOrganization"),
|
db.ref("organization").withSchema(TableName.InternalCertificateAuthority).as("internalOrganization"),
|
||||||
db.ref("ou").withSchema(TableName.InternalCertificateAuthority).as("internalOu"),
|
db.ref("ou").withSchema(TableName.InternalCertificateAuthority).as("internalOu"),
|
||||||
@@ -181,17 +254,11 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
db.ref("keyAlgorithm").withSchema(TableName.InternalCertificateAuthority).as("internalKeyAlgorithm"),
|
db.ref("keyAlgorithm").withSchema(TableName.InternalCertificateAuthority).as("internalKeyAlgorithm"),
|
||||||
db.ref("notBefore").withSchema(TableName.InternalCertificateAuthority).as("internalNotBefore"),
|
db.ref("notBefore").withSchema(TableName.InternalCertificateAuthority).as("internalNotBefore"),
|
||||||
db.ref("notAfter").withSchema(TableName.InternalCertificateAuthority).as("internalNotAfter"),
|
db.ref("notAfter").withSchema(TableName.InternalCertificateAuthority).as("internalNotAfter"),
|
||||||
db.ref("activeCaCertId").withSchema(TableName.InternalCertificateAuthority).as("internalActiveCaCertId"),
|
db.ref("activeCaCertId").withSchema(TableName.InternalCertificateAuthority).as("internalActiveCaCertId")
|
||||||
db
|
|
||||||
.ref("certificateAuthorityId")
|
|
||||||
.withSchema(TableName.InternalCertificateAuthority)
|
|
||||||
.as("internalCertificateAuthorityId")
|
|
||||||
)
|
)
|
||||||
.select(
|
.select(
|
||||||
db.ref("id").withSchema(TableName.ExternalCertificateAuthority).as("externalCaId"),
|
db.ref("id").withSchema(TableName.ExternalCertificateAuthority).as("externalCaId"),
|
||||||
db.ref("name").withSchema(TableName.ExternalCertificateAuthority).as("externalName"),
|
|
||||||
db.ref("type").withSchema(TableName.ExternalCertificateAuthority).as("externalType"),
|
db.ref("type").withSchema(TableName.ExternalCertificateAuthority).as("externalType"),
|
||||||
db.ref("status").withSchema(TableName.ExternalCertificateAuthority).as("externalStatus"),
|
|
||||||
db.ref("configuration").withSchema(TableName.ExternalCertificateAuthority).as("externalConfiguration"),
|
db.ref("configuration").withSchema(TableName.ExternalCertificateAuthority).as("externalConfiguration"),
|
||||||
db
|
db
|
||||||
.ref("dnsAppConnectionId")
|
.ref("dnsAppConnectionId")
|
||||||
@@ -220,7 +287,6 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
id: ca.internalCaId,
|
id: ca.internalCaId,
|
||||||
parentCaId: ca.internalParentCaId,
|
parentCaId: ca.internalParentCaId,
|
||||||
type: ca.internalType,
|
type: ca.internalType,
|
||||||
status: ca.internalStatus,
|
|
||||||
friendlyName: ca.internalFriendlyName,
|
friendlyName: ca.internalFriendlyName,
|
||||||
organization: ca.internalOrganization,
|
organization: ca.internalOrganization,
|
||||||
ou: ca.internalOu,
|
ou: ca.internalOu,
|
||||||
@@ -234,16 +300,13 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
keyAlgorithm: ca.internalKeyAlgorithm,
|
keyAlgorithm: ca.internalKeyAlgorithm,
|
||||||
notBefore: ca.internalNotBefore?.toISOString(),
|
notBefore: ca.internalNotBefore?.toISOString(),
|
||||||
notAfter: ca.internalNotAfter?.toISOString(),
|
notAfter: ca.internalNotAfter?.toISOString(),
|
||||||
activeCaCertId: ca.internalActiveCaCertId,
|
activeCaCertId: ca.internalActiveCaCertId
|
||||||
certificateAuthorityId: ca.internalCertificateAuthorityId
|
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
externalCa: ca
|
externalCa: ca
|
||||||
? {
|
? {
|
||||||
id: ca.externalCaId,
|
id: ca.externalCaId,
|
||||||
name: ca.externalName,
|
|
||||||
type: ca.externalType,
|
type: ca.externalType,
|
||||||
status: ca.externalStatus,
|
|
||||||
configuration: ca.externalConfiguration,
|
configuration: ca.externalConfiguration,
|
||||||
dnsAppConnectionId: ca.externalDnsAppConnectionId,
|
dnsAppConnectionId: ca.externalDnsAppConnectionId,
|
||||||
appConnectionId: ca.externalAppConnectionId,
|
appConnectionId: ca.externalAppConnectionId,
|
||||||
@@ -260,6 +323,7 @@ export const certificateAuthorityDALFactory = (db: TDbClient) => {
|
|||||||
...caOrm,
|
...caOrm,
|
||||||
findWithAssociatedCa,
|
findWithAssociatedCa,
|
||||||
buildCertificateChain,
|
buildCertificateChain,
|
||||||
findByIdWithAssociatedCa
|
findByIdWithAssociatedCa,
|
||||||
|
findByNameAndProjectIdWithAssociatedCa
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -329,6 +329,6 @@ export const expandInternalCa = (
|
|||||||
return {
|
return {
|
||||||
...ca.internalCa,
|
...ca.internalCa,
|
||||||
...ca,
|
...ca,
|
||||||
requireTemplateForIssuance: ca.disableDirectIssuance
|
requireTemplateForIssuance: !ca.enableDirectIssuance
|
||||||
} as const;
|
} as const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ import { CaStatus, CaType } from "./certificate-authority-enums";
|
|||||||
|
|
||||||
export const BaseCertificateAuthoritySchema = CertificateAuthoritiesSchema.pick({
|
export const BaseCertificateAuthoritySchema = CertificateAuthoritiesSchema.pick({
|
||||||
projectId: true,
|
projectId: true,
|
||||||
disableDirectIssuance: true,
|
enableDirectIssuance: true,
|
||||||
|
name: true,
|
||||||
id: true
|
id: true
|
||||||
}).extend({
|
}).extend({
|
||||||
name: z.string(),
|
|
||||||
status: z.nativeEnum(CaStatus)
|
status: z.nativeEnum(CaStatus)
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -19,13 +19,14 @@ export const GenericCreateCertificateAuthorityFieldsSchema = (type: CaType) =>
|
|||||||
z.object({
|
z.object({
|
||||||
name: slugSchema({ field: "name" }).describe(CertificateAuthorities.CREATE(type).name),
|
name: slugSchema({ field: "name" }).describe(CertificateAuthorities.CREATE(type).name),
|
||||||
projectId: z.string().trim().min(1, "Project ID required").describe(CertificateAuthorities.CREATE(type).projectId),
|
projectId: z.string().trim().min(1, "Project ID required").describe(CertificateAuthorities.CREATE(type).projectId),
|
||||||
disableDirectIssuance: z.boolean().describe(CertificateAuthorities.CREATE(type).disableDirectIssuance),
|
enableDirectIssuance: z.boolean().describe(CertificateAuthorities.CREATE(type).enableDirectIssuance),
|
||||||
status: z.nativeEnum(CaStatus).describe(CertificateAuthorities.CREATE(type).status)
|
status: z.nativeEnum(CaStatus).describe(CertificateAuthorities.CREATE(type).status)
|
||||||
});
|
});
|
||||||
|
|
||||||
export const GenericUpdateCertificateAuthorityFieldsSchema = (type: CaType) =>
|
export const GenericUpdateCertificateAuthorityFieldsSchema = (type: CaType) =>
|
||||||
z.object({
|
z.object({
|
||||||
name: slugSchema({ field: "name" }).optional().describe(CertificateAuthorities.UPDATE(type).name),
|
name: slugSchema({ field: "name" }).optional().describe(CertificateAuthorities.UPDATE(type).name),
|
||||||
disableDirectIssuance: z.boolean().optional().describe(CertificateAuthorities.UPDATE(type).disableDirectIssuance),
|
projectId: z.string().trim().min(1, "Project ID required").describe(CertificateAuthorities.UPDATE(type).projectId),
|
||||||
|
enableDirectIssuance: z.boolean().optional().describe(CertificateAuthorities.UPDATE(type).enableDirectIssuance),
|
||||||
status: z.nativeEnum(CaStatus).optional().describe(CertificateAuthorities.UPDATE(type).status)
|
status: z.nativeEnum(CaStatus).optional().describe(CertificateAuthorities.UPDATE(type).status)
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ type TCertificateAuthorityServiceFactoryDep = {
|
|||||||
| "findOne"
|
| "findOne"
|
||||||
| "findByIdWithAssociatedCa"
|
| "findByIdWithAssociatedCa"
|
||||||
| "findWithAssociatedCa"
|
| "findWithAssociatedCa"
|
||||||
|
| "findByNameAndProjectIdWithAssociatedCa"
|
||||||
>;
|
>;
|
||||||
externalCertificateAuthorityDAL: Pick<TExternalCertificateAuthorityDALFactory, "create" | "update">;
|
externalCertificateAuthorityDAL: Pick<TExternalCertificateAuthorityDALFactory, "create" | "update">;
|
||||||
internalCertificateAuthorityService: TInternalCertificateAuthorityServiceFactory;
|
internalCertificateAuthorityService: TInternalCertificateAuthorityServiceFactory;
|
||||||
@@ -94,7 +95,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const createCertificateAuthority = async (
|
const createCertificateAuthority = async (
|
||||||
{ type, projectId, name, disableDirectIssuance, configuration, status }: TCreateCertificateAuthorityDTO,
|
{ type, projectId, name, enableDirectIssuance, configuration, status }: TCreateCertificateAuthorityDTO,
|
||||||
actor: OrgServiceActor
|
actor: OrgServiceActor
|
||||||
) => {
|
) => {
|
||||||
let finalProjectId: string = projectId;
|
let finalProjectId: string = projectId;
|
||||||
@@ -126,7 +127,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
...(configuration as TCreateInternalCertificateAuthorityDTO["configuration"]),
|
...(configuration as TCreateInternalCertificateAuthorityDTO["configuration"]),
|
||||||
isInternal: true,
|
isInternal: true,
|
||||||
projectId: finalProjectId,
|
projectId: finalProjectId,
|
||||||
requireTemplateForIssuance: disableDirectIssuance
|
requireTemplateForIssuance: !enableDirectIssuance
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!ca.internalCa) {
|
if (!ca.internalCa) {
|
||||||
@@ -138,8 +139,8 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
return {
|
return {
|
||||||
id: ca.id,
|
id: ca.id,
|
||||||
type,
|
type,
|
||||||
disableDirectIssuance: ca.disableDirectIssuance,
|
enableDirectIssuance: ca.enableDirectIssuance,
|
||||||
name: ca.internalCa?.friendlyName,
|
name: ca.name,
|
||||||
projectId: finalProjectId,
|
projectId: finalProjectId,
|
||||||
status,
|
status,
|
||||||
configuration: ca.internalCa
|
configuration: ca.internalCa
|
||||||
@@ -151,7 +152,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
name,
|
name,
|
||||||
projectId: finalProjectId,
|
projectId: finalProjectId,
|
||||||
configuration: configuration as TCreateAcmeCertificateAuthorityDTO["configuration"],
|
configuration: configuration as TCreateAcmeCertificateAuthorityDTO["configuration"],
|
||||||
disableDirectIssuance,
|
enableDirectIssuance,
|
||||||
status,
|
status,
|
||||||
actor
|
actor
|
||||||
});
|
});
|
||||||
@@ -160,15 +161,18 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Invalid certificate authority type" });
|
throw new BadRequestError({ message: "Invalid certificate authority type" });
|
||||||
};
|
};
|
||||||
|
|
||||||
const findCertificateAuthorityById = async (
|
const findCertificateAuthorityByNameAndProjectId = async (
|
||||||
{ certificateAuthorityId, type }: { certificateAuthorityId: string; type: CaType },
|
{ caName, type, projectId }: { caName: string; type: CaType; projectId: string },
|
||||||
actor: OrgServiceActor
|
actor: OrgServiceActor
|
||||||
) => {
|
) => {
|
||||||
const certificateAuthority = await certificateAuthorityDAL.findByIdWithAssociatedCa(certificateAuthorityId);
|
const certificateAuthority = await certificateAuthorityDAL.findByNameAndProjectIdWithAssociatedCa(
|
||||||
|
caName,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
|
|
||||||
if (!certificateAuthority)
|
if (!certificateAuthority)
|
||||||
throw new NotFoundError({
|
throw new NotFoundError({
|
||||||
message: `Could not find certificate authority with ID "${certificateAuthorityId}"`
|
message: `Could not find certificate authority with name "${caName}" in project "${projectId}"`
|
||||||
});
|
});
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
@@ -188,24 +192,24 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
if (type === CaType.INTERNAL) {
|
if (type === CaType.INTERNAL) {
|
||||||
if (!certificateAuthority.internalCa?.id) {
|
if (!certificateAuthority.internalCa?.id) {
|
||||||
throw new NotFoundError({
|
throw new NotFoundError({
|
||||||
message: `Internal certificate authority with ID "${certificateAuthorityId}" not found`
|
message: `Internal certificate authority with name "${caName}" in project "${projectId}" not found`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
id: certificateAuthority.id,
|
id: certificateAuthority.id,
|
||||||
type,
|
type,
|
||||||
disableDirectIssuance: certificateAuthority.disableDirectIssuance,
|
enableDirectIssuance: certificateAuthority.enableDirectIssuance,
|
||||||
name: certificateAuthority.internalCa.friendlyName,
|
name: certificateAuthority.name,
|
||||||
projectId: certificateAuthority.projectId,
|
projectId: certificateAuthority.projectId,
|
||||||
configuration: certificateAuthority.internalCa,
|
configuration: certificateAuthority.internalCa,
|
||||||
status: certificateAuthority.internalCa.status
|
status: certificateAuthority.status
|
||||||
} as TCertificateAuthority;
|
} as TCertificateAuthority;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (certificateAuthority.externalCa?.type !== type) {
|
if (certificateAuthority.externalCa?.type !== type) {
|
||||||
throw new NotFoundError({
|
throw new NotFoundError({
|
||||||
message: `Could not find external certificate authority with ID "${certificateAuthorityId}" and type "${type}"`
|
message: `Could not find external certificate authority with name "${caName}" in project "${projectId}" and type "${type}"`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -255,11 +259,11 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
.map((ca) => ({
|
.map((ca) => ({
|
||||||
id: ca.id,
|
id: ca.id,
|
||||||
type,
|
type,
|
||||||
disableDirectIssuance: ca.disableDirectIssuance,
|
enableDirectIssuance: ca.enableDirectIssuance,
|
||||||
name: ca.internalCa.friendlyName,
|
name: ca.name,
|
||||||
projectId: ca.projectId,
|
projectId: ca.projectId,
|
||||||
configuration: ca.internalCa,
|
configuration: ca.internalCa,
|
||||||
status: ca.internalCa.status
|
status: ca.status
|
||||||
})) as TCertificateAuthority[];
|
})) as TCertificateAuthority[];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,14 +275,17 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const updateCertificateAuthority = async (
|
const updateCertificateAuthority = async (
|
||||||
{ id, type, configuration, disableDirectIssuance, status, name }: TUpdateCertificateAuthorityDTO,
|
{ caName, type, configuration, enableDirectIssuance, status, name, projectId }: TUpdateCertificateAuthorityDTO,
|
||||||
actor: OrgServiceActor
|
actor: OrgServiceActor
|
||||||
) => {
|
) => {
|
||||||
const certificateAuthority = await certificateAuthorityDAL.findByIdWithAssociatedCa(id);
|
const certificateAuthority = await certificateAuthorityDAL.findByNameAndProjectIdWithAssociatedCa(
|
||||||
|
caName,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
|
|
||||||
if (!certificateAuthority)
|
if (!certificateAuthority)
|
||||||
throw new NotFoundError({
|
throw new NotFoundError({
|
||||||
message: `Could not find certificate authority with ID "${id}"`
|
message: `Could not find certificate authority with name "${caName}" in project "${projectId}"`
|
||||||
});
|
});
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
@@ -298,15 +305,16 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
if (type === CaType.INTERNAL) {
|
if (type === CaType.INTERNAL) {
|
||||||
if (!certificateAuthority.internalCa?.id) {
|
if (!certificateAuthority.internalCa?.id) {
|
||||||
throw new NotFoundError({
|
throw new NotFoundError({
|
||||||
message: `Internal certificate authority with ID "${id}" not found`
|
message: `Internal certificate authority with name "${caName}" in project "${projectId}" not found`
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const updatedCa = await internalCertificateAuthorityService.updateCaById({
|
const updatedCa = await internalCertificateAuthorityService.updateCaById({
|
||||||
...configuration,
|
...configuration,
|
||||||
isInternal: true,
|
isInternal: true,
|
||||||
requireTemplateForIssuance: disableDirectIssuance,
|
requireTemplateForIssuance: !enableDirectIssuance,
|
||||||
caId: id
|
caId: certificateAuthority.id,
|
||||||
|
name
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!updatedCa.internalCa) {
|
if (!updatedCa.internalCa) {
|
||||||
@@ -318,19 +326,19 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
return {
|
return {
|
||||||
id: updatedCa.id,
|
id: updatedCa.id,
|
||||||
type,
|
type,
|
||||||
disableDirectIssuance: updatedCa.disableDirectIssuance,
|
enableDirectIssuance: updatedCa.enableDirectIssuance,
|
||||||
name: updatedCa.internalCa?.friendlyName,
|
name: updatedCa.name,
|
||||||
projectId: updatedCa.projectId,
|
projectId: updatedCa.projectId,
|
||||||
configuration: updatedCa.internalCa,
|
configuration: updatedCa.internalCa,
|
||||||
status: updatedCa.internalCa?.status
|
status: updatedCa.status
|
||||||
} as TCertificateAuthority;
|
} as TCertificateAuthority;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type === CaType.ACME) {
|
if (type === CaType.ACME) {
|
||||||
return acmeFns.updateCertificateAuthority({
|
return acmeFns.updateCertificateAuthority({
|
||||||
id,
|
id: certificateAuthority.id,
|
||||||
configuration: configuration as TUpdateAcmeCertificateAuthorityDTO["configuration"],
|
configuration: configuration as TUpdateAcmeCertificateAuthorityDTO["configuration"],
|
||||||
disableDirectIssuance,
|
enableDirectIssuance,
|
||||||
actor,
|
actor,
|
||||||
status,
|
status,
|
||||||
name
|
name
|
||||||
@@ -340,12 +348,18 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
throw new BadRequestError({ message: "Invalid certificate authority type" });
|
throw new BadRequestError({ message: "Invalid certificate authority type" });
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteCertificateAuthority = async ({ id, type }: { id: string; type: CaType }, actor: OrgServiceActor) => {
|
const deleteCertificateAuthority = async (
|
||||||
const certificateAuthority = await certificateAuthorityDAL.findByIdWithAssociatedCa(id);
|
{ caName, type, projectId }: { caName: string; type: CaType; projectId: string },
|
||||||
|
actor: OrgServiceActor
|
||||||
|
) => {
|
||||||
|
const certificateAuthority = await certificateAuthorityDAL.findByNameAndProjectIdWithAssociatedCa(
|
||||||
|
caName,
|
||||||
|
projectId
|
||||||
|
);
|
||||||
|
|
||||||
if (!certificateAuthority)
|
if (!certificateAuthority)
|
||||||
throw new NotFoundError({
|
throw new NotFoundError({
|
||||||
message: `Could not find certificate authority with ID "${id}"`
|
message: `Could not find certificate authority with name "${caName}" in project "${projectId}"`
|
||||||
});
|
});
|
||||||
|
|
||||||
const { permission } = await permissionService.getProjectPermission({
|
const { permission } = await permissionService.getProjectPermission({
|
||||||
@@ -374,17 +388,17 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
await certificateAuthorityDAL.deleteById(id);
|
await certificateAuthorityDAL.deleteById(certificateAuthority.id);
|
||||||
|
|
||||||
if (type === CaType.INTERNAL) {
|
if (type === CaType.INTERNAL) {
|
||||||
return {
|
return {
|
||||||
id: certificateAuthority.id,
|
id: certificateAuthority.id,
|
||||||
type,
|
type,
|
||||||
disableDirectIssuance: certificateAuthority.disableDirectIssuance,
|
enableDirectIssuance: certificateAuthority.enableDirectIssuance,
|
||||||
name: certificateAuthority.internalCa?.friendlyName,
|
name: certificateAuthority.name,
|
||||||
projectId: certificateAuthority.projectId,
|
projectId: certificateAuthority.projectId,
|
||||||
configuration: certificateAuthority.internalCa,
|
configuration: certificateAuthority.internalCa,
|
||||||
status: certificateAuthority.internalCa?.status
|
status: certificateAuthority.status
|
||||||
} as TCertificateAuthority;
|
} as TCertificateAuthority;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -397,7 +411,7 @@ export const certificateAuthorityServiceFactory = ({
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
createCertificateAuthority,
|
createCertificateAuthority,
|
||||||
findCertificateAuthorityById,
|
findCertificateAuthorityByNameAndProjectId,
|
||||||
listCertificateAuthoritiesByProjectId,
|
listCertificateAuthoritiesByProjectId,
|
||||||
updateCertificateAuthority,
|
updateCertificateAuthority,
|
||||||
deleteCertificateAuthority
|
deleteCertificateAuthority
|
||||||
|
|||||||
@@ -13,5 +13,6 @@ export type TCreateCertificateAuthorityDTO = Omit<TCertificateAuthority, "id">;
|
|||||||
|
|
||||||
export type TUpdateCertificateAuthorityDTO = Partial<Omit<TCreateCertificateAuthorityDTO, "projectId">> & {
|
export type TUpdateCertificateAuthorityDTO = Partial<Omit<TCreateCertificateAuthorityDTO, "projectId">> & {
|
||||||
type: CaType;
|
type: CaType;
|
||||||
id: string;
|
caName: string;
|
||||||
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|||||||
+24
-24
@@ -1,6 +1,7 @@
|
|||||||
/* eslint-disable no-bitwise */
|
/* eslint-disable no-bitwise */
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
import * as x509 from "@peculiar/x509";
|
import * as x509 from "@peculiar/x509";
|
||||||
|
import slugify from "@sindresorhus/slugify";
|
||||||
import crypto, { KeyObject } from "crypto";
|
import crypto, { KeyObject } from "crypto";
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
@@ -21,6 +22,7 @@ import { extractX509CertFromChain } from "@app/lib/certificates/extract-certific
|
|||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
import { ms } from "@app/lib/ms";
|
import { ms } from "@app/lib/ms";
|
||||||
|
import { alphaNumericNanoId } from "@app/lib/nanoid";
|
||||||
import { isFQDN } from "@app/lib/validator/validate-url";
|
import { isFQDN } from "@app/lib/validator/validate-url";
|
||||||
import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
|
import { TCertificateBodyDALFactory } from "@app/services/certificate/certificate-body-dal";
|
||||||
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
|
import { TCertificateDALFactory } from "@app/services/certificate/certificate-dal";
|
||||||
@@ -200,14 +202,16 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
const ca = await certificateAuthorityDAL.create(
|
const ca = await certificateAuthorityDAL.create(
|
||||||
{
|
{
|
||||||
projectId,
|
projectId,
|
||||||
disableDirectIssuance: requireTemplateForIssuance
|
enableDirectIssuance: !requireTemplateForIssuance,
|
||||||
|
name: slugify(`${friendlyName || dn}-${alphaNumericNanoId(8)}`),
|
||||||
|
status: type === InternalCaType.ROOT ? CaStatus.ACTIVE : CaStatus.PENDING_CERTIFICATE
|
||||||
},
|
},
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
|
||||||
const internalCa = await internalCertificateAuthorityDAL.create(
|
const internalCa = await internalCertificateAuthorityDAL.create(
|
||||||
{
|
{
|
||||||
certificateAuthorityId: ca.id,
|
caId: ca.id,
|
||||||
type,
|
type,
|
||||||
organization,
|
organization,
|
||||||
ou,
|
ou,
|
||||||
@@ -216,7 +220,6 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
locality,
|
locality,
|
||||||
friendlyName: friendlyName || dn,
|
friendlyName: friendlyName || dn,
|
||||||
commonName,
|
commonName,
|
||||||
status: type === InternalCaType.ROOT ? CaStatus.ACTIVE : CaStatus.PENDING_CERTIFICATE,
|
|
||||||
dn,
|
dn,
|
||||||
keyAlgorithm,
|
keyAlgorithm,
|
||||||
...(type === InternalCaType.ROOT && {
|
...(type === InternalCaType.ROOT && {
|
||||||
@@ -357,7 +360,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
* Update CA with id [caId].
|
* Update CA with id [caId].
|
||||||
* Note: Used to enable/disable CA
|
* Note: Used to enable/disable CA
|
||||||
*/
|
*/
|
||||||
const updateCaById = async ({ caId, status, requireTemplateForIssuance, ...dto }: TUpdateCaDTO) => {
|
const updateCaById = async ({ caId, status, requireTemplateForIssuance, name, ...dto }: TUpdateCaDTO) => {
|
||||||
const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId);
|
const ca = await certificateAuthorityDAL.findByIdWithAssociatedCa(caId);
|
||||||
if (!ca.internalCa) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
|
if (!ca.internalCa) throw new NotFoundError({ message: `CA with ID '${caId}' not found` });
|
||||||
|
|
||||||
@@ -378,20 +381,14 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const updatedCa = await certificateAuthorityDAL.transaction(async (tx) => {
|
const updatedCa = await certificateAuthorityDAL.transaction(async (tx) => {
|
||||||
if (status !== undefined) {
|
if (requireTemplateForIssuance !== undefined || status !== undefined || name !== undefined) {
|
||||||
await internalCertificateAuthorityDAL.update(
|
await certificateAuthorityDAL.updateById(
|
||||||
{
|
ca.id,
|
||||||
certificateAuthorityId: ca.id
|
{ enableDirectIssuance: !requireTemplateForIssuance, status, name },
|
||||||
},
|
|
||||||
{ status },
|
|
||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requireTemplateForIssuance !== undefined) {
|
|
||||||
await certificateAuthorityDAL.updateById(ca.id, { disableDirectIssuance: requireTemplateForIssuance }, tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
return certificateAuthorityDAL.findByIdWithAssociatedCa(caId, tx);
|
return certificateAuthorityDAL.findByIdWithAssociatedCa(caId, tx);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -509,7 +506,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
ProjectPermissionSub.CertificateAuthorities
|
ProjectPermissionSub.CertificateAuthorities
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ca.internalCa.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
if (ca.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
||||||
|
|
||||||
// get latest CA certificate
|
// get latest CA certificate
|
||||||
const caCert = await certificateAuthorityCertDAL.findById(ca.internalCa.activeCaCertId);
|
const caCert = await certificateAuthorityCertDAL.findById(ca.internalCa.activeCaCertId);
|
||||||
@@ -604,7 +601,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
|
|
||||||
await internalCertificateAuthorityDAL.update(
|
await internalCertificateAuthorityDAL.update(
|
||||||
{
|
{
|
||||||
certificateAuthorityId: ca.id
|
caId: ca.id
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
activeCaCertId: newCaCert.id,
|
activeCaCertId: newCaCert.id,
|
||||||
@@ -746,7 +743,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
|
|
||||||
await internalCertificateAuthorityDAL.update(
|
await internalCertificateAuthorityDAL.update(
|
||||||
{
|
{
|
||||||
certificateAuthorityId: ca.id
|
caId: ca.id
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
activeCaCertId: newCaCert.id,
|
activeCaCertId: newCaCert.id,
|
||||||
@@ -914,7 +911,7 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
ProjectPermissionSub.CertificateAuthorities
|
ProjectPermissionSub.CertificateAuthorities
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ca.internalCa.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
if (ca.status === CaStatus.DISABLED) throw new BadRequestError({ message: "CA is disabled" });
|
||||||
if (!ca.internalCa.activeCaCertId)
|
if (!ca.internalCa.activeCaCertId)
|
||||||
throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
||||||
|
|
||||||
@@ -1150,12 +1147,15 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
tx
|
tx
|
||||||
);
|
);
|
||||||
|
|
||||||
|
await certificateAuthorityDAL.updateById(ca.id, {
|
||||||
|
status: CaStatus.ACTIVE
|
||||||
|
});
|
||||||
|
|
||||||
await internalCertificateAuthorityDAL.update(
|
await internalCertificateAuthorityDAL.update(
|
||||||
{
|
{
|
||||||
certificateAuthorityId: ca.id
|
caId: ca.id
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: CaStatus.ACTIVE,
|
|
||||||
maxPathLength: maxPathLength === undefined ? -1 : maxPathLength,
|
maxPathLength: maxPathLength === undefined ? -1 : maxPathLength,
|
||||||
notBefore: new Date(certObj.notBefore),
|
notBefore: new Date(certObj.notBefore),
|
||||||
notAfter: new Date(certObj.notAfter),
|
notAfter: new Date(certObj.notAfter),
|
||||||
@@ -1231,10 +1231,10 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
ProjectPermissionSub.Certificates
|
ProjectPermissionSub.Certificates
|
||||||
);
|
);
|
||||||
|
|
||||||
if (ca.internalCa.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" });
|
if (ca.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" });
|
||||||
if (!ca.internalCa.activeCaCertId)
|
if (!ca.internalCa.activeCaCertId)
|
||||||
throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
||||||
if (ca.disableDirectIssuance && !certificateTemplate) {
|
if (!ca.enableDirectIssuance && !certificateTemplate) {
|
||||||
throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" });
|
throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" });
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1589,10 +1589,10 @@ export const internalCertificateAuthorityServiceFactory = ({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ca.internalCa.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" });
|
if (ca.status !== CaStatus.ACTIVE) throw new BadRequestError({ message: "CA is not active" });
|
||||||
if (!ca.internalCa.activeCaCertId)
|
if (!ca.internalCa.activeCaCertId)
|
||||||
throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
throw new BadRequestError({ message: "CA does not have a certificate installed" });
|
||||||
if (ca.disableDirectIssuance && !certificateTemplate) {
|
if (!ca.enableDirectIssuance && !certificateTemplate) {
|
||||||
throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" });
|
throw new BadRequestError({ message: "Certificate template or subscriber is required for issuance" });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
@@ -69,12 +69,14 @@ export type TUpdateCaDTO =
|
|||||||
| {
|
| {
|
||||||
isInternal: true;
|
isInternal: true;
|
||||||
caId: string;
|
caId: string;
|
||||||
|
name?: string;
|
||||||
status?: CaStatus;
|
status?: CaStatus;
|
||||||
requireTemplateForIssuance?: boolean;
|
requireTemplateForIssuance?: boolean;
|
||||||
}
|
}
|
||||||
| ({
|
| ({
|
||||||
isInternal: false;
|
isInternal: false;
|
||||||
caId: string;
|
caId: string;
|
||||||
|
name?: string;
|
||||||
status?: CaStatus;
|
status?: CaStatus;
|
||||||
requireTemplateForIssuance?: boolean;
|
requireTemplateForIssuance?: boolean;
|
||||||
} & Omit<TProjectPermission, "projectId">);
|
} & Omit<TProjectPermission, "projectId">);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export const certificateTemplateDALFactory = (db: TDbClient) => {
|
|||||||
)
|
)
|
||||||
.join(
|
.join(
|
||||||
TableName.InternalCertificateAuthority,
|
TableName.InternalCertificateAuthority,
|
||||||
`${TableName.InternalCertificateAuthority}.certificateAuthorityId`,
|
`${TableName.InternalCertificateAuthority}.caId`,
|
||||||
`${TableName.CertificateAuthority}.id`
|
`${TableName.CertificateAuthority}.id`
|
||||||
)
|
)
|
||||||
.where(`${TableName.CertificateAuthority}.projectId`, "=", projectId)
|
.where(`${TableName.CertificateAuthority}.projectId`, "=", projectId)
|
||||||
@@ -48,7 +48,7 @@ export const certificateTemplateDALFactory = (db: TDbClient) => {
|
|||||||
.join(TableName.Project, `${TableName.Project}.id`, `${TableName.CertificateAuthority}.projectId`)
|
.join(TableName.Project, `${TableName.Project}.id`, `${TableName.CertificateAuthority}.projectId`)
|
||||||
.join(
|
.join(
|
||||||
TableName.InternalCertificateAuthority,
|
TableName.InternalCertificateAuthority,
|
||||||
`${TableName.InternalCertificateAuthority}.certificateAuthorityId`,
|
`${TableName.InternalCertificateAuthority}.caId`,
|
||||||
`${TableName.CertificateAuthority}.id`
|
`${TableName.CertificateAuthority}.id`
|
||||||
)
|
)
|
||||||
.where(`${TableName.CertificateTemplate}.id`, "=", id)
|
.where(`${TableName.CertificateTemplate}.id`, "=", id)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export const pkiAlertDALFactory = (db: TDbClient) => {
|
|||||||
"pci.pkiCollectionId"
|
"pci.pkiCollectionId"
|
||||||
)
|
)
|
||||||
.from(`${TableName.CertificateAuthority} as ${PkiItemType.CA}`)
|
.from(`${TableName.CertificateAuthority} as ${PkiItemType.CA}`)
|
||||||
.join(`${TableName.InternalCertificateAuthority} as ic`, `${PkiItemType.CA}.id`, "ic.certificateAuthorityId")
|
.join(`${TableName.InternalCertificateAuthority} as ic`, `${PkiItemType.CA}.id`, "ic.caId")
|
||||||
.join(`${TableName.PkiCollectionItem} as pci`, `${PkiItemType.CA}.id`, "pci.caId")
|
.join(`${TableName.PkiCollectionItem} as pci`, `${PkiItemType.CA}.id`, "pci.caId")
|
||||||
.unionAll((qb) => {
|
.unionAll((qb) => {
|
||||||
void qb
|
void qb
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export const pkiCollectionItemDALFactory = (db: TDbClient) => {
|
|||||||
.leftJoin(
|
.leftJoin(
|
||||||
TableName.InternalCertificateAuthority,
|
TableName.InternalCertificateAuthority,
|
||||||
`${TableName.PkiCollectionItem}.caId`,
|
`${TableName.PkiCollectionItem}.caId`,
|
||||||
`${TableName.InternalCertificateAuthority}.certificateAuthorityId`
|
`${TableName.InternalCertificateAuthority}.caId`
|
||||||
)
|
)
|
||||||
.leftJoin(TableName.Certificate, `${TableName.PkiCollectionItem}.certId`, `${TableName.Certificate}.id`)
|
.leftJoin(TableName.Certificate, `${TableName.PkiCollectionItem}.certId`, `${TableName.Certificate}.id`)
|
||||||
.where((builder) => {
|
.where((builder) => {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: "Delete"
|
title: "Delete"
|
||||||
openapi: "DELETE /api/v1/pki/ca/acme/{certificateAuthorityId}"
|
openapi: "DELETE /api/v1/pki/ca/acme/{caName}"
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: "Read"
|
title: "Read"
|
||||||
openapi: "GET /api/v1/pki/ca/acme/{certificateAuthorityId}"
|
openapi: "GET /api/v1/pki/ca/acme/{caName}"
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
---
|
---
|
||||||
title: "Update"
|
title: "Update"
|
||||||
openapi: "PATCH /api/v1/pki/ca/acme/{certificateAuthorityId}"
|
openapi: "PATCH /api/v1/pki/ca/acme/{caName}"
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
---
|
|
||||||
title: "Retrieve active certificate bundle"
|
|
||||||
openapi: "GET /api/v1/pki/subscribers/{subscriberName}/active-certificate/bundle"
|
|
||||||
---
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
title: "Retrieve latest certificate bundle"
|
||||||
|
openapi: "GET /api/v1/pki/subscribers/{subscriberName}/latest-certificate-bundle"
|
||||||
|
---
|
||||||
+1
-1
@@ -1522,7 +1522,7 @@
|
|||||||
"api-reference/endpoints/pki/subscribers/issue-cert",
|
"api-reference/endpoints/pki/subscribers/issue-cert",
|
||||||
"api-reference/endpoints/pki/subscribers/sign-cert",
|
"api-reference/endpoints/pki/subscribers/sign-cert",
|
||||||
"api-reference/endpoints/pki/subscribers/order-cert",
|
"api-reference/endpoints/pki/subscribers/order-cert",
|
||||||
"api-reference/endpoints/pki/subscribers/get-active-cert-bundle"
|
"api-reference/endpoints/pki/subscribers/get-latest-cert-bundle"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ export {
|
|||||||
useUpdateUnifiedCa
|
useUpdateUnifiedCa
|
||||||
} from "./mutations";
|
} from "./mutations";
|
||||||
export {
|
export {
|
||||||
|
useGetCa,
|
||||||
useGetCaById,
|
useGetCaById,
|
||||||
useGetCaByTypeAndId,
|
|
||||||
useGetCaCert,
|
useGetCaCert,
|
||||||
useGetCaCerts,
|
useGetCaCerts,
|
||||||
useGetCaCertTemplates,
|
useGetCaCertTemplates,
|
||||||
|
|||||||
@@ -26,15 +26,13 @@ import {
|
|||||||
export const useUpdateUnifiedCa = () => {
|
export const useUpdateUnifiedCa = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation<TUnifiedCertificateAuthority, object, TUpdateUnifiedCertificateAuthorityDTO>({
|
return useMutation<TUnifiedCertificateAuthority, object, TUpdateUnifiedCertificateAuthorityDTO>({
|
||||||
mutationFn: async ({ id, ...body }) => {
|
mutationFn: async ({ caName, ...body }) => {
|
||||||
const {
|
const { data } = await apiRequest.patch<TUnifiedCertificateAuthority>(
|
||||||
data: { certificateAuthority }
|
`/api/v1/pki/ca/${body.type}/${caName}`,
|
||||||
} = await apiRequest.patch<{ certificateAuthority: TUnifiedCertificateAuthority }>(
|
|
||||||
`/api/v1/pki/ca/${body.type}/${id}`,
|
|
||||||
body
|
body
|
||||||
);
|
);
|
||||||
|
|
||||||
return certificateAuthority;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: ({ projectId, type }) => {
|
onSuccess: ({ projectId, type }) => {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
@@ -65,11 +63,16 @@ export const useCreateUnifiedCa = () => {
|
|||||||
export const useDeleteUnifiedCa = () => {
|
export const useDeleteUnifiedCa = () => {
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation<TUnifiedCertificateAuthority, object, TDeleteUnifiedCertificateAuthorityDTO>({
|
return useMutation<TUnifiedCertificateAuthority, object, TDeleteUnifiedCertificateAuthorityDTO>({
|
||||||
mutationFn: async ({ caId, type }) => {
|
mutationFn: async ({ caName, type, projectId }) => {
|
||||||
const {
|
const {
|
||||||
data: { certificateAuthority }
|
data: { certificateAuthority }
|
||||||
} = await apiRequest.delete<{ certificateAuthority: TUnifiedCertificateAuthority }>(
|
} = await apiRequest.delete<{ certificateAuthority: TUnifiedCertificateAuthority }>(
|
||||||
`/api/v1/pki/ca/${type}/${caId}`
|
`/api/v1/pki/ca/${type}/${caName}`,
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
projectId
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
return certificateAuthority;
|
return certificateAuthority;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { TCertificateAuthority, TUnifiedCertificateAuthority } from "./types";
|
|||||||
|
|
||||||
export const caKeys = {
|
export const caKeys = {
|
||||||
getCaById: (caId: string) => [{ caId }, "ca"],
|
getCaById: (caId: string) => [{ caId }, "ca"],
|
||||||
getCaByTypeAndId: (type: CaType, caId: string) => [{ type, caId }, "ca"],
|
getCaByNameAndProjectId: (caName: string, projectId: string) => [{ caName, projectId }, "ca"],
|
||||||
listCasByTypeAndProjectId: (type: CaType, projectId: string) => [{ type, projectId }, "cas"],
|
listCasByTypeAndProjectId: (type: CaType, projectId: string) => [{ type, projectId }, "cas"],
|
||||||
listCasByProjectId: (projectId: string) => [{ projectId }, "cas"],
|
listCasByProjectId: (projectId: string) => [{ projectId }, "cas"],
|
||||||
getCaCerts: (caId: string) => [{ caId }, "ca-cert"],
|
getCaCerts: (caId: string) => [{ caId }, "ca-cert"],
|
||||||
@@ -20,18 +20,24 @@ export const caKeys = {
|
|||||||
getCaEstConfig: (caId: string) => [{ caId }, "ca-est-config"]
|
getCaEstConfig: (caId: string) => [{ caId }, "ca-est-config"]
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useGetCaByTypeAndId = (type: CaType, caId: string) => {
|
export const useGetCa = ({
|
||||||
|
caName,
|
||||||
|
projectId,
|
||||||
|
type
|
||||||
|
}: {
|
||||||
|
caName: string;
|
||||||
|
projectId: string;
|
||||||
|
type: CaType;
|
||||||
|
}) => {
|
||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: caKeys.getCaByTypeAndId(type, caId),
|
queryKey: caKeys.getCaByNameAndProjectId(caName, projectId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const {
|
const { data } = await apiRequest.get<TUnifiedCertificateAuthority>(
|
||||||
data: { certificateAuthority }
|
`/api/v1/pki/ca/${type}/${caName}?projectId=${projectId}`
|
||||||
} = await apiRequest.get<{ certificateAuthority: TUnifiedCertificateAuthority }>(
|
|
||||||
`/api/v1/pki/ca/${type}/${caId}`
|
|
||||||
);
|
);
|
||||||
return certificateAuthority;
|
return data;
|
||||||
},
|
},
|
||||||
enabled: Boolean(caId)
|
enabled: Boolean(caName && projectId && type)
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -39,11 +45,11 @@ export const useListCasByTypeAndProjectId = (type: CaType, projectId: string) =>
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: caKeys.listCasByTypeAndProjectId(type, projectId),
|
queryKey: caKeys.listCasByTypeAndProjectId(type, projectId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
const { data } = await apiRequest.get<{
|
const { data } = await apiRequest.get<TUnifiedCertificateAuthority[]>(
|
||||||
certificateAuthorities: TUnifiedCertificateAuthority[];
|
`/api/v1/pki/ca/${type}?projectId=${projectId}`
|
||||||
}>(`/api/v1/pki/ca/${type}?projectId=${projectId}`);
|
);
|
||||||
|
|
||||||
return data.certificateAuthorities;
|
return data;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export type TAcmeCertificateAuthority = {
|
|||||||
type: CaType.ACME;
|
type: CaType.ACME;
|
||||||
status: CaStatus;
|
status: CaStatus;
|
||||||
name: string;
|
name: string;
|
||||||
disableDirectIssuance: boolean;
|
enableDirectIssuance: boolean;
|
||||||
configuration: {
|
configuration: {
|
||||||
dnsAppConnectionId: string;
|
dnsAppConnectionId: string;
|
||||||
dnsProviderConfig: {
|
dnsProviderConfig: {
|
||||||
@@ -25,7 +25,7 @@ export type TInternalCertificateAuthority = {
|
|||||||
type: CaType.INTERNAL;
|
type: CaType.INTERNAL;
|
||||||
status: CaStatus;
|
status: CaStatus;
|
||||||
name: string;
|
name: string;
|
||||||
disableDirectIssuance: boolean;
|
enableDirectIssuance: boolean;
|
||||||
configuration: {
|
configuration: {
|
||||||
type: InternalCaType;
|
type: InternalCaType;
|
||||||
friendlyName?: string;
|
friendlyName?: string;
|
||||||
@@ -52,12 +52,13 @@ export type TUnifiedCertificateAuthority =
|
|||||||
|
|
||||||
export type TCreateUnifiedCertificateAuthorityDTO = Omit<TUnifiedCertificateAuthority, "id">;
|
export type TCreateUnifiedCertificateAuthorityDTO = Omit<TUnifiedCertificateAuthority, "id">;
|
||||||
export type TUpdateUnifiedCertificateAuthorityDTO = Partial<TUnifiedCertificateAuthority> & {
|
export type TUpdateUnifiedCertificateAuthorityDTO = Partial<TUnifiedCertificateAuthority> & {
|
||||||
id: string;
|
caName: string;
|
||||||
|
projectId: string;
|
||||||
type: CaType;
|
type: CaType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TDeleteUnifiedCertificateAuthorityDTO = {
|
export type TDeleteUnifiedCertificateAuthorityDTO = {
|
||||||
caId: string;
|
caName: string;
|
||||||
type: CaType;
|
type: CaType;
|
||||||
projectId: string;
|
projectId: string;
|
||||||
};
|
};
|
||||||
|
|||||||
+16
-15
@@ -23,7 +23,7 @@ import {
|
|||||||
CaStatus,
|
CaStatus,
|
||||||
CaType,
|
CaType,
|
||||||
useCreateUnifiedCa,
|
useCreateUnifiedCa,
|
||||||
useGetCaByTypeAndId,
|
useGetCa,
|
||||||
useUpdateUnifiedCa
|
useUpdateUnifiedCa
|
||||||
} from "@app/hooks/api/ca";
|
} from "@app/hooks/api/ca";
|
||||||
import { UsePopUpState } from "@app/hooks/usePopUp";
|
import { UsePopUpState } from "@app/hooks/usePopUp";
|
||||||
@@ -35,7 +35,7 @@ const schema = z
|
|||||||
name: slugSchema({
|
name: slugSchema({
|
||||||
field: "Name"
|
field: "Name"
|
||||||
}),
|
}),
|
||||||
disableDirectIssuance: z.boolean(),
|
enableDirectIssuance: z.boolean(),
|
||||||
status: z.nativeEnum(CaStatus),
|
status: z.nativeEnum(CaStatus),
|
||||||
configuration: z.object({
|
configuration: z.object({
|
||||||
dnsAppConnection: z.object({
|
dnsAppConnection: z.object({
|
||||||
@@ -65,10 +65,11 @@ const caTypes = [{ label: "ACME", value: CaType.ACME }];
|
|||||||
export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
||||||
const { currentWorkspace } = useWorkspace();
|
const { currentWorkspace } = useWorkspace();
|
||||||
|
|
||||||
const { data: ca } = useGetCaByTypeAndId(
|
const { data: ca } = useGetCa({
|
||||||
(popUp?.ca?.data as { type: CaType })?.type || "",
|
caName: (popUp?.ca?.data as { name: string })?.name || "",
|
||||||
(popUp?.ca?.data as { caId: string })?.caId || ""
|
projectId: currentWorkspace?.id || "",
|
||||||
);
|
type: (popUp?.ca?.data as { type: CaType })?.type || ""
|
||||||
|
});
|
||||||
|
|
||||||
const { mutateAsync: createMutateAsync } = useCreateUnifiedCa();
|
const { mutateAsync: createMutateAsync } = useCreateUnifiedCa();
|
||||||
const { mutateAsync: updateMutateAsync } = useUpdateUnifiedCa();
|
const { mutateAsync: updateMutateAsync } = useUpdateUnifiedCa();
|
||||||
@@ -85,7 +86,7 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
type: CaType.ACME,
|
type: CaType.ACME,
|
||||||
name: "",
|
name: "",
|
||||||
status: CaStatus.ACTIVE,
|
status: CaStatus.ACTIVE,
|
||||||
disableDirectIssuance: false,
|
enableDirectIssuance: true,
|
||||||
configuration: {
|
configuration: {
|
||||||
dnsAppConnection: {
|
dnsAppConnection: {
|
||||||
id: "",
|
id: "",
|
||||||
@@ -122,7 +123,7 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
type: ca.type,
|
type: ca.type,
|
||||||
name: ca.name,
|
name: ca.name,
|
||||||
status: ca.status,
|
status: ca.status,
|
||||||
disableDirectIssuance: ca.disableDirectIssuance,
|
enableDirectIssuance: ca.enableDirectIssuance,
|
||||||
configuration: {
|
configuration: {
|
||||||
dnsAppConnection: {
|
dnsAppConnection: {
|
||||||
id: ca.configuration.dnsAppConnectionId,
|
id: ca.configuration.dnsAppConnectionId,
|
||||||
@@ -142,7 +143,7 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
type: CaType.ACME,
|
type: CaType.ACME,
|
||||||
name: "",
|
name: "",
|
||||||
status: CaStatus.ACTIVE,
|
status: CaStatus.ACTIVE,
|
||||||
disableDirectIssuance: false,
|
enableDirectIssuance: true,
|
||||||
configuration: {
|
configuration: {
|
||||||
dnsAppConnection: {
|
dnsAppConnection: {
|
||||||
id: "",
|
id: "",
|
||||||
@@ -162,7 +163,7 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
const onFormSubmit = async ({
|
const onFormSubmit = async ({
|
||||||
type,
|
type,
|
||||||
name,
|
name,
|
||||||
disableDirectIssuance,
|
enableDirectIssuance,
|
||||||
status,
|
status,
|
||||||
configuration
|
configuration
|
||||||
}: FormData) => {
|
}: FormData) => {
|
||||||
@@ -171,12 +172,12 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
|
|
||||||
if (ca && type !== CaType.INTERNAL) {
|
if (ca && type !== CaType.INTERNAL) {
|
||||||
await updateMutateAsync({
|
await updateMutateAsync({
|
||||||
id: ca.id,
|
caName: ca.name,
|
||||||
projectId: currentWorkspace.id,
|
projectId: currentWorkspace.id,
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
status,
|
status,
|
||||||
disableDirectIssuance,
|
enableDirectIssuance,
|
||||||
configuration: {
|
configuration: {
|
||||||
...configuration,
|
...configuration,
|
||||||
dnsAppConnectionId: configuration.dnsAppConnection.id
|
dnsAppConnectionId: configuration.dnsAppConnection.id
|
||||||
@@ -188,7 +189,7 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
status,
|
status,
|
||||||
disableDirectIssuance,
|
enableDirectIssuance,
|
||||||
configuration: {
|
configuration: {
|
||||||
...configuration,
|
...configuration,
|
||||||
dnsAppConnectionId: configuration.dnsAppConnection.id
|
dnsAppConnectionId: configuration.dnsAppConnection.id
|
||||||
@@ -369,7 +370,7 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
)}
|
)}
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="disableDirectIssuance"
|
name="enableDirectIssuance"
|
||||||
render={({ field, fieldState: { error } }) => {
|
render={({ field, fieldState: { error } }) => {
|
||||||
return (
|
return (
|
||||||
<FormControl isError={Boolean(error)} errorText={error?.message} className="my-8">
|
<FormControl isError={Boolean(error)} errorText={error?.message} className="my-8">
|
||||||
@@ -378,7 +379,7 @@ export const ExternalCaModal = ({ popUp, handlePopUpToggle }: Props) => {
|
|||||||
onCheckedChange={(value) => field.onChange(value)}
|
onCheckedChange={(value) => field.onChange(value)}
|
||||||
isChecked={field.value}
|
isChecked={field.value}
|
||||||
>
|
>
|
||||||
<p className="w-full">Disable Direct Issuance</p>
|
<p className="w-full">Enable Direct Issuance</p>
|
||||||
</Switch>
|
</Switch>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
);
|
);
|
||||||
|
|||||||
+7
-7
@@ -24,11 +24,11 @@ export const ExternalCaSection = () => {
|
|||||||
"upgradePlan"
|
"upgradePlan"
|
||||||
] as const);
|
] as const);
|
||||||
|
|
||||||
const onRemoveCaSubmit = async (caId: string, type: CaType) => {
|
const onRemoveCaSubmit = async (caName: string, type: CaType) => {
|
||||||
try {
|
try {
|
||||||
if (!currentWorkspace?.id) return;
|
if (!currentWorkspace?.id) return;
|
||||||
|
|
||||||
await deleteCa({ caId, type, projectId: currentWorkspace.id });
|
await deleteCa({ caName, type, projectId: currentWorkspace.id });
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: "Successfully deleted CA",
|
text: "Successfully deleted CA",
|
||||||
@@ -45,18 +45,18 @@ export const ExternalCaSection = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onUpdateCaStatus = async ({
|
const onUpdateCaStatus = async ({
|
||||||
caId,
|
name,
|
||||||
type,
|
type,
|
||||||
status
|
status
|
||||||
}: {
|
}: {
|
||||||
caId: string;
|
name: string;
|
||||||
type: CaType;
|
type: CaType;
|
||||||
status: CaStatus;
|
status: CaStatus;
|
||||||
}) => {
|
}) => {
|
||||||
try {
|
try {
|
||||||
if (!currentWorkspace?.slug) return;
|
if (!currentWorkspace?.slug) return;
|
||||||
|
|
||||||
await updateCa({ id: caId, type, status });
|
await updateCa({ caName: name, type, status, projectId: currentWorkspace.id });
|
||||||
|
|
||||||
createNotification({
|
createNotification({
|
||||||
text: `Successfully ${status === CaStatus.ACTIVE ? "enabled" : "disabled"} CA`,
|
text: `Successfully ${status === CaStatus.ACTIVE ? "enabled" : "disabled"} CA`,
|
||||||
@@ -105,7 +105,7 @@ export const ExternalCaSection = () => {
|
|||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={() =>
|
onDeleteApproved={() =>
|
||||||
onRemoveCaSubmit(
|
onRemoveCaSubmit(
|
||||||
(popUp?.deleteCa?.data as { caId: string })?.caId,
|
(popUp?.deleteCa?.data as { name: string })?.name,
|
||||||
(popUp?.deleteCa?.data as { type: CaType })?.type
|
(popUp?.deleteCa?.data as { type: CaType })?.type
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -127,7 +127,7 @@ export const ExternalCaSection = () => {
|
|||||||
deleteKey="confirm"
|
deleteKey="confirm"
|
||||||
onDeleteApproved={() =>
|
onDeleteApproved={() =>
|
||||||
onUpdateCaStatus(
|
onUpdateCaStatus(
|
||||||
popUp?.caStatus?.data as { caId: string; type: CaType; status: CaStatus }
|
popUp?.caStatus?.data as { name: string; type: CaType; status: CaStatus }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
+5
-5
@@ -35,7 +35,7 @@ type Props = {
|
|||||||
handlePopUpOpen: (
|
handlePopUpOpen: (
|
||||||
popUpName: keyof UsePopUpState<["ca", "deleteCa", "caStatus", "upgradePlan"]>,
|
popUpName: keyof UsePopUpState<["ca", "deleteCa", "caStatus", "upgradePlan"]>,
|
||||||
data?: {
|
data?: {
|
||||||
caId?: string;
|
name?: string;
|
||||||
type?: CaType;
|
type?: CaType;
|
||||||
status?: CaStatus;
|
status?: CaStatus;
|
||||||
description?: string;
|
description?: string;
|
||||||
@@ -71,7 +71,7 @@ export const ExternalCaTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
key={`ca-${ca.id}`}
|
key={`ca-${ca.id}`}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
handlePopUpOpen("ca", {
|
handlePopUpOpen("ca", {
|
||||||
caId: ca.id,
|
name: ca.name,
|
||||||
type: ca.type
|
type: ca.type
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@@ -105,7 +105,7 @@ export const ExternalCaTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handlePopUpOpen("ca", {
|
handlePopUpOpen("ca", {
|
||||||
caId: ca.id,
|
name: ca.name,
|
||||||
type: ca.type
|
type: ca.type
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
@@ -130,7 +130,7 @@ export const ExternalCaTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handlePopUpOpen("caStatus", {
|
handlePopUpOpen("caStatus", {
|
||||||
caId: ca.id,
|
name: ca.name,
|
||||||
type: ca.type,
|
type: ca.type,
|
||||||
status:
|
status:
|
||||||
ca.status === CaStatus.ACTIVE
|
ca.status === CaStatus.ACTIVE
|
||||||
@@ -158,7 +158,7 @@ export const ExternalCaTable = ({ handlePopUpOpen }: Props) => {
|
|||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handlePopUpOpen("deleteCa", {
|
handlePopUpOpen("deleteCa", {
|
||||||
caId: ca.id,
|
name: ca.name,
|
||||||
type: ca.type
|
type: ca.type
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user