mirror of https://github.com/certd/certd
154 lines
4.3 KiB
JavaScript
154 lines
4.3 KiB
JavaScript
/**
|
|
* Example of acme.Client API
|
|
*/
|
|
|
|
const acme = require('./../');
|
|
|
|
|
|
function log(m) {
|
|
process.stdout.write(`${m}\n`);
|
|
}
|
|
|
|
|
|
/**
|
|
* Function used to satisfy an ACME challenge
|
|
*
|
|
* @param {object} authz Authorization object
|
|
* @param {object} challenge Selected challenge
|
|
* @param {string} keyAuthorization Authorization key
|
|
* @returns {Promise}
|
|
*/
|
|
|
|
async function challengeCreateFn(authz, challenge, keyAuthorization) {
|
|
/* Do something here */
|
|
log(JSON.stringify(authz));
|
|
log(JSON.stringify(challenge));
|
|
log(keyAuthorization);
|
|
}
|
|
|
|
|
|
/**
|
|
* Function used to remove an ACME challenge response
|
|
*
|
|
* @param {object} authz Authorization object
|
|
* @param {object} challenge Selected challenge
|
|
* @returns {Promise}
|
|
*/
|
|
|
|
async function challengeRemoveFn(authz, challenge, keyAuthorization) {
|
|
/* Do something here */
|
|
log(JSON.stringify(authz));
|
|
log(JSON.stringify(challenge));
|
|
log(keyAuthorization);
|
|
}
|
|
|
|
|
|
/**
|
|
* Main
|
|
*/
|
|
|
|
module.exports = async function() {
|
|
/* Init client */
|
|
const client = new acme.Client({
|
|
directoryUrl: acme.directory.letsencrypt.staging,
|
|
accountKey: await acme.crypto.createPrivateKey()
|
|
});
|
|
|
|
/* Register account */
|
|
await client.createAccount({
|
|
termsOfServiceAgreed: true,
|
|
contact: ['mailto:test@example.com']
|
|
});
|
|
|
|
/* Place new order */
|
|
const order = await client.createOrder({
|
|
identifiers: [
|
|
{ type: 'dns', value: 'example.com' },
|
|
{ type: 'dns', value: '*.example.com' }
|
|
]
|
|
});
|
|
|
|
/**
|
|
* authorizations / client.getAuthorizations(order);
|
|
* An array with one item per DNS name in the certificate order.
|
|
* All items require at least one satisfied challenge before order can be completed.
|
|
*/
|
|
|
|
const authorizations = await client.getAuthorizations(order);
|
|
|
|
const promises = authorizations.map(async (authz) => {
|
|
let challengeCompleted = false;
|
|
|
|
try {
|
|
/**
|
|
* challenges / authz.challenges
|
|
* An array of all available challenge types for a single DNS name.
|
|
* One of these challenges needs to be satisfied.
|
|
*/
|
|
|
|
const { challenges } = authz;
|
|
|
|
/* Just select any challenge */
|
|
const challenge = challenges.pop();
|
|
const keyAuthorization = await client.getChallengeKeyAuthorization(challenge);
|
|
|
|
try {
|
|
/* Satisfy challenge */
|
|
await challengeCreateFn(authz, challenge, keyAuthorization);
|
|
|
|
/* Verify that challenge is satisfied */
|
|
await client.verifyChallenge(authz, challenge);
|
|
|
|
/* Notify ACME provider that challenge is satisfied */
|
|
await client.completeChallenge(challenge);
|
|
challengeCompleted = true;
|
|
|
|
/* Wait for ACME provider to respond with valid status */
|
|
await client.waitForValidStatus(challenge);
|
|
}
|
|
finally {
|
|
/* Clean up challenge response */
|
|
try {
|
|
await challengeRemoveFn(authz, challenge, keyAuthorization);
|
|
}
|
|
catch (e) {
|
|
/**
|
|
* Catch errors thrown by challengeRemoveFn() so the order can
|
|
* be finalized, even though something went wrong during cleanup
|
|
*/
|
|
}
|
|
}
|
|
}
|
|
catch (e) {
|
|
/* Deactivate pending authz when unable to complete challenge */
|
|
if (!challengeCompleted) {
|
|
try {
|
|
await client.deactivateAuthorization(authz);
|
|
}
|
|
catch (f) {
|
|
/* Catch and suppress deactivateAuthorization() errors */
|
|
}
|
|
}
|
|
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
/* Wait for challenges to complete */
|
|
await Promise.all(promises);
|
|
|
|
/* Finalize order */
|
|
const [key, csr] = await acme.crypto.createCsr({
|
|
commonName: '*.example.com',
|
|
altNames: ['example.com']
|
|
});
|
|
|
|
const finalized = await client.finalizeOrder(order, csr);
|
|
const cert = await client.getCertificate(finalized);
|
|
|
|
/* Done */
|
|
log(`CSR:\n${csr.toString()}`);
|
|
log(`Private key:\n${key.toString()}`);
|
|
log(`Certificate:\n${cert.toString()}`);
|
|
};
|