mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 14:28:20 +00:00
Add more scheme
This commit is contained in:
@@ -0,0 +1,436 @@
|
|||||||
|
/**
|
||||||
|
* ACME Error Classes based on RFC 8555 Section 6.2
|
||||||
|
* https://datatracker.ietf.org/doc/html/rfc8555#section-6.2
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface IAcmeError {
|
||||||
|
type: string;
|
||||||
|
detail: string;
|
||||||
|
status: number;
|
||||||
|
subproblems?: Array<{ type: string; detail: string; identifier?: { type: string; value: string } }>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class AcmeError extends Error implements IAcmeError {
|
||||||
|
type: string;
|
||||||
|
|
||||||
|
detail: string;
|
||||||
|
|
||||||
|
status: number;
|
||||||
|
|
||||||
|
subproblems?: Array<{ type: string; detail: string; identifier?: { type: string; value: string } }>;
|
||||||
|
|
||||||
|
error?: unknown;
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
type,
|
||||||
|
detail,
|
||||||
|
status,
|
||||||
|
subproblems,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
type: string;
|
||||||
|
detail: string;
|
||||||
|
status: number;
|
||||||
|
subproblems?: Array<{ type: string; detail: string; identifier?: { type: string; value: string } }>;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
}) {
|
||||||
|
super(message || detail);
|
||||||
|
this.type = type;
|
||||||
|
this.detail = detail;
|
||||||
|
this.status = status;
|
||||||
|
this.subproblems = subproblems;
|
||||||
|
this.error = error;
|
||||||
|
this.name = "AcmeError";
|
||||||
|
}
|
||||||
|
|
||||||
|
toAcmeResponse(): IAcmeError {
|
||||||
|
return {
|
||||||
|
type: this.type,
|
||||||
|
detail: this.detail,
|
||||||
|
status: this.status,
|
||||||
|
subproblems: this.subproblems
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* malformed - The request message was malformed (RFC 8555 Section 6.7.1)
|
||||||
|
*/
|
||||||
|
export class AcmeMalformedError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The request message was malformed",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "malformed",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeMalformedError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unauthorized - The client lacks sufficient authorization (RFC 8555 Section 6.7.2)
|
||||||
|
*/
|
||||||
|
export class AcmeUnauthorizedError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The client lacks sufficient authorization",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "unauthorized",
|
||||||
|
detail,
|
||||||
|
status: 403,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeUnauthorizedError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* accountDoesNotExist - The request specified an account that does not exist
|
||||||
|
* (RFC 8555 Section 6.7.3)
|
||||||
|
*/
|
||||||
|
export class AcmeAccountDoesNotExistError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The request specified an account that does not exist",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "accountDoesNotExist",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeAccountDoesNotExistError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* badNonce - The client sent an unacceptable anti-replay nonce (RFC 8555 Section 6.7.4)
|
||||||
|
*/
|
||||||
|
export class AcmeBadNonceError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The client sent an unacceptable anti-replay nonce",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "badNonce",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeBadNonceError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* badSignature - The JWS signature is invalid (RFC 8555 Section 6.7.5)
|
||||||
|
*/
|
||||||
|
export class AcmeBadSignatureError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The JWS signature is invalid",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "badSignature",
|
||||||
|
detail,
|
||||||
|
status: 401,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeBadSignatureError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* badPublicKey - The public key is not acceptable (RFC 8555 Section 6.7.6)
|
||||||
|
*/
|
||||||
|
export class AcmeBadPublicKeyError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The public key is not acceptable",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "badPublicKey",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeBadPublicKeyError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* badCSR - The CSR is unacceptable (RFC 8555 Section 6.7.7)
|
||||||
|
*/
|
||||||
|
export class AcmeBadCsrError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The CSR is unacceptable",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "badCSR",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeBadCsrError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* badRevocationReason - The revocation reason provided is not allowed
|
||||||
|
* (RFC 8555 Section 6.7.8)
|
||||||
|
*/
|
||||||
|
export class AcmeBadRevocationReasonError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The revocation reason provided is not allowed",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "badRevocationReason",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeBadRevocationReasonError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rateLimited - The client has exceeded a rate limit (RFC 8555 Section 6.7.9)
|
||||||
|
*/
|
||||||
|
export class AcmeRateLimitedError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The client has exceeded a rate limit",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "rateLimited",
|
||||||
|
detail,
|
||||||
|
status: 429,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeRateLimitedError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rejectedIdentifier - The server will not issue certificates for the identifier
|
||||||
|
* (RFC 8555 Section 6.7.10)
|
||||||
|
*/
|
||||||
|
export class AcmeRejectedIdentifierError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The server will not issue certificates for the identifier",
|
||||||
|
subproblems,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
subproblems?: Array<{ type: string; detail: string; identifier?: { type: string; value: string } }>;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "rejectedIdentifier",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
subproblems,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeRejectedIdentifierError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serverInternal - An internal error occurred (RFC 8555 Section 6.7.11)
|
||||||
|
*/
|
||||||
|
export class AcmeServerInternalError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "An internal error occurred",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "serverInternal",
|
||||||
|
detail,
|
||||||
|
status: 500,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeServerInternalError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* serviceUnavailable - The service is unavailable (RFC 8555 Section 6.7.12)
|
||||||
|
*/
|
||||||
|
export class AcmeServiceUnavailableError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "The service is unavailable",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "serviceUnavailable",
|
||||||
|
detail,
|
||||||
|
status: 503,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeServiceUnavailableError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unsupportedContact - A contact URL is of an unsupported type (RFC 8555 Section 6.7.13)
|
||||||
|
*/
|
||||||
|
export class AcmeUnsupportedContactError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "A contact URL is of an unsupported type",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "unsupportedContact",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeUnsupportedContactError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* unsupportedIdentifier - An identifier is of an unsupported type
|
||||||
|
* (RFC 8555 Section 6.7.14)
|
||||||
|
*/
|
||||||
|
export class AcmeUnsupportedIdentifierError extends AcmeError {
|
||||||
|
constructor({
|
||||||
|
detail = "An identifier is of an unsupported type",
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "unsupportedIdentifier",
|
||||||
|
detail,
|
||||||
|
status: 400,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.name = "AcmeUnsupportedIdentifierError";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* userActionRequired - Visit the "instance" URL and take actions specified there
|
||||||
|
* (RFC 8555 Section 6.7.15)
|
||||||
|
*/
|
||||||
|
export class AcmeUserActionRequiredError extends AcmeError {
|
||||||
|
instance?: string;
|
||||||
|
|
||||||
|
constructor({
|
||||||
|
detail = "Visit the instance URL and take actions specified there",
|
||||||
|
instance,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
}: {
|
||||||
|
detail?: string;
|
||||||
|
instance?: string;
|
||||||
|
error?: unknown;
|
||||||
|
message?: string;
|
||||||
|
} = {}) {
|
||||||
|
super({
|
||||||
|
type: "userActionRequired",
|
||||||
|
detail,
|
||||||
|
status: 403,
|
||||||
|
error,
|
||||||
|
message
|
||||||
|
});
|
||||||
|
this.instance = instance;
|
||||||
|
this.name = "AcmeUserActionRequiredError";
|
||||||
|
}
|
||||||
|
|
||||||
|
toAcmeResponse(): IAcmeError & { instance?: string } {
|
||||||
|
return {
|
||||||
|
...super.toAcmeResponse(),
|
||||||
|
instance: this.instance
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,25 @@
|
|||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
|
|
||||||
|
export const ProtectedHeaderSchema = z.object({
|
||||||
|
alg: z.string(),
|
||||||
|
nonce: z.string(),
|
||||||
|
url: z.string(),
|
||||||
|
kid: z.string().optional(),
|
||||||
|
jwk: z.record(z.string(), z.string()).optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
// Raw JWS payload schema before parsing and verification
|
||||||
|
export const RawJwsPayloadSchema = z.object({
|
||||||
|
protected: z.string(),
|
||||||
|
payload: z.string(),
|
||||||
|
signature: z.string()
|
||||||
|
});
|
||||||
|
|
||||||
|
export const JwsPayloadSchema = z.object({
|
||||||
|
protectedHeader: ProtectedHeaderSchema,
|
||||||
|
payload: z.any()
|
||||||
|
});
|
||||||
|
|
||||||
// Directory endpoint
|
// Directory endpoint
|
||||||
export const GetAcmeDirectorySchema = z.object({
|
export const GetAcmeDirectorySchema = z.object({
|
||||||
params: z.object({
|
params: z.object({
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { getConfig } from "@app/lib/config/env";
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { NotFoundError } from "@app/lib/errors";
|
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||||
|
|
||||||
import { TCertificateProfileDALFactory } from "@app/services/certificate-profile/certificate-profile-dal";
|
import { TCertificateProfileDALFactory } from "@app/services/certificate-profile/certificate-profile-dal";
|
||||||
|
|
||||||
|
import { AcmeMalformedError, AcmeBadPublicKeyError } from "./pki-acme-errors";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
EnrollmentType,
|
EnrollmentType,
|
||||||
TCertificateProfileWithConfigs
|
TCertificateProfileWithConfigs
|
||||||
@@ -19,18 +21,20 @@ import {
|
|||||||
TGetAcmeAuthorizationResponse,
|
TGetAcmeAuthorizationResponse,
|
||||||
TGetAcmeDirectoryResponse,
|
TGetAcmeDirectoryResponse,
|
||||||
TGetAcmeOrderResponse,
|
TGetAcmeOrderResponse,
|
||||||
|
TRawJwsPayload,
|
||||||
TListAcmeOrdersResponse,
|
TListAcmeOrdersResponse,
|
||||||
TPkiAcmeServiceFactory,
|
TPkiAcmeServiceFactory,
|
||||||
TRespondToAcmeChallengeResponse
|
TRespondToAcmeChallengeResponse,
|
||||||
|
TJwsPayload,
|
||||||
|
TProtectedHeader
|
||||||
} from "./pki-acme-types";
|
} from "./pki-acme-types";
|
||||||
|
import { flattenedVerify, importJWK, JWK, JWSHeaderParameters } from "jose";
|
||||||
|
|
||||||
type TPkiAcmeServiceFactoryDep = {
|
type TPkiAcmeServiceFactoryDep = {
|
||||||
certificateProfileDAL: Pick<TCertificateProfileDALFactory, "findById">;
|
certificateProfileDAL: Pick<TCertificateProfileDALFactory, "findById">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
|
export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
|
||||||
const appCfg = getConfig();
|
|
||||||
|
|
||||||
const validateAcmeProfile = async (profileId: string): Promise<TCertificateProfileWithConfigs> => {
|
const validateAcmeProfile = async (profileId: string): Promise<TCertificateProfileWithConfigs> => {
|
||||||
const profile = await certificateProfileDAL.findById(profileId);
|
const profile = await certificateProfileDAL.findById(profileId);
|
||||||
if (!profile) {
|
if (!profile) {
|
||||||
@@ -43,18 +47,35 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
};
|
};
|
||||||
|
|
||||||
const buildUrl = (path: string): string => {
|
const buildUrl = (path: string): string => {
|
||||||
|
const appCfg = getConfig();
|
||||||
const baseUrl = appCfg.SITE_URL ?? "";
|
const baseUrl = appCfg.SITE_URL ?? "";
|
||||||
return `${baseUrl}${path}`;
|
return `${baseUrl}${path}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const validateCreateAcmeAccountJwsPayload = async (rawPayload: TRawJwsPayload): Promise<TJwsPayload> => {
|
||||||
|
const { payload, protectedHeader } = await flattenedVerify(
|
||||||
|
rawPayload,
|
||||||
|
async (protectedHeader: JWSHeaderParameters | undefined) => {
|
||||||
|
if (protectedHeader === undefined) {
|
||||||
|
throw new AcmeMalformedError({ detail: "Protected header is required" });
|
||||||
|
}
|
||||||
|
if (protectedHeader.jwk === undefined) {
|
||||||
|
throw new AcmeBadPublicKeyError({ detail: "JWK is required in the protected header" });
|
||||||
|
}
|
||||||
|
// For the create account request, the JWK is provided in the protected header.
|
||||||
|
// Let use it to verify the signature.
|
||||||
|
const imported = await importJWK(protectedHeader.jwk as JWK, protectedHeader.alg);
|
||||||
|
return imported;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const decoder = new TextDecoder();
|
||||||
|
const parsedPayload = JSON.parse(decoder.decode(payload)) as TCreateAcmeAccountPayload;
|
||||||
|
// TODO: also consume the nonce here
|
||||||
|
return { payload: parsedPayload, protectedHeader: protectedHeader as TProtectedHeader };
|
||||||
|
};
|
||||||
|
|
||||||
const getAcmeDirectory = async (profileId: string): Promise<TGetAcmeDirectoryResponse> => {
|
const getAcmeDirectory = async (profileId: string): Promise<TGetAcmeDirectoryResponse> => {
|
||||||
// FIXME: Implement ACME directory endpoint
|
await validateAcmeProfile(profileId);
|
||||||
// Validate profile exists and is for ACME enrollment
|
|
||||||
const profile = await validateAcmeProfile(profileId);
|
|
||||||
|
|
||||||
// FIXME: Validate profile is configured for ACME enrollment
|
|
||||||
|
|
||||||
// Return absolute URLs using SITE_URL
|
|
||||||
return {
|
return {
|
||||||
newNonce: buildUrl(`/api/v1/pki/acme/profiles/${profileId}/new-nonce`),
|
newNonce: buildUrl(`/api/v1/pki/acme/profiles/${profileId}/new-nonce`),
|
||||||
newAccount: buildUrl(`/api/v1/pki/acme/profiles/${profileId}/new-account`),
|
newAccount: buildUrl(`/api/v1/pki/acme/profiles/${profileId}/new-account`),
|
||||||
@@ -71,7 +92,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
|
|
||||||
const createAcmeAccount = async (
|
const createAcmeAccount = async (
|
||||||
profileId: string,
|
profileId: string,
|
||||||
body: TCreateAcmeAccountPayload
|
payload: TCreateAcmeAccountPayload
|
||||||
): Promise<TCreateAcmeAccountResponse> => {
|
): Promise<TCreateAcmeAccountResponse> => {
|
||||||
const profile = await validateAcmeProfile(profileId);
|
const profile = await validateAcmeProfile(profileId);
|
||||||
// FIXME: Implement ACME new account registration
|
// FIXME: Implement ACME new account registration
|
||||||
@@ -88,7 +109,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
|
|
||||||
const createAcmeOrder = async (
|
const createAcmeOrder = async (
|
||||||
profileId: string,
|
profileId: string,
|
||||||
body: TCreateAcmeOrderPayload
|
payload: TCreateAcmeOrderPayload
|
||||||
): Promise<TCreateAcmeOrderResponse> => {
|
): Promise<TCreateAcmeOrderResponse> => {
|
||||||
const profile = await validateAcmeProfile(profileId);
|
const profile = await validateAcmeProfile(profileId);
|
||||||
// FIXME: Implement ACME new order creation
|
// FIXME: Implement ACME new order creation
|
||||||
@@ -105,7 +126,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
const deactivateAcmeAccount = async (
|
const deactivateAcmeAccount = async (
|
||||||
profileId: string,
|
profileId: string,
|
||||||
accountId: string,
|
accountId: string,
|
||||||
body?: TDeactivateAcmeAccountPayload
|
payload?: TDeactivateAcmeAccountPayload
|
||||||
): Promise<TDeactivateAcmeAccountResponse> => {
|
): Promise<TDeactivateAcmeAccountResponse> => {
|
||||||
const profile = await validateAcmeProfile(profileId);
|
const profile = await validateAcmeProfile(profileId);
|
||||||
// FIXME: Implement ACME account deactivation
|
// FIXME: Implement ACME account deactivation
|
||||||
@@ -137,10 +158,10 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
const finalizeAcmeOrder = async (
|
const finalizeAcmeOrder = async (
|
||||||
profileId: string,
|
profileId: string,
|
||||||
orderId: string,
|
orderId: string,
|
||||||
body: TFinalizeAcmeOrderPayload
|
payload: TFinalizeAcmeOrderPayload
|
||||||
): Promise<TFinalizeAcmeOrderResponse> => {
|
): Promise<TFinalizeAcmeOrderResponse> => {
|
||||||
const profile = await validateAcmeProfile(profileId);
|
const profile = await validateAcmeProfile(profileId);
|
||||||
const { csr } = body;
|
const { csr } = payload;
|
||||||
// FIXME: Implement ACME finalize order
|
// FIXME: Implement ACME finalize order
|
||||||
return {
|
return {
|
||||||
status: "processing",
|
status: "processing",
|
||||||
@@ -196,6 +217,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
validateCreateAcmeAccountJwsPayload,
|
||||||
getAcmeDirectory,
|
getAcmeDirectory,
|
||||||
getAcmeNewNonce,
|
getAcmeNewNonce,
|
||||||
createAcmeAccount,
|
createAcmeAccount,
|
||||||
|
|||||||
@@ -12,7 +12,10 @@ import {
|
|||||||
GetAcmeAuthorizationResponseSchema,
|
GetAcmeAuthorizationResponseSchema,
|
||||||
GetAcmeDirectoryResponseSchema,
|
GetAcmeDirectoryResponseSchema,
|
||||||
GetAcmeOrderResponseSchema,
|
GetAcmeOrderResponseSchema,
|
||||||
|
JwsPayloadSchema,
|
||||||
ListAcmeOrdersResponseSchema,
|
ListAcmeOrdersResponseSchema,
|
||||||
|
ProtectedHeaderSchema,
|
||||||
|
RawJwsPayloadSchema,
|
||||||
RespondToAcmeChallengeResponseSchema
|
RespondToAcmeChallengeResponseSchema
|
||||||
} from "./pki-acme-schemas";
|
} from "./pki-acme-schemas";
|
||||||
|
|
||||||
@@ -28,12 +31,16 @@ export type TGetAcmeAuthorizationResponse = z.infer<typeof GetAcmeAuthorizationR
|
|||||||
export type TRespondToAcmeChallengeResponse = z.infer<typeof RespondToAcmeChallengeResponseSchema>;
|
export type TRespondToAcmeChallengeResponse = z.infer<typeof RespondToAcmeChallengeResponseSchema>;
|
||||||
|
|
||||||
// Payload types
|
// Payload types
|
||||||
|
export type TRawJwsPayload = z.infer<typeof RawJwsPayloadSchema>;
|
||||||
|
export type TJwsPayload = z.infer<typeof JwsPayloadSchema>;
|
||||||
|
export type TProtectedHeader = z.infer<typeof ProtectedHeaderSchema>;
|
||||||
export type TCreateAcmeAccountPayload = z.infer<typeof CreateAcmeAccountBodySchema>;
|
export type TCreateAcmeAccountPayload = z.infer<typeof CreateAcmeAccountBodySchema>;
|
||||||
export type TCreateAcmeOrderPayload = z.infer<typeof CreateAcmeOrderBodySchema>;
|
export type TCreateAcmeOrderPayload = z.infer<typeof CreateAcmeOrderBodySchema>;
|
||||||
export type TDeactivateAcmeAccountPayload = z.infer<typeof DeactivateAcmeAccountBodySchema>;
|
export type TDeactivateAcmeAccountPayload = z.infer<typeof DeactivateAcmeAccountBodySchema>;
|
||||||
export type TFinalizeAcmeOrderPayload = z.infer<typeof FinalizeAcmeOrderBodySchema>;
|
export type TFinalizeAcmeOrderPayload = z.infer<typeof FinalizeAcmeOrderBodySchema>;
|
||||||
|
|
||||||
export type TPkiAcmeServiceFactory = {
|
export type TPkiAcmeServiceFactory = {
|
||||||
|
validateCreateAcmeAccountJwsPayload(body: TRawJwsPayload): Promise<TJwsPayload>;
|
||||||
getAcmeDirectory: (profileId: string) => Promise<TGetAcmeDirectoryResponse>;
|
getAcmeDirectory: (profileId: string) => Promise<TGetAcmeDirectoryResponse>;
|
||||||
getAcmeNewNonce: (profileId: string) => Promise<string>;
|
getAcmeNewNonce: (profileId: string) => Promise<string>;
|
||||||
createAcmeAccount: (profileId: string, body: TCreateAcmeAccountPayload) => Promise<TCreateAcmeAccountResponse>;
|
createAcmeAccount: (profileId: string, body: TCreateAcmeAccountPayload) => Promise<TCreateAcmeAccountResponse>;
|
||||||
|
|||||||
Reference in New Issue
Block a user