diff --git a/dist/smartacme.classes.acmeaccount.d.ts b/dist/smartacme.classes.acmeaccount.d.ts
index 709829e..a93d7d9 100644
--- a/dist/smartacme.classes.acmeaccount.d.ts
+++ b/dist/smartacme.classes.acmeaccount.d.ts
@@ -1,3 +1,22 @@
-import 'typings-global';
+///
+import * as q from 'q';
+import { SmartAcme } from './smartacme.classes.smartacme';
+/**
+ * class AcmeAccount represents an AcmeAccount
+ */
export declare class AcmeAccount {
+ parentSmartAcme: SmartAcme;
+ location: string;
+ link: string;
+ JWK: any;
+ constructor(smartAcmeParentArg: SmartAcme);
+ /**
+ * register the account with letsencrypt
+ */
+ register(): q.Promise<{}>;
+ /**
+ * agree to letsencrypr terms of service
+ */
+ agreeTos(): q.Promise<{}>;
+ createAcmeCert(domainNameArg: string): void;
}
diff --git a/dist/smartacme.classes.acmeaccount.js b/dist/smartacme.classes.acmeaccount.js
index 9ad1454..fd073dc 100644
--- a/dist/smartacme.classes.acmeaccount.js
+++ b/dist/smartacme.classes.acmeaccount.js
@@ -1,6 +1,54 @@
"use strict";
-require("typings-global");
+const q = require("q");
+/**
+ * class AcmeAccount represents an AcmeAccount
+ */
class AcmeAccount {
+ constructor(smartAcmeParentArg) {
+ this.parentSmartAcme = smartAcmeParentArg;
+ }
+ /**
+ * register the account with letsencrypt
+ */
+ register() {
+ let done = q.defer();
+ this.parentSmartAcme.rawacmeClient.newReg({
+ contact: ['mailto:domains@lossless.org']
+ }, (err, res) => {
+ if (err) {
+ console.error('smartacme: something went wrong:');
+ console.log(err);
+ done.reject(err);
+ return;
+ }
+ this.JWK = res.body.key;
+ this.link = res.headers.link;
+ console.log(this.link);
+ this.location = res.headers.location;
+ done.resolve();
+ });
+ return done.promise;
+ }
+ /**
+ * agree to letsencrypr terms of service
+ */
+ agreeTos() {
+ let done = q.defer();
+ let tosPart = this.link.split(',')[1];
+ let tosLinkPortion = tosPart.split(';')[0];
+ let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '');
+ this.parentSmartAcme.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
+ if (err) {
+ console.log(err);
+ done.reject(err);
+ return;
+ }
+ done.resolve();
+ });
+ return done.promise;
+ }
+ createAcmeCert(domainNameArg) {
+ }
}
exports.AcmeAccount = AcmeAccount;
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWFjY291bnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEJBQXVCO0FBRXZCO0NBRUM7QUFGRCxrQ0FFQyJ9
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWFjY291bnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsdUJBQXNCO0FBUXRCOztHQUVHO0FBQ0g7SUFLSSxZQUFZLGtCQUE2QjtRQUNyQyxJQUFJLENBQUMsZUFBZSxHQUFHLGtCQUFrQixDQUFBO0lBQzdDLENBQUM7SUFFRDs7T0FFRztJQUNILFFBQVE7UUFDSixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDcEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUNyQztZQUNJLE9BQU8sRUFBRSxDQUFDLDZCQUE2QixDQUFDO1NBQzNDLEVBQ0QsQ0FBQyxHQUFHLEVBQUUsR0FBRztZQUNMLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ04sT0FBTyxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFBO2dCQUNqRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixNQUFNLENBQUE7WUFDVixDQUFDO1lBQ0QsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQTtZQUN2QixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFBO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUE7WUFDcEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ04sTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNKLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNyQyxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzFDLElBQUksR0FBRyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUNsRSxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUc7WUFDakcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDTixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixNQUFNLENBQUE7WUFDVixDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztJQUVELGNBQWMsQ0FBQyxhQUFxQjtJQUVwQyxDQUFDO0NBQ0o7QUF4REQsa0NBd0RDIn0=
\ No newline at end of file
diff --git a/dist/smartacme.classes.acmecert.d.ts b/dist/smartacme.classes.acmecert.d.ts
index d66570b..3766f48 100644
--- a/dist/smartacme.classes.acmecert.d.ts
+++ b/dist/smartacme.classes.acmecert.d.ts
@@ -1,3 +1,71 @@
-import 'typings-global';
-export declare class AcmeCert {
+///
+import * as q from 'q';
+import { IRsaKeypair } from './smartacme.classes.smartacme';
+import { AcmeAccount } from './smartacme.classes.acmeaccount';
+/**
+ * types of challenges supported by letsencrypt and this module
+ */
+export declare type TChallengeType = 'dns-01' | 'http-01';
+/**
+ * values that a challenge's status can have
+ */
+export declare type TChallengeStatus = 'pending';
+export interface ISmartAcmeChallenge {
+ uri: string;
+ status: TChallengeStatus;
+ type: TChallengeType;
+ token: string;
+ keyAuthorization: string;
+}
+export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
+ keyHash: string;
+}
+export interface IAcmeCsrConstructorOptions {
+ bit: number;
+ key: string;
+ domain: string;
+ country: string;
+ country_short: string;
+ locality: string;
+ organization: string;
+ organization_short: string;
+ password: string;
+ unstructured: string;
+ subject_alt_names: string[];
+}
+/**
+ * class AcmeCert represents a cert for domain
+ */
+export declare class AcmeCert {
+ attributes: any;
+ fullchain: string;
+ parentAcmeAccount: AcmeAccount;
+ csr: any;
+ validFrom: Date;
+ validTo: Date;
+ keypair: IRsaKeypair;
+ keyPairFinal: IRsaKeypair;
+ constructor(optionsArg: IAcmeCsrConstructorOptions, parentSmartAcmeArg: any);
+ /**
+ * requests a challenge for a domain
+ * @param domainNameArg - the domain name to request a challenge for
+ * @param challengeType - the challenge type to request
+ */
+ requestChallenge(domainNameArg: string, challengeTypeArg?: TChallengeType): q.Promise;
+ /**
+ * validates a challenge, only call after you have set the challenge at the expected location
+ */
+ validate(challenge: ISmartAcmeChallengeAccepted): q.Promise<{}>;
+ /**
+ * requests a certificate
+ */
+ requestCert(): q.Promise<{}>;
+ /**
+ * getCertificate - takes care of cooldown, validation polling and certificate retrieval
+ */
+ getCertificate(): void;
+ /**
+ * accept a challenge - for private use only
+ */
+ private acceptChallenge(challenge);
}
diff --git a/dist/smartacme.classes.acmecert.js b/dist/smartacme.classes.acmecert.js
index 967677a..c13a1dc 100644
--- a/dist/smartacme.classes.acmecert.js
+++ b/dist/smartacme.classes.acmecert.js
@@ -1,6 +1,144 @@
"use strict";
-require("typings-global");
+const q = require("q");
+const plugins = require("./smartacme.plugins");
+const helpers = require("./smartacme.helpers");
+/**
+ * class AcmeCert represents a cert for domain
+ */
class AcmeCert {
+ constructor(optionsArg, parentSmartAcmeArg) {
+ this.parentAcmeAccount = parentSmartAcmeArg;
+ this.keypair = helpers.createKeypair(optionsArg.bit);
+ let privateKeyForged = plugins.nodeForge.pki.privateKeyFromPem(this.keypair.privateKey);
+ let publicKeyForged = plugins.nodeForge.pki.publicKeyToPem(plugins.nodeForge.pki.setRsaPublicKey(privateKeyForged.n, privateKeyForged.e));
+ this.keyPairFinal = {
+ privateKey: privateKeyForged,
+ publicKey: publicKeyForged
+ };
+ // set dates
+ this.validFrom = new Date();
+ this.validTo = new Date();
+ this.validTo.setDate(this.validFrom.getDate() + 90);
+ // set attributes
+ this.attributes = [
+ { name: 'commonName', value: optionsArg.domain },
+ { name: 'countryName', value: optionsArg.country },
+ { shortName: 'ST', value: optionsArg.country_short },
+ { name: 'localityName', value: optionsArg.locality },
+ { name: 'organizationName', value: optionsArg.organization },
+ { shortName: 'OU', value: optionsArg.organization_short },
+ { name: 'challengePassword', value: optionsArg.password },
+ { name: 'unstructuredName', value: optionsArg.unstructured }
+ ];
+ // set up csr
+ this.csr = plugins.nodeForge.pki.createCertificationRequest();
+ this.csr.setSubject(this.attributes);
+ this.csr.setAttributes(this.attributes);
+ }
+ /**
+ * requests a challenge for a domain
+ * @param domainNameArg - the domain name to request a challenge for
+ * @param challengeType - the challenge type to request
+ */
+ requestChallenge(domainNameArg, challengeTypeArg = 'dns-01') {
+ let done = q.defer();
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.newAuthz({
+ identifier: {
+ type: 'dns',
+ value: domainNameArg
+ }
+ }, this.parentAcmeAccount.parentSmartAcme.keyPair, (err, res) => {
+ if (err) {
+ console.error('smartacme: something went wrong:');
+ console.log(err);
+ done.reject(err);
+ }
+ console.log(JSON.stringify(res.body));
+ let dnsChallenge = res.body.challenges.filter(x => {
+ return x.type === challengeTypeArg;
+ })[0];
+ this.acceptChallenge(dnsChallenge)
+ .then((x) => {
+ done.resolve(x);
+ });
+ });
+ return done.promise;
+ }
+ /**
+ * validates a challenge, only call after you have set the challenge at the expected location
+ */
+ validate(challenge) {
+ let done = q.defer();
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.poll(challenge.uri, function (err, res) {
+ if (err) {
+ console.log(err);
+ done.reject(err);
+ }
+ console.log(res.status);
+ console.log(JSON.stringify(res.body));
+ done.resolve();
+ });
+ return done.promise;
+ }
+ /**
+ * requests a certificate
+ */
+ requestCert() {
+ let done = q.defer();
+ let payload = {
+ csr: plugins.rawacme.base64.encode(plugins.rawacme.toDer(plugins.nodeForge.pki.certificationRequestToPem(this.csr))),
+ notBefore: this.validFrom.toISOString(),
+ notAfter: this.validTo.toISOString()
+ };
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.newCert(payload, helpers.createKeypair(), (err, res) => {
+ if (err) {
+ console.log(err);
+ done.reject(err);
+ }
+ });
+ return done.promise;
+ }
+ /**
+ * getCertificate - takes care of cooldown, validation polling and certificate retrieval
+ */
+ getCertificate() {
+ }
+ /**
+ * accept a challenge - for private use only
+ */
+ acceptChallenge(challenge) {
+ let done = q.defer();
+ /**
+ * the key is needed to accept the challenge
+ */
+ let authKey = plugins.rawacme.keyAuthz(challenge.token, this.parentAcmeAccount.parentSmartAcme.keyPair.publicKey);
+ /**
+ * needed in case selected challenge is of type dns-01
+ */
+ let keyHash = plugins.rawacme.dnsKeyAuthzHash(authKey); // needed if dns challenge is chosen
+ /**
+ * the return challenge
+ */
+ let returnDNSChallenge = {
+ uri: challenge.uri,
+ type: challenge.type,
+ token: challenge.token,
+ keyAuthorization: challenge.keyAuthorization,
+ keyHash: keyHash,
+ status: challenge.status
+ };
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.post(challenge.uri, {
+ resource: 'challenge',
+ keyAuthorization: authKey
+ }, this.parentAcmeAccount.parentSmartAcme.keyPair, (err, res) => {
+ if (err) {
+ console.log(err);
+ done.reject(err);
+ }
+ done.resolve(returnDNSChallenge);
+ });
+ return done.promise;
+ }
}
exports.AcmeCert = AcmeCert;
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWNlcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lY2VydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEJBQXVCO0FBRXZCO0NBRUM7QUFGRCw0QkFFQyJ9
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWNlcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lY2VydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsdUJBQXNCO0FBRXRCLCtDQUE4QztBQUM5QywrQ0FBOEM7QUF5QzlDOztHQUVHO0FBQ0g7SUFTSSxZQUFZLFVBQXNDLEVBQUUsa0JBQWtCO1FBQ2xFLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxrQkFBa0IsQ0FBQTtRQUMzQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxhQUFhLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3BELElBQUksZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUN2RixJQUFJLGVBQWUsR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQ3RELE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQ2hGLENBQUE7UUFDRCxJQUFJLENBQUMsWUFBWSxHQUFHO1lBQ2hCLFVBQVUsRUFBRSxnQkFBZ0I7WUFDNUIsU0FBUyxFQUFFLGVBQWU7U0FDN0IsQ0FBQTtRQUVELFlBQVk7UUFDWixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUE7UUFDM0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFBO1FBQ3pCLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUE7UUFFbkQsaUJBQWlCO1FBQ2pCLElBQUksQ0FBQyxVQUFVLEdBQUc7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
\ No newline at end of file
diff --git a/dist/smartacme.classes.helper.d.ts b/dist/smartacme.classes.helper.d.ts
deleted file mode 100644
index e20c4eb..0000000
--- a/dist/smartacme.classes.helper.d.ts
+++ /dev/null
@@ -1,21 +0,0 @@
-///
-import 'typings-global';
-import * as q from 'q';
-import { SmartAcme } from './smartacme.classes.smartacme';
-export interface IRsaKeypair {
- publicKey: string;
- privateKey: string;
-}
-export declare class SmartacmeHelper {
- parentSmartAcme: SmartAcme;
- constructor(smartAcmeArg: SmartAcme);
- /**
- * creates a keypair to use with requests and to generate JWK from
- */
- createKeypair(bit?: number): IRsaKeypair;
- /**
- * gets an existing registration
- * @executes ASYNC
- */
- getReg(): q.Promise<{}>;
-}
diff --git a/dist/smartacme.classes.helper.js b/dist/smartacme.classes.helper.js
deleted file mode 100644
index a04892c..0000000
--- a/dist/smartacme.classes.helper.js
+++ /dev/null
@@ -1,40 +0,0 @@
-"use strict";
-require("typings-global");
-const q = require("q");
-let rsaKeygen = require('rsa-keygen');
-class SmartacmeHelper {
- constructor(smartAcmeArg) {
- this.parentSmartAcme = smartAcmeArg;
- }
- /**
- * creates a keypair to use with requests and to generate JWK from
- */
- createKeypair(bit = 2048) {
- let result = rsaKeygen.generate(bit);
- return {
- publicKey: result.public_key,
- privateKey: result.private_key
- };
- }
- /**
- * gets an existing registration
- * @executes ASYNC
- */
- getReg() {
- let done = q.defer();
- let body = { resource: 'reg' };
- this.parentSmartAcme.rawacmeClient.post(this.parentSmartAcme.location, body, this.parentSmartAcme.keyPair, (err, res) => {
- if (err) {
- console.error('smartacme: something went wrong:');
- console.log(err);
- done.reject(err);
- return;
- }
- console.log(JSON.stringify(res.body));
- done.resolve();
- });
- return done.promise;
- }
-}
-exports.SmartacmeHelper = SmartacmeHelper;
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuaGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRhY21lLmNsYXNzZXMuaGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwwQkFBdUI7QUFDdkIsdUJBQXNCO0FBQ3RCLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQVNyQztJQUdJLFlBQVksWUFBdUI7UUFDL0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxZQUFZLENBQUE7SUFDdkMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYSxDQUFDLEdBQUcsR0FBRyxJQUFJO1FBQ3BCLElBQUksTUFBTSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDcEMsTUFBTSxDQUFDO1lBQ0gsU0FBUyxFQUFFLE1BQU0sQ0FBQyxVQUFVO1lBQzVCLFVBQVUsRUFBRSxNQUFNLENBQUMsV0FBVztTQUNqQyxDQUFBO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU07UUFDRixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDcEIsSUFBSSxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUE7UUFDOUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUNuQyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFDN0IsSUFBSSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUNsQyxDQUFDLEdBQUcsRUFBRSxHQUFHO1lBQ0wsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDTixPQUFPLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7Z0JBQ2pELE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLE1BQU0sQ0FBQTtZQUNWLENBQUM7WUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7WUFDckMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FDSixDQUFBO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztDQUNKO0FBekNELDBDQXlDQyJ9
\ No newline at end of file
diff --git a/dist/smartacme.classes.smartacme.d.ts b/dist/smartacme.classes.smartacme.d.ts
index 5a2df31..1792cba 100644
--- a/dist/smartacme.classes.smartacme.d.ts
+++ b/dist/smartacme.classes.smartacme.d.ts
@@ -1,57 +1,34 @@
///
-import 'typings-global';
import * as q from 'q';
-import { SmartacmeHelper, IRsaKeypair } from './smartacme.classes.helper';
-export declare type TChallengeType = 'dns-01' | 'http-01';
-export declare type TChallengeStatus = 'pending';
-export interface ISmartAcmeChallenge {
- uri: string;
- status: TChallengeStatus;
- type: TChallengeType;
- token: string;
- keyAuthorization: string;
-}
-export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
- keyHash: string;
+import { AcmeAccount } from './smartacme.classes.acmeaccount';
+/**
+ * a rsa keypair needed for account creation and subsequent requests
+ */
+export interface IRsaKeypair {
+ publicKey: string;
+ privateKey: string;
}
+export { AcmeAccount } from './smartacme.classes.acmeaccount';
+export { AcmeCert, ISmartAcmeChallenge, ISmartAcmeChallengeAccepted } from './smartacme.classes.acmecert';
/**
* class SmartAcme exports methods for maintaining SSL Certificates
*/
export declare class SmartAcme {
- helper: SmartacmeHelper;
acmeUrl: string;
productionBool: boolean;
keyPair: IRsaKeypair;
- location: string;
- link: string;
rawacmeClient: any;
- JWK: any;
/**
* the constructor for class SmartAcme
*/
constructor(productionArg?: boolean);
+ /**
+ * init the smartacme instance
+ */
+ init(): q.Promise<{}>;
/**
* creates an account if not currently present in module
* @executes ASYNC
*/
- createAccount(): q.Promise<{}>;
- agreeTos(): q.Promise<{}>;
- /**
- * requests a challenge for a domain
- * @param domainNameArg - the domain name to request a challenge for
- * @param challengeType - the challenge type to request
- */
- requestChallenge(domainNameArg: string, challengeTypeArg?: TChallengeType): q.Promise;
- /**
- * getCertificate - takes care of cooldown, validation polling and certificate retrieval
- */
- getCertificate(): void;
- /**
- * validates a challenge
- */
- validate(challenge: ISmartAcmeChallengeAccepted): q.Promise<{}>;
- /**
- * accept a challenge - for private use only
- */
- private acceptChallenge(challenge);
+ createAccount(): q.Promise;
}
diff --git a/dist/smartacme.classes.smartacme.js b/dist/smartacme.classes.smartacme.js
index d20f434..50b6ed0 100644
--- a/dist/smartacme.classes.smartacme.js
+++ b/dist/smartacme.classes.smartacme.js
@@ -1,11 +1,13 @@
"use strict";
-// typings
-require("typings-global"); // typings for node
// third party modules
const q = require("q"); // promises
-let rsaKeygen = require('rsa-keygen'); // rsa keygen
-let rawacme = require('rawacme'); // acme helper functions
-const smartacme_classes_helper_1 = require("./smartacme.classes.helper");
+const plugins = require("./smartacme.plugins");
+const helpers = require("./smartacme.helpers");
+const smartacme_classes_acmeaccount_1 = require("./smartacme.classes.acmeaccount");
+var smartacme_classes_acmeaccount_2 = require("./smartacme.classes.acmeaccount");
+exports.AcmeAccount = smartacme_classes_acmeaccount_2.AcmeAccount;
+var smartacme_classes_acmecert_1 = require("./smartacme.classes.acmecert");
+exports.AcmeCert = smartacme_classes_acmecert_1.AcmeCert;
/**
* class SmartAcme exports methods for maintaining SSL Certificates
*/
@@ -15,22 +17,20 @@ class SmartAcme {
*/
constructor(productionArg = false) {
this.productionBool = productionArg;
- this.helper = new smartacme_classes_helper_1.SmartacmeHelper(this);
- this.keyPair = this.helper.createKeypair();
+ this.keyPair = helpers.createKeypair();
if (this.productionBool) {
- this.acmeUrl = rawacme.LETSENCRYPT_URL;
+ this.acmeUrl = plugins.rawacme.LETSENCRYPT_URL;
}
else {
- this.acmeUrl = rawacme.LETSENCRYPT_STAGING_URL;
+ this.acmeUrl = plugins.rawacme.LETSENCRYPT_STAGING_URL;
}
}
/**
- * creates an account if not currently present in module
- * @executes ASYNC
+ * init the smartacme instance
*/
- createAccount() {
+ init() {
let done = q.defer();
- rawacme.createClient({
+ plugins.rawacme.createClient({
url: this.acmeUrl,
publicKey: this.keyPair.publicKey,
privateKey: this.keyPair.privateKey
@@ -43,126 +43,24 @@ class SmartAcme {
}
// make client available in class
this.rawacmeClient = client;
- // create the registration
- client.newReg({
- contact: ['mailto:domains@lossless.org']
- }, (err, res) => {
- if (err) {
- console.error('smartacme: something went wrong:');
- console.log(err);
- done.reject(err);
- return;
- }
- this.JWK = res.body.key;
- this.link = res.headers.link;
- console.log(this.link);
- this.location = res.headers.location;
- done.resolve();
- });
- });
- return done.promise;
- }
- agreeTos() {
- let done = q.defer();
- let tosPart = this.link.split(',')[1];
- let tosLinkPortion = tosPart.split(';')[0];
- let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '');
- this.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
- if (err) {
- console.log(err);
- done.reject(err);
- return;
- }
done.resolve();
});
return done.promise;
}
/**
- * requests a challenge for a domain
- * @param domainNameArg - the domain name to request a challenge for
- * @param challengeType - the challenge type to request
+ * creates an account if not currently present in module
+ * @executes ASYNC
*/
- requestChallenge(domainNameArg, challengeTypeArg = 'dns-01') {
+ createAccount() {
let done = q.defer();
- this.rawacmeClient.newAuthz({
- identifier: {
- type: 'dns',
- value: domainNameArg
- }
- }, this.keyPair, (err, res) => {
- if (err) {
- console.error('smartacme: something went wrong:');
- console.log(err);
- done.reject(err);
- }
- console.log(JSON.stringify(res.body));
- let dnsChallenge = res.body.challenges.filter(x => {
- return x.type === challengeTypeArg;
- })[0];
- this.acceptChallenge(dnsChallenge)
- .then((x) => {
- done.resolve(x);
- });
- });
- return done.promise;
- }
- /**
- * getCertificate - takes care of cooldown, validation polling and certificate retrieval
- */
- getCertificate() {
- }
- /**
- * validates a challenge
- */
- validate(challenge) {
- let done = q.defer();
- this.rawacmeClient.poll(challenge.uri, function (err, res) {
- if (err) {
- console.log(err);
- done.reject(err);
- }
- console.log(res.status);
- console.log(JSON.stringify(res.body));
- done.resolve();
- });
- return done.promise;
- }
- /**
- * accept a challenge - for private use only
- */
- acceptChallenge(challenge) {
- let done = q.defer();
- /**
- * the key is needed to accept the challenge
- */
- let authKey = rawacme.keyAuthz(challenge.token, this.keyPair.publicKey);
- /**
- * needed in case selected challenge is of type dns-01
- */
- let keyHash = rawacme.dnsKeyAuthzHash(authKey); // needed if dns challenge is chosen
- /**
- * the return challenge
- */
- let returnDNSChallenge = {
- uri: challenge.uri,
- type: challenge.type,
- token: challenge.token,
- keyAuthorization: challenge.keyAuthorization,
- keyHash: keyHash,
- status: challenge.status
- };
- this.rawacmeClient.post(challenge.uri, {
- resource: 'challenge',
- keyAuthorization: authKey
- }, this.keyPair, (err, res) => {
- if (err) {
- console.log(err);
- done.reject(err);
- }
- done.resolve(returnDNSChallenge);
+ let acmeAccount = new smartacme_classes_acmeaccount_1.AcmeAccount(this);
+ acmeAccount.register().then(() => {
+ return acmeAccount.agreeTos();
+ }).then(() => {
+ done.resolve(acmeAccount);
});
return done.promise;
}
}
exports.SmartAcme = SmartAcme;
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxVQUFVO0FBQ1YsMEJBQXVCLENBQUMsbUJBQW1CO0FBRTNDLHNCQUFzQjtBQUN0Qix1QkFBc0IsQ0FBQyxXQUFXO0FBRWxDLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQSxDQUFDLGFBQWE7QUFDbkQsSUFBSSxPQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBLENBQUMsd0JBQXdCO0FBT3pELHlFQUF5RTtBQWlCekU7O0dBRUc7QUFDSDtJQVVJOztPQUVHO0lBQ0gsWUFBWSxnQkFBeUIsS0FBSztRQUN0QyxJQUFJLENBQUMsY0FBYyxHQUFHLGFBQWEsQ0FBQTtRQUNuQyxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksMENBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUN2QyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUE7UUFDMUMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDdEIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsZUFBZSxDQUFBO1FBQzFDLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNKLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLHVCQUF1QixDQUFBO1FBQ2xELENBQUM7SUFDTCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYTtRQUNULElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixPQUFPLENBQUMsWUFBWSxDQUNoQjtZQUNJLEdBQUcsRUFBRSxJQUFJLENBQUMsT0FBTztZQUNqQixTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTO1lBQ2pDLFVBQVUsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVU7U0FDdEMsRUFDRCxDQUFDLEdBQUcsRUFBRSxNQUFNO1lBQ1IsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDTixPQUFPLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7Z0JBQ2pELE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLE1BQU0sQ0FBQTtZQUNWLENBQUM7WUFFRCxrQ0FBa0M7WUFDbEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxNQUFNLENBQUE7WUFFM0IsMEJBQTBCO1lBQzFCLE1BQU0sQ0FBQyxNQUFNLENBQ1Q7Z0JBQ0ksT0FBTyxFQUFFLENBQUMsNkJBQTZCLENBQUM7YUFDM0MsRUFDRCxDQUFDLEdBQUcsRUFBRSxHQUFHO2dCQUNMLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQ04sT0FBTyxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFBO29CQUNqRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO29CQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO29CQUNoQixNQUFNLENBQUE7Z0JBQ1YsQ0FBQztnQkFDRCxJQUFJLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFBO2dCQUN2QixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFBO2dCQUM1QixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtnQkFDdEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQTtnQkFDcEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1lBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBRVYsQ0FBQyxDQUNKLENBQUE7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQsUUFBUTtRQUNKLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNyQyxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzFDLElBQUksR0FBRyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUNsRSxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEVBQUUsR0FBRztZQUNqRixFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLE1BQU0sQ0FBQTtZQUNWLENBQUM7WUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDbEIsQ0FBQyxDQUFDLENBQUE7UUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGdCQUFnQixDQUFDLGFBQXFCLEVBQUUsbUJBQW1DLFFBQVE7UUFDL0UsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBK0IsQ0FBQTtRQUNqRCxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FDdkI7WUFDSSxVQUFVLEVBQUU7Z0JBQ1IsSUFBSSxFQUFFLEtBQUs7Z0JBQ1gsS0FBSyxFQUFFLGFBQWE7YUFDdkI7U0FDSixFQUNELElBQUksQ0FBQyxPQUFPLEVBQ1osQ0FBQyxHQUFHLEVBQUUsR0FBRztZQUNMLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ04sT0FBTyxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFBO2dCQUNqRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ3BCLENBQUM7WUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7WUFDckMsSUFBSSxZQUFZLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQzNDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLGdCQUFnQixDQUFBO1lBQ3RDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQ0wsSUFBSSxDQUFDLGVBQWUsQ0FBQyxZQUFZLENBQUM7aUJBQzdCLElBQUksQ0FBQyxDQUFDLENBQThCO2dCQUNqQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFBO1lBQ25CLENBQUMsQ0FBQyxDQUFBO1FBQ1YsQ0FBQyxDQUNKLENBQUE7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjO0lBRWQsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUSxDQUFDLFNBQXNDO1FBQzNDLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLFVBQVMsR0FBRyxFQUFFLEdBQUc7WUFDcEQsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDTixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ3BCLENBQUM7WUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtZQUN2QixPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7WUFDckMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztJQUdEOztPQUVHO0lBQ0ssZUFBZSxDQUFDLFNBQThCO1FBQ2xELElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUVwQjs7V0FFRztRQUNILElBQUksT0FBTyxHQUFXLE9BQU8sQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFBO1FBRS9FOztXQUVHO1FBQ0gsSUFBSSxPQUFPLEdBQVcsT0FBTyxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQSxDQUFDLG9DQUFvQztRQUUzRjs7V0FFRztRQUNILElBQUksa0JBQWtCLEdBQWdDO1lBQ2xELEdBQUcsRUFBRSxTQUFTLENBQUMsR0FBRztZQUNsQixJQUFJLEVBQUUsU0FBUyxDQUFDLElBQUk7WUFDcEIsS0FBSyxFQUFFLFNBQVMsQ0FBQyxLQUFLO1lBQ3RCLGdCQUFnQixFQUFFLFNBQVMsQ0FBQyxnQkFBZ0I7WUFDNUMsT0FBTyxFQUFFLE9BQU87WUFDaEIsTUFBTSxFQUFFLFNBQVMsQ0FBQyxNQUFNO1NBQzNCLENBQUE7UUFFRCxJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FDbkIsU0FBUyxDQUFDLEdBQUcsRUFDYjtZQUNJLFFBQVEsRUFBRSxXQUFXO1lBQ3JCLGdCQUFnQixFQUFFLE9BQU87U0FDNUIsRUFDRCxJQUFJLENBQUMsT0FBTyxFQUNaLENBQUMsR0FBRyxFQUFFLEdBQUc7WUFDTCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO2dCQUNOLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7WUFDcEIsQ0FBQztZQUNELElBQUksQ0FBQyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtRQUNwQyxDQUFDLENBQ0osQ0FBQTtRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7Q0FHSjtBQWpNRCw4QkFpTUMifQ==
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRhY21lLmNsYXNzZXMuc21hcnRhY21lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxzQkFBc0I7QUFDdEIsdUJBQXNCLENBQUMsV0FBVztBQUNsQywrQ0FBOEM7QUFDOUMsK0NBQThDO0FBRTlDLG1GQUE2RDtBQVU3RCxpRkFBNkQ7QUFBcEQsc0RBQUEsV0FBVyxDQUFBO0FBQ3BCLDJFQUF5RztBQUFoRyxnREFBQSxRQUFRLENBQUE7QUFFakI7O0dBRUc7QUFDSDtJQU1JOztPQUVHO0lBQ0gsWUFBWSxnQkFBeUIsS0FBSztRQUN0QyxJQUFJLENBQUMsY0FBYyxHQUFHLGFBQWEsQ0FBQTtRQUNuQyxJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxhQUFhLEVBQUUsQ0FBQTtRQUN0QyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztZQUN0QixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsZUFBZSxDQUFBO1FBQ2xELENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNKLElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sQ0FBQyx1QkFBdUIsQ0FBQTtRQUMxRCxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSTtRQUNBLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixPQUFPLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FDeEI7WUFDSSxHQUFHLEVBQUUsSUFBSSxDQUFDLE9BQU87WUFDakIsU0FBUyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUztZQUNqQyxVQUFVLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVO1NBQ3RDLEVBQ0QsQ0FBQyxHQUFHLEVBQUUsTUFBTTtZQUNSLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ04sT0FBTyxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFBO2dCQUNqRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixNQUFNLENBQUE7WUFDVixDQUFDO1lBRUQsa0NBQWtDO1lBQ2xDLElBQUksQ0FBQyxhQUFhLEdBQUcsTUFBTSxDQUFBO1lBQzNCLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtRQUNsQixDQUFDLENBQ0osQ0FBQTtRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7O09BR0c7SUFDSCxhQUFhO1FBQ1QsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBZSxDQUFBO1FBQ2pDLElBQUksV0FBVyxHQUFHLElBQUksMkNBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUN2QyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxXQUFXLENBQUMsUUFBUSxFQUFFLENBQUE7UUFDakMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1lBQ0osSUFBSSxDQUFDLE9BQU8sQ0FBQyxXQUFXLENBQUMsQ0FBQTtRQUM3QixDQUFDLENBQUMsQ0FBQTtRQUNGLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7Q0FDSjtBQTVERCw4QkE0REMifQ==
\ No newline at end of file
diff --git a/dist/smartacme.helpers.d.ts b/dist/smartacme.helpers.d.ts
new file mode 100644
index 0000000..4acef35
--- /dev/null
+++ b/dist/smartacme.helpers.d.ts
@@ -0,0 +1,6 @@
+import 'typings-global';
+import { IRsaKeypair } from './smartacme.classes.smartacme';
+/**
+ * creates a keypair to use with requests and to generate JWK from
+ */
+export declare let createKeypair: (bit?: number) => IRsaKeypair;
diff --git a/dist/smartacme.helpers.js b/dist/smartacme.helpers.js
new file mode 100644
index 0000000..f0049fd
--- /dev/null
+++ b/dist/smartacme.helpers.js
@@ -0,0 +1,34 @@
+"use strict";
+require("typings-global");
+const q = require("q");
+const plugins = require("./smartacme.plugins");
+/**
+ * creates a keypair to use with requests and to generate JWK from
+ */
+exports.createKeypair = (bit = 2048) => {
+ let result = plugins.rsaKeygen.generate(bit);
+ return {
+ publicKey: result.public_key,
+ privateKey: result.private_key
+ };
+};
+/**
+ * gets an existing registration
+ * @executes ASYNC
+ */
+let getReg = (SmartAcmeArg, location) => {
+ let done = q.defer();
+ let body = { resource: 'reg' };
+ SmartAcmeArg.rawacmeClient.post(location, body, SmartAcmeArg.keyPair, (err, res) => {
+ if (err) {
+ console.error('smartacme: something went wrong:');
+ console.log(err);
+ done.reject(err);
+ return;
+ }
+ console.log(JSON.stringify(res.body));
+ done.resolve();
+ });
+ return done.promise;
+};
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEJBQXVCO0FBQ3ZCLHVCQUFzQjtBQUV0QiwrQ0FBOEM7QUFLOUM7O0dBRUc7QUFDUSxRQUFBLGFBQWEsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJO0lBQ2xDLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQzVDLE1BQU0sQ0FBQztRQUNILFNBQVMsRUFBRSxNQUFNLENBQUMsVUFBVTtRQUM1QixVQUFVLEVBQUUsTUFBTSxDQUFDLFdBQVc7S0FDakMsQ0FBQTtBQUNMLENBQUMsQ0FBQTtBQUVEOzs7R0FHRztBQUNILElBQUksTUFBTSxHQUFHLENBQUMsWUFBdUIsRUFBRSxRQUFnQjtJQUNuRCxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDcEIsSUFBSSxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUE7SUFDOUIsWUFBWSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzNCLFFBQVEsRUFDUixJQUFJLEVBQ0osWUFBWSxDQUFDLE9BQU8sRUFDcEIsQ0FBQyxHQUFHLEVBQUUsR0FBRztRQUNMLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDTixPQUFPLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7WUFDakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLE1BQU0sQ0FBQTtRQUNWLENBQUM7UUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7UUFDckMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO0lBQ2xCLENBQUMsQ0FDSixDQUFBO0lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7QUFDdkIsQ0FBQyxDQUFBIn0=
\ No newline at end of file
diff --git a/dist/smartacme.plugins.d.ts b/dist/smartacme.plugins.d.ts
new file mode 100644
index 0000000..0b48b83
--- /dev/null
+++ b/dist/smartacme.plugins.d.ts
@@ -0,0 +1,8 @@
+import 'typings-global';
+declare let rsaKeygen: any;
+declare let rawacme: any;
+declare let nodeForge: any;
+import * as smartfile from 'smartfile';
+import * as smartstring from 'smartstring';
+import * as paths from './smartacme.paths';
+export { rsaKeygen, rawacme, nodeForge, smartfile, smartstring, paths };
diff --git a/dist/smartacme.plugins.js b/dist/smartacme.plugins.js
new file mode 100644
index 0000000..9f636d2
--- /dev/null
+++ b/dist/smartacme.plugins.js
@@ -0,0 +1,16 @@
+"use strict";
+require("typings-global"); // typings for node
+let rsaKeygen = require('rsa-keygen'); // rsa keygen
+exports.rsaKeygen = rsaKeygen;
+let rawacme = require('rawacme'); // acme helper functions
+exports.rawacme = rawacme;
+let nodeForge = require('node-forge');
+exports.nodeForge = nodeForge;
+// push.rocks modules here
+const smartfile = require("smartfile");
+exports.smartfile = smartfile;
+const smartstring = require("smartstring");
+exports.smartstring = smartstring;
+const paths = require("./smartacme.paths");
+exports.paths = paths;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEJBQXVCLENBQUMsbUJBQW1CO0FBRzNDLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQSxDQUFDLGFBQWE7QUFVL0MsOEJBQVM7QUFUYixJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUEsQ0FBQyx3QkFBd0I7QUFVckQsMEJBQU87QUFUWCxJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUE7QUFVakMsOEJBQVM7QUFSYiwwQkFBMEI7QUFDMUIsdUNBQXNDO0FBUWxDLDhCQUFTO0FBUGIsMkNBQTBDO0FBUXRDLGtDQUFXO0FBUGYsMkNBQTBDO0FBUXRDLHNCQUFLIn0=
\ No newline at end of file
diff --git a/package.json b/package.json
index d290b81..d53fe49 100644
--- a/package.json
+++ b/package.json
@@ -35,6 +35,7 @@
},
"devDependencies": {
"@types/should": "^8.1.30",
+ "cflare": "0.0.10",
"should": "^11.1.1",
"typings-test": "^1.0.3"
}
diff --git a/test/test.js b/test/test.js
index 594d74b..4810dce 100644
--- a/test/test.js
+++ b/test/test.js
@@ -4,44 +4,42 @@ const should = require("should");
// import the module to test
const smartacme = require("../dist/index");
describe('smartacme', function () {
- let testAcme;
+ let testSmartAcme;
+ let testAcmeAccount;
let testChallenge;
- it('should create a valid instance', function () {
+ it('should create a valid instance', function (done) {
this.timeout(10000);
- testAcme = new smartacme.SmartAcme();
- should(testAcme).be.instanceOf(smartacme.SmartAcme);
+ testSmartAcme = new smartacme.SmartAcme();
+ testSmartAcme.init().then(() => {
+ should(testSmartAcme).be.instanceOf(smartacme.SmartAcme);
+ done();
+ }).catch(err => { done(err); });
});
it('should have created keyPair', function () {
- should(testAcme.acmeUrl).be.of.type('string');
+ should(testSmartAcme.acmeUrl).be.of.type('string');
});
it('should register a new account', function (done) {
this.timeout(10000);
- testAcme.createAccount().then(x => {
+ testSmartAcme.createAccount().then(x => {
done();
}).catch(err => {
console.log(err);
done(err);
});
});
- it('should agree to ToS', function (done) {
+ it.skip('should request a cert for a domain', function (done) {
this.timeout(10000);
- testAcme.agreeTos().then(() => {
- done();
- });
- });
- it('should request a challenge for a domain', function (done) {
- this.timeout(10000);
- testAcme.requestChallenge('bleu.de').then((challengeAccepted) => {
+ testAcmeAccount.requestChallenge('bleu.de').then((challengeAccepted) => {
console.log(challengeAccepted);
testChallenge = challengeAccepted;
done();
});
});
- it('should poll for validation of a challenge', function (done) {
+ it.skip('should poll for validation of a challenge', function (done) {
this.timeout(10000);
- testAcme.validate(testChallenge).then(x => {
+ testSmartAcme.validate(testChallenge).then(x => {
done();
});
});
});
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFFaEMsNEJBQTRCO0FBQzVCLDJDQUEwQztBQUUxQyxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ2xCLElBQUksUUFBNkIsQ0FBQTtJQUNqQyxJQUFJLGFBQW9ELENBQUE7SUFDeEQsRUFBRSxDQUFDLGdDQUFnQyxFQUFFO1FBQ2pDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxHQUFHLElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFBO1FBQ3BDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUN2RCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyw2QkFBNkIsRUFBRTtRQUM5QixNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ2pELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLCtCQUErQixFQUFFLFVBQVUsSUFBSTtRQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLFFBQVEsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzQixJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHO1lBQ1IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNoQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDYixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHFCQUFxQixFQUFFLFVBQVMsSUFBSTtRQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDckIsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHlDQUF5QyxFQUFFLFVBQVMsSUFBSTtRQUN2RCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxpQkFBaUI7WUFDeEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1lBQzlCLGFBQWEsR0FBRyxpQkFBaUIsQ0FBQTtZQUNqQyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsMkNBQTJDLEVBQUMsVUFBUyxJQUFJO1FBQ3hELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQSJ9
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFHaEMsNEJBQTRCO0FBQzVCLDJDQUEwQztBQUUxQyxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ2xCLElBQUksYUFBa0MsQ0FBQTtJQUN0QyxJQUFJLGVBQXNDLENBQUE7SUFDMUMsSUFBSSxhQUFvRCxDQUFBO0lBQ3hELEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxVQUFVLElBQUk7UUFDL0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNuQixhQUFhLEdBQUcsSUFBSSxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUE7UUFDekMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQztZQUN0QixNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUE7WUFDeEQsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2xDLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDZCQUE2QixFQUFFO1FBQzlCLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDdEQsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsK0JBQStCLEVBQUUsVUFBVSxJQUFJO1FBQzlDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsYUFBYSxDQUFDLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hDLElBQUksRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDUixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNiLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxFQUFFLFVBQVUsSUFBSTtRQUN4RCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxpQkFBaUI7WUFDL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1lBQzlCLGFBQWEsR0FBRyxpQkFBaUIsQ0FBQTtZQUNqQyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsSUFBSSxDQUFDLDJDQUEyQyxFQUFFLFVBQVUsSUFBSTtRQUMvRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLGFBQWEsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEMsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUEifQ==
\ No newline at end of file
diff --git a/test/test.ts b/test/test.ts
index 99219e4..35a24ee 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -1,25 +1,30 @@
import 'typings-test'
import * as should from 'should'
+import * as cflare from 'cflare'
// import the module to test
import * as smartacme from '../dist/index'
describe('smartacme', function () {
- let testAcme: smartacme.SmartAcme
+ let testSmartAcme: smartacme.SmartAcme
+ let testAcmeAccount: smartacme.AcmeAccount
let testChallenge: smartacme.ISmartAcmeChallengeAccepted
- it('should create a valid instance', function () {
+ it('should create a valid instance', function (done) {
this.timeout(10000)
- testAcme = new smartacme.SmartAcme()
- should(testAcme).be.instanceOf(smartacme.SmartAcme)
+ testSmartAcme = new smartacme.SmartAcme()
+ testSmartAcme.init().then(() => {
+ should(testSmartAcme).be.instanceOf(smartacme.SmartAcme)
+ done()
+ }).catch(err => { done(err) })
})
it('should have created keyPair', function () {
- should(testAcme.acmeUrl).be.of.type('string')
+ should(testSmartAcme.acmeUrl).be.of.type('string')
})
it('should register a new account', function (done) {
this.timeout(10000)
- testAcme.createAccount().then(x => {
+ testSmartAcme.createAccount().then(x => {
done()
}).catch(err => {
console.log(err)
@@ -27,25 +32,18 @@ describe('smartacme', function () {
})
})
- it('should agree to ToS', function(done) {
+ it.skip('should request a cert for a domain', function (done) {
this.timeout(10000)
- testAcme.agreeTos().then(() => {
- done()
- })
- })
-
- it('should request a challenge for a domain', function(done) {
- this.timeout(10000)
- testAcme.requestChallenge('bleu.de').then((challengeAccepted) => {
+ testAcmeAccount.requestChallenge('bleu.de').then((challengeAccepted) => {
console.log(challengeAccepted)
testChallenge = challengeAccepted
done()
})
})
- it('should poll for validation of a challenge',function(done) {
+ it.skip('should poll for validation of a challenge', function (done) {
this.timeout(10000)
- testAcme.validate(testChallenge).then(x => {
+ testSmartAcme.validate(testChallenge).then(x => {
done()
})
})
diff --git a/ts/smartacme.classes.acmeaccount.ts b/ts/smartacme.classes.acmeaccount.ts
index ba2666f..c727f75 100644
--- a/ts/smartacme.classes.acmeaccount.ts
+++ b/ts/smartacme.classes.acmeaccount.ts
@@ -1,8 +1,68 @@
-import 'typings-global'
+import * as q from 'q'
+
+import * as plugins from './smartacme.plugins'
+import * as helpers from './smartacme.helpers'
+
+import { SmartAcme, IRsaKeypair } from './smartacme.classes.smartacme'
+import { AcmeCert } from './smartacme.classes.acmecert'
/**
* class AcmeAccount represents an AcmeAccount
*/
export class AcmeAccount {
-
-}
\ No newline at end of file
+ parentSmartAcme: SmartAcme
+ location: string
+ link: string
+ JWK
+ constructor(smartAcmeParentArg: SmartAcme) {
+ this.parentSmartAcme = smartAcmeParentArg
+ }
+
+ /**
+ * register the account with letsencrypt
+ */
+ register() {
+ let done = q.defer()
+ this.parentSmartAcme.rawacmeClient.newReg(
+ {
+ contact: ['mailto:domains@lossless.org']
+ },
+ (err, res) => {
+ if (err) {
+ console.error('smartacme: something went wrong:')
+ console.log(err)
+ done.reject(err)
+ return
+ }
+ this.JWK = res.body.key
+ this.link = res.headers.link
+ console.log(this.link)
+ this.location = res.headers.location
+ done.resolve()
+ })
+ return done.promise
+ }
+
+ /**
+ * agree to letsencrypr terms of service
+ */
+ agreeTos() {
+ let done = q.defer()
+ let tosPart = this.link.split(',')[1]
+ let tosLinkPortion = tosPart.split(';')[0]
+ let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '')
+ this.parentSmartAcme.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
+ if (err) {
+ console.log(err)
+ done.reject(err)
+ return
+ }
+ done.resolve()
+ })
+ return done.promise
+ }
+
+ createAcmeCert(domainNameArg: string) {
+
+ }
+}
diff --git a/ts/smartacme.classes.acmecert.ts b/ts/smartacme.classes.acmecert.ts
index 6b17e50..a07d7ee 100644
--- a/ts/smartacme.classes.acmecert.ts
+++ b/ts/smartacme.classes.acmecert.ts
@@ -1,8 +1,226 @@
-import 'typings-global'
+import * as q from 'q'
+
+import * as plugins from './smartacme.plugins'
+import * as helpers from './smartacme.helpers'
+
+import { SmartAcme, IRsaKeypair } from './smartacme.classes.smartacme'
+import { AcmeAccount } from './smartacme.classes.acmeaccount'
+
+/**
+ * types of challenges supported by letsencrypt and this module
+ */
+export type TChallengeType = 'dns-01' | 'http-01'
+
+/**
+ * values that a challenge's status can have
+ */
+export type TChallengeStatus = 'pending'
+
+export interface ISmartAcmeChallenge {
+ uri: string
+ status: TChallengeStatus
+ type: TChallengeType
+ token: string
+ keyAuthorization: string
+}
+
+export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
+ keyHash: string
+}
+
+export interface IAcmeCsrConstructorOptions {
+ bit: number,
+ key: string,
+ domain: string,
+ country: string,
+ country_short: string,
+ locality: string,
+ organization: string,
+ organization_short: string,
+ password: string,
+ unstructured: string,
+ subject_alt_names: string[]
+}
/**
* class AcmeCert represents a cert for domain
*/
export class AcmeCert {
+ attributes
fullchain: string
-}
\ No newline at end of file
+ parentAcmeAccount: AcmeAccount
+ csr
+ validFrom: Date
+ validTo: Date
+ keypair: IRsaKeypair
+ keyPairFinal: IRsaKeypair
+ constructor(optionsArg: IAcmeCsrConstructorOptions, parentSmartAcmeArg) {
+ this.parentAcmeAccount = parentSmartAcmeArg
+ this.keypair = helpers.createKeypair(optionsArg.bit)
+ let privateKeyForged = plugins.nodeForge.pki.privateKeyFromPem(this.keypair.privateKey)
+ let publicKeyForged = plugins.nodeForge.pki.publicKeyToPem(
+ plugins.nodeForge.pki.setRsaPublicKey(privateKeyForged.n, privateKeyForged.e)
+ )
+ this.keyPairFinal = {
+ privateKey: privateKeyForged,
+ publicKey: publicKeyForged
+ }
+
+ // set dates
+ this.validFrom = new Date()
+ this.validTo = new Date()
+ this.validTo.setDate(this.validFrom.getDate() + 90)
+
+ // set attributes
+ this.attributes = [
+ { name: 'commonName', value: optionsArg.domain },
+ { name: 'countryName', value: optionsArg.country },
+ { shortName: 'ST', value: optionsArg.country_short },
+ { name: 'localityName', value: optionsArg.locality },
+ { name: 'organizationName', value: optionsArg.organization },
+ { shortName: 'OU', value: optionsArg.organization_short },
+ { name: 'challengePassword', value: optionsArg.password },
+ { name: 'unstructuredName', value: optionsArg.unstructured }
+ ]
+
+ // set up csr
+ this.csr = plugins.nodeForge.pki.createCertificationRequest()
+ this.csr.setSubject(this.attributes)
+ this.csr.setAttributes(this.attributes)
+ }
+
+ /**
+ * requests a challenge for a domain
+ * @param domainNameArg - the domain name to request a challenge for
+ * @param challengeType - the challenge type to request
+ */
+ requestChallenge(domainNameArg: string, challengeTypeArg: TChallengeType = 'dns-01') {
+ let done = q.defer()
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.newAuthz(
+ {
+ identifier: {
+ type: 'dns',
+ value: domainNameArg
+ }
+ },
+ this.parentAcmeAccount.parentSmartAcme.keyPair,
+ (err, res) => {
+ if (err) {
+ console.error('smartacme: something went wrong:')
+ console.log(err)
+ done.reject(err)
+ }
+ console.log(JSON.stringify(res.body))
+ let dnsChallenge = res.body.challenges.filter(x => {
+ return x.type === challengeTypeArg
+ })[0]
+ this.acceptChallenge(dnsChallenge)
+ .then((x: ISmartAcmeChallengeAccepted) => {
+ done.resolve(x)
+ })
+ }
+ )
+ return done.promise
+ }
+
+ /**
+ * validates a challenge, only call after you have set the challenge at the expected location
+ */
+ validate(challenge: ISmartAcmeChallengeAccepted) {
+ let done = q.defer()
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.poll(challenge.uri, function (err, res) {
+ if (err) {
+ console.log(err)
+ done.reject(err)
+ }
+ console.log(res.status)
+ console.log(JSON.stringify(res.body))
+ done.resolve()
+ })
+ return done.promise
+ }
+
+ /**
+ * requests a certificate
+ */
+ requestCert() {
+ let done = q.defer()
+ let payload = {
+ csr: plugins.rawacme.base64.encode(
+ plugins.rawacme.toDer(
+ plugins.nodeForge.pki.certificationRequestToPem(
+ this.csr
+ )
+ )
+ ),
+ notBefore: this.validFrom.toISOString(),
+ notAfter: this.validTo.toISOString()
+ }
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.newCert(
+ payload,
+ helpers.createKeypair(),
+ (err, res) => {
+ if (err) {
+ console.log(err)
+ done.reject(err)
+ }
+ })
+ return done.promise
+ }
+
+ /**
+ * getCertificate - takes care of cooldown, validation polling and certificate retrieval
+ */
+ getCertificate() {
+
+ }
+
+ /**
+ * accept a challenge - for private use only
+ */
+ private acceptChallenge(challenge: ISmartAcmeChallenge) {
+ let done = q.defer()
+
+ /**
+ * the key is needed to accept the challenge
+ */
+ let authKey: string = plugins.rawacme.keyAuthz(
+ challenge.token,
+ this.parentAcmeAccount.parentSmartAcme.keyPair.publicKey
+ )
+
+ /**
+ * needed in case selected challenge is of type dns-01
+ */
+ let keyHash: string = plugins.rawacme.dnsKeyAuthzHash(authKey) // needed if dns challenge is chosen
+
+ /**
+ * the return challenge
+ */
+ let returnDNSChallenge: ISmartAcmeChallengeAccepted = {
+ uri: challenge.uri,
+ type: challenge.type,
+ token: challenge.token,
+ keyAuthorization: challenge.keyAuthorization,
+ keyHash: keyHash,
+ status: challenge.status
+ }
+
+ this.parentAcmeAccount.parentSmartAcme.rawacmeClient.post(
+ challenge.uri,
+ {
+ resource: 'challenge',
+ keyAuthorization: authKey
+ },
+ this.parentAcmeAccount.parentSmartAcme.keyPair,
+ (err, res) => {
+ if (err) {
+ console.log(err)
+ done.reject(err)
+ }
+ done.resolve(returnDNSChallenge)
+ }
+ )
+ return done.promise
+ }
+}
diff --git a/ts/smartacme.classes.acmecsr.ts b/ts/smartacme.classes.acmecsr.ts
deleted file mode 100644
index 097ef6f..0000000
--- a/ts/smartacme.classes.acmecsr.ts
+++ /dev/null
@@ -1,52 +0,0 @@
-import * as plugins from './smartacme.plugins'
-import * as helpers from './smartacme.helpers'
-
-import { IRsaKeypair } from './smartacme.classes.smartacme'
-
-export interface IAcmeCsrConstructorOptions {
- bit: number,
- key: string,
- domain: string,
- country: string,
- country_short: string,
- locality: string,
- organization: string,
- organization_short: string,
- password: string,
- unstructured: string,
- subject_alt_names: string[]
-}
-
-export class AcmeCsr {
- validFrom: Date
- validTo: Date
- keypair: IRsaKeypair
- keyPairForged: IRsaKeypair
- constructor(optionsArg: IAcmeCsrConstructorOptions) {
- this.keypair = helpers.createKeypair(optionsArg.bit)
- let privateKeyForged = plugins.nodeForge.pki.privateKeyFromPem(this.keypair.privateKey)
- let publicKeyForged = plugins.nodeForge.pki.publicKeyToPem(
- plugins.nodeForge.pki.setRsaPublicKey(privateKeyForged.n, privateKeyForged.e)
- )
- this.keyPairForged = {
- privateKey: privateKeyForged,
- publicKey: publicKeyForged
- }
-
- // set dates
- this.validFrom = new Date()
- this.validTo = new Date()
- this.validTo.setDate(this.validFrom.getDate() + 90)
-
- // create the csr
- let attributes = [
- { name: "commonName", value: domain },
- { name: "countryName", value: country },
- { shortName: "ST", value: country_short },
- { name: "localityName", value: locality },
- { name: "organizationName", value: organization },
- { shortName: "OU", value: organization_short }
- ]
-
- }
-}
diff --git a/ts/smartacme.classes.smartacme.ts b/ts/smartacme.classes.smartacme.ts
index 475e6a6..68bfa4e 100644
--- a/ts/smartacme.classes.smartacme.ts
+++ b/ts/smartacme.classes.smartacme.ts
@@ -3,37 +3,27 @@ import * as q from 'q' // promises
import * as plugins from './smartacme.plugins'
import * as helpers from './smartacme.helpers'
+import { AcmeAccount } from './smartacme.classes.acmeaccount'
+
+/**
+ * a rsa keypair needed for account creation and subsequent requests
+ */
export interface IRsaKeypair {
publicKey: string
privateKey: string
}
-export type TChallengeType = 'dns-01' | 'http-01'
-export type TChallengeStatus = 'pending'
-
-export interface ISmartAcmeChallenge {
- uri: string
- status: TChallengeStatus
- type: TChallengeType
- token: string
- keyAuthorization: string
-}
-
-export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
- keyHash: string
-}
+export { AcmeAccount } from './smartacme.classes.acmeaccount'
+export { AcmeCert, ISmartAcmeChallenge, ISmartAcmeChallengeAccepted } from './smartacme.classes.acmecert'
/**
* class SmartAcme exports methods for maintaining SSL Certificates
*/
export class SmartAcme {
- acmeUrl: string // the acme url to use
+ acmeUrl: string // the acme url to use for this instance
productionBool: boolean // a boolean to quickly know wether we are in production or not
keyPair: IRsaKeypair // the keyPair needed for account creation
- location: string
- link: string
rawacmeClient
- JWK
/**
* the constructor for class SmartAcme
@@ -49,10 +39,9 @@ export class SmartAcme {
}
/**
- * creates an account if not currently present in module
- * @executes ASYNC
+ * init the smartacme instance
*/
- createAccount() {
+ init() {
let done = q.defer()
plugins.rawacme.createClient(
{
@@ -70,151 +59,24 @@ export class SmartAcme {
// make client available in class
this.rawacmeClient = client
-
- // create the registration
- client.newReg(
- {
- contact: ['mailto:domains@lossless.org']
- },
- (err, res) => {
- if (err) {
- console.error('smartacme: something went wrong:')
- console.log(err)
- done.reject(err)
- return
- }
- this.JWK = res.body.key
- this.link = res.headers.link
- console.log(this.link)
- this.location = res.headers.location
- done.resolve()
- })
-
+ done.resolve()
}
)
return done.promise
}
- agreeTos() {
- let done = q.defer()
- let tosPart = this.link.split(',')[1]
- let tosLinkPortion = tosPart.split(';')[0]
- let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '')
- this.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
- if (err) {
- console.log(err)
- done.reject(err)
- return
- }
- done.resolve()
+ /**
+ * creates an account if not currently present in module
+ * @executes ASYNC
+ */
+ createAccount() {
+ let done = q.defer()
+ let acmeAccount = new AcmeAccount(this)
+ acmeAccount.register().then(() => {
+ return acmeAccount.agreeTos()
+ }).then(() => {
+ done.resolve(acmeAccount)
})
return done.promise
}
-
- /**
- * requests a challenge for a domain
- * @param domainNameArg - the domain name to request a challenge for
- * @param challengeType - the challenge type to request
- */
- requestChallenge(domainNameArg: string, challengeTypeArg: TChallengeType = 'dns-01') {
- let done = q.defer()
- this.rawacmeClient.newAuthz(
- {
- identifier: {
- type: 'dns',
- value: domainNameArg
- }
- },
- this.keyPair,
- (err, res) => {
- if (err) {
- console.error('smartacme: something went wrong:')
- console.log(err)
- done.reject(err)
- }
- console.log(JSON.stringify(res.body))
- let dnsChallenge = res.body.challenges.filter(x => {
- return x.type === challengeTypeArg
- })[0]
- this.acceptChallenge(dnsChallenge)
- .then((x: ISmartAcmeChallengeAccepted) => {
- done.resolve(x)
- })
- }
- )
- return done.promise
- }
-
- /**
- * getCertificate - takes care of cooldown, validation polling and certificate retrieval
- */
- getCertificate() {
-
- }
-
- /**
- * validates a challenge
- */
- validate(challenge: ISmartAcmeChallengeAccepted) {
- let done = q.defer()
- this.rawacmeClient.poll(challenge.uri, function(err, res) {
- if (err) {
- console.log(err)
- done.reject(err)
- }
- console.log(res.status)
- console.log(JSON.stringify(res.body))
- done.resolve()
- })
- return done.promise
- }
-
-
- /**
- * accept a challenge - for private use only
- */
- private acceptChallenge(challenge: ISmartAcmeChallenge) {
- let done = q.defer()
-
- /**
- * the key is needed to accept the challenge
- */
- let authKey: string = plugins.rawacme.keyAuthz(challenge.token, this.keyPair.publicKey)
-
- /**
- * needed in case selected challenge is of type dns-01
- */
- let keyHash: string = plugins.rawacme.dnsKeyAuthzHash(authKey) // needed if dns challenge is chosen
-
- /**
- * the return challenge
- */
- let returnDNSChallenge: ISmartAcmeChallengeAccepted = {
- uri: challenge.uri,
- type: challenge.type,
- token: challenge.token,
- keyAuthorization: challenge.keyAuthorization,
- keyHash: keyHash,
- status: challenge.status
- }
-
- this.rawacmeClient.post(
- challenge.uri,
- {
- resource: 'challenge',
- keyAuthorization: authKey
- },
- this.keyPair,
- (err, res) => {
- if (err) {
- console.log(err)
- done.reject(err)
- }
- done.resolve(returnDNSChallenge)
- }
- )
- return done.promise
- }
-
-
}
diff --git a/ts/smartacme.helpers.ts b/ts/smartacme.helpers.ts
index 85e1b35..06d550b 100644
--- a/ts/smartacme.helpers.ts
+++ b/ts/smartacme.helpers.ts
@@ -4,8 +4,7 @@ import * as q from 'q'
import * as plugins from './smartacme.plugins'
import { SmartAcme, IRsaKeypair } from './smartacme.classes.smartacme'
-
-
+import { AcmeAccount } from './smartacme.classes.acmeaccount'
/**
* creates a keypair to use with requests and to generate JWK from
@@ -22,12 +21,13 @@ export let createKeypair = (bit = 2048): IRsaKeypair => {
* gets an existing registration
* @executes ASYNC
*/
-let getReg = (smartAcmeArg: SmartAcme) => {
+let getReg = (SmartAcmeArg: SmartAcme, location: string) => {
let done = q.defer()
let body = { resource: 'reg' }
- smartAcmeArg.rawacmeClient.post(
- smartAcmeArg.location,
- body, smartAcmeArg.keyPair,
+ SmartAcmeArg.rawacmeClient.post(
+ location,
+ body,
+ SmartAcmeArg.keyPair,
(err, res) => {
if (err) {
console.error('smartacme: something went wrong:')
diff --git a/ts/smartacme.plugins.ts b/ts/smartacme.plugins.ts
index 795e22d..4848784 100644
--- a/ts/smartacme.plugins.ts
+++ b/ts/smartacme.plugins.ts
@@ -17,4 +17,4 @@ export {
smartfile,
smartstring,
paths
-}
\ No newline at end of file
+}