mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
Add link headers
This commit is contained in:
@@ -424,7 +424,7 @@ export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
||||
// Respond to Challenge (RFC 8555 Section 7.5.1)
|
||||
server.route({
|
||||
method: "POST",
|
||||
url: "/profiles/:profileId/authorizations/:authzId/challenges/http-01",
|
||||
url: "/profiles/:profileId/authorizations/:authzId/challenges/:challengeId",
|
||||
config: {
|
||||
rateLimit: writeLimit
|
||||
},
|
||||
@@ -433,7 +433,8 @@ export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
||||
tags: [ApiDocsTags.PkiAcme],
|
||||
description: "ACME Respond to Challenge - let ACME server know challenge is ready",
|
||||
params: SharedParamsSchema.extend({
|
||||
authzId: z.string().uuid()
|
||||
authzId: z.string().uuid(),
|
||||
challengeId: z.string().uuid()
|
||||
}),
|
||||
response: {
|
||||
200: RespondToAcmeChallengeResponseSchema
|
||||
@@ -447,9 +448,13 @@ export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
||||
return sendAcmeResponse(
|
||||
res,
|
||||
profileId,
|
||||
await server.services.pkiAcme.respondToAcmeChallenge({ profileId, authzId: req.params.authzId })
|
||||
await server.services.pkiAcme.respondToAcmeChallenge({
|
||||
profileId,
|
||||
accountId,
|
||||
authzId: req.params.authzId,
|
||||
challengeId: req.params.challengeId
|
||||
})
|
||||
);
|
||||
return challenge;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,13 +1,41 @@
|
||||
import { TDbClient } from "@app/db";
|
||||
import { TableName } from "@app/db/schemas";
|
||||
import { ormify } from "@app/lib/knex";
|
||||
import { DatabaseError } from "@app/lib/errors";
|
||||
import { ormify, selectAllTableCols } from "@app/lib/knex";
|
||||
import { Knex } from "knex";
|
||||
|
||||
export type TPkiAcmeChallengeDALFactory = ReturnType<typeof pkiAcmeChallengeDALFactory>;
|
||||
|
||||
export const pkiAcmeChallengeDALFactory = (db: TDbClient) => {
|
||||
const pkiAcmeChallengeOrm = ormify(db, TableName.PkiAcmeChallenge);
|
||||
|
||||
const findByAccountAuthAndChallengeIdWithToken = async (
|
||||
accountId: string,
|
||||
authId: string,
|
||||
challengeId: string,
|
||||
tx?: Knex
|
||||
) => {
|
||||
try {
|
||||
const challenge = await (tx || db)(TableName.PkiAcmeChallenge)
|
||||
.join(TableName.PkiAcmeAuth, `${TableName.PkiAcmeChallenge}.authId`, `${TableName.PkiAcmeAuth}.id`)
|
||||
.select(
|
||||
selectAllTableCols(TableName.PkiAcmeChallenge),
|
||||
db.ref("token").withSchema(TableName.PkiAcmeChallenge).as("token")
|
||||
)
|
||||
.where(`${TableName.PkiAcmeChallenge}.id`, challengeId)
|
||||
.where(`${TableName.PkiAcmeChallenge}.authId`, authId)
|
||||
.where(`${TableName.PkiAcmeAuth}.accountId`, accountId)
|
||||
.first();
|
||||
if (!challenge) {
|
||||
return null;
|
||||
}
|
||||
return challenge;
|
||||
} catch (error) {
|
||||
throw new DatabaseError({ error, name: "Find PKI ACME challenge by account id, auth id and challenge id" });
|
||||
}
|
||||
};
|
||||
return {
|
||||
...pkiAcmeChallengeOrm
|
||||
...pkiAcmeChallengeOrm,
|
||||
findByAccountAuthAndChallengeIdWithToken
|
||||
};
|
||||
};
|
||||
|
||||
@@ -61,7 +61,7 @@ type TPkiAcmeServiceFactoryDep = {
|
||||
acmeOrderDAL: Pick<TPkiAcmeOrderDALFactory, "create" | "transaction" | "findByAccountAndOrderIdWithAuthorizations">;
|
||||
acmeAuthDAL: Pick<TPkiAcmeAuthDALFactory, "create" | "findByAccountIdAndAuthIdWithChallenges">;
|
||||
acmeOrderAuthDAL: Pick<TPkiAcmeOrderAuthDALFactory, "insertMany">;
|
||||
acmeChallengeDAL: Pick<TPkiAcmeChallengeDALFactory, "create">;
|
||||
acmeChallengeDAL: Pick<TPkiAcmeChallengeDALFactory, "create" | "findByAccountAuthAndChallengeIdWithToken">;
|
||||
};
|
||||
|
||||
export const pkiAcmeServiceFactory = ({
|
||||
@@ -300,9 +300,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
contact: existingAccount.emails,
|
||||
orders: buildUrl(profile.id, `/accounts/${existingAccount.id}/orders`)
|
||||
},
|
||||
headers: {
|
||||
Location: buildUrl(profile.id, `/accounts/${existingAccount.id}`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profile.id, `/accounts/${existingAccount.id}`)],
|
||||
["Link", `<${buildUrl(profile.id, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
@@ -321,9 +322,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
contact: newAccount.emails,
|
||||
orders: buildUrl(profile.id, `/accounts/${newAccount.id}/orders`)
|
||||
},
|
||||
headers: {
|
||||
Location: buildUrl(profile.id, `/accounts/${newAccount.id}`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profile.id, `/accounts/${newAccount.id}`)],
|
||||
["Link", `<${buildUrl(profile.id, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -343,9 +345,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
body: {
|
||||
status: "deactivated"
|
||||
},
|
||||
headers: {
|
||||
Location: buildUrl(profileId, `/accounts/${accountId}`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/accounts/${accountId}`)],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -429,9 +432,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
profileId,
|
||||
order
|
||||
}),
|
||||
headers: {
|
||||
Location: buildUrl(profileId, `/orders/${order.id}`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/orders/${order.id}`)],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -451,7 +455,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
return {
|
||||
status: 200,
|
||||
body: buildAcmeOrderResource({ profileId, order }),
|
||||
headers: { Location: buildUrl(profileId, `/orders/${orderId}`) }
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/orders/${orderId}`)],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -475,9 +482,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
return {
|
||||
status: 200,
|
||||
body: buildAcmeOrderResource({ profileId, order }),
|
||||
headers: {
|
||||
Location: buildUrl(profileId, `/orders/${orderId}`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/orders/${orderId}`)],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -499,9 +507,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
return {
|
||||
status: 200,
|
||||
body: "FIXME-certificate-pem",
|
||||
headers: {
|
||||
Location: buildUrl(profileId, `/orders/${orderId}/certificate`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/orders/${orderId}/certificate`)],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -519,9 +528,10 @@ export const pkiAcmeServiceFactory = ({
|
||||
body: {
|
||||
orders: []
|
||||
},
|
||||
headers: {
|
||||
Location: buildUrl(profileId, `/accounts/${accountId}/orders`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/accounts/${accountId}/orders`)],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
@@ -559,33 +569,42 @@ export const pkiAcmeServiceFactory = ({
|
||||
};
|
||||
})
|
||||
},
|
||||
headers: {
|
||||
Location: buildUrl(profileId, `/authorizations/${authzId}`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/authorizations/${authzId}`)],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
const respondToAcmeChallenge = async ({
|
||||
profileId,
|
||||
authzId
|
||||
accountId,
|
||||
authzId,
|
||||
challengeId
|
||||
}: {
|
||||
profileId: string;
|
||||
accountId: string;
|
||||
authzId: string;
|
||||
challengeId: string;
|
||||
}): Promise<TAcmeResponse<TRespondToAcmeChallengeResponse>> => {
|
||||
const profile = await validateAcmeProfile(profileId);
|
||||
// FIXME: Implement ACME challenge response
|
||||
// Trigger verification process
|
||||
const challenge = await acmeChallengeDAL.findByAccountAuthAndChallengeIdWithToken(accountId, authzId, challengeId);
|
||||
if (!challenge) {
|
||||
throw new NotFoundError({ message: "ACME challenge not found" });
|
||||
}
|
||||
// TODO: Implement ACME challenge response
|
||||
return {
|
||||
status: 200,
|
||||
body: {
|
||||
type: "http-01",
|
||||
url: buildUrl(profileId, `/authorizations/${authzId}/challenges/http-01`),
|
||||
status: "pending",
|
||||
token: "FIXME-challenge-token"
|
||||
type: challenge.type,
|
||||
url: buildUrl(profileId, `/authorizations/${authzId}/challenges/${challengeId}`),
|
||||
status: challenge.status,
|
||||
token: challenge.token
|
||||
},
|
||||
headers: {
|
||||
Location: buildUrl(profileId, `/authorizations/${authzId}/challenges/http-01`)
|
||||
}
|
||||
headers: [
|
||||
["Location", buildUrl(profileId, `/authorizations/${authzId}/challenges/http-01`)],
|
||||
["Link", `<${buildUrl(profileId, `/authorizations/${authzId}`)}>;rel="up"`],
|
||||
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ export type TAuthenciatedJwsPayload<T> = TJwsPayload<T> & {
|
||||
};
|
||||
export type TAcmeResponse<TPayload> = {
|
||||
status: number;
|
||||
headers: Record<string, string>;
|
||||
headers: [string, string][];
|
||||
body: TPayload;
|
||||
};
|
||||
|
||||
@@ -164,9 +164,13 @@ export type TPkiAcmeServiceFactory = {
|
||||
}) => Promise<TAcmeResponse<TGetAcmeAuthorizationResponse>>;
|
||||
respondToAcmeChallenge: ({
|
||||
profileId,
|
||||
authzId
|
||||
accountId,
|
||||
authzId,
|
||||
challengeId
|
||||
}: {
|
||||
profileId: string;
|
||||
accountId: string;
|
||||
authzId: string;
|
||||
challengeId: string;
|
||||
}) => Promise<TAcmeResponse<TRespondToAcmeChallengeResponse>>;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user