diff --git a/package.json b/package.json index aa6befa..c539194 100644 --- a/package.json +++ b/package.json @@ -28,11 +28,12 @@ "homepage": "https://gitlab.com/pushrocks/cert#readme", "dependencies": { "@types/minimatch": "2.x.x", - "@types/q": "0.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", + "letsencrypt": "^2.1.8", "lik": "^1.0.24", "q": "^1.4.1", "shelljs": "^0.7.4", diff --git a/ts/cert.classes.cert.ts b/ts/cert.classes.cert.ts index c2c713b..3a0c86c 100644 --- a/ts/cert.classes.cert.ts +++ b/ts/cert.classes.cert.ts @@ -1,6 +1,7 @@ -import * as plugins from "./cert.plugins"; -import * as paths from "./cert.paths"; -import * as helpers from "./cert.classes.cert.helpers" +import * as q from 'q' +import * as plugins from './cert.plugins' +import * as paths from './cert.paths' +import * as helpers from './cert.classes.cert.helpers' export interface ICertConstructorOptions { cfEmail: string, @@ -8,27 +9,27 @@ export interface ICertConstructorOptions { sslDir?: string, gitOriginRepo?: string, testMode?: boolean -}; +} export class Cert { - private _cfEmail: string; - private _cfKey: string; - private _sslDir: string; - private _gitOriginRepo: string; - private _testMode: boolean; - domainCertRequestMap: plugins.lik.Stringmap = new plugins.lik.Stringmap(); - certificatesPresent: Certificate[]; - certificatesValid: Certificate[]; + 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 /** * 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; + 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, @@ -36,129 +37,111 @@ export class Cert { } plugins.smartfile.memory.toFsSync( JSON.stringify(config), - plugins.path.join(__dirname, "assets/config.json") - ); + plugins.path.join(__dirname, 'assets/config.json') + ) // setup sslDir - if (!this._sslDir) this._sslDir = paths.defaultSslDir; + 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(); + 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 - }); - }; + } /** * Pulls already requested certificates from git origin */ sslGitOriginPull = () => { if (this._gitOriginRepo) { - plugins.smartgit.pull(this._sslDir, "origin", "master"); + 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"); + 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 }) { - let done = plugins.q.defer(); - let domainStringData = new plugins.smartstring.Domain(domainNameArg); - let sameZoneRequesting: boolean = this.domainCertRequestMap.checkMinimatch("*" + domainStringData.zoneName) + 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); + 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}`); + 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 (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(); + 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(); + 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); + plugins.beautylog.warn(`${domainNameArg} scheduled for retry. Waiting 1 minute!`) + helpers.scheduleRetry(domainNameArg, this).then(done.resolve) } - this.domainCertRequestMap.removeString(domainNameArg); + this.domainCertRequestMap.removeString(domainNameArg) } - ); + ) } else { - plugins.beautylog.info(`${domainNameArg} is waiting for domains names of same zone to finish`); - this.domainCertRequestMap.removeString(domainNameArg); + 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); + return !this.domainCertRequestMap.checkMinimatch('*' + domainStringData.zoneName) }, () => { - this.getDomainCert(domainNameArg).then(done.resolve); + 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(); - }; + plugins.beautylog.info('certificate for ' + domainNameArg + ' is still valid! Not fetching new one!') + this.domainCertRequestMap.removeString(domainNameArg) + done.resolve() + } } else { - plugins.beautylog.warn(`${domainNameArg} is already requesting`); - }; + plugins.beautylog.warn(`${domainNameArg} is already requesting`) + } - return done.promise; - }; + return done.promise + } cleanOldCertificates() { - }; + } } export class Certificate { - domainName: string; - creationDate: Date; - expiryDate: Date; + domainName: string + creationDate: Date + expiryDate: Date constructor() { - }; -}; + } +} diff --git a/ts/cert.hook.ts b/ts/cert.hook.ts index a85503d..9c9495c 100644 --- a/ts/cert.hook.ts +++ b/ts/cert.hook.ts @@ -1,6 +1,3 @@ -#!/usr/bin/env node -// the shebang line above makes sure this script will get interpreted by node - import * as plugins from "./cert.plugins"; import * as paths from "./cert.paths"; diff --git a/ts/cert.plugins.ts b/ts/cert.plugins.ts index 782dd0c..1537296 100644 --- a/ts/cert.plugins.ts +++ b/ts/cert.plugins.ts @@ -1,13 +1,28 @@ -import "typings-global"; -export import beautylog = require("beautylog"); -export import cflare = require("cflare"); -export let fs = require("fs-extra"); -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' +let fs = require('fs-extra') +let letsencrypt = require('letsencrypt') +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, + letsencrypt, + lik, + path, + q, + shelljs, + smartcli, + smartfile, + smartgit, + smartstring +} diff --git a/ts/install.ts b/ts/install.ts deleted file mode 100644 index a06ca40..0000000 --- a/ts/install.ts +++ /dev/null @@ -1,23 +0,0 @@ -import * as plugins from "./cert.plugins"; -import * as paths from "./cert.paths"; - -export let 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(startInstall); -smartcli.startParse(); \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..45052ad --- /dev/null +++ b/tslint.json @@ -0,0 +1,3 @@ +{ + "extends": "tslint-config-standard" +}