28 Commits

Author SHA1 Message Date
adcf49d729 1.0.2 2016-07-22 03:28:33 +02:00
22d79491ce testing 2016-07-22 03:28:30 +02:00
1b23d1e435 1.0.1 2016-07-22 02:59:33 +02:00
1c2063ef82 now retrying 2016-07-22 02:59:11 +02:00
d48a6c8315 1.0.0 2016-07-22 02:13:23 +02:00
1185480b91 0.0.18 2016-07-22 02:12:58 +02:00
afddfe5217 improve README 2016-07-22 02:12:49 +02:00
159ffe0728 now requesting in parallel 2016-07-22 02:11:04 +02:00
3c3da30966 update README 2016-07-21 15:02:51 +02:00
d4b249a59b update 2016-07-21 14:58:05 +02:00
06256f7a4d 0.0.17 2016-07-13 16:06:27 +02:00
be6fc3adfd cleanup after oneself 2016-07-13 16:06:16 +02:00
5ccf5b81e2 0.0.16 2016-07-13 12:09:41 +02:00
d06a2cee2f update sslDir handling 2016-07-13 12:09:34 +02:00
a7525184ef 0.0.15 2016-07-12 18:00:15 +02:00
ae9865749a use interface for Cert constructor 2016-07-12 18:00:08 +02:00
b2482b3cfd 0.0.14 2016-07-12 16:36:34 +02:00
41988da3ed fix types 2016-07-12 16:36:29 +02:00
55d450be69 0.0.13 2016-07-06 03:23:54 +02:00
ae2ade8680 updated test 2016-07-06 03:23:51 +02:00
d7ec7e254e 0.0.12 2016-07-06 03:10:49 +02:00
4bd7aee8ea add typings to package.json 2016-07-06 03:10:36 +02:00
bf711c2bb6 update tests 2016-07-04 21:57:14 +02:00
eb9e6679c4 0.0.11 2016-07-04 09:00:31 +02:00
96c801cdbd now fully working 2016-07-04 08:41:58 +02:00
ee844fd348 implement Git Repo Sync 2016-07-04 04:56:49 +02:00
d06c7059bb update dependency typings 2016-07-01 06:26:10 +02:00
d36f2f0c33 update for latest npmts compatibility 2016-07-01 06:18:48 +02:00
21 changed files with 498 additions and 174 deletions

View File

