diff --git a/.gitignore b/.gitignore
index edd60d0..7036b29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,7 @@
node_modules
docs/
+public/
+pages/
coverage/
.nogit/
dist/assets/
diff --git a/dist/cert.classes.cert.d.ts b/dist/cert.classes.cert.d.ts
index a739484..68d0ccc 100644
--- a/dist/cert.classes.cert.d.ts
+++ b/dist/cert.classes.cert.d.ts
@@ -1,44 +1,37 @@
///
-import * as plugins from "./cert.plugins";
+import * as q from 'q';
+import { Stringmap, Objectmap } from 'lik';
+import { Certificate } from './cert.classes.certificate';
+import { Letsencrypt, TLeEnv } from './cert.classes.letsencrypt';
export interface ICertConstructorOptions {
cfEmail: string;
cfKey: string;
- sslDir?: string;
+ sslDirPath?: string;
gitOriginRepo?: string;
- testMode?: boolean;
+ leEnv?: TLeEnv;
}
export declare class Cert {
- private _cfEmail;
- private _cfKey;
- private _sslDir;
- private _gitOriginRepo;
- private _testMode;
- domainCertRequestMap: plugins.lik.Stringmap;
- certificatesPresent: Certificate[];
- certificatesValid: Certificate[];
+ domainStringRequestMap: Stringmap;
+ certificateMap: Objectmap;
+ letsencrypt: Letsencrypt;
+ private _challengeHandler;
+ private _certRepo;
/**
* Constructor for Cert object
*/
constructor(optionsArg: ICertConstructorOptions);
/**
- * Pulls already requested certificates from git origin
+ * adds a Certificate for a given domain
*/
- sslGitOriginPull: () => void;
- /**
- * Pushes all new requested certificates to git origin
- */
- sslGitOriginAddCommitPush: () => void;
- /**
- * gets a ssl cert for a given domain
- */
- getDomainCert(domainNameArg: string, optionsArg?: {
+ addCertificate(domainNameArg: string, optionsArg?: {
force: boolean;
- }): plugins.q.Promise<{}>;
+ }): q.Promise<{}>;
+ /**
+ * cleans up old certificates
+ */
cleanOldCertificates(): void;
-}
-export declare class Certificate {
- domainName: string;
- creationDate: Date;
- expiryDate: Date;
- constructor();
+ /**
+ * executes the current batch of jobs
+ */
+ deploy(): void;
}
diff --git a/dist/cert.classes.cert.helpers.d.ts b/dist/cert.classes.cert.helpers.d.ts
deleted file mode 100644
index 6d04a73..0000000
--- a/dist/cert.classes.cert.helpers.d.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-///
-import * as plugins from "./cert.plugins";
-/**
- * schedule a retry of certificate request
- */
-export declare let scheduleRetry: (domainArg: string, certClassArg: any) => plugins.q.Promise<{}>;
-/**
- * check if a given domainCert is still valid
- */
-export declare let checkDomainsStillValid: (domainNameArg: string, sslDirArg: string) => boolean;
-export interface certConfig {
- domainName: string;
- created: number;
- expires: number;
-}
-/**
- * update a ssl directory
- */
-export declare let updateSslDirSync: (sslDirArg: string, domainNameArg: string) => void;
diff --git a/dist/cert.classes.cert.helpers.js b/dist/cert.classes.cert.helpers.js
deleted file mode 100644
index 72ad546..0000000
--- a/dist/cert.classes.cert.helpers.js
+++ /dev/null
@@ -1,59 +0,0 @@
-"use strict";
-const plugins = require("./cert.plugins");
-const paths = require("./cert.paths");
-/**
- * schedule a retry of certificate request
- */
-exports.scheduleRetry = (domainArg, certClassArg) => {
- let done = plugins.q.defer();
- setTimeout(() => {
- certClassArg.getDomainCert(domainArg)
- .then(done.resolve);
- }, 60000);
- return done.promise;
-};
-/**
- * check if a given domainCert is still valid
- */
-exports.checkDomainsStillValid = (domainNameArg, sslDirArg) => {
- let domainConfigPath = plugins.path.join(sslDirArg, domainNameArg, "config.json");
- if (plugins.smartfile.fs.fileExistsSync(domainConfigPath)) {
- let domainConfig = plugins.smartfile.fs.toObjectSync(domainConfigPath, "json");
- if (Date.now() >= ((domainConfig.expires - 604800) * 1000)) {
- return false;
- }
- else {
- return true;
- }
- }
- else {
- return false;
- }
-};
-;
-/**
- * update a ssl directory
- */
-exports.updateSslDirSync = (sslDirArg, domainNameArg) => {
- plugins.smartfile.fs.ensureDirSync(sslDirArg);
- let domainCertFolder = plugins.path.join(paths.certDir, domainNameArg);
- if (plugins.smartfile.fs.listFoldersSync(paths.certDir).indexOf(domainNameArg) != -1) {
- plugins.smartfile.fs.copySync(plugins.path.join(domainCertFolder, "fullchain.pem"), plugins.path.join(sslDirArg, domainNameArg, "fullchain.pem"));
- plugins.smartfile.fs.copySync(plugins.path.join(domainCertFolder, "privkey.pem"), plugins.path.join(sslDirArg, domainNameArg, "privkey.pem"));
- // create cert config
- let certRegex = /.*\-([0-9]*)\.pem/;
- let certFileNameWithTime = plugins.smartfile.fs.listFilesSync(domainCertFolder, certRegex)[0];
- let certTime = parseInt(certRegex.exec(certFileNameWithTime)[1]);
- let certConfig = {
- domainName: domainNameArg,
- created: certTime,
- expires: certTime + 7776000
- };
- plugins.smartfile.memory.toFsSync(JSON.stringify(certConfig), plugins.path.join(sslDirArg, domainNameArg, "config.json"));
- }
- ;
-};
-let updateGitOrigin = (syncDirectionArg) => {
-};
-updateGitOrigin(0 /* toOrigin */);
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnQuaGVscGVycy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NlcnQuY2xhc3Nlcy5jZXJ0LmhlbHBlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFJdEM7O0dBRUc7QUFDUSxRQUFBLGFBQWEsR0FBRyxDQUFDLFNBQWdCLEVBQUMsWUFBaUI7SUFDMUQsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM3QixVQUFVLENBQUM7UUFDUCxZQUFZLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQzthQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVCLENBQUMsRUFBQyxLQUFLLENBQUMsQ0FBQztJQUNULE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQ3hCLENBQUMsQ0FBQztBQUVGOztHQUVHO0FBQ1EsUUFBQSxzQkFBc0IsR0FBRyxDQUFDLGFBQXFCLEVBQUUsU0FBaUI7SUFDekUsSUFBSSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsYUFBYSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ2xGLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4RCxJQUFJLFlBQVksR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxZQUFZLENBQ2hELGdCQUFnQixFQUNoQixNQUFNLENBQ1QsQ0FBQztRQUNGLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsWUFBWSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekQsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUNqQixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDSixNQUFNLENBQUMsSUFBSSxDQUFDO1FBQ2hCLENBQUM7SUFDTCxDQUFDO0lBQUMsSUFBSSxDQUFDLENBQUM7UUFDSixNQUFNLENBQUMsS0FBSyxDQUFDO0lBQ2pCLENBQUM7QUFFTCxDQUFDLENBQUE7QUFNQSxDQUFDO0FBRUY7O0dBRUc7QUFDUSxRQUFBLGdCQUFnQixHQUFHLENBQUMsU0FBaUIsRUFBRSxhQUFxQjtJQUNuRSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDOUMsSUFBSSxnQkFBZ0IsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFBO0lBQ3RFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRixPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQ3pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLGVBQWUsQ0FBQyxFQUNwRCxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsYUFBYSxFQUFFLGVBQWUsQ0FBQyxDQUMvRCxDQUFDO1FBQ0YsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsUUFBUSxDQUN6QixPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxhQUFhLENBQUMsRUFDbEQsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FDN0QsQ0FBQztRQUNGLHFCQUFxQjtRQUNyQixJQUFJLFNBQVMsR0FBRyxtQkFBbUIsQ0FBQztRQUNwQyxJQUFJLG9CQUFvQixHQUFXLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxnQkFBZ0IsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RyxJQUFJLFFBQVEsR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakUsSUFBSSxVQUFVLEdBQWU7WUFDekIsVUFBVSxFQUFFLGFBQWE7WUFDekIsT0FBTyxFQUFFLFFBQVE7WUFDakIsT0FBTyxFQUFFLFFBQVEsR0FBRyxPQUFPO1NBQzlCLENBQUM7UUFDRixPQUFPLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQzdCLElBQUksQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLEVBQzFCLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxhQUFhLEVBQUUsYUFBYSxDQUFDLENBQzdELENBQUM7SUFDTixDQUFDO0lBQUEsQ0FBQztBQUNOLENBQUMsQ0FBQTtBQU9ELElBQUksZUFBZSxHQUFHLENBQUMsZ0JBQWtDO0FBRXpELENBQUMsQ0FBQztBQUVGLGVBQWUsQ0FBQyxnQkFBeUIsQ0FBQyxDQUFDIn0=
\ No newline at end of file
diff --git a/dist/cert.classes.cert.js b/dist/cert.classes.cert.js
index a7c7124..257acdb 100644
--- a/dist/cert.classes.cert.js
+++ b/dist/cert.classes.cert.js
@@ -1,142 +1,69 @@
"use strict";
-const plugins = require("./cert.plugins");
-const paths = require("./cert.paths");
-const helpers = require("./cert.classes.cert.helpers");
-;
+const q = require("q");
+const lik_1 = require("lik");
+// classes
+const cert_classes_certificate_1 = require("./cert.classes.certificate");
+const cert_classes_certrepo_1 = require("./cert.classes.certrepo");
+const cert_classes_letsencrypt_1 = require("./cert.classes.letsencrypt");
+const cert_classes_challengehandler_1 = require("./cert.classes.challengehandler");
class Cert {
/**
* Constructor for Cert object
*/
constructor(optionsArg) {
- this.domainCertRequestMap = new plugins.lik.Stringmap();
- /**
- * Pulls already requested certificates from git origin
- */
- this.sslGitOriginPull = () => {
- if (this._gitOriginRepo) {
- plugins.smartgit.pull(this._sslDir, "origin", "master");
- }
- };
- /**
- * Pushes all new requested certificates to git origin
- */
- this.sslGitOriginAddCommitPush = () => {
- if (this._gitOriginRepo) {
- plugins.smartgit.add.addAll(this._sslDir);
- plugins.smartgit.commit(this._sslDir, "added new SSL certificates and deleted obsolete ones.");
- plugins.smartgit.push(this._sslDir, "origin", "master");
- }
- };
- this._cfEmail = optionsArg.cfEmail;
- this._cfKey = optionsArg.cfKey;
- this._sslDir = optionsArg.sslDir;
- this._gitOriginRepo = optionsArg.gitOriginRepo;
- this._testMode = optionsArg.testMode;
- // write hook config
- let config = {
- cfEmail: this._cfEmail,
- cfKey: this._cfKey
- };
- plugins.smartfile.memory.toFsSync(JSON.stringify(config), plugins.path.join(__dirname, "assets/config.json"));
- // setup sslDir
- if (!this._sslDir)
- this._sslDir = paths.defaultSslDir;
- // setup Git
- if (this._gitOriginRepo) {
- plugins.smartgit.init(this._sslDir);
- plugins.smartgit.remote.add(this._sslDir, "origin", this._gitOriginRepo);
- this.sslGitOriginPull();
- }
- // setup leSh config;
- let leShConfigString;
- if (this._testMode) {
- leShConfigString = `CA="https://acme-staging.api.letsencrypt.org/directory"\n`;
- }
- else {
- leShConfigString = " ";
- }
- ;
- plugins.smartfile.memory.toFsSync(leShConfigString, paths.leShConfig);
- plugins.shelljs.exec("chmod 700 " + paths.letsencryptSh);
- plugins.shelljs.exec("chmod 700 " + paths.certHook);
- plugins.shelljs.exec(`bash -c "${paths.letsencryptSh} -c --no-lock -f ${paths.leShConfig} -d notthere.notthere -t dns-01 -k ${paths.certHook} -o ${paths.certDir}"`, {
- silent: true
+ this.domainStringRequestMap = new lik_1.Stringmap();
+ this.certificateMap = new lik_1.Objectmap();
+ // set up challengehandler
+ this._challengeHandler = new cert_classes_challengehandler_1.ChallengeHandler({
+ cfEmail: optionsArg.cfEmail,
+ cfKey: optionsArg.cfKey
});
+ // setup Letsencrypt
+ this.letsencrypt = new cert_classes_letsencrypt_1.Letsencrypt({
+ leEnv: optionsArg.leEnv,
+ sslDir: optionsArg.sslDirPath,
+ challengeHandler: this._challengeHandler
+ });
+ // setup CertRpo
+ this._certRepo = new cert_classes_certrepo_1.CertRepo({
+ sslDirPath: optionsArg.sslDirPath,
+ gitOriginRepo: optionsArg.gitOriginRepo,
+ certInstance: this
+ });
+ this._certRepo;
}
- ;
/**
- * gets a ssl cert for a given domain
+ * adds a Certificate for a given domain
*/
- getDomainCert(domainNameArg, optionsArg = { force: false }) {
- let done = plugins.q.defer();
- let domainStringData = new plugins.smartstring.Domain(domainNameArg);
- let sameZoneRequesting = this.domainCertRequestMap.checkMinimatch("*" + domainStringData.zoneName);
- // make sure no one else requires the same domain at the same time
- if (!this.domainCertRequestMap.checkString(domainNameArg)) {
- this.domainCertRequestMap.addString(domainNameArg);
- if (!helpers.checkDomainsStillValid(domainNameArg, this._sslDir) || optionsArg.force) {
- if (!sameZoneRequesting) {
- this.sslGitOriginPull();
- plugins.smartfile.fs.ensureDir(paths.certDir);
- plugins.beautylog.info(`getting cert for ${domainNameArg}`);
- plugins.shelljs.exec(`bash -c "${paths.letsencryptSh} -c --no-lock -f ${paths.leShConfig} -d ${domainNameArg} -t dns-01 -k ${paths.certHook} -o ${paths.certDir}"`, {
- silent: true
- }, (codeArg, stdoutArg) => {
- if (codeArg == 0) {
- console.log(stdoutArg);
- let fetchedCertsArray = plugins.smartfile.fs.listFoldersSync(paths.certDir);
- if (fetchedCertsArray.indexOf(domainNameArg) != -1) {
- helpers.updateSslDirSync(this._sslDir, domainNameArg);
- plugins.smartfile.fs.removeSync(plugins.path.join(paths.certDir, domainNameArg));
- this.sslGitOriginAddCommitPush();
- }
- else {
- plugins.beautylog.error(`Couldn't copy final certificate for ${domainNameArg}!`);
- }
- ;
- done.resolve();
- }
- else {
- plugins.beautylog.warn(`${domainNameArg} scheduled for retry. Waiting 1 minute!`);
- helpers.scheduleRetry(domainNameArg, this).then(done.resolve);
- }
- this.domainCertRequestMap.removeString(domainNameArg);
- });
- }
- else {
- plugins.beautylog.info(`${domainNameArg} is waiting for domains names of same zone to finish`);
- this.domainCertRequestMap.removeString(domainNameArg);
- this.domainCertRequestMap.registerUntilTrue(() => {
- return !this.domainCertRequestMap.checkMinimatch("*" + domainStringData.zoneName);
- }, () => {
- this.getDomainCert(domainNameArg).then(done.resolve);
- });
- }
- }
- else {
- plugins.beautylog.info("certificate for " + domainNameArg + " is still valid! Not fetching new one!");
- this.domainCertRequestMap.removeString(domainNameArg);
- done.resolve();
- }
- ;
+ addCertificate(domainNameArg, optionsArg = { force: false }) {
+ let done = q.defer();
+ let certificateForDomain = this.certificateMap.find((certificate) => {
+ return certificate.domainName === domainNameArg;
+ });
+ if (certificateForDomain instanceof cert_classes_certificate_1.Certificate) {
+ certificateForDomain.renew()
+ .then(done.resolve);
}
else {
- plugins.beautylog.warn(`${domainNameArg} is already requesting`);
+ certificateForDomain = new cert_classes_certificate_1.Certificate({
+ certInstance: this,
+ domainName: domainNameArg
+ });
+ certificateForDomain.renew()
+ .then(done.resolve);
}
- ;
return done.promise;
}
- ;
+ /**
+ * cleans up old certificates
+ */
cleanOldCertificates() {
}
- ;
+ /**
+ * executes the current batch of jobs
+ */
+ deploy() {
+ }
}
exports.Cert = Cert;
-class Certificate {
- constructor() {
- }
- ;
-}
-exports.Certificate = Certificate;
-;
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jZXJ0LmNsYXNzZXMuY2VydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMENBQTBDO0FBQzFDLHNDQUFzQztBQUN0Qyx1REFBc0Q7QUFRckQsQ0FBQztBQUVGO0lBVUk7O09BRUc7SUFDSCxZQUFZLFVBQW1DO1FBUC9DLHlCQUFvQixHQUEwQixJQUFJLE9BQU8sQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLENBQUM7UUFrRDFFOztXQUVHO1FBQ0gscUJBQWdCLEdBQUc7WUFDZixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztnQkFDdEIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDNUQsQ0FBQztRQUNMLENBQUMsQ0FBQztRQUVGOztXQUVHO1FBQ0gsOEJBQXlCLEdBQUc7WUFDeEIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsdURBQXVELENBQUMsQ0FBQztnQkFDL0YsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUM7WUFDNUQsQ0FBQztRQUNMLENBQUMsQ0FBQztRQTVERSxJQUFJLENBQUMsUUFBUSxHQUFHLFVBQVUsQ0FBQyxPQUFPLENBQUM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBQy9CLElBQUksQ0FBQyxPQUFPLEdB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
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jZXJ0LmNsYXNzZXMuY2VydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsdUJBQXNCO0FBQ3RCLDZCQUEwQztBQUsxQyxVQUFVO0FBQ1YseUVBQXdEO0FBQ3hELG1FQUFrRDtBQUNsRCx5RUFBZ0U7QUFDaEUsbUZBQWtFO0FBV2xFO0lBT0k7O09BRUc7SUFDSCxZQUFZLFVBQW1DO1FBVC9DLDJCQUFzQixHQUFHLElBQUksZUFBUyxFQUFFLENBQUE7UUFDeEMsbUJBQWMsR0FBRyxJQUFJLGVBQVMsRUFBZSxDQUFBO1FBVXpDLDBCQUEwQjtRQUMxQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxnREFBZ0IsQ0FBQztZQUMxQyxPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU87WUFDM0IsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLO1NBQzFCLENBQUMsQ0FBQTtRQUVGLG9CQUFvQjtRQUNwQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksc0NBQVcsQ0FBQztZQUMvQixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7WUFDdkIsTUFBTSxFQUFFLFVBQVUsQ0FBQyxVQUFVO1lBQzdCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxpQkFBaUI7U0FDM0MsQ0FBQyxDQUFBO1FBRUYsZ0JBQWdCO1FBQ2hCLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxnQ0FBUSxDQUFDO1lBQzFCLFVBQVUsRUFBRSxVQUFVLENBQUMsVUFBVTtZQUNqQyxhQUFhLEVBQUUsVUFBVSxDQUFDLGFBQWE7WUFDdkMsWUFBWSxFQUFFLElBQUk7U0FDckIsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLFNBQVMsQ0FBQTtJQUNsQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjLENBQUMsYUFBcUIsRUFBRSxhQUFpQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7UUFDbkYsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ3BCLElBQUksb0JBQW9CLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXO1lBQzVELE1BQU0sQ0FBQyxXQUFXLENBQUMsVUFBVSxLQUFLLGFBQWEsQ0FBQTtRQUNuRCxDQUFDLENBQUMsQ0FBQTtRQUNGLEVBQUUsQ0FBQyxDQUFDLG9CQUFvQixZQUFZLHNDQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzlDLG9CQUFvQixDQUFDLEtBQUssRUFBRTtpQkFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMzQixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDSixvQkFBb0IsR0FBRyxJQUFJLHNDQUFXLENBQUM7Z0JBQ25DLFlBQVksRUFBRSxJQUFJO2dCQUNsQixVQUFVLEVBQUUsYUFBYTthQUM1QixDQUFDLENBQUE7WUFDRixvQkFBb0IsQ0FBQyxLQUFLLEVBQUU7aUJBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDM0IsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILG9CQUFvQjtJQUVwQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNO0lBRU4sQ0FBQztDQUNKO0FBdEVELG9CQXNFQyJ9
\ No newline at end of file
diff --git a/dist/cert.classes.certificate.d.ts b/dist/cert.classes.certificate.d.ts
new file mode 100644
index 0000000..29b9975
--- /dev/null
+++ b/dist/cert.classes.certificate.d.ts
@@ -0,0 +1,48 @@
+///
+import * as q from 'q';
+import * as plugins from './cert.plugins';
+import { Cert } from './cert.classes.cert';
+export interface ICertificateFsConfig {
+ domainName: string;
+ creationTime: number;
+ expiryTime: number;
+}
+export interface ICertificateConstructorOptions {
+ domainName: string;
+ certInstance: Cert;
+}
+export declare type TCertificateStatus = 'unregistered' | 'valid' | 'expiring' | 'expired';
+export declare class Certificate {
+ domainName: string;
+ certInstance: Cert;
+ domainData: plugins.smartstring.Domain;
+ creationDate: Date;
+ expiryDate: Date;
+ publicKey: string;
+ privKey: string;
+ /**
+ * run when creating a new instance of Certificate
+ */
+ constructor(optionsArg: ICertificateConstructorOptions);
+ /**
+ * the status of the Certificate
+ */
+ readonly status: TCertificateStatus;
+ readonly sameZoneRequesting: boolean;
+ /**
+ * schedule a retry of certificate request
+ */
+ scheduleRetry(): q.Promise<{}>;
+ /**
+ * renew certificate if needed
+ */
+ renew(force?: boolean): q.Promise<{}>;
+ /**
+ * syncFs syncs the certificate with disk
+ */
+ syncFs(): void;
+ /**
+ * deletes the certificate
+ */
+ delete(): void;
+}
diff --git a/dist/cert.classes.certificate.js b/dist/cert.classes.certificate.js
new file mode 100644
index 0000000..6aee6f2
--- /dev/null
+++ b/dist/cert.classes.certificate.js
@@ -0,0 +1,103 @@
+"use strict";
+const q = require("q");
+const plugins = require("./cert.plugins");
+class Certificate {
+ /**
+ * run when creating a new instance of Certificate
+ */
+ constructor(optionsArg) {
+ this.creationDate = null;
+ this.expiryDate = null;
+ this.publicKey = null;
+ this.privKey = null;
+ this.domainName = optionsArg.domainName;
+ this.domainData = new plugins.smartstring.Domain(this.domainName);
+ this.certInstance = optionsArg.certInstance;
+ }
+ /**
+ * the status of the Certificate
+ */
+ get status() {
+ let validTimeRemaining = 0;
+ if (this.creationDate !== null && this.expiryDate !== null) {
+ validTimeRemaining = this.expiryDate.getTime() - Date.now();
+ }
+ let MonthMilliseconds = 2629746000;
+ if (this.publicKey === null || this.privKey === null) {
+ return 'unregistered';
+ }
+ else if (validTimeRemaining >= MonthMilliseconds) {
+ return 'valid';
+ }
+ else if (validTimeRemaining < MonthMilliseconds && validTimeRemaining >= 0) {
+ return 'expiring';
+ }
+ else {
+ return 'expired';
+ }
+ }
+ get sameZoneRequesting() {
+ return this.certInstance.domainStringRequestMap.checkMinimatch('*' + this.domainData.zoneName);
+ }
+ /**
+ * schedule a retry of certificate request
+ */
+ scheduleRetry() {
+ let done = plugins.q.defer();
+ setTimeout(() => {
+ this.renew()
+ .then(done.resolve);
+ }, 60000);
+ return done.promise;
+ }
+ /**
+ * renew certificate if needed
+ */
+ renew(force = false) {
+ let done = q.defer();
+ if (this.status === 'valid') {
+ plugins.beautylog.log('Certificate still valid for more than 1 month, so it is not renewed now');
+ done.resolve();
+ }
+ else if (this.status === 'expiring' || this.status === 'expired' || this.status === 'unregistered') {
+ plugins.beautylog.info('Certificate not valid currently, going to renew now!');
+ if (this.sameZoneRequesting) {
+ this.certInstance.domainStringRequestMap.registerUntilTrue(() => {
+ return !this.sameZoneRequesting;
+ }, () => {
+ this.renew().then(done.resolve);
+ });
+ }
+ else {
+ this.certInstance.letsencrypt.registerDomain(this.domainName)
+ .then(() => {
+ return this.syncFs();
+ })
+ .then(() => {
+ done.resolve();
+ }).catch((err) => { console.log(err); });
+ }
+ }
+ else {
+ throw Error(`weird status for certificate with domain name ${this.domainName}`);
+ }
+ done.resolve();
+ return done.promise;
+ }
+ /**
+ * syncFs syncs the certificate with disk
+ */
+ syncFs() {
+ let configJsonMemory = {
+ domainName: this.domainName,
+ creationTime: this.creationDate.getTime(),
+ expiryTime: this.expiryDate.getTime()
+ };
+ }
+ /**
+ * deletes the certificate
+ */
+ delete() { }
+}
+exports.Certificate = Certificate;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnRpZmljYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5jbGFzc2VzLmNlcnRpZmljYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx1QkFBc0I7QUFFdEIsMENBQXlDO0FBcUJ6QztJQVNJOztPQUVHO0lBQ0gsWUFBWSxVQUEwQztRQVJ0RCxpQkFBWSxHQUFTLElBQUksQ0FBQTtRQUN6QixlQUFVLEdBQVMsSUFBSSxDQUFBO1FBQ3ZCLGNBQVMsR0FBVyxJQUFJLENBQUE7UUFDeEIsWUFBTyxHQUFXLElBQUksQ0FBQTtRQU1sQixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUE7UUFDdkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUNqRSxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUE7SUFDL0MsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxNQUFNO1FBQ04sSUFBSSxrQkFBa0IsR0FBVyxDQUFDLENBQUE7UUFDbEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3hELGtCQUFrQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ2hFLENBQUM7UUFDRCxJQUFJLGlCQUFpQixHQUFHLFVBQVUsQ0FBQTtRQUNsQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDbkQsTUFBTSxDQUFDLGNBQWMsQ0FBQTtRQUN6QixDQUFDO1FBQUMsSUFBSSxD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
\ No newline at end of file
diff --git a/dist/cert.classes.certrepo.d.ts b/dist/cert.classes.certrepo.d.ts
new file mode 100644
index 0000000..3937125
--- /dev/null
+++ b/dist/cert.classes.certrepo.d.ts
@@ -0,0 +1,26 @@
+///
+import * as q from 'q';
+import { Cert } from './cert.classes.cert';
+export interface ICertRepoConstructorOptions {
+ sslDirPath: string;
+ gitOriginRepo: string;
+ certInstance: Cert;
+}
+export declare class CertRepo {
+ private _sslDirPath;
+ private _gitOriginRepo;
+ private _certInstance;
+ constructor(optionsArg: ICertRepoConstructorOptions);
+ /**
+ * syncs an objectmap of Certificates with repo
+ */
+ syncFs(): q.Promise<{}>;
+ /**
+ * Pulls already requested certificates from git origin
+ */
+ sslGitOriginPull: () => void;
+ /**
+ * Pushes all new requested certificates to git origin
+ */
+ sslGitOriginAddCommitPush: () => void;
+}
diff --git a/dist/cert.classes.certrepo.js b/dist/cert.classes.certrepo.js
new file mode 100644
index 0000000..9581f91
--- /dev/null
+++ b/dist/cert.classes.certrepo.js
@@ -0,0 +1,49 @@
+"use strict";
+const q = require("q");
+const plugins = require("./cert.plugins");
+const paths = require("./cert.paths");
+class CertRepo {
+ constructor(optionsArg) {
+ /**
+ * Pulls already requested certificates from git origin
+ */
+ this.sslGitOriginPull = () => {
+ if (this._gitOriginRepo) {
+ plugins.smartgit.pull(this._sslDirPath, 'origin', 'master');
+ }
+ };
+ /**
+ * Pushes all new requested certificates to git origin
+ */
+ this.sslGitOriginAddCommitPush = () => {
+ if (this._gitOriginRepo) {
+ plugins.smartgit.add.addAll(this._sslDirPath);
+ plugins.smartgit.commit(this._sslDirPath, 'added new SSL certificates and deleted obsolete ones.');
+ plugins.smartgit.push(this._sslDirPath, 'origin', 'master');
+ }
+ };
+ this._sslDirPath = optionsArg.sslDirPath;
+ this._gitOriginRepo = optionsArg.gitOriginRepo;
+ this._certInstance = optionsArg.certInstance;
+ // setup sslDir
+ if (!this._sslDirPath) {
+ this._sslDirPath = paths.defaultSslDir;
+ }
+ // setup Git
+ if (this._gitOriginRepo) {
+ plugins.smartgit.init(this._sslDirPath);
+ plugins.smartgit.remote.add(this._sslDirPath, 'origin', this._gitOriginRepo);
+ this.sslGitOriginPull();
+ }
+ }
+ /**
+ * syncs an objectmap of Certificates with repo
+ */
+ syncFs() {
+ let done = q.defer();
+ done.resolve();
+ return done.promise;
+ }
+}
+exports.CertRepo = CertRepo;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnRyZXBvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5jbGFzc2VzLmNlcnRyZXBvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx1QkFBc0I7QUFFdEIsMENBQXlDO0FBQ3pDLHNDQUFxQztBQVdyQztJQUlJLFlBQVksVUFBdUM7UUEyQm5EOztXQUVHO1FBQ0gscUJBQWdCLEdBQUc7WUFDZixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztnQkFDdEIsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUE7WUFDL0QsQ0FBQztRQUNMLENBQUMsQ0FBQTtRQUVEOztXQUVHO1FBQ0gsOEJBQXlCLEdBQUc7WUFDeEIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3RCLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7Z0JBQzdDLE9BQU8sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsdURBQXVELENBQUMsQ0FBQTtnQkFDbEcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUE7WUFDL0QsQ0FBQztRQUNMLENBQUMsQ0FBQTtRQTVDRyxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUE7UUFDeEMsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFBO1FBQzlDLElBQUksQ0FBQyxhQUFhLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQTtRQUU1QyxlQUFlO1FBQ2YsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUEsQ0FBQztZQUNuQixJQUFJLENBQUMsV0FBVyxHQUFHLEtBQUssQ0FBQyxhQUFhLENBQUE7UUFDMUMsQ0FBQztRQUVELFlBQVk7UUFDWixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQztZQUN0QixPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUE7WUFDdkMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQTtZQUM1RSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQTtRQUMzQixDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0gsTUFBTTtRQUNGLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0NBcUJKO0FBbERELDRCQWtEQyJ9
\ No newline at end of file
diff --git a/dist/cert.classes.challengehandler.d.ts b/dist/cert.classes.challengehandler.d.ts
new file mode 100644
index 0000000..b2da280
--- /dev/null
+++ b/dist/cert.classes.challengehandler.d.ts
@@ -0,0 +1,20 @@
+///
+export interface IChallengehandlerConstructorOptions {
+ cfEmail: string;
+ cfKey: string;
+}
+/**
+ * class ChallengeHandler handles challenges
+ */
+export declare class ChallengeHandler {
+ private _cfInstance;
+ constructor(optionsArg: IChallengehandlerConstructorOptions);
+ /**
+ * set a challenge
+ */
+ setChallenge(domainNameArg: string, challengeArg: string): Q.Promise<{}>;
+ /**
+ * cleans a challenge
+ */
+ cleanChallenge(domainNameArg: any): Q.Promise<{}>;
+}
diff --git a/dist/cert.classes.challengehandler.js b/dist/cert.classes.challengehandler.js
new file mode 100644
index 0000000..4657aa5
--- /dev/null
+++ b/dist/cert.classes.challengehandler.js
@@ -0,0 +1,75 @@
+"use strict";
+const plugins = require("./cert.plugins");
+/**
+ * class ChallengeHandler handles challenges
+ */
+class ChallengeHandler {
+ constructor(optionsArg) {
+ this._cfInstance = new plugins.cflare.CflareAccount();
+ this._cfInstance.auth({
+ email: optionsArg.cfEmail,
+ key: optionsArg.cfKey
+ });
+ }
+ /**
+ * set a challenge
+ */
+ setChallenge(domainNameArg, challengeArg) {
+ let done = plugins.q.defer();
+ plugins.beautylog.log('setting challenge for ' + domainNameArg);
+ this._cfInstance.createRecord(prefixName(domainNameArg), 'TXT', challengeArg).then(() => {
+ plugins.beautylog.ok('Challenge has been set!');
+ plugins.beautylog.info('We need to cool down to let DNS propagate to edge locations!');
+ cooldown().then(() => {
+ done.resolve();
+ });
+ });
+ return done.promise;
+ }
+ /**
+ * cleans a challenge
+ */
+ cleanChallenge(domainNameArg) {
+ let done = plugins.q.defer();
+ plugins.beautylog.log('cleaning challenge for ' + domainNameArg);
+ this._cfInstance.removeRecord(prefixName(domainNameArg), 'TXT');
+ cooldown().then(() => {
+ done.resolve();
+ });
+ return done.promise;
+ }
+}
+exports.ChallengeHandler = ChallengeHandler;
+/**
+ * cooldown timer for letting DNS settle before answering the challengerequest
+ */
+let cooldown = () => {
+ let done = plugins.q.defer();
+ let cooldowntime = 60000;
+ let passedTime = 0;
+ plugins.beautylog.log('Cooling down! ' + (cooldowntime / 1000).toString() + ' seconds left');
+ let coolDownCounter = () => {
+ setTimeout(() => {
+ if (cooldowntime <= passedTime) {
+ plugins.beautylog.ok('Cooled down!');
+ done.resolve();
+ }
+ else {
+ passedTime = passedTime + 5000;
+ plugins.beautylog.log('Cooling down! '
+ + ((cooldowntime - passedTime) / 1000).toString()
+ + ' seconds left');
+ coolDownCounter();
+ }
+ }, 5000);
+ };
+ coolDownCounter();
+ return done.promise;
+};
+/**
+ * prefix a domain name to make sure it complies with letsencrypt
+ */
+let prefixName = (domainNameArg) => {
+ return '_acme-challenge.' + domainNameArg;
+};
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNoYWxsZW5nZWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jZXJ0LmNsYXNzZXMuY2hhbGxlbmdlaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMENBQXlDO0FBUXpDOztHQUVHO0FBQ0g7SUFFSSxZQUFZLFVBQStDO1FBQ3ZELElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLGFBQWEsRUFBRSxDQUFBO1FBQ3JELElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDO1lBQ2xCLEtBQUssRUFBRSxVQUFVLENBQUMsT0FBTztZQUN6QixHQUFHLEVBQUUsVUFBVSxDQUFDLEtBQUs7U0FDeEIsQ0FBQyxDQUFBO0lBQ04sQ0FBQztJQUVEOztPQUVHO0lBQ0gsWUFBWSxDQUFDLGFBQXFCLEVBQUUsWUFBb0I7UUFDcEQsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUM1QixPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyx3QkFBd0IsR0FBRyxhQUFhLENBQUMsQ0FBQTtRQUMvRCxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQztZQUMvRSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFBO1lBQy9DLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLDhEQUE4RCxDQUFDLENBQUE7WUFDdEYsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDO2dCQUNaLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtZQUNsQixDQUFDLENBQUMsQ0FBQTtRQUNOLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsY0FBYyxDQUFDLGFBQWE7UUFDeEIsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUM1QixPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyx5QkFBeUIsR0FBRyxhQUFhLENBQUMsQ0FBQTtRQUNoRSxJQUFJLENBQUMsV0FBVyxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUE7UUFDL0QsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ1osSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztDQUNKO0FBdENELDRDQXNDQztBQUVEOztHQUVHO0FBQ0gsSUFBSSxRQUFRLEdBQUc7SUFDWCxJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFBO0lBQzVCLElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQTtJQUN4QixJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUE7SUFDbEIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEdBQUcsQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFLEdBQUcsZUFBZSxDQUFDLENBQUE7SUFDNUYsSUFBSSxlQUFlLEdBQUc7UUFDbEIsVUFBVSxDQUFDO1lBQ1AsRUFBRSxDQUFDLENBQUMsWUFBWSxJQUFJLFVBQVUsQ0FBQyxDQUFDLENBQUM7Z0JBQzdCLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGNBQWMsQ0FBQyxDQUFBO2dCQUNwQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7WUFDbEIsQ0FBQztZQUFDLElBQUksQ0FBQyxDQUFDO2dCQUNKLFVBQVUsR0FBRyxVQUFVLEdBQUcsSUFBSSxDQUFBO2dCQUM5QixPQUFPLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxnQkFBZ0I7c0JBQ2hDLENBQUMsQ0FBQyxZQUFZLEdBQUcsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsUUFBUSxFQUFFO3NCQUMvQyxlQUFlLENBQ3BCLENBQUE7Z0JBQ0QsZUFBZSxFQUFFLENBQUE7WUFDckIsQ0FBQztRQUNMLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQTtJQUNaLENBQUMsQ0FBQTtJQUNELGVBQWUsRUFBRSxDQUFBO0lBQ2pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0FBQ3ZCLENBQUMsQ0FBQTtBQUVEOztHQUVHO0FBQ0gsSUFBSSxVQUFVLEdBQUcsQ0FBQyxhQUFxQjtJQUNuQyxNQUFNLENBQUMsa0JBQWtCLEdBQUcsYUFBYSxDQUFBO0FBQzdDLENBQUMsQ0FBQSJ9
\ No newline at end of file
diff --git a/dist/cert.classes.letsencrypt.d.ts b/dist/cert.classes.letsencrypt.d.ts
new file mode 100644
index 0000000..5f62936
--- /dev/null
+++ b/dist/cert.classes.letsencrypt.d.ts
@@ -0,0 +1,27 @@
+///
+import * as q from 'q';
+import { ChallengeHandler } from './cert.classes.challengehandler';
+export declare type TLeEnv = 'production' | 'staging';
+export interface ILetsencryptConstructorOptions {
+ leEnv: TLeEnv;
+ challengeHandler: ChallengeHandler;
+ sslDir: string;
+}
+export declare class Letsencrypt {
+ leEnv: TLeEnv;
+ challengeHandler: ChallengeHandler;
+ sslDir: string;
+ private _leInstance;
+ private _leServerUrl;
+ constructor(optionsArg: ILetsencryptConstructorOptions);
+ /**
+ * register a domain
+ */
+ registerDomain(domainNameArg: string): q.Promise<{}>;
+ private _leCopyToDestination(domainNameArg);
+ /**
+ * translates to the format expected by letsencrypt node implementation
+ */
+ private _leChallengeHandler();
+ private _leAgree(opts, agreeCb);
+}
diff --git a/dist/cert.classes.letsencrypt.js b/dist/cert.classes.letsencrypt.js
new file mode 100644
index 0000000..9d5761c
--- /dev/null
+++ b/dist/cert.classes.letsencrypt.js
@@ -0,0 +1,114 @@
+"use strict";
+const q = require("q");
+let letsencrypt = require('letsencrypt');
+const plugins = require("./cert.plugins");
+const paths = require("./cert.paths");
+class Letsencrypt {
+ constructor(optionsArg) {
+ // determine leEnv
+ this.leEnv = optionsArg.leEnv;
+ this.challengeHandler = optionsArg.challengeHandler;
+ this.sslDir = optionsArg.sslDir;
+ // set letsencrypt environment
+ if (this.leEnv === 'production') {
+ this._leServerUrl = letsencrypt.productionServerUrl;
+ }
+ else if (this.leEnv === 'staging') {
+ this._leServerUrl = letsencrypt.stagingServerUrl;
+ }
+ // create leInstance
+ this._leInstance = letsencrypt.create({
+ server: this._leServerUrl,
+ challenges: { 'dns-01': this._leChallengeHandler() },
+ challengeType: 'dns-01',
+ configDir: paths.leConfigDir,
+ privkeyPath: ':configDir/live/:hostname/privkey.pem',
+ fullchainPath: ':configDir/live/:hostname/fullchain.pem',
+ certPath: ':config/live/:hostname/cert.pem',
+ chainPath: ':config/live/:hostname/chain.pem',
+ agreeToTerms: this._leAgree,
+ debug: true
+ });
+ }
+ /**
+ * register a domain
+ */
+ registerDomain(domainNameArg) {
+ plugins.beautylog.log(`trying to register domain ${domainNameArg}`);
+ let done = q.defer();
+ console.log('test');
+ this._leInstance.register({
+ domains: [domainNameArg],
+ email: 'domains@lossless.org',
+ agreeTos: true,
+ rsaKeySize: 2048,
+ challengeType: 'dns-01'
+ }).then((results) => {
+ plugins.beautylog.success(`Got certificates for ${domainNameArg}`);
+ this._leCopyToDestination(domainNameArg).then(done.resolve);
+ }, (err) => {
+ console.error('[Error]: node-letsencrypt/examples/standalone');
+ console.error(err.stack);
+ done.resolve();
+ }).catch(err => { console.log(err); });
+ return done.promise;
+ }
+ // --------------------------------------------
+ // Translate for official letsencrypt stuff
+ // --------------------------------------------
+ _leCopyToDestination(domainNameArg) {
+ let done = q.defer();
+ return done.promise;
+ }
+ /**
+ * translates to the format expected by letsencrypt node implementation
+ */
+ _leChallengeHandler() {
+ return {
+ getOptions: (...args) => {
+ return {
+ debug: true
+ };
+ },
+ set: (args, domain, challenge, keyAuthorization, cb) => {
+ let keyAuthDigest = require('crypto')
+ .createHash('sha256').update(keyAuthorization || '')
+ .digest('base64')
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_')
+ .replace(/=+$/g, '');
+ this.challengeHandler.setChallenge(domain, keyAuthDigest)
+ .then(() => {
+ cb();
+ });
+ },
+ get: (defaults, domain, challenge, cb) => {
+ console.log(defaults);
+ console.log(domain);
+ console.log(challenge);
+ cb();
+ },
+ remove: (args, domain, challenge, cb) => {
+ this.challengeHandler.cleanChallenge(domain)
+ .then(() => {
+ cb();
+ });
+ },
+ loopback: (args, domain, challenge, cb) => {
+ console.log(args);
+ console.log(domain);
+ console.log(challenge);
+ cb();
+ },
+ test: (defaults, domain, challenge, cb) => {
+ cb();
+ }
+ };
+ }
+ _leAgree(opts, agreeCb) {
+ // opts = { email, domains, tosUrl }
+ agreeCb(null, opts.tosUrl);
+ }
+}
+exports.Letsencrypt = Letsencrypt;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmxldHNlbmNyeXB0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5jbGFzc2VzLmxldHNlbmNyeXB0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx1QkFBc0I7QUFDdEIsSUFBSSxXQUFXLEdBQUcsT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQUFBO0FBRXhDLDBDQUF5QztBQUN6QyxzQ0FBcUM7QUFZckM7SUFRSSxZQUFZLFVBQTBDO1FBQ2xELGtCQUFrQjtRQUNsQixJQUFJLENBQUMsS0FBSyxHQUFHLFVBQVUsQ0FBQyxLQUFLLENBQUE7UUFDN0IsSUFBSSxDQUFDLGdCQUFnQixHQUFHLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQTtRQUNuRCxJQUFJLENBQUMsTUFBTSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUE7UUFFL0IsOEJBQThCO1FBQzlCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssWUFBWSxDQUFDLENBQUMsQ0FBQztZQUM5QixJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQyxtQkFBbUIsQ0FBQTtRQUN2RCxDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQztZQUNsQyxJQUFJLENBQUMsWUFBWSxHQUFHLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQTtRQUNwRCxDQUFDO1FBRUQsb0JBQW9CO1FBQ3BCLElBQUksQ0FBQyxXQUFXLEdBQUcsV0FBVyxDQUFDLE1BQU0sQ0FBQztZQUNsQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFlBQVk7WUFDekIsVUFBVSxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxFQUFFO1lBQ3BELGFBQWEsRUFBRSxRQUFRO1lBQ3ZCLFNBQVMsRUFBRSxLQUFLLENBQUMsV0FBVztZQUM1QixXQUFXLEVBQUUsdUNBQXVDO1lBQ3BELGFBQWEsRUFBRSx5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
\ No newline at end of file
diff --git a/dist/cert.hook.d.ts b/dist/cert.hook.d.ts
deleted file mode 100644
index e69de29..0000000
diff --git a/dist/cert.hook.js b/dist/cert.hook.js
deleted file mode 100755
index 422ca6f..0000000
--- a/dist/cert.hook.js
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env node
-"use strict";
-const plugins = require("./cert.plugins");
-const paths = require("./cert.paths");
-let smartcli = new plugins.smartcli.Smartcli();
-let config = plugins.smartfile.fs.toObjectSync(paths.config);
-let cflare = new plugins.cflare.CflareAccount();
-cflare.auth({
- email: config.cfEmail,
- key: config.cfKey
-});
-let setChallenge = (domainNameArg, challengeArg) => {
- let done = plugins.q.defer();
- plugins.beautylog.log("setting challenge for " + domainNameArg);
- cflare.createRecord(prefixName(domainNameArg), "TXT", challengeArg).then(() => {
- plugins.beautylog.ok("Challenge has been set!");
- plugins.beautylog.info("We need to cool down to let DNS propagate to edge locations!");
- cooldown().then(() => {
- done.resolve();
- });
- });
- return done.promise;
-};
-let cleanChallenge = (domainNameArg) => {
- let done = plugins.q.defer();
- plugins.beautylog.log("cleaning challenge for " + domainNameArg);
- cflare.removeRecord(prefixName(domainNameArg), "TXT");
- cooldown().then(() => {
- done.resolve();
- });
- return done.promise;
-};
-let cooldown = () => {
- let done = plugins.q.defer();
- let cooldowntime = 60000;
- let passedTime = 0;
- plugins.beautylog.log("Cooling down! " + (cooldowntime / 1000).toString() + " seconds left");
- let coolDownCounter = () => {
- setTimeout(() => {
- if (cooldowntime <= passedTime) {
- plugins.beautylog.ok("Cooled down!");
- done.resolve();
- }
- else {
- passedTime = passedTime + 5000;
- plugins.beautylog.log("Cooling down! " + ((cooldowntime - passedTime) / 1000).toString() + " seconds left");
- coolDownCounter();
- }
- }, 5000);
- };
- coolDownCounter();
- return done.promise;
-};
-let prefixName = (domainNameArg) => {
- return "_acme-challenge." + domainNameArg;
-};
-smartcli.addCommand({
- commandName: "deploy_challenge"
-}).then((argv) => {
- setChallenge(argv._[1], argv._[3]);
-});
-smartcli.addCommand({
- commandName: "clean_challenge"
-}).then((argv) => {
- cleanChallenge(argv._[1]);
-});
-smartcli.startParse();
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5ob29rLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5ob29rLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBR0EsMENBQTBDO0FBQzFDLHNDQUFzQztBQUV0QyxJQUFJLFFBQVEsR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7QUFFL0MsSUFBSSxNQUFNLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM3RCxJQUFJLE1BQU0sR0FBRyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsYUFBYSxFQUFFLENBQUM7QUFDaEQsTUFBTSxDQUFDLElBQUksQ0FBQztJQUNSLEtBQUssRUFBRSxNQUFNLENBQUMsT0FBTztJQUNyQixHQUFHLEVBQUUsTUFBTSxDQUFDLEtBQUs7Q0FDcEIsQ0FBQyxDQUFDO0FBRUgsSUFBSSxZQUFZLEdBQUcsQ0FBQyxhQUFxQixFQUFFLFlBQW9CO0lBQzNELElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDN0IsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsd0JBQXdCLEdBQUcsYUFBYSxDQUFDLENBQUM7SUFDaEUsTUFBTSxDQUFDLFlBQVksQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLEVBQUUsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNyRSxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDO1FBQ2hELE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLDhEQUE4RCxDQUFDLENBQUM7UUFDdkYsUUFBUSxFQUFFLENBQUMsSUFBSSxDQUFDO1lBQ1osSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQyxDQUFDLENBQUM7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
\ No newline at end of file
diff --git a/dist/cert.paths.d.ts b/dist/cert.paths.d.ts
index cf04b3b..dc51658 100644
--- a/dist/cert.paths.d.ts
+++ b/dist/cert.paths.d.ts
@@ -1,8 +1,4 @@
-export declare let certDir: string;
-export declare let defaultSslDir: string;
+export declare let projectDir: string;
export declare let assetDir: string;
-export declare let accountsDir: string;
-export declare let certHook: string;
-export declare let config: string;
-export declare let leShConfig: string;
-export declare let letsencryptSh: string;
+export declare let defaultSslDir: string;
+export declare let leConfigDir: string;
diff --git a/dist/cert.paths.js b/dist/cert.paths.js
index 680e5f5..616a02d 100644
--- a/dist/cert.paths.js
+++ b/dist/cert.paths.js
@@ -1,13 +1,10 @@
"use strict";
const plugins = require("./cert.plugins");
-//dirs
-exports.certDir = plugins.path.join(__dirname, "assets/certs");
-exports.defaultSslDir = plugins.path.join(__dirname, "assets/defaultSslDir");
-exports.assetDir = plugins.path.join(__dirname, "assets/");
-exports.accountsDir = plugins.path.join(__dirname, "assets/accounts/");
-// files
-exports.certHook = plugins.path.join(__dirname, "cert.hook.js");
-exports.config = plugins.path.join(__dirname, "assets/config.json");
-exports.leShConfig = plugins.path.join(__dirname, "assets/leshconfig.json");
-exports.letsencryptSh = plugins.path.join(__dirname, "assets/letsencrypt.sh");
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBDQUEwQztBQUUxQyxNQUFNO0FBQ0ssUUFBQSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3RELFFBQUEsYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBQ3BFLFFBQUEsUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxTQUFTLENBQUMsQ0FBQztBQUNsRCxRQUFBLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUV6RSxRQUFRO0FBQ0csUUFBQSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3ZELFFBQUEsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQzNELFFBQUEsVUFBVSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQ25FLFFBQUEsYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyx1QkFBdUIsQ0FBQyxDQUFDIn0=
\ No newline at end of file
+// dirs
+exports.projectDir = plugins.path.join(__dirname, '../');
+exports.assetDir = plugins.path.join(exports.projectDir, 'assets');
+exports.defaultSslDir = plugins.path.join(exports.assetDir, 'defaultSslDir');
+exports.leConfigDir = plugins.path.join(exports.assetDir, 'letsencrypt');
+plugins.smartfile.fs.ensureDirSync(exports.leConfigDir);
+plugins.smartfile.fs.ensureDirSync(exports.defaultSslDir);
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBDQUF5QztBQUV6QyxPQUFPO0FBQ0ksUUFBQSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLEtBQUssQ0FBQyxDQUFBO0FBQy9DLFFBQUEsUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFVLEVBQUMsUUFBUSxDQUFDLENBQUE7QUFDakQsUUFBQSxhQUFhLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQVEsRUFBQyxlQUFlLENBQUMsQ0FBQTtBQUMzRCxRQUFBLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBUSxFQUFDLGFBQWEsQ0FBQyxDQUFBO0FBQ2xFLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxtQkFBVyxDQUFDLENBQUE7QUFDL0MsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLHFCQUFhLENBQUMsQ0FBQSJ9
\ No newline at end of file
diff --git a/dist/cert.plugins.d.ts b/dist/cert.plugins.d.ts
index 4523d89..1d5bc0c 100644
--- a/dist/cert.plugins.d.ts
+++ b/dist/cert.plugins.d.ts
@@ -1,12 +1,13 @@
-import "typings-global";
-export import beautylog = require("beautylog");
-export import cflare = require("cflare");
-export declare let fs: any;
-export import lik = require("lik");
-export import path = require("path");
-export import q = require("q");
-export import shelljs = require("shelljs");
-export import smartcli = require("smartcli");
-export import smartfile = require("smartfile");
-export import smartgit = require("smartgit");
-export import smartstring = require("smartstring");
+import 'typings-global';
+import * as beautylog from 'beautylog';
+import * as cflare from 'cflare';
+declare let fs: any;
+import * as lik from 'lik';
+import * as path from 'path';
+import * as q from 'q';
+import * as shelljs from 'shelljs';
+import * as smartcli from 'smartcli';
+import * as smartfile from 'smartfile';
+import * as smartgit from 'smartgit';
+import * as smartstring from 'smartstring';
+export { beautylog, cflare, fs, lik, path, q, shelljs, smartcli, smartfile, smartgit, smartstring };
diff --git a/dist/cert.plugins.js b/dist/cert.plugins.js
index a943e99..b8205f1 100644
--- a/dist/cert.plugins.js
+++ b/dist/cert.plugins.js
@@ -1,14 +1,25 @@
"use strict";
require("typings-global");
-exports.beautylog = require("beautylog");
-exports.cflare = require("cflare");
-exports.fs = require("fs-extra");
-exports.lik = require("lik");
-exports.path = require("path");
-exports.q = require("q");
-exports.shelljs = require("shelljs");
-exports.smartcli = require("smartcli");
-exports.smartfile = require("smartfile");
-exports.smartgit = require("smartgit");
-exports.smartstring = require("smartstring");
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwwQkFBd0I7QUFDeEIseUNBQStDO0FBQy9DLG1DQUF5QztBQUM5QixRQUFBLEVBQUUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDcEMsNkJBQW1DO0FBQ25DLCtCQUFxQztBQUNyQyx5QkFBK0I7QUFDL0IscUNBQTJDO0FBQzNDLHVDQUE2QztBQUM3Qyx5Q0FBK0M7QUFDL0MsdUNBQTZDO0FBQzdDLDZDQUFtRCJ9
\ No newline at end of file
+const beautylog = require("beautylog");
+exports.beautylog = beautylog;
+const cflare = require("cflare");
+exports.cflare = cflare;
+let fs = require('fs-extra');
+exports.fs = fs;
+const lik = require("lik");
+exports.lik = lik;
+const path = require("path");
+exports.path = path;
+const q = require("q");
+exports.q = q;
+const shelljs = require("shelljs");
+exports.shelljs = shelljs;
+const smartcli = require("smartcli");
+exports.smartcli = smartcli;
+const smartfile = require("smartfile");
+exports.smartfile = smartfile;
+const smartgit = require("smartgit");
+exports.smartgit = smartgit;
+const smartstring = require("smartstring");
+exports.smartstring = smartstring;
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwwQkFBdUI7QUFDdkIsdUNBQXNDO0FBYWxDLG9CQWJRLFNBQVMsQ0FhUjtBQVpiLGlDQUFnQztBQWE1QixpQkFiUSxNQUFNLENBYVI7QUFaVixJQUFJLEVBQUUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUE7QUFheEIsYUFiQSxFQUFFLENBYUE7QUFaTiwyQkFBMEI7QUFhdEIsY0FiUSxHQUFHLENBYVI7QUFaUCw2QkFBNEI7QUFheEIsZUFiUSxJQUFJLENBYVI7QUFaUix1QkFBc0I7QUFhbEIsWUFiUSxDQUFDLENBYVI7QUFaTCxtQ0FBa0M7QUFhOUIsa0JBYlEsT0FBTyxDQWFSO0FBWlgscUNBQW9DO0FBYWhDLG1CQWJRLFFBQVEsQ0FhUjtBQVpaLHVDQUFzQztBQWFsQyxvQkFiUSxTQUFTLENBYVI7QUFaYixxQ0FBb0M7QUFhaEMsbUJBYlEsUUFBUSxDQWFSO0FBWlosMkNBQTBDO0FBYXRDLHNCQWJRLFdBQVcsQ0FhUiJ9
\ No newline at end of file
diff --git a/dist/index.d.ts b/dist/index.d.ts
index b406cb4..5e745a6 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -1 +1 @@
-export * from "./cert.classes.cert";
+export * from './cert.classes.cert';
diff --git a/dist/index.js b/dist/index.js
index f15dc71..84c0870 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -3,4 +3,4 @@ function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
__export(require("./cert.classes.cert"));
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBR0EseUNBQW9DIn0=
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEseUNBQW1DIn0=
\ No newline at end of file
diff --git a/dist/install.d.ts b/dist/install.d.ts
deleted file mode 100644
index 4b21607..0000000
--- a/dist/install.d.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-///
-import * as plugins from "./cert.plugins";
-export declare let startInstall: () => plugins.q.Promise<{}>;
diff --git a/dist/install.js b/dist/install.js
deleted file mode 100644
index 9339416..0000000
--- a/dist/install.js
+++ /dev/null
@@ -1,19 +0,0 @@
-"use strict";
-const plugins = require("./cert.plugins");
-const paths = require("./cert.paths");
-exports.startInstall = () => {
- let done = plugins.q.defer();
- plugins.beautylog.info("installing letsencrypt.sh locally...");
- plugins.fs.ensureDir(plugins.path.join(__dirname, "assets/"));
- plugins.smartfile.remote.toFs("https://raw.githubusercontent.com/lukas2511/letsencrypt.sh/master/letsencrypt.sh", paths.letsencryptSh).then(() => {
- plugins.beautylog.success("Done!");
- done.resolve();
- });
- return done.promise;
-};
-let smartcli = new plugins.smartcli.Smartcli();
-smartcli.addCommand({
- commandName: "install"
-}).then(exports.startInstall);
-smartcli.startParse();
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2luc3RhbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBDQUEwQztBQUMxQyxzQ0FBc0M7QUFFM0IsUUFBQSxZQUFZLEdBQUc7SUFDdEIsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM3QixPQUFPLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxzQ0FBc0MsQ0FBQyxDQUFDO0lBRS9ELE9BQU8sQ0FBQyxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO0lBQzlELE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDekIsa0ZBQWtGLEVBQ2xGLEtBQUssQ0FBQyxhQUFhLENBQ3RCLENBQUMsSUFBSSxDQUFDO1FBQ0gsT0FBTyxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDbkMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ25CLENBQUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDeEIsQ0FBQyxDQUFDO0FBRUYsSUFBSSxRQUFRLEdBQUcsSUFBSSxPQUFPLENBQUMsUUFBUSxDQUFDLFFBQVEsRUFBRSxDQUFDO0FBQy9DLFFBQVEsQ0FBQyxVQUFVLENBQUM7SUFDaEIsV0FBVyxFQUFDLFNBQVM7Q0FDeEIsQ0FBQyxDQUFDLElBQUksQ0FBQyxvQkFBWSxDQUFDLENBQUM7QUFDdEIsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDIn0=
\ No newline at end of file
diff --git a/package.json b/package.json
index c539194..7090ed0 100644
--- a/package.json
+++ b/package.json
@@ -7,7 +7,6 @@
"scripts": {
"test": "(npm run cleanTest && npmts)",
"cleanTest": "(rm -rf ./test/assets)",
- "install": "node dist/install.js install",
"compile": "(npmts --notest)"
},
"repository": {
@@ -29,14 +28,13 @@
"dependencies": {
"@types/minimatch": "2.x.x",
"@types/q": "0.0.32",
- "@types/shelljs": "0.x.x",
"beautylog": "^6.0.0",
"cflare": "0.0.10",
"fs-extra": "^0.30.0",
+ "le-store-certbot": "^2.0.3",
"letsencrypt": "^2.1.8",
"lik": "^1.0.24",
"q": "^1.4.1",
- "shelljs": "^0.7.4",
"smartcli": "^1.0.10",
"smartfile": "^4.0.24",
"smartgit": "0.1.9",
@@ -44,6 +42,7 @@
"typings-global": "^1.0.14"
},
"devDependencies": {
+ "@types/should": "^8.1.30",
"npmts-g": "^5.2.8",
"qenv": "^1.1.1",
"should": "^11.1.1",
diff --git a/test/test.d.ts b/test/test.d.ts
index b973566..2fd432a 100644
--- a/test/test.d.ts
+++ b/test/test.d.ts
@@ -1,2 +1 @@
-import "typings-test";
-import "should";
+import 'typings-test';
diff --git a/test/test.js b/test/test.js
index 8beafb8..3cac396 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,47 +1,38 @@
"use strict";
require("typings-test");
-require("should");
+const should = require("should");
const qenv_1 = require("qenv");
const path = require("path");
const q = require("q");
-const install_1 = require("../dist/install");
const cert = require("../dist/index");
-let testQenv = new qenv_1.Qenv(process.cwd(), process.cwd() + "/.nogit");
+let testQenv = new qenv_1.Qenv(process.cwd(), process.cwd() + '/.nogit');
let testCert;
-describe("cert", function () {
- describe("install", function () {
- it("should download letsencrypt.sh", function (done) {
- this.timeout(5000);
- install_1.startInstall().then(() => {
- done();
- });
- });
- });
- describe("Cert", function () {
- it("should create a new Cert object from class", function () {
+describe('cert', function () {
+ describe('Cert', function () {
+ it('should create a new Cert object from class', function () {
this.timeout(40000);
testCert = new cert.Cert({
cfEmail: process.env.CF_EMAIL,
cfKey: process.env.CF_KEY,
- sslDir: path.join(process.cwd(), "test/assets"),
- gitOriginRepo: "git@gitlab.com:sandboxzone/sandbox-sslorigin.git",
- testMode: true
+ sslDirPath: path.join(process.cwd(), 'test/assets'),
+ gitOriginRepo: 'git@gitlab.com:sandboxzone/sandbox-sslorigin.git',
+ leEnv: 'staging'
});
- testCert.should.be.instanceof(cert.Cert);
+ should(testCert).be.instanceof(cert.Cert);
});
- it("should get a valid certificate", function (done) {
+ it('should get a valid certificate', function (done) {
this.timeout(1200000);
let promiseArray = [];
function getRandomArbitrary(min, max) {
return Math.floor(Math.random() * (max - min) + min);
}
- promiseArray.push(testCert.getDomainCert(`testing${getRandomArbitrary(1, 100000)}.bleu.de`));
- promiseArray.push(testCert.getDomainCert(`testing${getRandomArbitrary(1, 100000)}.bleu.de`));
- promiseArray.push(testCert.getDomainCert(`testing${getRandomArbitrary(1, 100000)}.bleu.de`));
+ promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1, 100000)}.bleu.de`));
+ // promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
+ // promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
q.all(promiseArray).then(() => {
done();
});
});
});
});
-//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFzQjtBQUN0QixrQkFBZ0I7QUFDaEIsK0JBQTBCO0FBQzFCLDZCQUE4QjtBQUM5Qix1QkFBd0I7QUFDeEIsNkNBQTZDO0FBQzdDLHNDQUFzQztBQUd0QyxJQUFJLFFBQVEsR0FBRyxJQUFJLFdBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0FBRWxFLElBQUksUUFBa0IsQ0FBQztBQUV2QixRQUFRLENBQUMsTUFBTSxFQUFDO0lBQ1osUUFBUSxDQUFDLFNBQVMsRUFBQztRQUNmLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBQyxVQUFTLElBQUk7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQixzQkFBWSxFQUFFLENBQUMsSUFBSSxDQUFDO2dCQUNoQixJQUFJLEVBQUUsQ0FBQztZQUNYLENBQUMsQ0FBQyxDQUFBO1FBQ04sQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtJQUNGLFFBQVEsQ0FBQyxNQUFNLEVBQUM7UUFDWixFQUFFLENBQUMsNENBQTRDLEVBQUM7WUFDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwQixRQUFRLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNyQixPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRO2dCQUM3QixLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNO2dCQUN6QixNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUMsYUFBYSxDQUFDO2dCQUM5QyxhQUFhLEVBQUMsa0RBQWtEO2dCQUNoRSxRQUFRLEVBQUMsSUFBSTthQUNoQixDQUFDLENBQUM7WUFDSCxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFBO1FBQ0YsRUFBRSxDQUFDLGdDQUFnQyxFQUFDLFVBQVMsSUFBSTtZQUM3QyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQztZQUN0Qiw0QkFBNEIsR0FBRyxFQUFFLEdBQUc7Z0JBQ2hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUN6RCxDQUFDO1lBQ0QsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFVBQVUsa0JBQWtCLENBQUMsQ0FBQyxFQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzVGLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxVQUFVLGtCQUFrQixDQUFDLENBQUMsRUFBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM1RixZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxrQkFBa0IsQ0FBQyxDQUFDLEVBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDNUYsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksRUFBRSxDQUFDO1lBQ1gsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUMifQ==
\ No newline at end of file
+//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFDaEMsK0JBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix1QkFBdUI7QUFDdkIsc0NBQXFDO0FBR3JDLElBQUksUUFBUSxHQUFHLElBQUksV0FBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUE7QUFFakUsSUFBSSxRQUFtQixDQUFBO0FBRXZCLFFBQVEsQ0FBQyxNQUFNLEVBQUM7SUFDWixRQUFRLENBQUMsTUFBTSxFQUFDO1FBQ1osRUFBRSxDQUFDLDRDQUE0QyxFQUFDO1lBQzVDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDbkIsUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDckIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUTtnQkFDN0IsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTTtnQkFDekIsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFDLGFBQWEsQ0FBQztnQkFDbEQsYUFBYSxFQUFFLGtEQUFrRDtnQkFDakUsS0FBSyxFQUFFLFNBQVM7YUFDbkIsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzdDLENBQUMsQ0FBQyxDQUFBO1FBQ0YsRUFBRSxDQUFDLGdDQUFnQyxFQUFDLFVBQVMsSUFBSTtZQUM3QyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3JCLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQTtZQUNyQiw0QkFBNEIsR0FBRyxFQUFFLEdBQUc7Z0JBQ2hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQTtZQUN4RCxDQUFDO1lBQ0QsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFVBQVUsa0JBQWtCLENBQUMsQ0FBQyxFQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFBO1lBQzVGLCtGQUErRjtZQUMvRiwrRkFBK0Y7WUFDL0YsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksRUFBRSxDQUFBO1lBQ1YsQ0FBQyxDQUFDLENBQUE7UUFDTixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUEifQ==
\ No newline at end of file
diff --git a/test/test.ts b/test/test.ts
index 51802cb..827f4ae 100644
--- a/test/test.ts
+++ b/test/test.ts
@@ -1,49 +1,40 @@
-import "typings-test";
-import "should";
-import {Qenv} from "qenv";
-import path = require("path");
-import q = require("q");
-import {startInstall} from "../dist/install";
-import * as cert from "../dist/index";
+import 'typings-test'
+import * as should from 'should'
+import {Qenv} from 'qenv'
+import path = require('path')
+import q = require('q')
+import * as cert from '../dist/index'
-let testQenv = new Qenv(process.cwd(), process.cwd() + "/.nogit");
+let testQenv = new Qenv(process.cwd(), process.cwd() + '/.nogit')
-let testCert:cert.Cert;
+let testCert: cert.Cert
-describe("cert",function(){
- describe("install",function(){
- it("should download letsencrypt.sh",function(done){
- this.timeout(5000);
- startInstall().then(() => {
- done();
- })
- })
- })
- describe("Cert",function(){
- it("should create a new Cert object from class",function(){
- this.timeout(40000);
+describe('cert',function(){
+ describe('Cert',function(){
+ it('should create a new Cert object from class',function(){
+ this.timeout(40000)
testCert = new cert.Cert({
cfEmail: process.env.CF_EMAIL,
cfKey: process.env.CF_KEY,
- sslDir: path.join(process.cwd(),"test/assets"),
- gitOriginRepo:"git@gitlab.com:sandboxzone/sandbox-sslorigin.git",
- testMode:true
- });
- testCert.should.be.instanceof(cert.Cert);
+ sslDirPath: path.join(process.cwd(),'test/assets'),
+ gitOriginRepo: 'git@gitlab.com:sandboxzone/sandbox-sslorigin.git',
+ leEnv: 'staging'
+ })
+ should(testCert).be.instanceof(cert.Cert)
})
- it("should get a valid certificate",function(done){
- this.timeout(1200000);
- let promiseArray = [];
+ it('should get a valid certificate',function(done){
+ this.timeout(1200000)
+ let promiseArray = []
function getRandomArbitrary(min, max) {
- return Math.floor(Math.random() * (max - min) + min);
+ return Math.floor(Math.random() * (max - min) + min)
}
- promiseArray.push(testCert.getDomainCert(`testing${getRandomArbitrary(1,100000)}.bleu.de`));
- promiseArray.push(testCert.getDomainCert(`testing${getRandomArbitrary(1,100000)}.bleu.de`));
- promiseArray.push(testCert.getDomainCert(`testing${getRandomArbitrary(1,100000)}.bleu.de`));
+ promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
+ // promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
+ // promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
q.all(promiseArray).then(() => {
- done();
- });
+ done()
+ })
})
})
-});
\ No newline at end of file
+})
\ No newline at end of file
diff --git a/ts/cert.classes.cert.helpers.ts b/ts/cert.classes.cert.helpers.ts
deleted file mode 100644
index 7688bca..0000000
--- a/ts/cert.classes.cert.helpers.ts
+++ /dev/null
@@ -1,86 +0,0 @@
-import {Cert} from "./index.ts";
-import * as plugins from "./cert.plugins";
-import * as paths from "./cert.paths";
-
-
-
-/**
- * schedule a retry of certificate request
- */
-export let scheduleRetry = (domainArg:string,certClassArg:Cert) => {
- let done = plugins.q.defer();
- setTimeout(() => {
- certClassArg.getDomainCert(domainArg)
- .then(done.resolve);
- },60000);
- return done.promise;
-};
-
-/**
- * check if a given domainCert is still valid
- */
-export let checkDomainsStillValid = (domainNameArg: string, sslDirArg: string): boolean => {
- let domainConfigPath = plugins.path.join(sslDirArg, domainNameArg, "config.json");
- if (plugins.smartfile.fs.fileExistsSync(domainConfigPath)) {
- let domainConfig = plugins.smartfile.fs.toObjectSync(
- domainConfigPath,
- "json"
- );
- if (Date.now() >= ((domainConfig.expires - 604800) * 1000)) {
- return false;
- } else {
- return true;
- }
- } else {
- return false;
- }
-
-}
-
-export interface certConfig {
- domainName: string;
- created: number;
- expires: number;
-};
-
-/**
- * update a ssl directory
- */
-export let updateSslDirSync = (sslDirArg: string, domainNameArg: string) => {
- plugins.smartfile.fs.ensureDirSync(sslDirArg);
- let domainCertFolder = plugins.path.join(paths.certDir, domainNameArg)
- if (plugins.smartfile.fs.listFoldersSync(paths.certDir).indexOf(domainNameArg) != -1) {
- plugins.smartfile.fs.copySync(
- plugins.path.join(domainCertFolder, "fullchain.pem"),
- plugins.path.join(sslDirArg, domainNameArg, "fullchain.pem")
- );
- plugins.smartfile.fs.copySync(
- plugins.path.join(domainCertFolder, "privkey.pem"),
- plugins.path.join(sslDirArg, domainNameArg, "privkey.pem")
- );
- // create cert config
- let certRegex = /.*\-([0-9]*)\.pem/;
- let certFileNameWithTime: string = plugins.smartfile.fs.listFilesSync(domainCertFolder, certRegex)[0];
- let certTime = parseInt(certRegex.exec(certFileNameWithTime)[1]);
- let certConfig: certConfig = {
- domainName: domainNameArg,
- created: certTime,
- expires: certTime + 7776000
- };
- plugins.smartfile.memory.toFsSync(
- JSON.stringify(certConfig),
- plugins.path.join(sslDirArg, domainNameArg, "config.json")
- );
- };
-}
-
-const enum gitSyncDirection {
- toOrigin,
- fromOrigin
-}
-
-let updateGitOrigin = (syncDirectionArg: gitSyncDirection) => {
-
-};
-
-updateGitOrigin(gitSyncDirection.toOrigin);
\ No newline at end of file
diff --git a/ts/cert.classes.cert.ts b/ts/cert.classes.cert.ts
index feb3182..bfa367e 100644
--- a/ts/cert.classes.cert.ts
+++ b/ts/cert.classes.cert.ts
@@ -1,148 +1,92 @@
import * as q from 'q'
+import { Stringmap, Objectmap } from 'lik'
+
import * as plugins from './cert.plugins'
import * as paths from './cert.paths'
-import * as helpers from './cert.classes.cert.helpers'
+
+// classes
+import { Certificate } from './cert.classes.certificate'
+import { CertRepo } from './cert.classes.certrepo'
+import { Letsencrypt, TLeEnv } from './cert.classes.letsencrypt'
+import { ChallengeHandler } from './cert.classes.challengehandler'
+
export interface ICertConstructorOptions {
cfEmail: string,
cfKey: string,
- sslDir?: string,
+ sslDirPath?: string,
gitOriginRepo?: string,
- testMode?: boolean
+ leEnv?: TLeEnv
}
export class Cert {
- domainCertRequestMap: plugins.lik.Stringmap = new plugins.lik.Stringmap()
- certificatesPresent: Certificate[]
- certificatesValid: Certificate[]
- private _cfEmail: string
- private _cfKey: string
- private _sslDir: string
- private _gitOriginRepo: string
- private _testMode: boolean
- private letsencryptInstance
+ domainStringRequestMap = new Stringmap()
+ certificateMap = new Objectmap()
+ letsencrypt: Letsencrypt
+ private _challengeHandler: ChallengeHandler
+ private _certRepo: CertRepo
/**
* Constructor for Cert object
*/
constructor(optionsArg: ICertConstructorOptions) {
- this._cfEmail = optionsArg.cfEmail
- this._cfKey = optionsArg.cfKey
- this._sslDir = optionsArg.sslDir
- this._gitOriginRepo = optionsArg.gitOriginRepo
- this._testMode = optionsArg.testMode
- // write hook config
- let config = {
- cfEmail: this._cfEmail,
- cfKey: this._cfKey
- }
- plugins.smartfile.memory.toFsSync(
- JSON.stringify(config),
- plugins.path.join(__dirname, 'assets/config.json')
- )
- // setup sslDir
- if (!this._sslDir) this._sslDir = paths.defaultSslDir
- // setup Git
- if (this._gitOriginRepo) {
- plugins.smartgit.init(this._sslDir)
- plugins.smartgit.remote.add(this._sslDir, 'origin', this._gitOriginRepo)
- this.sslGitOriginPull()
- }
+
+ // set up challengehandler
+ this._challengeHandler = new ChallengeHandler({
+ cfEmail: optionsArg.cfEmail,
+ cfKey: optionsArg.cfKey
+ })
+
+ // setup Letsencrypt
+ this.letsencrypt = new Letsencrypt({
+ leEnv: optionsArg.leEnv,
+ sslDir: optionsArg.sslDirPath,
+ challengeHandler: this._challengeHandler
+ })
+
+ // setup CertRpo
+ this._certRepo = new CertRepo({
+ sslDirPath: optionsArg.sslDirPath,
+ gitOriginRepo: optionsArg.gitOriginRepo,
+ certInstance: this
+ })
+
+ this._certRepo
}
/**
- * Pulls already requested certificates from git origin
+ * adds a Certificate for a given domain
*/
- sslGitOriginPull = () => {
- if (this._gitOriginRepo) {
- plugins.smartgit.pull(this._sslDir, 'origin', 'master')
- }
- }
-
- /**
- * Pushes all new requested certificates to git origin
- */
- sslGitOriginAddCommitPush = () => {
- if (this._gitOriginRepo) {
- plugins.smartgit.add.addAll(this._sslDir)
- plugins.smartgit.commit(this._sslDir, 'added new SSL certificates and deleted obsolete ones.')
- plugins.smartgit.push(this._sslDir, 'origin', 'master')
- }
- }
-
- /**
- * gets a ssl cert for a given domain
- */
- getDomainCert(domainNameArg: string, optionsArg: { force: boolean } = { force: false }) {
+ addCertificate(domainNameArg: string, optionsArg: { force: boolean } = { force: false }) {
let done = q.defer()
- let domainStringData = new plugins.smartstring.Domain(domainNameArg)
- let sameZoneRequesting: boolean = this.domainCertRequestMap.checkMinimatch('*' + domainStringData.zoneName)
- // make sure no one else requires the same domain at the same time
- if (!this.domainCertRequestMap.checkString(domainNameArg)) {
- this.domainCertRequestMap.addString(domainNameArg)
- if (!helpers.checkDomainsStillValid(domainNameArg, this._sslDir) || optionsArg.force) {
- if (!sameZoneRequesting) {
- this.sslGitOriginPull()
- plugins.smartfile.fs.ensureDir(paths.certDir)
- plugins.beautylog.info(`getting cert for ${domainNameArg}`)
- plugins.shelljs.exec(
- `bash -c "${paths.letsencryptSh} -c --no-lock -f ${paths.leShConfig} -d ${domainNameArg} -t dns-01 -k ${paths.certHook} -o ${paths.certDir}"`,
- {
- silent: true
- },
- (codeArg, stdoutArg) => {
- if (codeArg === 0) {
- console.log(stdoutArg)
- let fetchedCertsArray: string[] = plugins.smartfile.fs.listFoldersSync(paths.certDir)
- if (fetchedCertsArray.indexOf(domainNameArg) != -1) {
- helpers.updateSslDirSync(this._sslDir, domainNameArg)
- plugins.smartfile.fs.removeSync(plugins.path.join(paths.certDir, domainNameArg))
- this.sslGitOriginAddCommitPush()
- } else {
- plugins.beautylog.error(`Couldn't copy final certificate for ${domainNameArg}!`)
- }
- done.resolve()
- } else {
- plugins.beautylog.warn(`${domainNameArg} scheduled for retry. Waiting 1 minute!`)
- helpers.scheduleRetry(domainNameArg, this).then(done.resolve)
- }
- this.domainCertRequestMap.removeString(domainNameArg)
- }
- )
- } else {
- plugins.beautylog.info(`${domainNameArg} is waiting for domains names of same zone to finish`)
- this.domainCertRequestMap.removeString(domainNameArg)
- this.domainCertRequestMap.registerUntilTrue(
- () => {
- return !this.domainCertRequestMap.checkMinimatch('*' + domainStringData.zoneName)
- },
- () => {
- this.getDomainCert(domainNameArg).then(done.resolve)
- }
- )
- }
- } else {
- plugins.beautylog.info('certificate for ' + domainNameArg + ' is still valid! Not fetching new one!')
- this.domainCertRequestMap.removeString(domainNameArg)
- done.resolve()
- }
+ let certificateForDomain = this.certificateMap.find((certificate) => {
+ return certificate.domainName === domainNameArg
+ })
+ if (certificateForDomain instanceof Certificate) {
+ certificateForDomain.renew()
+ .then(done.resolve)
} else {
- plugins.beautylog.warn(`${domainNameArg} is already requesting`)
+ certificateForDomain = new Certificate({
+ certInstance: this,
+ domainName: domainNameArg
+ })
+ certificateForDomain.renew()
+ .then(done.resolve)
}
-
return done.promise
}
+
+ /**
+ * cleans up old certificates
+ */
cleanOldCertificates() {
}
-}
-export class Certificate {
- domainName: string
- creationDate: Date
- expiryDate: Date
- constructor() {
+ /**
+ * executes the current batch of jobs
+ */
+ deploy() {
}
}
-
diff --git a/ts/cert.classes.certificate.ts b/ts/cert.classes.certificate.ts
new file mode 100644
index 0000000..1694e7f
--- /dev/null
+++ b/ts/cert.classes.certificate.ts
@@ -0,0 +1,129 @@
+import * as q from 'q'
+
+import * as plugins from './cert.plugins'
+import * as paths from './cert.paths'
+
+// import classes
+import { Cert } from './cert.classes.cert'
+import { Letsencrypt } from './cert.classes.letsencrypt'
+import { CertRepo } from './cert.classes.certrepo'
+
+export interface ICertificateFsConfig {
+ domainName: string
+ creationTime: number
+ expiryTime: number
+}
+
+export interface ICertificateConstructorOptions {
+ domainName: string,
+ certInstance: Cert
+}
+
+export type TCertificateStatus = 'unregistered' | 'valid' | 'expiring' | 'expired'
+
+export class Certificate {
+ domainName: string
+ certInstance: Cert
+ domainData: plugins.smartstring.Domain
+ creationDate: Date = null
+ expiryDate: Date = null
+ publicKey: string = null
+ privKey: string = null
+
+ /**
+ * run when creating a new instance of Certificate
+ */
+ constructor(optionsArg: ICertificateConstructorOptions) {
+ this.domainName = optionsArg.domainName
+ this.domainData = new plugins.smartstring.Domain(this.domainName)
+ this.certInstance = optionsArg.certInstance
+ }
+
+ /**
+ * the status of the Certificate
+ */
+ get status(): TCertificateStatus {
+ let validTimeRemaining: number = 0
+ if (this.creationDate !== null && this.expiryDate !== null) {
+ validTimeRemaining = this.expiryDate.getTime() - Date.now()
+ }
+ let MonthMilliseconds = 2629746000
+ if (this.publicKey === null || this.privKey === null) {
+ return 'unregistered'
+ } else if (validTimeRemaining >= MonthMilliseconds) {
+ return 'valid'
+ } else if (validTimeRemaining < MonthMilliseconds && validTimeRemaining >= 0) {
+ return 'expiring'
+ } else {
+ return 'expired'
+ }
+ }
+
+ get sameZoneRequesting(): boolean {
+ return this.certInstance.domainStringRequestMap.checkMinimatch('*' + this.domainData.zoneName)
+ }
+
+ /**
+ * schedule a retry of certificate request
+ */
+ scheduleRetry() {
+ let done = plugins.q.defer()
+ setTimeout(() => {
+ this.renew()
+ .then(done.resolve)
+ }, 60000)
+ return done.promise
+ }
+
+ /**
+ * renew certificate if needed
+ */
+ renew(force: boolean = false) {
+ let done = q.defer()
+ if (this.status === 'valid') {
+ plugins.beautylog.log('Certificate still valid for more than 1 month, so it is not renewed now')
+ done.resolve()
+ } else if (this.status === 'expiring' || this.status === 'expired' || this.status === 'unregistered') {
+ plugins.beautylog.info('Certificate not valid currently, going to renew now!')
+ if (this.sameZoneRequesting) {
+ this.certInstance.domainStringRequestMap.registerUntilTrue(
+ () => {
+ return !this.sameZoneRequesting
+ },
+ () => {
+ this.renew().then(done.resolve)
+ }
+ )
+ } else {
+ this.certInstance.letsencrypt.registerDomain(this.domainName)
+ .then(() => {
+ return this.syncFs()
+ })
+ .then(() => {
+ done.resolve()
+ }).catch((err) => { console.log(err) })
+ }
+ } else {
+ throw Error(`weird status for certificate with domain name ${this.domainName}`)
+ }
+ done.resolve()
+ return done.promise
+ }
+
+ /**
+ * syncFs syncs the certificate with disk
+ */
+ syncFs() {
+ let configJsonMemory: ICertificateFsConfig = {
+ domainName: this.domainName,
+ creationTime: this.creationDate.getTime(),
+ expiryTime: this.expiryDate.getTime()
+ }
+
+ }
+
+ /**
+ * deletes the certificate
+ */
+ delete() { }
+}
diff --git a/ts/cert.classes.certrepo.ts b/ts/cert.classes.certrepo.ts
new file mode 100644
index 0000000..5f8f756
--- /dev/null
+++ b/ts/cert.classes.certrepo.ts
@@ -0,0 +1,65 @@
+import * as q from 'q'
+
+import * as plugins from './cert.plugins'
+import * as paths from './cert.paths'
+
+import { Cert } from './cert.classes.cert'
+import { Certificate } from './cert.classes.certificate'
+
+export interface ICertRepoConstructorOptions {
+ sslDirPath: string
+ gitOriginRepo: string
+ certInstance: Cert
+}
+
+export class CertRepo {
+ private _sslDirPath: string
+ private _gitOriginRepo: string
+ private _certInstance: Cert
+ constructor(optionsArg: ICertRepoConstructorOptions) {
+ this._sslDirPath = optionsArg.sslDirPath
+ this._gitOriginRepo = optionsArg.gitOriginRepo
+ this._certInstance = optionsArg.certInstance
+
+ // setup sslDir
+ if (!this._sslDirPath){
+ this._sslDirPath = paths.defaultSslDir
+ }
+
+ // setup Git
+ if (this._gitOriginRepo) {
+ plugins.smartgit.init(this._sslDirPath)
+ plugins.smartgit.remote.add(this._sslDirPath, 'origin', this._gitOriginRepo)
+ this.sslGitOriginPull()
+ }
+ }
+
+ /**
+ * syncs an objectmap of Certificates with repo
+ */
+ syncFs() {
+ let done = q.defer()
+ done.resolve()
+ return done.promise
+ }
+
+ /**
+ * Pulls already requested certificates from git origin
+ */
+ sslGitOriginPull = () => {
+ if (this._gitOriginRepo) {
+ plugins.smartgit.pull(this._sslDirPath, 'origin', 'master')
+ }
+ }
+
+ /**
+ * Pushes all new requested certificates to git origin
+ */
+ sslGitOriginAddCommitPush = () => {
+ if (this._gitOriginRepo) {
+ plugins.smartgit.add.addAll(this._sslDirPath)
+ plugins.smartgit.commit(this._sslDirPath, 'added new SSL certificates and deleted obsolete ones.')
+ plugins.smartgit.push(this._sslDirPath, 'origin', 'master')
+ }
+ }
+}
diff --git a/ts/cert.classes.challengehandler.ts b/ts/cert.classes.challengehandler.ts
new file mode 100644
index 0000000..3c8c2ad
--- /dev/null
+++ b/ts/cert.classes.challengehandler.ts
@@ -0,0 +1,84 @@
+import * as plugins from './cert.plugins'
+import * as paths from './cert.paths'
+
+export interface IChallengehandlerConstructorOptions {
+ cfEmail: string,
+ cfKey: string,
+}
+
+/**
+ * class ChallengeHandler handles challenges
+ */
+export class ChallengeHandler {
+ private _cfInstance: plugins.cflare.CflareAccount
+ constructor(optionsArg: IChallengehandlerConstructorOptions) {
+ this._cfInstance = new plugins.cflare.CflareAccount()
+ this._cfInstance.auth({
+ email: optionsArg.cfEmail,
+ key: optionsArg.cfKey
+ })
+ }
+
+ /**
+ * set a challenge
+ */
+ setChallenge(domainNameArg: string, challengeArg: string) {
+ let done = plugins.q.defer()
+ plugins.beautylog.log('setting challenge for ' + domainNameArg)
+ this._cfInstance.createRecord(prefixName(domainNameArg), 'TXT', challengeArg).then(() => {
+ plugins.beautylog.ok('Challenge has been set!')
+ plugins.beautylog.info('We need to cool down to let DNS propagate to edge locations!')
+ cooldown().then(() => {
+ done.resolve()
+ })
+ })
+ return done.promise
+ }
+
+ /**
+ * cleans a challenge
+ */
+ cleanChallenge(domainNameArg) {
+ let done = plugins.q.defer()
+ plugins.beautylog.log('cleaning challenge for ' + domainNameArg)
+ this._cfInstance.removeRecord(prefixName(domainNameArg), 'TXT')
+ cooldown().then(() => {
+ done.resolve()
+ })
+ return done.promise
+ }
+}
+
+/**
+ * cooldown timer for letting DNS settle before answering the challengerequest
+ */
+let cooldown = () => {
+ let done = plugins.q.defer()
+ let cooldowntime = 60000
+ let passedTime = 0
+ plugins.beautylog.log('Cooling down! ' + (cooldowntime / 1000).toString() + ' seconds left')
+ let coolDownCounter = () => {
+ setTimeout(() => {
+ if (cooldowntime <= passedTime) {
+ plugins.beautylog.ok('Cooled down!')
+ done.resolve()
+ } else {
+ passedTime = passedTime + 5000
+ plugins.beautylog.log('Cooling down! '
+ + ((cooldowntime - passedTime) / 1000).toString()
+ + ' seconds left'
+ )
+ coolDownCounter()
+ }
+ }, 5000)
+ }
+ coolDownCounter()
+ return done.promise
+}
+
+/**
+ * prefix a domain name to make sure it complies with letsencrypt
+ */
+let prefixName = (domainNameArg: string): string => {
+ return '_acme-challenge.' + domainNameArg
+}
diff --git a/ts/cert.classes.letsencrypt.ts b/ts/cert.classes.letsencrypt.ts
new file mode 100644
index 0000000..32a9f70
--- /dev/null
+++ b/ts/cert.classes.letsencrypt.ts
@@ -0,0 +1,139 @@
+import * as q from 'q'
+let letsencrypt = require('letsencrypt')
+
+import * as plugins from './cert.plugins'
+import * as paths from './cert.paths'
+
+import { ChallengeHandler } from './cert.classes.challengehandler'
+
+export type TLeEnv = 'production' | 'staging'
+
+export interface ILetsencryptConstructorOptions {
+ leEnv: TLeEnv,
+ challengeHandler: ChallengeHandler,
+ sslDir: string
+}
+
+export class Letsencrypt {
+ leEnv: TLeEnv
+ challengeHandler: ChallengeHandler // this is the format we use
+ sslDir: string
+
+ private _leInstance: any
+ private _leServerUrl: string
+
+ constructor(optionsArg: ILetsencryptConstructorOptions) {
+ // determine leEnv
+ this.leEnv = optionsArg.leEnv
+ this.challengeHandler = optionsArg.challengeHandler
+ this.sslDir = optionsArg.sslDir
+
+ // set letsencrypt environment
+ if (this.leEnv === 'production') {
+ this._leServerUrl = letsencrypt.productionServerUrl
+ } else if (this.leEnv === 'staging') {
+ this._leServerUrl = letsencrypt.stagingServerUrl
+ }
+
+ // create leInstance
+ this._leInstance = letsencrypt.create({
+ server: this._leServerUrl,
+ challenges: { 'dns-01': this._leChallengeHandler() },
+ challengeType: 'dns-01',
+ configDir: paths.leConfigDir,
+ privkeyPath: ':configDir/live/:hostname/privkey.pem', //
+ fullchainPath: ':configDir/live/:hostname/fullchain.pem', // Note: both that :config and :hostname
+ certPath: ':config/live/:hostname/cert.pem', // will be templated as expected
+ chainPath: ':config/live/:hostname/chain.pem',
+ agreeToTerms: this._leAgree,
+ debug: true
+ })
+ }
+
+ /**
+ * register a domain
+ */
+ registerDomain(domainNameArg: string) {
+ plugins.beautylog.log(`trying to register domain ${domainNameArg}`)
+ let done = q.defer()
+ console.log('test')
+ this._leInstance.register({
+ domains: [domainNameArg],
+ email: 'domains@lossless.org',
+ agreeTos: true,
+ rsaKeySize: 2048,
+ challengeType: 'dns-01'
+ }).then(
+ (results) => {
+ plugins.beautylog.success(`Got certificates for ${domainNameArg}`)
+ this._leCopyToDestination(domainNameArg).then(done.resolve)
+ },
+ (err) => {
+ console.error('[Error]: node-letsencrypt/examples/standalone')
+ console.error(err.stack)
+ done.resolve()
+ }
+ ).catch(err => { console.log(err) })
+ return done.promise
+ }
+
+ // --------------------------------------------
+ // Translate for official letsencrypt stuff
+ // --------------------------------------------
+
+ private _leCopyToDestination(domainNameArg) {
+ let done = q.defer()
+ return done.promise
+ }
+
+ /**
+ * translates to the format expected by letsencrypt node implementation
+ */
+ private _leChallengeHandler() {
+ return {
+ getOptions: (...args) => {
+ return {
+ debug: true
+ }
+ },
+ set: (args, domain, challenge, keyAuthorization, cb) => {
+ let keyAuthDigest = require('crypto')
+ .createHash('sha256').update(keyAuthorization || '')
+ .digest('base64')
+ .replace(/\+/g, '-')
+ .replace(/\//g, '_')
+ .replace(/=+$/g, '')
+ this.challengeHandler.setChallenge(domain, keyAuthDigest)
+ .then(() => {
+ cb()
+ })
+ },
+ get: (defaults, domain, challenge, cb) => {
+ console.log(defaults)
+ console.log(domain)
+ console.log(challenge)
+ cb()
+ },
+ remove: (args, domain, challenge, cb) => {
+ this.challengeHandler.cleanChallenge(domain)
+ .then(() => {
+ cb()
+ })
+ },
+ loopback: (args, domain, challenge, cb) => {
+ console.log(args)
+ console.log(domain)
+ console.log(challenge)
+ cb()
+ },
+ test: (defaults, domain, challenge, cb) => {
+ cb()
+ }
+ }
+ }
+
+ private _leAgree(opts, agreeCb) {
+ // opts = { email, domains, tosUrl }
+ agreeCb(null, opts.tosUrl);
+ }
+}
diff --git a/ts/cert.hook.ts b/ts/cert.hook.ts
deleted file mode 100644
index 9c9495c..0000000
--- a/ts/cert.hook.ts
+++ /dev/null
@@ -1,73 +0,0 @@
-import * as plugins from "./cert.plugins";
-import * as paths from "./cert.paths";
-
-let smartcli = new plugins.smartcli.Smartcli();
-
-let config = plugins.smartfile.fs.toObjectSync(paths.config);
-let cflare = new plugins.cflare.CflareAccount();
-cflare.auth({
- email: config.cfEmail,
- key: config.cfKey
-});
-
-let setChallenge = (domainNameArg: string, challengeArg: string) => {
- let done = plugins.q.defer();
- plugins.beautylog.log("setting challenge for " + domainNameArg);
- cflare.createRecord(prefixName(domainNameArg), "TXT", challengeArg).then(() => {
- plugins.beautylog.ok("Challenge has been set!");
- plugins.beautylog.info("We need to cool down to let DNS propagate to edge locations!");
- cooldown().then(() => {
- done.resolve();
- });
- });
- return done.promise;
-}
-
-let cleanChallenge = (domainNameArg) => {
- let done = plugins.q.defer();
- plugins.beautylog.log("cleaning challenge for " + domainNameArg);
- cflare.removeRecord(prefixName(domainNameArg), "TXT");
- cooldown().then(() => {
- done.resolve();
- });
- return done.promise;
-}
-
-let cooldown = () => {
- let done = plugins.q.defer();
- let cooldowntime = 60000;
- let passedTime = 0;
- plugins.beautylog.log("Cooling down! " + (cooldowntime/1000).toString() + " seconds left");
- let coolDownCounter = () => {
- setTimeout(() => {
- if(cooldowntime <= passedTime){
- plugins.beautylog.ok("Cooled down!");
- done.resolve();
- } else {
- passedTime = passedTime + 5000;
- plugins.beautylog.log("Cooling down! " + ((cooldowntime - passedTime)/1000).toString() + " seconds left");
- coolDownCounter();
- }
- }, 5000);
- }
- coolDownCounter();
- return done.promise;
-}
-
-let prefixName = (domainNameArg: string): string => {
- return "_acme-challenge." + domainNameArg;
-}
-
-smartcli.addCommand({
- commandName: "deploy_challenge"
-}).then((argv) => {
- setChallenge(argv._[1], argv._[3]);
-});
-
-smartcli.addCommand({
- commandName: "clean_challenge"
-}).then((argv) => {
- cleanChallenge(argv._[1]);
-});
-
-smartcli.startParse();
diff --git a/ts/cert.paths.ts b/ts/cert.paths.ts
index ba38048..3745631 100644
--- a/ts/cert.paths.ts
+++ b/ts/cert.paths.ts
@@ -1,14 +1,9 @@
-import * as plugins from "./cert.plugins";
-
-//dirs
-export let certDir = plugins.path.join(__dirname,"assets/certs");
-export let defaultSslDir = plugins.path.join(__dirname,"assets/defaultSslDir");
-export let assetDir = plugins.path.join(__dirname,"assets/");
-export let accountsDir = plugins.path.join(__dirname,"assets/accounts/");
-
-// files
-export let certHook = plugins.path.join(__dirname,"cert.hook.js");
-export let config = plugins.path.join(__dirname,"assets/config.json");
-export let leShConfig = plugins.path.join(__dirname,"assets/leshconfig.json");
-export let letsencryptSh = plugins.path.join(__dirname,"assets/letsencrypt.sh");
+import * as plugins from './cert.plugins'
+// dirs
+export let projectDir = plugins.path.join(__dirname,'../')
+export let assetDir = plugins.path.join(projectDir,'assets')
+export let defaultSslDir = plugins.path.join(assetDir,'defaultSslDir')
+export let leConfigDir = plugins.path.join(assetDir,'letsencrypt')
+plugins.smartfile.fs.ensureDirSync(leConfigDir)
+plugins.smartfile.fs.ensureDirSync(defaultSslDir)
diff --git a/ts/cert.plugins.ts b/ts/cert.plugins.ts
index 1537296..909ae7e 100644
--- a/ts/cert.plugins.ts
+++ b/ts/cert.plugins.ts
@@ -2,7 +2,6 @@ import 'typings-global'
import * as beautylog from 'beautylog'
import * as cflare from 'cflare'
let fs = require('fs-extra')
-let letsencrypt = require('letsencrypt')
import * as lik from 'lik'
import * as path from 'path'
import * as q from 'q'
@@ -16,7 +15,6 @@ export {
beautylog,
cflare,
fs,
- letsencrypt,
lik,
path,
q,
diff --git a/ts/index.ts b/ts/index.ts
index 6c686ef..f635b28 100644
--- a/ts/index.ts
+++ b/ts/index.ts
@@ -1,4 +1 @@
-import * as plugins from "./cert.plugins";
-import * as paths from "./cert.paths";
-
-export * from "./cert.classes.cert";
\ No newline at end of file
+export * from './cert.classes.cert'
diff --git a/ts/temp b/ts/temp
new file mode 100644
index 0000000..74bd985
--- /dev/null
+++ b/ts/temp
@@ -0,0 +1,3 @@
+helpers.updateSslDirSync(this._sslDir, domainNameArg)
+helpers.scheduleRetry(domainNameArg, this).then(done.resolve)
+this.domainCertRequestMap.removeString(domainNameArg)
\ No newline at end of file