mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-10 17:29:14 +00:00
More challenge logic
This commit is contained in:
@@ -2,6 +2,7 @@ import { Knex } from "knex";
|
||||
|
||||
import { getConfig } from "@app/lib/config/env";
|
||||
import { BadRequestError, NotFoundError } from "@app/lib/errors";
|
||||
import { logger } from "@app/lib/logger";
|
||||
import { TPkiAcmeAuthDALFactory } from "./pki-acme-auth-dal";
|
||||
import { TPkiAcmeChallengeDALFactory } from "./pki-acme-challenge-dal";
|
||||
import { AcmeAuthStatus, AcmeChallengeStatus, AcmeChallengeType } from "./pki-acme-schemas";
|
||||
@@ -18,15 +19,16 @@ export const pkiAcmeChallengeServiceFactory = ({
|
||||
}: TPkiAcmeChallengeServiceFactoryDep): TPkiAcmeChallengeServiceFactory => {
|
||||
const appCfg = getConfig();
|
||||
|
||||
const validateChallengeResponse = async (challengeId: string): Promise<void> => {
|
||||
const validateChallengeResponse = async (challengeId: string, tx?: Knex): Promise<void> => {
|
||||
return await acmeChallengeDAL.transaction(async (tx: Knex) => {
|
||||
logger.info({ challengeId }, "Validating ACME challenge response");
|
||||
const challenge = await acmeChallengeDAL.findByIdForChallengeValidation(challengeId, tx);
|
||||
if (!challenge) {
|
||||
throw new NotFoundError({ message: "ACME challenge not found" });
|
||||
}
|
||||
if (challenge.status !== AcmeChallengeStatus.Processing) {
|
||||
if (challenge.status !== AcmeChallengeStatus.Pending) {
|
||||
throw new BadRequestError({
|
||||
message: `ACME challenge is ${challenge.status} instead of ${AcmeChallengeStatus.Processing}`
|
||||
message: `ACME challenge is ${challenge.status} instead of ${AcmeChallengeStatus.Pending}`
|
||||
});
|
||||
}
|
||||
if (challenge.auth.expiresAt < new Date()) {
|
||||
@@ -46,8 +48,8 @@ export const pkiAcmeChallengeServiceFactory = ({
|
||||
const actualBaseUrl = appCfg.isAcmeDevelopmentMode
|
||||
? `${baseUrl}:${appCfg.ACME_DEVELOPMENT_HTTP01_CHALLENGE_PORT}`
|
||||
: baseUrl;
|
||||
|
||||
const challengeUrl = new URL(`/.well-known/acme-challenge/${challenge.auth.token}`, actualBaseUrl);
|
||||
try {
|
||||
// Notice: well, we are in a transaction, ideally we should not hold transaction and perform
|
||||
// a long running operation for long time. But assuming we are not performing a tons of
|
||||
// challenge validation at the same time, it should be fine.
|
||||
@@ -68,6 +70,14 @@ export const pkiAcmeChallengeServiceFactory = ({
|
||||
tx
|
||||
);
|
||||
await acmeAuthDAL.updateById(challenge.auth.account.id, { status: AcmeAuthStatus.Valid }, tx);
|
||||
await acmeAuthDAL.updateById(challenge.auth.account.id, { status: AcmeAuthStatus.Valid }, tx);
|
||||
} catch (error) {
|
||||
logger.error(error, "Error validating ACME challenge response");
|
||||
// TODO: we should retry the challenge validation a few times, but let's keep it simple for now
|
||||
await acmeChallengeDAL.updateById(challengeId, { status: AcmeChallengeStatus.Invalid }, tx);
|
||||
await acmeAuthDAL.updateById(challenge.auth.account.id, { status: AcmeAuthStatus.Invalid }, tx);
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -631,6 +631,9 @@ export const pkiAcmeServiceFactory = ({
|
||||
if (!challenge.auth.token) {
|
||||
throw new AcmeServerInternalError({ message: "ACME challenge token is required" });
|
||||
}
|
||||
if (challenge.type !== AcmeChallengeType.HTTP_01) {
|
||||
throw new BadRequestError({ message: "Only HTTP-01 challenges are supported for now" });
|
||||
}
|
||||
const updatedChallenge = await acmeChallengeDAL.updateById(
|
||||
challengeId,
|
||||
{ status: AcmeChallengeStatus.Pending },
|
||||
|
||||
Reference in New Issue
Block a user