@ -1,6 +1,9 @@
# Cert
Easily obain SSL certificates from LetsEncrypt. Supports DNS-01 challenge. TypeScript ready.
## Status
[![build status](https://gitlab.com/pushrocks/cert/badges/master/build.svg)](https://gitlab.com/pushrocks/cert/commits/master)
## Usage
```typescript
@ -13,13 +16,15 @@ let myCert = new Cert({
gitOriginRepo: "git@githhub.com/someuser/somereopo" // good for persistence in highly volatile environments like docker
});
myCert.getDomainCert("example.com");
myCert.getDomainCert("example.com"); // returns promise
```
### sslDir
> **Note:** cert supports async parallel cert fetching. If called twice for the same domain, only the first one will trigger.
## sslDir
to use the certificates it is important to understand what the structure of the ssl directory looks like.
### using a git origin repo.
## using a git origin repo.
Often times you want to keep track of certificates in order to keep them
even if the point of initial certificate request is gone. Imagine you have a dockerenvironement
and you keep starting new container versions for the same domain. YOu ideally want to use a proxy
@ -27,3 +32,8 @@ that handles SSL managemet for you. But even the proxy needs to be updated from
So you need some kind of persistence between versions. This is why you can sync up all certificates to a git repo over ssh
Just make sure your id_rsa is in place for the node user and is allowed for the origin repo.
## Environment
Since cert relies on [letsencrypt.sh](https://github.com/lukas2511/letsencrypt.sh) in the background bash is needed on the system.
If you plan on using this on Windows check out [npmdocker](https://www.npmjs.com/package/npmdocker) which runs node programs in docker.
As of summer 2016 Windows will also ship with bash nativly included.

5
dist/cert.helpers.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
/// <reference types="q" />
import { Cert } from "./index.ts";
import * as plugins from "./cert.plugins";
export declare let accountsKeyPresent: () => plugins.q.Promise<{}>;
export declare let scheduleRetry: (domainArg: string, certClassArg: Cert) => plugins.q.Promise<{}>;

25
dist/cert.helpers.js vendored Normal file
View File

@ -0,0 +1,25 @@
"use strict";
const plugins = require("./cert.plugins");
let firstCall = true;
let enoughTime = false;
exports.accountsKeyPresent = () => {
let done = plugins.q.defer();
if (firstCall) {
done.resolve();
firstCall = false;
}
else {
setTimeout(done.resolve, 5000);
}
;
return done.promise;
};
exports.scheduleRetry = (domainArg, certClassArg) => {
let done = plugins.q.defer();
setTimeout(() => {
certClassArg.getDomainCert(domainArg)
.then(done.resolve);
}, 20000);
return done.promise;
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5oZWxwZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5oZWxwZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFDQSxNQUFZLE9BQU8sV0FBTSxnQkFBZ0IsQ0FBQyxDQUFBO0FBRzFDLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQztBQUNyQixJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUM7QUFDWiwwQkFBa0IsR0FBRztJQUM1QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzdCLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7UUFDWixJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDZixTQUFTLEdBQUcsS0FBSyxDQUFDO0lBQ3RCLENBQUM7SUFBRSxJQUFJLENBQUMsQ0FBQztRQUNMLFVBQVUsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFBQSxDQUFDO0lBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7QUFDeEIsQ0FBQyxDQUFDO0FBRVMscUJBQWEsR0FBRyxDQUFDLFNBQWdCLEVBQUMsWUFBaUI7SUFDMUQsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUM3QixVQUFVLENBQUM7UUFDUCxZQUFZLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQzthQUNoQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzVCLENBQUMsRUFBQyxLQUFLLENBQUMsQ0FBQztJQUNULE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDO0FBQ3hCLENBQUMsQ0FBQyJ9

1
dist/cert.hook.d.ts vendored
View File

@ -1 +0,0 @@
import "typings-global";

44
dist/cert.hook.js vendored Executable file → Normal file

File diff suppressed because one or more lines are too long

View File

@ -1,5 +1,8 @@
import "typings-global";
export declare let certDir: string;
export declare let defaultSslDir: 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 certDir: string;

14
dist/cert.paths.js vendored
View File

@ -1,9 +1,13 @@
"use strict";
require("typings-global");
var plugins = require("./cert.plugins");
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");
exports.certDir = plugins.path.join(__dirname, "/assets/certs");
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sZ0JBQWdCLENBQUMsQ0FBQTtBQUN4QixJQUFZLE9BQU8sV0FBTSxnQkFBZ0IsQ0FBQyxDQUFBO0FBRS9CLGdCQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3ZELGNBQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsb0JBQW9CLENBQUMsQ0FBQztBQUMzRCxxQkFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyx1QkFBdUIsQ0FBQyxDQUFDO0FBQ3JFLGVBQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsZUFBZSxDQUFDLENBQUMiLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBcInR5cGluZ3MtZ2xvYmFsXCI7XG5pbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gXCIuL2NlcnQucGx1Z2luc1wiO1xuXG5leHBvcnQgbGV0IGNlcnRIb29rID0gcGx1Z2lucy5wYXRoLmpvaW4oX19kaXJuYW1lLFwiY2VydC5ob29rLmpzXCIpO1xuZXhwb3J0IGxldCBjb25maWcgPSBwbHVnaW5zLnBhdGguam9pbihfX2Rpcm5hbWUsXCJhc3NldHMvY29uZmlnLmpzb25cIik7XG5leHBvcnQgbGV0IGxldHNlbmNyeXB0U2ggPSBwbHVnaW5zLnBhdGguam9pbihfX2Rpcm5hbWUsXCJhc3NldHMvbGV0c2VuY3J5cHQuc2hcIik7XG5leHBvcnQgbGV0IGNlcnREaXIgPSBwbHVnaW5zLnBhdGguam9pbihfX2Rpcm5hbWUsXCIvYXNzZXRzL2NlcnRzXCIpOyJdfQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE1BQVksT0FBTyxXQUFNLGdCQUFnQixDQUFDLENBQUE7QUFFMUMsTUFBTTtBQUNLLGVBQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsY0FBYyxDQUFDLENBQUM7QUFDdEQscUJBQWEsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsc0JBQXNCLENBQUMsQ0FBQztBQUNwRSxnQkFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxTQUFTLENBQUMsQ0FBQztBQUNsRCxtQkFBVyxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxrQkFBa0IsQ0FBQyxDQUFDO0FBRXpFLFFBQVE7QUFDRyxnQkFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxjQUFjLENBQUMsQ0FBQztBQUN2RCxjQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLG9CQUFvQixDQUFDLENBQUM7QUFDM0Qsa0JBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsd0JBQXdCLENBQUMsQ0FBQztBQUNuRSxxQkFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyx1QkFBdUIsQ0FBQyxDQUFDIn0=

View File

@ -2,9 +2,10 @@ 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 declare let q: any;
export declare let shelljs: any;
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");

View File

@ -3,6 +3,7 @@ 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");
@ -10,5 +11,4 @@ exports.smartcli = require("smartcli");
exports.smartfile = require("smartfile");
exports.smartgit = require("smartgit");
exports.smartstring = require("smartstring");
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNlcnQucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsUUFBTyxnQkFBZ0IsQ0FBQyxDQUFBO0FBQ1YsaUJBQVMsV0FBVyxXQUFXLENBQUMsQ0FBQztBQUNqQyxjQUFNLFdBQVcsUUFBUSxDQUFDLENBQUM7QUFDOUIsVUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUN0QixZQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFDMUIsU0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixlQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzFCLGdCQUFRLFdBQVcsVUFBVSxDQUFDLENBQUM7QUFDL0IsaUJBQVMsV0FBVyxXQUFXLENBQUMsQ0FBQztBQUNqQyxnQkFBUSxXQUFXLFVBQVUsQ0FBQyxDQUFDO0FBQy9CLG1CQUFXLFdBQVcsYUFBYSxDQUFDLENBQUMiLCJmaWxlIjoiY2VydC5wbHVnaW5zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIjtcbmV4cG9ydCBpbXBvcnQgYmVhdXR5bG9nID0gcmVxdWlyZShcImJlYXV0eWxvZ1wiKTtcbmV4cG9ydCBpbXBvcnQgY2ZsYXJlID0gcmVxdWlyZShcImNmbGFyZVwiKTtcbmV4cG9ydCBsZXQgZnMgPSByZXF1aXJlKFwiZnMtZXh0cmFcIik7XG5leHBvcnQgaW1wb3J0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcbmV4cG9ydCBsZXQgcSA9IHJlcXVpcmUoXCJxXCIpO1xuZXhwb3J0IGxldCBzaGVsbGpzID0gcmVxdWlyZShcInNoZWxsanNcIik7XG5leHBvcnQgaW1wb3J0IHNtYXJ0Y2xpID0gcmVxdWlyZShcInNtYXJ0Y2xpXCIpO1xuZXhwb3J0IGltcG9ydCBzbWFydGZpbGUgPSByZXF1aXJlKFwic21hcnRmaWxlXCIpO1xuZXhwb3J0IGltcG9ydCBzbWFydGdpdCA9IHJlcXVpcmUoXCJzbWFydGdpdFwiKTtcbmV4cG9ydCBpbXBvcnQgc21hcnRzdHJpbmcgPSByZXF1aXJlKFwic21hcnRzdHJpbmdcIik7XG5cbiJdfQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxRQUFPLGdCQUFnQixDQUFDLENBQUE7QUFDVixpQkFBUyxXQUFXLFdBQVcsQ0FBQyxDQUFDO0FBQ2pDLGNBQU0sV0FBVyxRQUFRLENBQUMsQ0FBQztBQUM5QixVQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0FBQ3RCLFdBQUcsV0FBVyxLQUFLLENBQUMsQ0FBQztBQUNyQixZQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFDdkIsU0FBQyxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBQ2pCLGVBQU8sV0FBVyxTQUFTLENBQUMsQ0FBQztBQUM3QixnQkFBUSxXQUFXLFVBQVUsQ0FBQyxDQUFDO0FBQy9CLGlCQUFTLFdBQVcsV0FBVyxDQUFDLENBQUM7QUFDakMsZ0JBQVEsV0FBVyxVQUFVLENBQUMsQ0FBQztBQUMvQixtQkFBVyxXQUFXLGFBQWEsQ0FBQyxDQUFDIn0=

37
dist/index.d.ts vendored
View File

@ -1,19 +1,40 @@
/// <reference types="q" />
import * as plugins from "./cert.plugins";
export interface ICertConstructorOptions {
cfEmail: string;
cfKey: string;
sslDir?: string;
gitOriginRepo?: string;
testMode?: boolean;
}
export declare class Cert {
private _cfEmail;
private _cfKey;
private _sslDir;
private _gitOriginRepo;
private _testMode;
domainsCurrentlyRequesting: plugins.lik.Stringmap;
certificatesPresent: Certificate[];
certificatesValid: Certificate[];
gitOriginRepo: any;
constructor(optionsArg: {
cfEmail: string;
cfKey: string;
sslDir: string;
gitOriginRepo?: string;
});
/**
* Constructor for Cert object
*/
constructor(optionsArg: ICertConstructorOptions);
/**
* Pulls already requested certificates from git origin
*/
sslGitOriginPull: () => void;
/**
* Pushes all new requested certificates to git origin
*/
sslGitOriginAddCommitPush: () => void;
/**
* gets a ssl cert for a given domain
*/
getDomainCert(domainNameArg: string, optionsArg?: {
force: boolean;
}): any;
}): plugins.q.Promise<{}>;
cleanOldCertificates(): void;
}
export declare class Certificate {
domainName: string;

150
dist/index.js vendored

File diff suppressed because one or more lines are too long

4
dist/install.d.ts vendored
View File

@ -1 +1,3 @@
export declare let startInstall: () => any;
/// <reference types="q" />
import * as plugins from "./cert.plugins";
export declare let startInstall: () => plugins.q.Promise<{}>;

15
dist/install.js vendored
View File

@ -1,20 +1,19 @@
"use strict";
var plugins = require("./cert.plugins");
var paths = require("./cert.paths");
exports.startInstall = function () {
var done = plugins.q.defer();
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(function () {
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;
};
var smartcli = new plugins.smartcli.Smartcli();
let smartcli = new plugins.smartcli.Smartcli();
smartcli.addCommand({
commandName: "install"
}).then(exports.startInstall);
smartcli.startParse();
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluc3RhbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLElBQVksT0FBTyxXQUFNLGdCQUFnQixDQUFDLENBQUE7QUFDMUMsSUFBWSxLQUFLLFdBQU0sY0FBYyxDQUFDLENBQUE7QUFFM0Isb0JBQVksR0FBRztJQUN0QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzdCLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFFL0QsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDOUQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixrRkFBa0YsRUFDbEYsS0FBSyxDQUFDLGFBQWEsQ0FDdEIsQ0FBQyxJQUFJLENBQUM7UUFDSCxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUN4QixDQUFDLENBQUM7QUFFRixJQUFJLFFBQVEsR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDL0MsUUFBUSxDQUFDLFVBQVUsQ0FBQztJQUNoQixXQUFXLEVBQUMsU0FBUztDQUN4QixDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFZLENBQUMsQ0FBQztBQUN0QixRQUFRLENBQUMsVUFBVSxFQUFFLENBQUMiLCJmaWxlIjoiaW5zdGFsbC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSBcIi4vY2VydC5wbHVnaW5zXCI7XG5pbXBvcnQgKiBhcyBwYXRocyBmcm9tIFwiLi9jZXJ0LnBhdGhzXCI7XG5cbmV4cG9ydCBsZXQgc3RhcnRJbnN0YWxsID0gKCkgPT4ge1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgcGx1Z2lucy5iZWF1dHlsb2cuaW5mbyhcImluc3RhbGxpbmcgbGV0c2VuY3J5cHQuc2ggbG9jYWxseS4uLlwiKTtcblxuICAgIHBsdWdpbnMuZnMuZW5zdXJlRGlyKHBsdWdpbnMucGF0aC5qb2luKF9fZGlybmFtZSwgXCJhc3NldHMvXCIpKTtcbiAgICBwbHVnaW5zLnNtYXJ0ZmlsZS5yZW1vdGUudG9GcyhcbiAgICAgICAgXCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbHVrYXMyNTExL2xldHNlbmNyeXB0LnNoL21hc3Rlci9sZXRzZW5jcnlwdC5zaFwiLFxuICAgICAgICBwYXRocy5sZXRzZW5jcnlwdFNoXG4gICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgcGx1Z2lucy5iZWF1dHlsb2cuc3VjY2VzcyhcIkRvbmUhXCIpO1xuICAgICAgICBkb25lLnJlc29sdmUoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufTtcblxubGV0IHNtYXJ0Y2xpID0gbmV3IHBsdWdpbnMuc21hcnRjbGkuU21hcnRjbGkoKTtcbnNtYXJ0Y2xpLmFkZENvbW1hbmQoe1xuICAgIGNvbW1hbmROYW1lOlwiaW5zdGFsbFwiXG59KS50aGVuKHN0YXJ0SW5zdGFsbCk7XG5zbWFydGNsaS5zdGFydFBhcnNlKCk7Il19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5zdGFsbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2luc3RhbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE1BQVksT0FBTyxXQUFNLGdCQUFnQixDQUFDLENBQUE7QUFDMUMsTUFBWSxLQUFLLFdBQU0sY0FBYyxDQUFDLENBQUE7QUFFM0Isb0JBQVksR0FBRztJQUN0QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzdCLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFFL0QsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDOUQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixrRkFBa0YsRUFDbEYsS0FBSyxDQUFDLGFBQWEsQ0FDdEIsQ0FBQyxJQUFJLENBQUM7UUFDSCxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUN4QixDQUFDLENBQUM7QUFFRixJQUFJLFFBQVEsR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDL0MsUUFBUSxDQUFDLFVBQVUsQ0FBQztJQUNoQixXQUFXLEVBQUMsU0FBUztDQUN4QixDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFZLENBQUMsQ0FBQztBQUN0QixRQUFRLENBQUMsVUFBVSxFQUFFLENBQUMifQ==

View File

@ -1,11 +1,14 @@
{
"name": "cert",
"version": "0.0.10",
"version": "1.0.2",
"description": "Easily obain SSL certificates from LetsEncrypt. Supports DNS-01 challenge. TypeScript ready.",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"scripts": {
"test": "(npmts)",
"install": "node dist/install.js install"
"test": "(npm run cleanTest && npmts)",
"cleanTest": "(rm -rf ./test/assets)",
"install": "node dist/install.js install",
"compile": "(npmts --notest)"
},
"repository": {
"type": "git",
@ -24,21 +27,25 @@
},
"homepage": "https://gitlab.com/pushrocks/cert#readme",
"dependencies": {
"beautylog": "^5.0.12",
"@types/minimatch": "^2.0.28",
"@types/q": "^0.0.27",
"@types/shelljs": "^0.3.27",
"beautylog": "^5.0.14",
"cflare": "0.0.9",
"fs-extra": "^0.30.0",
"lik": "^1.0.2",
"q": "^1.4.1",
"shelljs": "^0.7.0",
"smartcli": "^1.0.4",
"smartfile": "^4.0.8",
"smartgit": "0.1.0",
"smartstring": "^2.0.10",
"typings-global": "^1.0.3"
"smartfile": "^4.0.12",
"smartgit": "0.1.9",
"smartstring": "^2.0.15",
"typings-global": "^1.0.6"
},
"devDependencies": {
"npmts-g": "^5.2.6",
"qenv": "^1.0.8",
"should": "^9.0.2",
"should": "^10.0.0",
"typings-test": "^1.0.1"
}
}

View File

@ -1,37 +1,47 @@
"use strict";
require("typings-test");
require("should");
var qenv_1 = require("qenv");
var path = require("path");
var install_1 = require("../dist/install");
var cert = require("../dist/index");
var testQenv = new qenv_1.Qenv(process.cwd(), process.cwd() + "/.nogit");
var testCert;
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 testCert;
describe("cert", function () {
describe("install", function () {
it("should download letsencrypt.sh", function (done) {
this.timeout(5000);
install_1.startInstall().then(function () {
install_1.startInstall().then(() => {
done();
});
});
});
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")
sslDir: path.join(process.cwd(), "test/assets"),
gitOriginRepo: "git@gitlab.com:sandboxzone/sandbox-sslorigin.git",
testMode: true
});
testCert.should.be.instanceof(cert.Cert);
});
it("should get a valid certificate", function (done) {
this.timeout(120000);
testCert.getDomainCert("sub9.bleu.de").then(function () {
this.timeout(400000);
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`));
q.all(promiseArray).then(() => {
done();
});
});
});
});
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sY0FBYyxDQUFDLENBQUE7QUFDdEIsUUFBTyxRQUFRLENBQUMsQ0FBQTtBQUNoQixxQkFBbUIsTUFBTSxDQUFDLENBQUE7QUFDMUIsSUFBTyxJQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFFOUIsd0JBQTJCLGlCQUFpQixDQUFDLENBQUE7QUFDN0MsSUFBWSxJQUFJLFdBQU0sZUFBZSxDQUFDLENBQUE7QUFHdEMsSUFBSSxRQUFRLEdBQUcsSUFBSSxXQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQztBQUVsRSxJQUFJLFFBQWtCLENBQUM7QUFFdkIsUUFBUSxDQUFDLE1BQU0sRUFBQztJQUNaLFFBQVEsQ0FBQyxTQUFTLEVBQUM7UUFDZixFQUFFLENBQUMsZ0NBQWdDLEVBQUMsVUFBUyxJQUFJO1lBQzdDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkIsc0JBQVksRUFBRSxDQUFDLElBQUksQ0FBQztnQkFDaEIsSUFBSSxFQUFFLENBQUM7WUFDWCxDQUFDLENBQUMsQ0FBQTtRQUNOLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFDRixRQUFRLENBQUMsTUFBTSxFQUFDO1FBQ1osRUFBRSxDQUFDLDRDQUE0QyxFQUFDO1lBQzVDLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVE7Z0JBQzdCLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU07Z0JBQ3pCLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBQyxhQUFhLENBQUM7YUFDakQsQ0FBQyxDQUFDO1lBQ0gsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQTtRQUNGLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBQyxVQUFTLElBQUk7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyQixRQUFRLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDeEMsSUFBSSxFQUFFLENBQUM7WUFDWCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy10ZXN0XCI7XG5pbXBvcnQgXCJzaG91bGRcIjtcbmltcG9ydCB7UWVudn0gZnJvbSBcInFlbnZcIjtcbmltcG9ydCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XG5cbmltcG9ydCB7c3RhcnRJbnN0YWxsfSBmcm9tIFwiLi4vZGlzdC9pbnN0YWxsXCI7XG5pbXBvcnQgKiBhcyBjZXJ0IGZyb20gXCIuLi9kaXN0L2luZGV4XCI7XG5cblxubGV0IHRlc3RRZW52ID0gbmV3IFFlbnYocHJvY2Vzcy5jd2QoKSwgcHJvY2Vzcy5jd2QoKSArIFwiLy5ub2dpdFwiKTtcblxubGV0IHRlc3RDZXJ0OmNlcnQuQ2VydDtcblxuZGVzY3JpYmUoXCJjZXJ0XCIsZnVuY3Rpb24oKXtcbiAgICBkZXNjcmliZShcImluc3RhbGxcIixmdW5jdGlvbigpe1xuICAgICAgICBpdChcInNob3VsZCBkb3dubG9hZCBsZXRzZW5jcnlwdC5zaFwiLGZ1bmN0aW9uKGRvbmUpe1xuICAgICAgICAgICAgdGhpcy50aW1lb3V0KDUwMDApO1xuICAgICAgICAgICAgc3RhcnRJbnN0YWxsKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICB9KVxuICAgIGRlc2NyaWJlKFwiQ2VydFwiLGZ1bmN0aW9uKCl7XG4gICAgICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBhIG5ldyBDZXJ0IG9iamVjdCBmcm9tIGNsYXNzXCIsZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHRlc3RDZXJ0ID0gbmV3IGNlcnQuQ2VydCh7XG4gICAgICAgICAgICAgICAgY2ZFbWFpbDogcHJvY2Vzcy5lbnYuQ0ZfRU1BSUwsXG4gICAgICAgICAgICAgICAgY2ZLZXk6IHByb2Nlc3MuZW52LkNGX0tFWSxcbiAgICAgICAgICAgICAgICBzc2xEaXI6IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLFwidGVzdC9hc3NldHNcIilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGVzdENlcnQuc2hvdWxkLmJlLmluc3RhbmNlb2YoY2VydC5DZXJ0KTtcbiAgICAgICAgfSlcbiAgICAgICAgaXQoXCJzaG91bGQgZ2V0IGEgdmFsaWQgY2VydGlmaWNhdGVcIixmdW5jdGlvbihkb25lKXtcbiAgICAgICAgICAgIHRoaXMudGltZW91dCgxMjAwMDApO1xuICAgICAgICAgICAgdGVzdENlcnQuZ2V0RG9tYWluQ2VydChcInN1YjkuYmxldS5kZVwiKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICB9KVxufSk7Il19
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sY0FBYyxDQUFDLENBQUE7QUFDdEIsUUFBTyxRQUFRLENBQUMsQ0FBQTtBQUNoQix1QkFBbUIsTUFBTSxDQUFDLENBQUE7QUFDMUIsTUFBTyxJQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFDOUIsTUFBTyxDQUFDLFdBQVcsR0FBRyxDQUFDLENBQUM7QUFDeEIsMEJBQTJCLGlCQUFpQixDQUFDLENBQUE7QUFDN0MsTUFBWSxJQUFJLFdBQU0sZUFBZSxDQUFDLENBQUE7QUFHdEMsSUFBSSxRQUFRLEdBQUcsSUFBSSxXQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQztBQUVsRSxJQUFJLFFBQWtCLENBQUM7QUFFdkIsUUFBUSxDQUFDLE1BQU0sRUFBQztJQUNaLFFBQVEsQ0FBQyxTQUFTLEVBQUM7UUFDZixFQUFFLENBQUMsZ0NBQWdDLEVBQUMsVUFBUyxJQUFJO1lBQzdDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkIsc0JBQVksRUFBRSxDQUFDLElBQUksQ0FBQztnQkFDaEIsSUFBSSxFQUFFLENBQUM7WUFDWCxDQUFDLENBQUMsQ0FBQTtRQUNOLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFDRixRQUFRLENBQUMsTUFBTSxFQUFDO1FBQ1osRUFBRSxDQUFDLDRDQUE0QyxFQUFDO1lBQzVDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDcEIsUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDckIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUTtnQkFDN0IsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTTtnQkFDekIsTUFBTSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFDLGFBQWEsQ0FBQztnQkFDOUMsYUFBYSxFQUFDLGtEQUFrRDtnQkFDaEUsUUFBUSxFQUFDLElBQUk7YUFDaEIsQ0FBQyxDQUFDO1lBQ0gsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQTtRQUNGLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBQyxVQUFTLElBQUk7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyQixJQUFJLFlBQVksR0FBRyxFQUFFLENBQUM7WUFDdEIsNEJBQTRCLEdBQUcsRUFBRSxHQUFHO2dCQUNoQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7WUFDekQsQ0FBQztZQUNELFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxVQUFVLGtCQUFrQixDQUFDLENBQUMsRUFBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM1RixZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxrQkFBa0IsQ0FBQyxDQUFDLEVBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDNUYsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFVBQVUsa0JBQWtCLENBQUMsQ0FBQyxFQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzVGLENBQUMsQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsSUFBSSxDQUFDO2dCQUNyQixJQUFJLEVBQUUsQ0FBQztZQUNYLENBQUMsQ0FBQyxDQUFDO1FBQ1AsQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtBQUNOLENBQUMsQ0FBQyxDQUFDIn0=

View File

@ -2,7 +2,7 @@ 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";
@ -22,16 +22,26 @@ 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")
sslDir: path.join(process.cwd(),"test/assets"),
gitOriginRepo:"git@gitlab.com:sandboxzone/sandbox-sslorigin.git",
testMode:true
});
testCert.should.be.instanceof(cert.Cert);
})
it("should get a valid certificate",function(done){
this.timeout(120000);
testCert.getDomainCert("sub9.bleu.de").then(() => {
this.timeout(400000);
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`));
q.all(promiseArray).then(() => {
done();
});
})

25
ts/cert.helpers.ts Normal file
View File

@ -0,0 +1,25 @@
import {Cert} from "./index.ts";
import * as plugins from "./cert.plugins";
import * as paths from "./cert.paths";
let firstCall = true;
let enoughTime = false;
export let accountsKeyPresent = () => {
let done = plugins.q.defer();
if (firstCall) {
done.resolve();
firstCall = false;
}  else {
setTimeout(done.resolve,5000);
};
return done.promise;
};
export let scheduleRetry = (domainArg:string,certClassArg:Cert) => {
let done = plugins.q.defer();
setTimeout(() => {
certClassArg.getDomainCert(domainArg)
.then(done.resolve);
},20000);
return done.promise;
};

View File

@ -1,7 +1,6 @@
#!/usr/bin/env node
// the shebang line above makes sure this script will get interpreted by node
import "typings-global";
import * as plugins from "./cert.plugins";
import * as paths from "./cert.paths";
@ -36,7 +35,7 @@ let cleanChallenge = (domainNameArg) => {
let cooldown = () => {
let done = plugins.q.defer();
let cooldowntime = 40000;
let cooldowntime = 120000;
let passedTime = 0;
plugins.beautylog.log("Cooling down! " + (cooldowntime/1000).toString() + " seconds left");
let coolDownCounter = () => {

View File

@ -1,7 +1,14 @@
import "typings-global";
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");
export let certDir = plugins.path.join(__dirname,"/assets/certs");

View File

@ -2,9 +2,10 @@ 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 let q = require("q");
export let shelljs = require("shelljs");
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");

View File

@ -1,46 +1,135 @@
import * as plugins from "./cert.plugins";
import * as paths from "./cert.paths";
import * as helpers from "./cert.helpers"
export interface ICertConstructorOptions {
cfEmail: string,
cfKey: string,
sslDir?: string,
gitOriginRepo?: string,
testMode?: boolean
};
export class Cert {
private _cfEmail: string;
private _cfKey: string;
private _sslDir: string;
private _gitOriginRepo: string;
private _testMode: boolean;
domainsCurrentlyRequesting: plugins.lik.Stringmap = new plugins.lik.Stringmap();
certificatesPresent: Certificate[];
certificatesValid: Certificate[];
gitOriginRepo;
constructor(optionsArg: {
cfEmail: string,
cfKey: string,
sslDir: string,
gitOriginRepo?: string
}) {
/**
* Constructor for Cert object
*/
constructor(optionsArg: ICertConstructorOptions) {
this._cfEmail = optionsArg.cfEmail;
this._cfKey = optionsArg.cfKey;
this._sslDir = optionsArg.sslDir;
this.gitOriginRepo = optionsArg.gitOriginRepo;
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"));
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 = " ";
};
getDomainCert(domainNameArg: string,optionsArg?:{force:boolean}) {
let done = plugins.q.defer();
if (!checkDomainsStillValid(domainNameArg) || optionsArg.force) {
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 -d " + domainNameArg + " -t dns-01 -k " + paths.certHook + " -o " + paths.certDir + "\"");
};
/**
* Pulls already requested certificates from git origin
*/
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 }) {
let done = plugins.q.defer();
// make sure no one else requires the same domain at the same time
helpers.accountsKeyPresent().then(() => {
if (!this.domainsCurrentlyRequesting.checkString(domainNameArg)) {
this.domainsCurrentlyRequesting.addString(domainNameArg);
if (!checkDomainsStillValid(domainNameArg, this._sslDir) || optionsArg.force) {
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) {
updateSslDirSync(this._sslDir, domainNameArg);
plugins.smartfile.fs.removeSync(plugins.path.join(paths.certDir, domainNameArg));
}
this.domainsCurrentlyRequesting.removeString(domainNameArg);
done.resolve();
} else {
plugins.beautylog.info("certificate for " + domainNameArg + " is still valid! Not fetching new one!");
done.resolve();
this.domainsCurrentlyRequesting.removeString(domainNameArg);
plugins.beautylog.warn(`${domainNameArg} scheduled for retry`);
helpers.scheduleRetry(domainNameArg,this).then(done.resolve);
}
}
);
} else {
plugins.beautylog.info("certificate for " + domainNameArg + " is still valid! Not fetching new one!");
this.domainsCurrentlyRequesting.removeString(domainNameArg);
done.resolve();
};
} else {
plugins.beautylog.warn(`${domainNameArg} is already requesting`);
};
});
return done.promise;
};
cleanOldCertificates() {
};
}
export class Certificate {
@ -58,8 +147,22 @@ interface certConfig {
expires: number;
}
let checkDomainsStillValid = (domainNameArg: string): boolean => {
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;
}
}
let updateSslDirSync = (sslDirArg: string, domainNameArg: string) => {
@ -83,13 +186,20 @@ let updateSslDirSync = (sslDirArg:string,domainNameArg:string) => {
created: certTime,
expires: certTime + 7776000
};
plugins.smartfile.memory.toFs(
plugins.smartfile.memory.toFsSync(
JSON.stringify(certConfig),
plugins.path.join(sslDirArg, domainNameArg, "config.json")
);
};
}
let updateGitOrigin = () => {
const enum gitSyncDirection {
toOrigin,
fromOrigin
}
let updateGitOrigin = (syncDirectionArg: gitSyncDirection) => {
};
updateGitOrigin(gitSyncDirection.toOrigin);