mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-07 10:27:26 +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)
|
// Respond to Challenge (RFC 8555 Section 7.5.1)
|
||||||
server.route({
|
server.route({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
url: "/profiles/:profileId/authorizations/:authzId/challenges/http-01",
|
url: "/profiles/:profileId/authorizations/:authzId/challenges/:challengeId",
|
||||||
config: {
|
config: {
|
||||||
rateLimit: writeLimit
|
rateLimit: writeLimit
|
||||||
},
|
},
|
||||||
@@ -433,7 +433,8 @@ export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
|||||||
tags: [ApiDocsTags.PkiAcme],
|
tags: [ApiDocsTags.PkiAcme],
|
||||||
description: "ACME Respond to Challenge - let ACME server know challenge is ready",
|
description: "ACME Respond to Challenge - let ACME server know challenge is ready",
|
||||||
params: SharedParamsSchema.extend({
|
params: SharedParamsSchema.extend({
|
||||||
authzId: z.string().uuid()
|
authzId: z.string().uuid(),
|
||||||
|
challengeId: z.string().uuid()
|
||||||
}),
|
}),
|
||||||
response: {
|
response: {
|
||||||
200: RespondToAcmeChallengeResponseSchema
|
200: RespondToAcmeChallengeResponseSchema
|
||||||
@@ -447,9 +448,13 @@ export const registerPkiAcmeRouter = async (server: FastifyZodProvider) => {
|
|||||||
return sendAcmeResponse(
|
return sendAcmeResponse(
|
||||||
res,
|
res,
|
||||||
profileId,
|
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 { TDbClient } from "@app/db";
|
||||||
import { TableName } from "@app/db/schemas";
|
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 type TPkiAcmeChallengeDALFactory = ReturnType<typeof pkiAcmeChallengeDALFactory>;
|
||||||
|
|
||||||
export const pkiAcmeChallengeDALFactory = (db: TDbClient) => {
|
export const pkiAcmeChallengeDALFactory = (db: TDbClient) => {
|
||||||
const pkiAcmeChallengeOrm = ormify(db, TableName.PkiAcmeChallenge);
|
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 {
|
return {
|
||||||
...pkiAcmeChallengeOrm
|
...pkiAcmeChallengeOrm,
|
||||||
|
findByAccountAuthAndChallengeIdWithToken
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ type TPkiAcmeServiceFactoryDep = {
|
|||||||
acmeOrderDAL: Pick<TPkiAcmeOrderDALFactory, "create" | "transaction" | "findByAccountAndOrderIdWithAuthorizations">;
|
acmeOrderDAL: Pick<TPkiAcmeOrderDALFactory, "create" | "transaction" | "findByAccountAndOrderIdWithAuthorizations">;
|
||||||
acmeAuthDAL: Pick<TPkiAcmeAuthDALFactory, "create" | "findByAccountIdAndAuthIdWithChallenges">;
|
acmeAuthDAL: Pick<TPkiAcmeAuthDALFactory, "create" | "findByAccountIdAndAuthIdWithChallenges">;
|
||||||
acmeOrderAuthDAL: Pick<TPkiAcmeOrderAuthDALFactory, "insertMany">;
|
acmeOrderAuthDAL: Pick<TPkiAcmeOrderAuthDALFactory, "insertMany">;
|
||||||
acmeChallengeDAL: Pick<TPkiAcmeChallengeDALFactory, "create">;
|
acmeChallengeDAL: Pick<TPkiAcmeChallengeDALFactory, "create" | "findByAccountAuthAndChallengeIdWithToken">;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const pkiAcmeServiceFactory = ({
|
export const pkiAcmeServiceFactory = ({
|
||||||
@@ -300,9 +300,10 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
contact: existingAccount.emails,
|
contact: existingAccount.emails,
|
||||||
orders: buildUrl(profile.id, `/accounts/${existingAccount.id}/orders`)
|
orders: buildUrl(profile.id, `/accounts/${existingAccount.id}/orders`)
|
||||||
},
|
},
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profile.id, `/accounts/${existingAccount.id}`)
|
["Location", buildUrl(profile.id, `/accounts/${existingAccount.id}`)],
|
||||||
}
|
["Link", `<${buildUrl(profile.id, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,9 +322,10 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
contact: newAccount.emails,
|
contact: newAccount.emails,
|
||||||
orders: buildUrl(profile.id, `/accounts/${newAccount.id}/orders`)
|
orders: buildUrl(profile.id, `/accounts/${newAccount.id}/orders`)
|
||||||
},
|
},
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profile.id, `/accounts/${newAccount.id}`)
|
["Location", buildUrl(profile.id, `/accounts/${newAccount.id}`)],
|
||||||
}
|
["Link", `<${buildUrl(profile.id, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -343,9 +345,10 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
body: {
|
body: {
|
||||||
status: "deactivated"
|
status: "deactivated"
|
||||||
},
|
},
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profileId, `/accounts/${accountId}`)
|
["Location", buildUrl(profileId, `/accounts/${accountId}`)],
|
||||||
}
|
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -429,9 +432,10 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
profileId,
|
profileId,
|
||||||
order
|
order
|
||||||
}),
|
}),
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profileId, `/orders/${order.id}`)
|
["Location", buildUrl(profileId, `/orders/${order.id}`)],
|
||||||
}
|
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -451,7 +455,10 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: buildAcmeOrderResource({ profileId, order }),
|
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 {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: buildAcmeOrderResource({ profileId, order }),
|
body: buildAcmeOrderResource({ profileId, order }),
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profileId, `/orders/${orderId}`)
|
["Location", buildUrl(profileId, `/orders/${orderId}`)],
|
||||||
}
|
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -499,9 +507,10 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: "FIXME-certificate-pem",
|
body: "FIXME-certificate-pem",
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profileId, `/orders/${orderId}/certificate`)
|
["Location", buildUrl(profileId, `/orders/${orderId}/certificate`)],
|
||||||
}
|
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -519,9 +528,10 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
body: {
|
body: {
|
||||||
orders: []
|
orders: []
|
||||||
},
|
},
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profileId, `/accounts/${accountId}/orders`)
|
["Location", buildUrl(profileId, `/accounts/${accountId}/orders`)],
|
||||||
}
|
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -559,33 +569,42 @@ export const pkiAcmeServiceFactory = ({
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profileId, `/authorizations/${authzId}`)
|
["Location", buildUrl(profileId, `/authorizations/${authzId}`)],
|
||||||
}
|
["Link", `<${buildUrl(profileId, "/directory")}>;rel="index"`]
|
||||||
|
]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const respondToAcmeChallenge = async ({
|
const respondToAcmeChallenge = async ({
|
||||||
profileId,
|
profileId,
|
||||||
authzId
|
accountId,
|
||||||
|
authzId,
|
||||||
|
challengeId
|
||||||
}: {
|
}: {
|
||||||
profileId: string;
|
profileId: string;
|
||||||
|
accountId: string;
|
||||||
authzId: string;
|
authzId: string;
|
||||||
|
challengeId: string;
|
||||||
}): Promise<TAcmeResponse<TRespondToAcmeChallengeResponse>> => {
|
}): Promise<TAcmeResponse<TRespondToAcmeChallengeResponse>> => {
|
||||||
const profile = await validateAcmeProfile(profileId);
|
const challenge = await acmeChallengeDAL.findByAccountAuthAndChallengeIdWithToken(accountId, authzId, challengeId);
|
||||||
// FIXME: Implement ACME challenge response
|
if (!challenge) {
|
||||||
// Trigger verification process
|
throw new NotFoundError({ message: "ACME challenge not found" });
|
||||||
|
}
|
||||||
|
// TODO: Implement ACME challenge response
|
||||||
return {
|
return {
|
||||||
status: 200,
|
status: 200,
|
||||||
body: {
|
body: {
|
||||||
type: "http-01",
|
type: challenge.type,
|
||||||
url: buildUrl(profileId, `/authorizations/${authzId}/challenges/http-01`),
|
url: buildUrl(profileId, `/authorizations/${authzId}/challenges/${challengeId}`),
|
||||||
status: "pending",
|
status: challenge.status,
|
||||||
token: "FIXME-challenge-token"
|
token: challenge.token
|
||||||
},
|
},
|
||||||
headers: {
|
headers: [
|
||||||
Location: buildUrl(profileId, `/authorizations/${authzId}/challenges/http-01`)
|
["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> = {
|
export type TAcmeResponse<TPayload> = {
|
||||||
status: number;
|
status: number;
|
||||||
headers: Record<string, string>;
|
headers: [string, string][];
|
||||||
body: TPayload;
|
body: TPayload;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -164,9 +164,13 @@ export type TPkiAcmeServiceFactory = {
|
|||||||
}) => Promise<TAcmeResponse<TGetAcmeAuthorizationResponse>>;
|
}) => Promise<TAcmeResponse<TGetAcmeAuthorizationResponse>>;
|
||||||
respondToAcmeChallenge: ({
|
respondToAcmeChallenge: ({
|
||||||
profileId,
|
profileId,
|
||||||
authzId
|
accountId,
|
||||||
|
authzId,
|
||||||
|
challengeId
|
||||||
}: {
|
}: {
|
||||||
profileId: string;
|
profileId: string;
|
||||||
|
accountId: string;
|
||||||
authzId: string;
|
authzId: string;
|
||||||
|
challengeId: string;
|
||||||
}) => Promise<TAcmeResponse<TRespondToAcmeChallengeResponse>>;
|
}) => Promise<TAcmeResponse<TRespondToAcmeChallengeResponse>>;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user