fix
This commit is contained in:
parent
4094834446
commit
b03d8bfb65
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,5 +1,7 @@
|
|||||||
node_modules
|
node_modules
|
||||||
docs/
|
docs/
|
||||||
|
public/
|
||||||
|
pages/
|
||||||
coverage/
|
coverage/
|
||||||
.nogit/
|
.nogit/
|
||||||
dist/assets/
|
dist/assets/
|
||||||
|
49
dist/cert.classes.cert.d.ts
vendored
49
dist/cert.classes.cert.d.ts
vendored
@ -1,44 +1,37 @@
|
|||||||
/// <reference types="q" />
|
/// <reference types="q" />
|
||||||
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 {
|
export interface ICertConstructorOptions {
|
||||||
cfEmail: string;
|
cfEmail: string;
|
||||||
cfKey: string;
|
cfKey: string;
|
||||||
sslDir?: string;
|
sslDirPath?: string;
|
||||||
gitOriginRepo?: string;
|
gitOriginRepo?: string;
|
||||||
testMode?: boolean;
|
leEnv?: TLeEnv;
|
||||||
}
|
}
|
||||||
export declare class Cert {
|
export declare class Cert {
|
||||||
private _cfEmail;
|
domainStringRequestMap: Stringmap;
|
||||||
private _cfKey;
|
certificateMap: Objectmap<Certificate>;
|
||||||
private _sslDir;
|
letsencrypt: Letsencrypt;
|
||||||
private _gitOriginRepo;
|
private _challengeHandler;
|
||||||
private _testMode;
|
private _certRepo;
|
||||||
domainCertRequestMap: plugins.lik.Stringmap;
|
|
||||||
certificatesPresent: Certificate[];
|
|
||||||
certificatesValid: Certificate[];
|
|
||||||
/**
|
/**
|
||||||
* Constructor for Cert object
|
* Constructor for Cert object
|
||||||
*/
|
*/
|
||||||
constructor(optionsArg: ICertConstructorOptions);
|
constructor(optionsArg: ICertConstructorOptions);
|
||||||
/**
|
/**
|
||||||
* Pulls already requested certificates from git origin
|
* adds a Certificate for a given domain
|
||||||
*/
|
*/
|
||||||
sslGitOriginPull: () => void;
|
addCertificate(domainNameArg: string, optionsArg?: {
|
||||||
/**
|
|
||||||
* Pushes all new requested certificates to git origin
|
|
||||||
*/
|
|
||||||
sslGitOriginAddCommitPush: () => void;
|
|
||||||
/**
|
|
||||||
* gets a ssl cert for a given domain
|
|
||||||
*/
|
|
||||||
getDomainCert(domainNameArg: string, optionsArg?: {
|
|
||||||
force: boolean;
|
force: boolean;
|
||||||
}): plugins.q.Promise<{}>;
|
}): q.Promise<{}>;
|
||||||
|
/**
|
||||||
|
* cleans up old certificates
|
||||||
|
*/
|
||||||
cleanOldCertificates(): void;
|
cleanOldCertificates(): void;
|
||||||
}
|
/**
|
||||||
export declare class Certificate {
|
* executes the current batch of jobs
|
||||||
domainName: string;
|
*/
|
||||||
creationDate: Date;
|
deploy(): void;
|
||||||
expiryDate: Date;
|
|
||||||
constructor();
|
|
||||||
}
|
}
|
||||||
|
19
dist/cert.classes.cert.helpers.d.ts
vendored
19
dist/cert.classes.cert.helpers.d.ts
vendored
@ -1,19 +0,0 @@
|
|||||||
/// <reference types="q" />
|
|
||||||
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;
|
|
59
dist/cert.classes.cert.helpers.js
vendored
59
dist/cert.classes.cert.helpers.js
vendored
@ -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=
|
|
169
dist/cert.classes.cert.js
vendored
169
dist/cert.classes.cert.js
vendored
File diff suppressed because one or more lines are too long
48
dist/cert.classes.certificate.d.ts
vendored
Normal file
48
dist/cert.classes.certificate.d.ts
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/// <reference types="q" />
|
||||||
|
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;
|
||||||
|
}
|
103
dist/cert.classes.certificate.js
vendored
Normal file
103
dist/cert.classes.certificate.js
vendored
Normal file
@ -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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
|
26
dist/cert.classes.certrepo.d.ts
vendored
Normal file
26
dist/cert.classes.certrepo.d.ts
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/// <reference types="q" />
|
||||||
|
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;
|
||||||
|
}
|
49
dist/cert.classes.certrepo.js
vendored
Normal file
49
dist/cert.classes.certrepo.js
vendored
Normal file
@ -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
|
20
dist/cert.classes.challengehandler.d.ts
vendored
Normal file
20
dist/cert.classes.challengehandler.d.ts
vendored
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/// <reference types="q" />
|
||||||
|
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<{}>;
|
||||||
|
}
|
75
dist/cert.classes.challengehandler.js
vendored
Normal file
75
dist/cert.classes.challengehandler.js
vendored
Normal file
@ -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
|
27
dist/cert.classes.letsencrypt.d.ts
vendored
Normal file
27
dist/cert.classes.letsencrypt.d.ts
vendored
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/// <reference types="q" />
|
||||||
|
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);
|
||||||
|
}
|
114
dist/cert.classes.letsencrypt.js
vendored
Normal file
114
dist/cert.classes.letsencrypt.js
vendored
Normal file
@ -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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
|
0
dist/cert.hook.d.ts
vendored
0
dist/cert.hook.d.ts
vendored
68
dist/cert.hook.js
vendored
68
dist/cert.hook.js
vendored
@ -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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
|
|
10
dist/cert.paths.d.ts
vendored
10
dist/cert.paths.d.ts
vendored
@ -1,8 +1,4 @@
|
|||||||
export declare let certDir: string;
|
export declare let projectDir: string;
|
||||||
export declare let defaultSslDir: string;
|
|
||||||
export declare let assetDir: string;
|
export declare let assetDir: string;
|
||||||
export declare let accountsDir: string;
|
export declare let defaultSslDir: string;
|
||||||
export declare let certHook: string;
|
export declare let leConfigDir: string;
|
||||||
export declare let config: string;
|
|
||||||
export declare let leShConfig: string;
|
|
||||||
export declare let letsencryptSh: string;
|
|
||||||
|
19
dist/cert.paths.js
vendored
19
dist/cert.paths.js
vendored
@ -1,13 +1,10 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
const plugins = require("./cert.plugins");
|
const plugins = require("./cert.plugins");
|
||||||
//dirs
|
// dirs
|
||||||
exports.certDir = plugins.path.join(__dirname, "assets/certs");
|
exports.projectDir = plugins.path.join(__dirname, '../');
|
||||||
exports.defaultSslDir = plugins.path.join(__dirname, "assets/defaultSslDir");
|
exports.assetDir = plugins.path.join(exports.projectDir, 'assets');
|
||||||
exports.assetDir = plugins.path.join(__dirname, "assets/");
|
exports.defaultSslDir = plugins.path.join(exports.assetDir, 'defaultSslDir');
|
||||||
exports.accountsDir = plugins.path.join(__dirname, "assets/accounts/");
|
exports.leConfigDir = plugins.path.join(exports.assetDir, 'letsencrypt');
|
||||||
// files
|
plugins.smartfile.fs.ensureDirSync(exports.leConfigDir);
|
||||||
exports.certHook = plugins.path.join(__dirname, "cert.hook.js");
|
plugins.smartfile.fs.ensureDirSync(exports.defaultSslDir);
|
||||||
exports.config = plugins.path.join(__dirname, "assets/config.json");
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBDQUF5QztBQUV6QyxPQUFPO0FBQ0ksUUFBQSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLEtBQUssQ0FBQyxDQUFBO0FBQy9DLFFBQUEsUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFVLEVBQUMsUUFBUSxDQUFDLENBQUE7QUFDakQsUUFBQSxhQUFhLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQVEsRUFBQyxlQUFlLENBQUMsQ0FBQTtBQUMzRCxRQUFBLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBUSxFQUFDLGFBQWEsQ0FBQyxDQUFBO0FBQ2xFLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxtQkFBVyxDQUFDLENBQUE7QUFDL0MsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLHFCQUFhLENBQUMsQ0FBQSJ9
|
||||||
exports.leShConfig = plugins.path.join(__dirname, "assets/leshconfig.json");
|
|
||||||
exports.letsencryptSh = plugins.path.join(__dirname, "assets/letsencrypt.sh");
|
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBDQUEwQztBQUUxQyxNQUFNO0FBQ0ssUUFBQSxPQUFPLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3RELFFBQUEsYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxzQkFBc0IsQ0FBQyxDQUFDO0FBQ3BFLFFBQUEsUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxTQUFTLENBQUMsQ0FBQztBQUNsRCxRQUFBLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsa0JBQWtCLENBQUMsQ0FBQztBQUV6RSxRQUFRO0FBQ0csUUFBQSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3ZELFFBQUEsTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyxvQkFBb0IsQ0FBQyxDQUFDO0FBQzNELFFBQUEsVUFBVSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyx3QkFBd0IsQ0FBQyxDQUFDO0FBQ25FLFFBQUEsYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyx1QkFBdUIsQ0FBQyxDQUFDIn0=
|
|
25
dist/cert.plugins.d.ts
vendored
25
dist/cert.plugins.d.ts
vendored
@ -1,12 +1,13 @@
|
|||||||
import "typings-global";
|
import 'typings-global';
|
||||||
export import beautylog = require("beautylog");
|
import * as beautylog from 'beautylog';
|
||||||
export import cflare = require("cflare");
|
import * as cflare from 'cflare';
|
||||||
export declare let fs: any;
|
declare let fs: any;
|
||||||
export import lik = require("lik");
|
import * as lik from 'lik';
|
||||||
export import path = require("path");
|
import * as path from 'path';
|
||||||
export import q = require("q");
|
import * as q from 'q';
|
||||||
export import shelljs = require("shelljs");
|
import * as shelljs from 'shelljs';
|
||||||
export import smartcli = require("smartcli");
|
import * as smartcli from 'smartcli';
|
||||||
export import smartfile = require("smartfile");
|
import * as smartfile from 'smartfile';
|
||||||
export import smartgit = require("smartgit");
|
import * as smartgit from 'smartgit';
|
||||||
export import smartstring = require("smartstring");
|
import * as smartstring from 'smartstring';
|
||||||
|
export { beautylog, cflare, fs, lik, path, q, shelljs, smartcli, smartfile, smartgit, smartstring };
|
||||||
|
35
dist/cert.plugins.js
vendored
35
dist/cert.plugins.js
vendored
@ -1,14 +1,25 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
require("typings-global");
|
require("typings-global");
|
||||||
exports.beautylog = require("beautylog");
|
const beautylog = require("beautylog");
|
||||||
exports.cflare = require("cflare");
|
exports.beautylog = beautylog;
|
||||||
exports.fs = require("fs-extra");
|
const cflare = require("cflare");
|
||||||
exports.lik = require("lik");
|
exports.cflare = cflare;
|
||||||
exports.path = require("path");
|
let fs = require('fs-extra');
|
||||||
exports.q = require("q");
|
exports.fs = fs;
|
||||||
exports.shelljs = require("shelljs");
|
const lik = require("lik");
|
||||||
exports.smartcli = require("smartcli");
|
exports.lik = lik;
|
||||||
exports.smartfile = require("smartfile");
|
const path = require("path");
|
||||||
exports.smartgit = require("smartgit");
|
exports.path = path;
|
||||||
exports.smartstring = require("smartstring");
|
const q = require("q");
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwwQkFBd0I7QUFDeEIseUNBQStDO0FBQy9DLG1DQUF5QztBQUM5QixRQUFBLEVBQUUsR0FBRyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7QUFDcEMsNkJBQW1DO0FBQ25DLCtCQUFxQztBQUNyQyx5QkFBK0I7QUFDL0IscUNBQTJDO0FBQzNDLHVDQUE2QztBQUM3Qyx5Q0FBK0M7QUFDL0MsdUNBQTZDO0FBQzdDLDZDQUFtRCJ9
|
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
|
2
dist/index.d.ts
vendored
2
dist/index.d.ts
vendored
@ -1 +1 @@
|
|||||||
export * from "./cert.classes.cert";
|
export * from './cert.classes.cert';
|
||||||
|
2
dist/index.js
vendored
2
dist/index.js
vendored
@ -3,4 +3,4 @@ function __export(m) {
|
|||||||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
|
||||||
}
|
}
|
||||||
__export(require("./cert.classes.cert"));
|
__export(require("./cert.classes.cert"));
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBR0EseUNBQW9DIn0=
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEseUNBQW1DIn0=
|
3
dist/install.d.ts
vendored
3
dist/install.d.ts
vendored
@ -1,3 +0,0 @@
|
|||||||
/// <reference types="q" />
|
|
||||||
import * as plugins from "./cert.plugins";
|
|
||||||
export declare let startInstall: () => plugins.q.Promise<{}>;
|
|
19
dist/install.js
vendored
19
dist/install.js
vendored
@ -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=
|
|
@ -7,7 +7,6 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "(npm run cleanTest && npmts)",
|
"test": "(npm run cleanTest && npmts)",
|
||||||
"cleanTest": "(rm -rf ./test/assets)",
|
"cleanTest": "(rm -rf ./test/assets)",
|
||||||
"install": "node dist/install.js install",
|
|
||||||
"compile": "(npmts --notest)"
|
"compile": "(npmts --notest)"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
@ -29,14 +28,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/minimatch": "2.x.x",
|
"@types/minimatch": "2.x.x",
|
||||||
"@types/q": "0.0.32",
|
"@types/q": "0.0.32",
|
||||||
"@types/shelljs": "0.x.x",
|
|
||||||
"beautylog": "^6.0.0",
|
"beautylog": "^6.0.0",
|
||||||
"cflare": "0.0.10",
|
"cflare": "0.0.10",
|
||||||
"fs-extra": "^0.30.0",
|
"fs-extra": "^0.30.0",
|
||||||
|
"le-store-certbot": "^2.0.3",
|
||||||
"letsencrypt": "^2.1.8",
|
"letsencrypt": "^2.1.8",
|
||||||
"lik": "^1.0.24",
|
"lik": "^1.0.24",
|
||||||
"q": "^1.4.1",
|
"q": "^1.4.1",
|
||||||
"shelljs": "^0.7.4",
|
|
||||||
"smartcli": "^1.0.10",
|
"smartcli": "^1.0.10",
|
||||||
"smartfile": "^4.0.24",
|
"smartfile": "^4.0.24",
|
||||||
"smartgit": "0.1.9",
|
"smartgit": "0.1.9",
|
||||||
@ -44,6 +42,7 @@
|
|||||||
"typings-global": "^1.0.14"
|
"typings-global": "^1.0.14"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@types/should": "^8.1.30",
|
||||||
"npmts-g": "^5.2.8",
|
"npmts-g": "^5.2.8",
|
||||||
"qenv": "^1.1.1",
|
"qenv": "^1.1.1",
|
||||||
"should": "^11.1.1",
|
"should": "^11.1.1",
|
||||||
|
3
test/test.d.ts
vendored
3
test/test.d.ts
vendored
@ -1,2 +1 @@
|
|||||||
import "typings-test";
|
import 'typings-test';
|
||||||
import "should";
|
|
||||||
|
37
test/test.js
37
test/test.js
@ -1,47 +1,38 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
require("typings-test");
|
require("typings-test");
|
||||||
require("should");
|
const should = require("should");
|
||||||
const qenv_1 = require("qenv");
|
const qenv_1 = require("qenv");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const q = require("q");
|
const q = require("q");
|
||||||
const install_1 = require("../dist/install");
|
|
||||||
const cert = require("../dist/index");
|
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;
|
let testCert;
|
||||||
describe("cert", function () {
|
describe('cert', function () {
|
||||||
describe("install", function () {
|
describe('Cert', function () {
|
||||||
it("should download letsencrypt.sh", function (done) {
|
it('should create a new Cert object from class', function () {
|
||||||
this.timeout(5000);
|
|
||||||
install_1.startInstall().then(() => {
|
|
||||||
done();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
describe("Cert", function () {
|
|
||||||
it("should create a new Cert object from class", function () {
|
|
||||||
this.timeout(40000);
|
this.timeout(40000);
|
||||||
testCert = new cert.Cert({
|
testCert = new cert.Cert({
|
||||||
cfEmail: process.env.CF_EMAIL,
|
cfEmail: process.env.CF_EMAIL,
|
||||||
cfKey: process.env.CF_KEY,
|
cfKey: process.env.CF_KEY,
|
||||||
sslDir: path.join(process.cwd(), "test/assets"),
|
sslDirPath: path.join(process.cwd(), 'test/assets'),
|
||||||
gitOriginRepo: "git@gitlab.com:sandboxzone/sandbox-sslorigin.git",
|
gitOriginRepo: 'git@gitlab.com:sandboxzone/sandbox-sslorigin.git',
|
||||||
testMode: true
|
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);
|
this.timeout(1200000);
|
||||||
let promiseArray = [];
|
let promiseArray = [];
|
||||||
function getRandomArbitrary(min, max) {
|
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.addCertificate(`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.getDomainCert(`testing${getRandomArbitrary(1, 100000)}.bleu.de`));
|
// promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
|
||||||
q.all(promiseArray).then(() => {
|
q.all(promiseArray).then(() => {
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFzQjtBQUN0QixrQkFBZ0I7QUFDaEIsK0JBQTBCO0FBQzFCLDZCQUE4QjtBQUM5Qix1QkFBd0I7QUFDeEIsNkNBQTZDO0FBQzdDLHNDQUFzQztBQUd0QyxJQUFJLFFBQVEsR0FBRyxJQUFJLFdBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRSxHQUFHLFNBQVMsQ0FBQyxDQUFDO0FBRWxFLElBQUksUUFBa0IsQ0FBQztBQUV2QixRQUFRLENBQUMsTUFBTSxFQUFDO0lBQ1osUUFBUSxDQUFDLFNBQVMsRUFBQztRQUNmLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBQyxVQUFTLElBQUk7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQixzQkFBWSxFQUFFLENBQUMsSUFBSSxDQUFDO2dCQUNoQixJQUFJLEVBQUUsQ0FBQztZQUNYLENBQUMsQ0FBQyxDQUFBO1FBQ04sQ0FBQyxDQUFDLENBQUE7SUFDTixDQUFDLENBQUMsQ0FBQTtJQUNGLFFBQVEsQ0FBQyxNQUFNLEVBQUM7UUFDWixFQUFFLENBQUMsNENBQTRDLEVBQUM7WUFDNUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNwQixRQUFRLEdBQUcsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNyQixPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxRQUFRO2dCQUM3QixLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxNQUFNO2dCQUN6QixNQUFNLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEVBQUMsYUFBYSxDQUFDO2dCQUM5QyxhQUFhLEVBQUMsa0RBQWtEO2dCQUNoRSxRQUFRLEVBQUMsSUFBSTthQUNoQixDQUFDLENBQUM7WUFDSCxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFBO1FBQ0YsRUFBRSxDQUFDLGdDQUFnQyxFQUFDLFVBQVMsSUFBSTtZQUM3QyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3RCLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQztZQUN0Qiw0QkFBNEIsR0FBRyxFQUFFLEdBQUc7Z0JBQ2hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUN6RCxDQUFDO1lBQ0QsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLFVBQVUsa0JBQWtCLENBQUMsQ0FBQyxFQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzVGLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxVQUFVLGtCQUFrQixDQUFDLENBQUMsRUFBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztZQUM1RixZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsVUFBVSxrQkFBa0IsQ0FBQyxDQUFDLEVBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7WUFDNUYsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksRUFBRSxDQUFDO1lBQ1gsQ0FBQyxDQUFDLENBQUM7UUFDUCxDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUMifQ==
|
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFDaEMsK0JBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix1QkFBdUI7QUFDdkIsc0NBQXFDO0FBR3JDLElBQUksUUFBUSxHQUFHLElBQUksV0FBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUE7QUFFakUsSUFBSSxRQUFtQixDQUFBO0FBRXZCLFFBQVEsQ0FBQyxNQUFNLEVBQUM7SUFDWixRQUFRLENBQUMsTUFBTSxFQUFDO1FBQ1osRUFBRSxDQUFDLDRDQUE0QyxFQUFDO1lBQzVDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7WUFDbkIsUUFBUSxHQUFHLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDckIsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsUUFBUTtnQkFDN0IsS0FBSyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTTtnQkFDekIsVUFBVSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFDLGFBQWEsQ0FBQztnQkFDbEQsYUFBYSxFQUFFLGtEQUFrRDtnQkFDakUsS0FBSyxFQUFFLFNBQVM7YUFDbkIsQ0FBQyxDQUFBO1lBQ0YsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQzdDLENBQUMsQ0FBQyxDQUFBO1FBQ0YsRUFBRSxDQUFDLGdDQUFnQyxFQUFDLFVBQVMsSUFBSTtZQUM3QyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBQ3JCLElBQUksWUFBWSxHQUFHLEVBQUUsQ0FBQTtZQUNyQiw0QkFBNEIsR0FBRyxFQUFFLEdBQUc7Z0JBQ2hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQTtZQUN4RCxDQUFDO1lBQ0QsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLFVBQVUsa0JBQWtCLENBQUMsQ0FBQyxFQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFBO1lBQzVGLCtGQUErRjtZQUMvRiwrRkFBK0Y7WUFDL0YsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLElBQUksRUFBRSxDQUFBO1lBQ1YsQ0FBQyxDQUFDLENBQUE7UUFDTixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUEifQ==
|
63
test/test.ts
63
test/test.ts
@ -1,49 +1,40 @@
|
|||||||
import "typings-test";
|
import 'typings-test'
|
||||||
import "should";
|
import * as should from 'should'
|
||||||
import {Qenv} from "qenv";
|
import {Qenv} from 'qenv'
|
||||||
import path = require("path");
|
import path = require('path')
|
||||||
import q = require("q");
|
import q = require('q')
|
||||||
import {startInstall} from "../dist/install";
|
import * as cert from '../dist/index'
|
||||||
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('cert',function(){
|
||||||
describe("install",function(){
|
describe('Cert',function(){
|
||||||
it("should download letsencrypt.sh",function(done){
|
it('should create a new Cert object from class',function(){
|
||||||
this.timeout(5000);
|
this.timeout(40000)
|
||||||
startInstall().then(() => {
|
|
||||||
done();
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
describe("Cert",function(){
|
|
||||||
it("should create a new Cert object from class",function(){
|
|
||||||
this.timeout(40000);
|
|
||||||
testCert = new cert.Cert({
|
testCert = new cert.Cert({
|
||||||
cfEmail: process.env.CF_EMAIL,
|
cfEmail: process.env.CF_EMAIL,
|
||||||
cfKey: process.env.CF_KEY,
|
cfKey: process.env.CF_KEY,
|
||||||
sslDir: path.join(process.cwd(),"test/assets"),
|
sslDirPath: path.join(process.cwd(),'test/assets'),
|
||||||
gitOriginRepo:"git@gitlab.com:sandboxzone/sandbox-sslorigin.git",
|
gitOriginRepo: 'git@gitlab.com:sandboxzone/sandbox-sslorigin.git',
|
||||||
testMode:true
|
leEnv: 'staging'
|
||||||
});
|
|
||||||
testCert.should.be.instanceof(cert.Cert);
|
|
||||||
})
|
})
|
||||||
it("should get a valid certificate",function(done){
|
should(testCert).be.instanceof(cert.Cert)
|
||||||
this.timeout(1200000);
|
})
|
||||||
let promiseArray = [];
|
it('should get a valid certificate',function(done){
|
||||||
|
this.timeout(1200000)
|
||||||
|
let promiseArray = []
|
||||||
function getRandomArbitrary(min, max) {
|
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.addCertificate(`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.getDomainCert(`testing${getRandomArbitrary(1,100000)}.bleu.de`));
|
// promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
|
||||||
q.all(promiseArray).then(() => {
|
q.all(promiseArray).then(() => {
|
||||||
done();
|
done()
|
||||||
});
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
});
|
})
|
||||||
|
})
|
@ -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);
|
|
@ -1,148 +1,92 @@
|
|||||||
import * as q from 'q'
|
import * as q from 'q'
|
||||||
|
import { Stringmap, Objectmap } from 'lik'
|
||||||
|
|
||||||
import * as plugins from './cert.plugins'
|
import * as plugins from './cert.plugins'
|
||||||
import * as paths from './cert.paths'
|
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 {
|
export interface ICertConstructorOptions {
|
||||||
cfEmail: string,
|
cfEmail: string,
|
||||||
cfKey: string,
|
cfKey: string,
|
||||||
sslDir?: string,
|
sslDirPath?: string,
|
||||||
gitOriginRepo?: string,
|
gitOriginRepo?: string,
|
||||||
testMode?: boolean
|
leEnv?: TLeEnv
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Cert {
|
export class Cert {
|
||||||
domainCertRequestMap: plugins.lik.Stringmap = new plugins.lik.Stringmap()
|
domainStringRequestMap = new Stringmap()
|
||||||
certificatesPresent: Certificate[]
|
certificateMap = new Objectmap<Certificate>()
|
||||||
certificatesValid: Certificate[]
|
letsencrypt: Letsencrypt
|
||||||
private _cfEmail: string
|
private _challengeHandler: ChallengeHandler
|
||||||
private _cfKey: string
|
private _certRepo: CertRepo
|
||||||
private _sslDir: string
|
|
||||||
private _gitOriginRepo: string
|
|
||||||
private _testMode: boolean
|
|
||||||
private letsencryptInstance
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor for Cert object
|
* Constructor for Cert object
|
||||||
*/
|
*/
|
||||||
constructor(optionsArg: ICertConstructorOptions) {
|
constructor(optionsArg: ICertConstructorOptions) {
|
||||||
this._cfEmail = optionsArg.cfEmail
|
|
||||||
this._cfKey = optionsArg.cfKey
|
// set up challengehandler
|
||||||
this._sslDir = optionsArg.sslDir
|
this._challengeHandler = new ChallengeHandler({
|
||||||
this._gitOriginRepo = optionsArg.gitOriginRepo
|
cfEmail: optionsArg.cfEmail,
|
||||||
this._testMode = optionsArg.testMode
|
cfKey: optionsArg.cfKey
|
||||||
// write hook config
|
})
|
||||||
let config = {
|
|
||||||
cfEmail: this._cfEmail,
|
// setup Letsencrypt
|
||||||
cfKey: this._cfKey
|
this.letsencrypt = new Letsencrypt({
|
||||||
}
|
leEnv: optionsArg.leEnv,
|
||||||
plugins.smartfile.memory.toFsSync(
|
sslDir: optionsArg.sslDirPath,
|
||||||
JSON.stringify(config),
|
challengeHandler: this._challengeHandler
|
||||||
plugins.path.join(__dirname, 'assets/config.json')
|
})
|
||||||
)
|
|
||||||
// setup sslDir
|
// setup CertRpo
|
||||||
if (!this._sslDir) this._sslDir = paths.defaultSslDir
|
this._certRepo = new CertRepo({
|
||||||
// setup Git
|
sslDirPath: optionsArg.sslDirPath,
|
||||||
if (this._gitOriginRepo) {
|
gitOriginRepo: optionsArg.gitOriginRepo,
|
||||||
plugins.smartgit.init(this._sslDir)
|
certInstance: this
|
||||||
plugins.smartgit.remote.add(this._sslDir, 'origin', this._gitOriginRepo)
|
})
|
||||||
this.sslGitOriginPull()
|
|
||||||
}
|
this._certRepo
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pulls already requested certificates from git origin
|
* adds a Certificate for a given domain
|
||||||
*/
|
*/
|
||||||
sslGitOriginPull = () => {
|
addCertificate(domainNameArg: string, optionsArg: { force: boolean } = { force: false }) {
|
||||||
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 = q.defer()
|
let done = q.defer()
|
||||||
let domainStringData = new plugins.smartstring.Domain(domainNameArg)
|
let certificateForDomain = this.certificateMap.find((certificate) => {
|
||||||
let sameZoneRequesting: boolean = this.domainCertRequestMap.checkMinimatch('*' + domainStringData.zoneName)
|
return certificate.domainName === domainNameArg
|
||||||
// make sure no one else requires the same domain at the same time
|
})
|
||||||
if (!this.domainCertRequestMap.checkString(domainNameArg)) {
|
if (certificateForDomain instanceof Certificate) {
|
||||||
this.domainCertRequestMap.addString(domainNameArg)
|
certificateForDomain.renew()
|
||||||
if (!helpers.checkDomainsStillValid(domainNameArg, this._sslDir) || optionsArg.force) {
|
.then(done.resolve)
|
||||||
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 {
|
} else {
|
||||||
plugins.beautylog.error(`Couldn't copy final certificate for ${domainNameArg}!`)
|
certificateForDomain = new Certificate({
|
||||||
|
certInstance: this,
|
||||||
|
domainName: domainNameArg
|
||||||
|
})
|
||||||
|
certificateForDomain.renew()
|
||||||
|
.then(done.resolve)
|
||||||
}
|
}
|
||||||
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()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
plugins.beautylog.warn(`${domainNameArg} is already requesting`)
|
|
||||||
}
|
|
||||||
|
|
||||||
return done.promise
|
return done.promise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cleans up old certificates
|
||||||
|
*/
|
||||||
cleanOldCertificates() {
|
cleanOldCertificates() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
export class Certificate {
|
/**
|
||||||
domainName: string
|
* executes the current batch of jobs
|
||||||
creationDate: Date
|
*/
|
||||||
expiryDate: Date
|
deploy() {
|
||||||
constructor() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
129
ts/cert.classes.certificate.ts
Normal file
129
ts/cert.classes.certificate.ts
Normal file
@ -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() { }
|
||||||
|
}
|
65
ts/cert.classes.certrepo.ts
Normal file
65
ts/cert.classes.certrepo.ts
Normal file
@ -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')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
84
ts/cert.classes.challengehandler.ts
Normal file
84
ts/cert.classes.challengehandler.ts
Normal file
@ -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
|
||||||
|
}
|
139
ts/cert.classes.letsencrypt.ts
Normal file
139
ts/cert.classes.letsencrypt.ts
Normal file
@ -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);
|
||||||
|
}
|
||||||
|
}
|
@ -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();
|
|
@ -1,14 +1,9 @@
|
|||||||
import * as plugins from "./cert.plugins";
|
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");
|
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
@ -2,7 +2,6 @@ import 'typings-global'
|
|||||||
import * as beautylog from 'beautylog'
|
import * as beautylog from 'beautylog'
|
||||||
import * as cflare from 'cflare'
|
import * as cflare from 'cflare'
|
||||||
let fs = require('fs-extra')
|
let fs = require('fs-extra')
|
||||||
let letsencrypt = require('letsencrypt')
|
|
||||||
import * as lik from 'lik'
|
import * as lik from 'lik'
|
||||||
import * as path from 'path'
|
import * as path from 'path'
|
||||||
import * as q from 'q'
|
import * as q from 'q'
|
||||||
@ -16,7 +15,6 @@ export {
|
|||||||
beautylog,
|
beautylog,
|
||||||
cflare,
|
cflare,
|
||||||
fs,
|
fs,
|
||||||
letsencrypt,
|
|
||||||
lik,
|
lik,
|
||||||
path,
|
path,
|
||||||
q,
|
q,
|
||||||
|
@ -1,4 +1 @@
|
|||||||
import * as plugins from "./cert.plugins";
|
export * from './cert.classes.cert'
|
||||||
import * as paths from "./cert.paths";
|
|
||||||
|
|
||||||
export * from "./cert.classes.cert";
|
|
||||||
|
Loading…
Reference in New Issue
Block a user