Files
smartacme/ts_server/server.handlers.authz.ts

59 lines
1.7 KiB
TypeScript

import type * as http from 'node:http';
import type { JwsVerifier } from './server.classes.jws.verifier.js';
import { AcmeServerError } from './server.classes.jws.verifier.js';
import type { IServerOrderStore } from './server.interfaces.js';
/**
* POST /authz/:id — Return authorization with embedded challenges (POST-as-GET).
*/
export function createAuthzHandler(
baseUrl: string,
jwsVerifier: JwsVerifier,
orderStore: IServerOrderStore,
) {
return async (
req: http.IncomingMessage,
res: http.ServerResponse,
params: Record<string, string>,
body: any,
): Promise<void> => {
const authzId = params.id;
const requestUrl = `${baseUrl}/authz/${authzId}`;
await jwsVerifier.verify(body, requestUrl);
const authz = await orderStore.getAuthorization(authzId);
if (!authz) {
throw new AcmeServerError(404, 'urn:ietf:params:acme:error:malformed', 'Authorization not found');
}
// Build challenge objects
const challenges = [];
for (const challengeId of authz.challengeIds) {
const challenge = await orderStore.getChallenge(challengeId);
if (challenge) {
challenges.push({
type: challenge.type,
url: `${baseUrl}/challenge/${challenge.id}`,
status: challenge.status,
token: challenge.token,
...(challenge.validated ? { validated: challenge.validated } : {}),
});
}
}
const responseBody: Record<string, any> = {
identifier: authz.identifier,
status: authz.status,
expires: authz.expires,
challenges,
};
if (authz.wildcard) {
responseBody.wildcard = true;
}
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(responseBody));
};
}