smartacme/ts/smartacme.classes.smartacme.ts

102 lines
3.2 KiB
TypeScript
Raw Normal View History

2019-01-06 19:41:21 +00:00
import * as plugins from './smartacme.plugins';
2017-01-14 13:14:50 +00:00
2019-01-06 19:41:21 +00:00
/**
*
*/
export interface ISmartAcmeStorage {}
2017-01-01 23:18:51 +00:00
2019-01-06 19:41:21 +00:00
export class SmartAcme {
// the acme client
private client: any;
2019-01-06 22:54:46 +00:00
private smartdns = new plugins.smartdns.Smartdns();
2016-11-01 19:16:43 +00:00
2019-01-06 19:41:21 +00:00
// the account private key
private privateKey: string;
2016-11-07 17:41:52 +00:00
2019-01-06 19:41:21 +00:00
// challenge fullfillment
2019-01-06 22:30:38 +00:00
private setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>;
private removeChallenge: (domainName: string) => Promise<any>;
2016-11-01 19:16:43 +00:00
2019-01-06 19:41:21 +00:00
public async init(optionsArg: {
accountPrivateKey?: string;
accountEmail: string;
2019-01-06 22:30:38 +00:00
setChallenge: (domainName: string, keyAuthorization: string) => Promise<any>
removeChallenge: (domainName: string) => Promise<any>;
2019-01-06 19:41:21 +00:00
}) {
this.privateKey = optionsArg.accountPrivateKey || (await plugins.acme.forge.createPrivateKey());
this.setChallenge = optionsArg.setChallenge;
this.removeChallenge = optionsArg.removeChallenge;
this.client = new plugins.acme.Client({
directoryUrl: plugins.acme.directory.letsencrypt.staging,
accountKey: this.privateKey
});
/* Register account */
await this.client.createAccount({
termsOfServiceAgreed: true,
contact: [`mailto:${optionsArg.accountEmail}`]
});
}
2019-01-06 19:41:21 +00:00
public async getCertificateForDomain(domainArg: string) {
const domain = domainArg;
/* Place new order */
const order = await this.client.createOrder({
identifiers: [{ type: 'dns', value: domain }, { type: 'dns', value: `*.${domain}` }]
});
/* Get authorizations and select challenges */
const authorizations = await this.client.getAuthorizations(order);
2019-01-06 22:54:46 +00:00
for (const authz of authorizations) {
2019-01-06 22:30:38 +00:00
console.log(authz);
const domainDnsName: string = `_acme-challenge.${authz.identifier.value}`;
const dnsChallenge: string = authz.challenges.find(challengeArg => {
return challengeArg.type === 'dns-01';
});
// process.exit(1);
const keyAuthorization: string = await this.client.getChallengeKeyAuthorization(dnsChallenge);
2019-01-06 19:41:21 +00:00
try {
/* Satisfy challenge */
2019-01-06 22:30:38 +00:00
await this.setChallenge(domainDnsName, keyAuthorization);
2019-01-07 00:08:50 +00:00
await this.smartdns.checkUntilAvailable(domainDnsName, 'TXT', keyAuthorization, 100, 5000);
2019-01-06 22:54:46 +00:00
2019-01-06 19:41:21 +00:00
/* Verify that challenge is satisfied */
2019-01-06 22:30:38 +00:00
await this.client.verifyChallenge(authz, dnsChallenge);
2019-01-06 19:41:21 +00:00
/* Notify ACME provider that challenge is satisfied */
2019-01-06 22:30:38 +00:00
await this.client.completeChallenge(dnsChallenge);
2019-01-06 19:41:21 +00:00
/* Wait for ACME provider to respond with valid status */
2019-01-06 22:30:38 +00:00
await this.client.waitForValidStatus(dnsChallenge);
2019-01-06 19:41:21 +00:00
} finally {
/* Clean up challenge response */
try {
2019-01-06 22:30:38 +00:00
await this.removeChallenge(domainDnsName);
2019-01-06 19:41:21 +00:00
} catch (e) {
console.log(e);
}
}
2019-01-06 22:54:46 +00:00
}
2019-01-06 19:41:21 +00:00
/* Finalize order */
const [key, csr] = await plugins.acme.forge.createCsr({
commonName: `*.${domain}`,
altNames: [domain]
});
await this.client.finalizeOrder(order, csr);
const cert = await this.client.getCertificate(order);
/* Done */
console.log(`CSR:\n${csr.toString()}`);
console.log(`Private key:\n${key.toString()}`);
console.log(`Certificate:\n${cert.toString()}`);
2017-04-28 16:56:55 +00:00
}
2019-01-06 19:41:21 +00:00
2019-01-06 22:30:38 +00:00
toStorageObject() {}
2016-11-01 17:27:57 +00:00
}