mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 18:27:19 +00:00
Acme stuff
This commit is contained in:
@@ -92,4 +92,4 @@ def step_impl(context: Context):
|
|||||||
def step_impl(context: Context, email: str, kid: str, secret: str, account_var: str):
|
def step_impl(context: Context, email: str, kid: str, secret: str, account_var: str):
|
||||||
# TODO: add EAB info here
|
# TODO: add EAB info here
|
||||||
registration = messages.NewRegistration.from_data(email=email)
|
registration = messages.NewRegistration.from_data(email=email)
|
||||||
context.var[account_var] = context.acme_client.new_account(registration)
|
context.vars[account_var] = context.acme_client.new_account(registration)
|
||||||
|
|||||||
@@ -27,6 +27,20 @@ import {
|
|||||||
} from "@app/ee/services/pki-acme/pki-acme-schemas";
|
} from "@app/ee/services/pki-acme/pki-acme-schemas";
|
||||||
|
|
||||||
export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
||||||
|
server.addContentTypeParser("application/jose+json", { parseAs: "string" }, (_, body, done) => {
|
||||||
|
try {
|
||||||
|
const strBody = body instanceof Buffer ? body.toString() : body;
|
||||||
|
if (!strBody) {
|
||||||
|
done(null, undefined);
|
||||||
|
}
|
||||||
|
const json: unknown = JSON.parse(strBody as string);
|
||||||
|
// TODO: deal with JWS payload here
|
||||||
|
done(null, json);
|
||||||
|
} catch (err) {
|
||||||
|
const error = err as Error;
|
||||||
|
done(error, undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
// GET /api/v1/pki/acme/profiles/<profile_id>/directory
|
// GET /api/v1/pki/acme/profiles/<profile_id>/directory
|
||||||
// Directory (RFC 8555 Section 7.1.1)
|
// Directory (RFC 8555 Section 7.1.1)
|
||||||
server.route({
|
server.route({
|
||||||
@@ -94,7 +108,10 @@ export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
|||||||
},
|
},
|
||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
const account = await server.services.pkiAcme.createAcmeAccount(req.params.profileId, req.body);
|
const account = await server.services.pkiAcme.createAcmeAccount(req.params.profileId, req.body);
|
||||||
|
// TODO: deal with existing account case here
|
||||||
res.code(201);
|
res.code(201);
|
||||||
|
const nonce = await server.services.pkiAcme.getAcmeNewNonce(req.params.profileId);
|
||||||
|
res.header("Replay-Nonce", nonce);
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const GetAcmeDirectoryResponseSchema = z.object({
|
|||||||
newNonce: z.string(),
|
newNonce: z.string(),
|
||||||
newAccount: z.string(),
|
newAccount: z.string(),
|
||||||
newOrder: z.string(),
|
newOrder: z.string(),
|
||||||
revokeCert: z.string()
|
revokeCert: z.string().optional()
|
||||||
});
|
});
|
||||||
|
|
||||||
// New Nonce endpoint
|
// New Nonce endpoint
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { getConfig } from "@app/lib/config/env";
|
||||||
import { NotFoundError } from "@app/lib/errors";
|
import { 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";
|
||||||
@@ -21,20 +22,24 @@ type TPkiAcmeServiceFactoryDep = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
|
export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeServiceFactoryDep): TPkiAcmeServiceFactory => {
|
||||||
|
const appCfg = getConfig();
|
||||||
|
|
||||||
const getAcmeDirectory = async (profileId: string): Promise<TGetAcmeDirectoryResponse> => {
|
const getAcmeDirectory = async (profileId: string): Promise<TGetAcmeDirectoryResponse> => {
|
||||||
// FIXME: Implement ACME directory endpoint
|
// FIXME: Implement ACME directory endpoint
|
||||||
// Validate profile exists and is for ACME enrollment
|
// Validate profile exists and is for ACME enrollment
|
||||||
const profile = await certificateProfileDAL.findById(profileId);
|
// const profile = await certificateProfileDAL.findById(profileId);
|
||||||
if (!profile) {
|
// if (!profile) {
|
||||||
throw new NotFoundError({ message: "Certificate profile not found" });
|
// throw new NotFoundError({ message: "Certificate profile not found" });
|
||||||
}
|
// }
|
||||||
|
|
||||||
// FIXME: Validate profile is configured for ACME enrollment
|
// FIXME: Validate profile is configured for ACME enrollment
|
||||||
|
|
||||||
|
// Return absolute URLs using SITE_URL
|
||||||
|
const baseUrl = appCfg.SITE_URL ?? "";
|
||||||
return {
|
return {
|
||||||
newNonce: `/api/v1/pki/acme/profiles/${profileId}/new-nonce`,
|
newNonce: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/new-nonce`,
|
||||||
newAccount: `/api/v1/pki/acme/profiles/${profileId}/new-account`,
|
newAccount: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/new-account`,
|
||||||
newOrder: `/api/v1/pki/acme/profiles/${profileId}/new-order`,
|
newOrder: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/new-order`
|
||||||
revokeCert: `/api/v1/pki/acme/profiles/${profileId}/revoke-cert`
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,23 +53,26 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
// FIXME: Implement ACME new account registration
|
// FIXME: Implement ACME new account registration
|
||||||
// Use EAB authentication to find corresponding Infisical machine identity
|
// Use EAB authentication to find corresponding Infisical machine identity
|
||||||
// Check permissions and return account information
|
// Check permissions and return account information
|
||||||
|
const baseUrl = appCfg.SITE_URL || "";
|
||||||
|
const accountId = "FIXME-account-id";
|
||||||
return {
|
return {
|
||||||
status: "valid",
|
status: "valid",
|
||||||
accountUrl: `/api/v1/pki/acme/profiles/${profileId}/accounts/FIXME-account-id`,
|
accountUrl: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/accounts/${accountId}`,
|
||||||
contact: [],
|
contact: [],
|
||||||
orders: `/api/v1/pki/acme/profiles/${profileId}/accounts/FIXME-account-id/orders`
|
orders: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/accounts/${accountId}/orders`
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const createAcmeOrder = async (profileId: string, body: unknown): Promise<TCreateAcmeOrderResponse> => {
|
const createAcmeOrder = async (profileId: string, body: unknown): Promise<TCreateAcmeOrderResponse> => {
|
||||||
// FIXME: Implement ACME new order creation
|
// FIXME: Implement ACME new order creation
|
||||||
const orderId = "FIXME-order-id";
|
const orderId = "FIXME-order-id";
|
||||||
|
const baseUrl = appCfg.SITE_URL || "";
|
||||||
return {
|
return {
|
||||||
status: "pending",
|
status: "pending",
|
||||||
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
||||||
identifiers: [],
|
identifiers: [],
|
||||||
authorizations: [],
|
authorizations: [],
|
||||||
finalize: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
|
finalize: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -87,12 +95,13 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
|
|
||||||
const getAcmeOrder = async (profileId: string, orderId: string): Promise<TGetAcmeOrderResponse> => {
|
const getAcmeOrder = async (profileId: string, orderId: string): Promise<TGetAcmeOrderResponse> => {
|
||||||
// FIXME: Implement ACME get order
|
// FIXME: Implement ACME get order
|
||||||
|
const baseUrl = appCfg.SITE_URL || "";
|
||||||
return {
|
return {
|
||||||
status: "pending",
|
status: "pending",
|
||||||
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
||||||
identifiers: [],
|
identifiers: [],
|
||||||
authorizations: [],
|
authorizations: [],
|
||||||
finalize: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
|
finalize: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -102,13 +111,14 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
csr: string
|
csr: string
|
||||||
): Promise<TFinalizeAcmeOrderResponse> => {
|
): Promise<TFinalizeAcmeOrderResponse> => {
|
||||||
// FIXME: Implement ACME finalize order
|
// FIXME: Implement ACME finalize order
|
||||||
|
const baseUrl = appCfg.SITE_URL || "";
|
||||||
return {
|
return {
|
||||||
status: "processing",
|
status: "processing",
|
||||||
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
||||||
identifiers: [],
|
identifiers: [],
|
||||||
authorizations: [],
|
authorizations: [],
|
||||||
finalize: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`,
|
finalize: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/finalize`,
|
||||||
certificate: `/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/certificate`
|
certificate: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/orders/${orderId}/certificate`
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -120,6 +130,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
|
|
||||||
const getAcmeAuthorization = async (profileId: string, authzId: string): Promise<TGetAcmeAuthorizationResponse> => {
|
const getAcmeAuthorization = async (profileId: string, authzId: string): Promise<TGetAcmeAuthorizationResponse> => {
|
||||||
// FIXME: Implement ACME authorization retrieval
|
// FIXME: Implement ACME authorization retrieval
|
||||||
|
const baseUrl = appCfg.SITE_URL || "";
|
||||||
return {
|
return {
|
||||||
status: "pending",
|
status: "pending",
|
||||||
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
expires: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
|
||||||
@@ -130,7 +141,7 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
challenges: [
|
challenges: [
|
||||||
{
|
{
|
||||||
type: "http-01",
|
type: "http-01",
|
||||||
url: `/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
|
url: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
|
||||||
status: "pending",
|
status: "pending",
|
||||||
token: "FIXME-challenge-token"
|
token: "FIXME-challenge-token"
|
||||||
}
|
}
|
||||||
@@ -144,9 +155,10 @@ export const pkiAcmeServiceFactory = ({ certificateProfileDAL }: TPkiAcmeService
|
|||||||
): Promise<TRespondToAcmeChallengeResponse> => {
|
): Promise<TRespondToAcmeChallengeResponse> => {
|
||||||
// FIXME: Implement ACME challenge response
|
// FIXME: Implement ACME challenge response
|
||||||
// Trigger verification process
|
// Trigger verification process
|
||||||
|
const baseUrl = appCfg.SITE_URL || "";
|
||||||
return {
|
return {
|
||||||
type: "http-01",
|
type: "http-01",
|
||||||
url: `/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
|
url: `${baseUrl}/api/v1/pki/acme/profiles/${profileId}/authorizations/${authzId}/challenges/http-01`,
|
||||||
status: "pending",
|
status: "pending",
|
||||||
token: "FIXME-challenge-token"
|
token: "FIXME-challenge-token"
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user