Compare commits
No commits in common. "master" and "v0.0.10" have entirely different histories.
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,8 +1,5 @@
|
||||
node_modules/
|
||||
assets/
|
||||
node_modules
|
||||
docs/
|
||||
public/
|
||||
pages/
|
||||
coverage/
|
||||
.nogit/
|
||||
dist/assets/
|
||||
|
@ -5,9 +5,6 @@ stages:
|
||||
- test2
|
||||
- release
|
||||
|
||||
before_script:
|
||||
- npmci prepare ssh
|
||||
|
||||
testLTS:
|
||||
stage: test1
|
||||
script:
|
||||
|
28
README.md
28
README.md
@ -1,22 +1,6 @@
|
||||
# Cert
|
||||
Easily obain SSL certificates from LetsEncrypt. Supports DNS-01 challenge. TypeScript ready.
|
||||
|
||||
## Availabililty
|
||||
[](https://www.npmjs.com/package/cert)
|
||||
[](https://gitlab.com/pushrocks/cert)
|
||||
[](https://github.com/pushrocks/cert)
|
||||
[](https://pushrocks.gitlab.io/cert/)
|
||||
|
||||
## Status for master
|
||||
[](https://gitlab.com/pushrocks/cert/commits/master)
|
||||
[](https://gitlab.com/pushrocks/cert/commits/master)
|
||||
[](https://david-dm.org/pushrocks/cert)
|
||||
[](https://www.bithound.io/github/pushrocks/cert/master/dependencies/npm)
|
||||
[](https://www.bithound.io/github/pushrocks/cert)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](https://nodejs.org/dist/latest-v6.x/docs/api/)
|
||||
[](http://standardjs.com/)
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
@ -29,17 +13,13 @@ let myCert = new Cert({
|
||||
gitOriginRepo: "git@githhub.com/someuser/somereopo" // good for persistence in highly volatile environments like docker
|
||||
});
|
||||
|
||||
myCert.getDomainCert("example.com"); // returns promise
|
||||
myCert.getDomainCert("example.com");
|
||||
```
|
||||
|
||||
> **Note:** cert supports async parallel cert fetching.
|
||||
However any subsequent calls will wait for the queue of the same dns zone to clear.
|
||||
In other words: test1.domain1.tld and test2.domain2.tld will run in parallel, but test2.domain1.tld will wait for test1.domain1.tld !
|
||||
|
||||
## sslDir
|
||||
### sslDir
|
||||
to use the certificates it is important to understand what the structure of the ssl directory looks like.
|
||||
|
||||
## using a git origin repo.
|
||||
### using a git origin repo.
|
||||
Often times you want to keep track of certificates in order to keep them
|
||||
even if the point of initial certificate request is gone. Imagine you have a dockerenvironement
|
||||
and you keep starting new container versions for the same domain. YOu ideally want to use a proxy
|
||||
@ -47,5 +27,3 @@ that handles SSL managemet for you. But even the proxy needs to be updated from
|
||||
|
||||
So you need some kind of persistence between versions. This is why you can sync up all certificates to a git repo over ssh
|
||||
Just make sure your id_rsa is in place for the node user and is allowed for the origin repo.
|
||||
|
||||
[](https://push.rocks)
|
||||
|
43
dist/cert.classes.cert.d.ts
vendored
43
dist/cert.classes.cert.d.ts
vendored
@ -1,43 +0,0 @@
|
||||
/// <reference types="q" />
|
||||
import * as q from 'q';
|
||||
import { Stringmap, Objectmap } from 'lik';
|
||||
import { Certificate } from './cert.classes.certificate';
|
||||
import { Letsencrypt, TLeEnv } from './cert.classes.letsencrypt';
|
||||
export interface ICertConstructorOptions {
|
||||
cfEmail: string;
|
||||
cfKey: string;
|
||||
sslDirPath?: string;
|
||||
gitOriginRepo?: string;
|
||||
leEnv?: TLeEnv;
|
||||
}
|
||||
export declare class Cert {
|
||||
domainStringRequestMap: Stringmap;
|
||||
certificateMap: Objectmap<Certificate>;
|
||||
letsencrypt: Letsencrypt;
|
||||
private _challengeHandler;
|
||||
private _certRepo;
|
||||
/**
|
||||
* Constructor for Cert object
|
||||
*/
|
||||
constructor(optionsArg: ICertConstructorOptions);
|
||||
/**
|
||||
* setup the Cert instanceof
|
||||
* @executes ASYNC
|
||||
* @return Promise
|
||||
*/
|
||||
setup(): q.Promise<{}>;
|
||||
/**
|
||||
* adds a Certificate for a given domain
|
||||
*/
|
||||
addCertificate(domainNameArg: string, optionsArg?: {
|
||||
force: boolean;
|
||||
}): q.Promise<{}>;
|
||||
/**
|
||||
* cleans up old certificates
|
||||
*/
|
||||
cleanOldCertificates(): void;
|
||||
/**
|
||||
* executes the current batch of jobs
|
||||
*/
|
||||
deploy(): void;
|
||||
}
|
75
dist/cert.classes.cert.js
vendored
75
dist/cert.classes.cert.js
vendored
@ -1,75 +0,0 @@
|
||||
"use strict";
|
||||
const q = require("q");
|
||||
const lik_1 = require("lik");
|
||||
// classes
|
||||
const cert_classes_certificate_1 = require("./cert.classes.certificate");
|
||||
const cert_classes_certrepo_1 = require("./cert.classes.certrepo");
|
||||
const cert_classes_letsencrypt_1 = require("./cert.classes.letsencrypt");
|
||||
const cert_classes_challengehandler_1 = require("./cert.classes.challengehandler");
|
||||
class Cert {
|
||||
/**
|
||||
* Constructor for Cert object
|
||||
*/
|
||||
constructor(optionsArg) {
|
||||
this.domainStringRequestMap = new lik_1.Stringmap();
|
||||
this.certificateMap = new lik_1.Objectmap();
|
||||
// set up challengehandler
|
||||
this._challengeHandler = new cert_classes_challengehandler_1.ChallengeHandler({
|
||||
cfEmail: optionsArg.cfEmail,
|
||||
cfKey: optionsArg.cfKey
|
||||
});
|
||||
// setup Letsencrypt
|
||||
this.letsencrypt = new cert_classes_letsencrypt_1.Letsencrypt({
|
||||
leEnv: optionsArg.leEnv,
|
||||
sslDir: optionsArg.sslDirPath,
|
||||
challengeHandler: this._challengeHandler
|
||||
});
|
||||
this._certRepo = new cert_classes_certrepo_1.CertRepo({
|
||||
sslDirPath: optionsArg.sslDirPath,
|
||||
remoteGitUrl: optionsArg.gitOriginRepo,
|
||||
certInstance: this
|
||||
});
|
||||
}
|
||||
/**
|
||||
* setup the Cert instanceof
|
||||
* @executes ASYNC
|
||||
* @return Promise
|
||||
*/
|
||||
setup() {
|
||||
return this._certRepo.setup();
|
||||
}
|
||||
/**
|
||||
* adds a Certificate for a given domain
|
||||
*/
|
||||
addCertificate(domainNameArg, optionsArg = { force: false }) {
|
||||
let done = q.defer();
|
||||
let certificateForDomain = this.certificateMap.find((certificate) => {
|
||||
return certificate.domainName === domainNameArg;
|
||||
});
|
||||
if (certificateForDomain instanceof cert_classes_certificate_1.Certificate) {
|
||||
certificateForDomain.renew()
|
||||
.then(done.resolve);
|
||||
}
|
||||
else {
|
||||
certificateForDomain = new cert_classes_certificate_1.Certificate({
|
||||
certInstance: this,
|
||||
domainName: domainNameArg
|
||||
});
|
||||
certificateForDomain.renew()
|
||||
.then(done.resolve);
|
||||
}
|
||||
return done.promise;
|
||||
}
|
||||
/**
|
||||
* cleans up old certificates
|
||||
*/
|
||||
cleanOldCertificates() {
|
||||
}
|
||||
/**
|
||||
* executes the current batch of jobs
|
||||
*/
|
||||
deploy() {
|
||||
}
|
||||
}
|
||||
exports.Cert = Cert;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jZXJ0LmNsYXNzZXMuY2VydC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsdUJBQXNCO0FBQ3RCLDZCQUEwQztBQUsxQyxVQUFVO0FBQ1YseUVBQXdEO0FBQ3hELG1FQUFrRDtBQUNsRCx5RUFBZ0U7QUFDaEUsbUZBQWtFO0FBV2xFO0lBT0k7O09BRUc7SUFDSCxZQUFZLFVBQW1DO1FBVC9DLDJCQUFzQixHQUFHLElBQUksZUFBUyxFQUFFLENBQUE7UUFDeEMsbUJBQWMsR0FBRyxJQUFJLGVBQVMsRUFBZSxDQUFBO1FBVXpDLDBCQUEwQjtRQUMxQixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxnREFBZ0IsQ0FBQztZQUMxQyxPQUFPLEVBQUUsVUFBVSxDQUFDLE9BQU87WUFDM0IsS0FBSyxFQUFFLFVBQVUsQ0FBQyxLQUFLO1NBQzFCLENBQUMsQ0FBQTtRQUVGLG9CQUFvQjtRQUNwQixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksc0NBQVcsQ0FBQztZQUMvQixLQUFLLEVBQUUsVUFBVSxDQUFDLEtBQUs7WUFDdkIsTUFBTSxFQUFFLFVBQVUsQ0FBQyxVQUFVO1lBQzdCLGdCQUFnQixFQUFFLElBQUksQ0FBQyxpQkFBaUI7U0FDM0MsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLGdDQUFRLENBQUM7WUFDMUIsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVO1lBQ2pDLFlBQVksRUFBRSxVQUFVLENBQUMsYUFBYTtZQUN0QyxZQUFZLEVBQUUsSUFBSTtTQUNyQixDQUFDLENBQUE7SUFDTixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUs7UUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUNqQyxDQUFDO0lBRUQ7O09BRUc7SUFDSCxjQUFjLENBQUMsYUFBcUIsRUFBRSxhQUFpQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUU7UUFDbkYsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ3BCLElBQUksb0JBQW9CLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXO1lBQzVELE1BQU0sQ0FBQyxXQUFXLENBQUMsVUFBVSxLQUFLLGFBQWEsQ0FBQTtRQUNuRCxDQUFDLENBQUMsQ0FBQTtRQUNGLEVBQUUsQ0FBQyxDQUFDLG9CQUFvQixZQUFZLHNDQUFXLENBQUMsQ0FBQyxDQUFDO1lBQzlDLG9CQUFvQixDQUFDLEtBQUssRUFBRTtpQkFDdkIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUMzQixDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDSixvQkFBb0IsR0FBRyxJQUFJLHNDQUFXLENBQUM7Z0JBQ25DLFlBQVksRUFBRSxJQUFJO2dCQUNsQixVQUFVLEVBQUUsYUFBYTthQUM1QixDQUFDLENBQUE7WUFDRixvQkFBb0IsQ0FBQyxLQUFLLEVBQUU7aUJBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDM0IsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILG9CQUFvQjtJQUVwQixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNO0lBRU4sQ0FBQztDQUNKO0FBNUVELG9CQTRFQyJ9
|
48
dist/cert.classes.certificate.d.ts
vendored
48
dist/cert.classes.certificate.d.ts
vendored
@ -1,48 +0,0 @@
|
||||
/// <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
103
dist/cert.classes.certificate.js
vendored
@ -1,103 +0,0 @@
|
||||
"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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnRpZmljYXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5jbGFzc2VzLmNlcnRpZmljYXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx1QkFBc0I7QUFFdEIsMENBQXlDO0FBcUJ6QztJQVNJOztPQUVHO0lBQ0gsWUFBWSxVQUEwQztRQVJ0RCxpQkFBWSxHQUFTLElBQUksQ0FBQTtRQUN6QixlQUFVLEdBQVMsSUFBSSxDQUFBO1FBQ3ZCLGNBQVMsR0FBVyxJQUFJLENBQUE7UUFDeEIsWUFBTyxHQUFXLElBQUksQ0FBQTtRQU1sQixJQUFJLENBQUMsVUFBVSxHQUFHLFVBQVUsQ0FBQyxVQUFVLENBQUE7UUFDdkMsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUNqRSxJQUFJLENBQUMsWUFBWSxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUE7SUFDL0MsQ0FBQztJQUVEOztPQUVHO0lBQ0gsSUFBSSxNQUFNO1FBQ04sSUFBSSxrQkFBa0IsR0FBVyxDQUFDLENBQUE7UUFDbEMsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksS0FBSyxJQUFJLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3hELGtCQUFrQixHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFBO1FBQ2hFLENBQUM7UUFDRCxJQUFJLGlCQUFpQixHQUFHLFVBQVUsQ0FBQTtRQUNsQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxLQUFLLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDbkQsTUFBTSxDQUFDLGNBQWMsQ0FBQTtRQUN6QixDQUFDO1FBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLGtCQUFrQixJQUFJLGlCQUFpQixDQUFDLENBQUMsQ0FBQztZQUNqRCxNQUFNLENBQUMsT0FBTyxDQUFBO1FBQ2xCLENBQUM7UUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsa0JBQWtCLEdBQUcsaUJBQWlCLElBQUksa0JBQWtCLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMzRSxNQUFNLENBQUMsVUFBVSxDQUFBO1FBQ3JCLENBQUM7UUFBQyxJQUFJLENBQUMsQ0FBQztZQUNKLE1BQU0sQ0FBQyxTQUFTLENBQUE7UUFDcEIsQ0FBQztJQUNMLENBQUM7SUFFRCxJQUFJLGtCQUFrQjtRQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxzQkFBc0IsQ0FBQyxjQUFjLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDbEcsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYTtRQUNULElBQUksSUFBSSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDNUIsVUFBVSxDQUFDO1lBQ1AsSUFBSSxDQUFDLEtBQUssRUFBRTtpQkFDUCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFBO1FBQzNCLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQTtRQUNULE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILEtBQUssQ0FBQyxRQUFpQixLQUFLO1FBQ3hCLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDMUIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMseUVBQXlFLENBQUMsQ0FBQTtZQUNoRyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDbEIsQ0FBQztRQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxLQUFLLFVBQVUsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLGNBQWMsQ0FBQyxDQUFDLENBQUM7WUFDbkcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsc0RBQXNELENBQUMsQ0FBQTtZQUM5RSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO2dCQUMxQixJQUFJLENBQUMsWUFBWSxDQUFDLHNCQUFzQixDQUFDLGlCQUFpQixDQUNsRDtvQkFDSSxNQUFNLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUE7Z0JBQ25DLENBQUMsRUFDRDtvQkFDSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQTtnQkFDbkMsQ0FBQyxDQUNKLENBQUE7WUFDVCxDQUFDO1lBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ0osSUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7cUJBQ3hELElBQUksQ0FBQztvQkFDRixNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFBO2dCQUN4QixDQUFDLENBQUM7cUJBQ0QsSUFBSSxDQUFDO29CQUNGLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtnQkFDbEIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUEsQ0FBQyxDQUFDLENBQUMsQ0FBQTtZQUMvQyxDQUFDO1FBQ0wsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ0osTUFBTSxLQUFLLENBQUMsaURBQWlELElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFBO1FBQ25GLENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUE7UUFDZCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQTtJQUN2QixDQUFDO0lBRUQ7O09BRUc7SUFDSCxNQUFNO1FBQ0YsSUFBSSxnQkFBZ0IsR0FBeUI7WUFDekMsVUFBVSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQzNCLFlBQVksRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLE9BQU8sRUFBRTtZQUN6QyxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxPQUFPLEVBQUU7U0FDeEMsQ0FBQTtJQUVMLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU0sS0FBSyxDQUFDO0NBQ2Y7QUF6R0Qsa0NBeUdDIn0=
|
31
dist/cert.classes.certrepo.d.ts
vendored
31
dist/cert.classes.certrepo.d.ts
vendored
@ -1,31 +0,0 @@
|
||||
/// <reference types="q" />
|
||||
import * as q from 'q';
|
||||
import { Cert } from './cert.classes.cert';
|
||||
export interface ICertRepoConstructorOptions {
|
||||
sslDirPath: string;
|
||||
remoteGitUrl: string;
|
||||
certInstance: Cert;
|
||||
}
|
||||
export declare class CertRepo {
|
||||
private _sslDirPath;
|
||||
private _remoteGitUrl;
|
||||
private gitRepo;
|
||||
private _certInstance;
|
||||
constructor(optionsArg: ICertRepoConstructorOptions);
|
||||
/**
|
||||
* setup the Cert instance
|
||||
*/
|
||||
setup(): q.Promise<{}>;
|
||||
/**
|
||||
* 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;
|
||||
}
|
59
dist/cert.classes.certrepo.js
vendored
59
dist/cert.classes.certrepo.js
vendored
@ -1,59 +0,0 @@
|
||||
"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.gitRepo) {
|
||||
this.gitRepo.pull('origin', 'master');
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Pushes all new requested certificates to git origin
|
||||
*/
|
||||
this.sslGitOriginAddCommitPush = () => {
|
||||
if (this._remoteGitUrl) {
|
||||
this.gitRepo.addAll();
|
||||
this.gitRepo.commit('added new SSL certificates and deleted obsolete ones.');
|
||||
this.gitRepo.push('origin', 'master');
|
||||
}
|
||||
};
|
||||
this._sslDirPath = optionsArg.sslDirPath;
|
||||
this._remoteGitUrl = optionsArg.remoteGitUrl;
|
||||
this._certInstance = optionsArg.certInstance;
|
||||
// setup sslDir
|
||||
if (!this._sslDirPath) {
|
||||
this._sslDirPath = paths.defaultSslDir;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* setup the Cert instance
|
||||
*/
|
||||
setup() {
|
||||
// setup Git
|
||||
let done = q.defer();
|
||||
if (this._remoteGitUrl) {
|
||||
plugins.smartfile.fs.ensureEmptyDirSync(paths.defaultSslDir);
|
||||
plugins.smartgit.createRepoFromClone(this._remoteGitUrl, paths.defaultSslDir)
|
||||
.then(gitRepoArg => {
|
||||
this.gitRepo = gitRepoArg;
|
||||
done.resolve();
|
||||
});
|
||||
}
|
||||
return done.promise;
|
||||
}
|
||||
/**
|
||||
* 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5jbGFzc2VzLmNlcnRyZXBvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5jbGFzc2VzLmNlcnRyZXBvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSx1QkFBc0I7QUFHdEIsMENBQXlDO0FBQ3pDLHNDQUFxQztBQVdyQztJQUtJLFlBQVksVUFBdUM7UUFxQ25EOztXQUVHO1FBQ0gscUJBQWdCLEdBQUc7WUFDZixFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDZixJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDLENBQUE7WUFDekMsQ0FBQztRQUNMLENBQUMsQ0FBQTtRQUVEOztXQUVHO1FBQ0gsOEJBQXlCLEdBQUc7WUFDeEIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLENBQUE7Z0JBQ3JCLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLHVEQUF1RCxDQUFDLENBQUE7Z0JBQzVFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQTtZQUN6QyxDQUFDO1FBQ0wsQ0FBQyxDQUFBO1FBdERHLElBQUksQ0FBQyxXQUFXLEdBQUcsVUFBVSxDQUFDLFVBQVUsQ0FBQTtRQUN4QyxJQUFJLENBQUMsYUFBYSxHQUFHLFVBQVUsQ0FBQyxZQUFZLENBQUE7UUFDNUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFBO1FBRTVDLGVBQWU7UUFDZixFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ3BCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLGFBQWEsQ0FBQTtRQUMxQyxDQUFDO0lBQ0wsQ0FBQztJQUVEOztPQUVHO0lBQ0gsS0FBSztRQUNELFlBQVk7UUFDWixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDcEIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7WUFDckIsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxDQUFBO1lBQzVELE9BQU8sQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYSxDQUFDO2lCQUN4RSxJQUFJLENBQUMsVUFBVTtnQkFDWixJQUFJLENBQUMsT0FBTyxHQUFHLFVBQVUsQ0FBQTtnQkFDekIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1lBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ1YsQ0FBQztRQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFBO0lBQ3ZCLENBQUM7SUFFRDs7T0FFRztJQUNILE1BQU07UUFDRixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDcEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2QsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztDQXFCSjtBQTdERCw0QkE2REMifQ==
|
20
dist/cert.classes.challengehandler.d.ts
vendored
20
dist/cert.classes.challengehandler.d.ts
vendored
@ -1,20 +0,0 @@
|
||||
/// <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
75
dist/cert.classes.challengehandler.js
vendored
@ -1,75 +0,0 @@
|
||||
"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
|
26
dist/cert.classes.letsencrypt.d.ts
vendored
26
dist/cert.classes.letsencrypt.d.ts
vendored
@ -1,26 +0,0 @@
|
||||
/// <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();
|
||||
}
|
136
dist/cert.classes.letsencrypt.js
vendored
136
dist/cert.classes.letsencrypt.js
vendored
File diff suppressed because one or more lines are too long
1
dist/cert.hook.d.ts
vendored
Normal file
1
dist/cert.hook.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
import "typings-global";
|
67
dist/cert.hook.js
vendored
Executable file
67
dist/cert.hook.js
vendored
Executable file
File diff suppressed because one or more lines are too long
9
dist/cert.paths.d.ts
vendored
9
dist/cert.paths.d.ts
vendored
@ -1,4 +1,5 @@
|
||||
export declare let projectDir: string;
|
||||
export declare let assetDir: string;
|
||||
export declare let defaultSslDir: string;
|
||||
export declare let leConfigDir: string;
|
||||
import "typings-global";
|
||||
export declare let certHook: string;
|
||||
export declare let config: string;
|
||||
export declare let letsencryptSh: string;
|
||||
export declare let certDir: string;
|
||||
|
17
dist/cert.paths.js
vendored
17
dist/cert.paths.js
vendored
@ -1,10 +1,9 @@
|
||||
"use strict";
|
||||
const plugins = require("./cert.plugins");
|
||||
// dirs
|
||||
exports.projectDir = plugins.path.join(__dirname, '../');
|
||||
exports.assetDir = plugins.path.join(exports.projectDir, 'assets');
|
||||
exports.defaultSslDir = plugins.path.join(exports.assetDir, 'defaultSslDir');
|
||||
exports.leConfigDir = plugins.path.join(exports.assetDir, 'letsencrypt');
|
||||
plugins.smartfile.fs.ensureDirSync(exports.leConfigDir);
|
||||
plugins.smartfile.fs.ensureDirSync(exports.defaultSslDir);
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLDBDQUF5QztBQUV6QyxPQUFPO0FBQ0ksUUFBQSxVQUFVLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLEtBQUssQ0FBQyxDQUFBO0FBQy9DLFFBQUEsUUFBUSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGtCQUFVLEVBQUMsUUFBUSxDQUFDLENBQUE7QUFDakQsUUFBQSxhQUFhLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQVEsRUFBQyxlQUFlLENBQUMsQ0FBQTtBQUMzRCxRQUFBLFdBQVcsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBUSxFQUFDLGFBQWEsQ0FBQyxDQUFBO0FBQ2xFLE9BQU8sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxtQkFBVyxDQUFDLENBQUE7QUFDL0MsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsYUFBYSxDQUFDLHFCQUFhLENBQUMsQ0FBQSJ9
|
||||
require("typings-global");
|
||||
var plugins = require("./cert.plugins");
|
||||
exports.certHook = plugins.path.join(__dirname, "cert.hook.js");
|
||||
exports.config = plugins.path.join(__dirname, "assets/config.json");
|
||||
exports.letsencryptSh = plugins.path.join(__dirname, "assets/letsencrypt.sh");
|
||||
exports.certDir = plugins.path.join(__dirname, "/assets/certs");
|
||||
|
||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNlcnQucGF0aHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sZ0JBQWdCLENBQUMsQ0FBQTtBQUN4QixJQUFZLE9BQU8sV0FBTSxnQkFBZ0IsQ0FBQyxDQUFBO0FBRS9CLGdCQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3ZELGNBQU0sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsb0JBQW9CLENBQUMsQ0FBQztBQUMzRCxxQkFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBQyx1QkFBdUIsQ0FBQyxDQUFDO0FBQ3JFLGVBQU8sR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUMsZUFBZSxDQUFDLENBQUMiLCJmaWxlIjoiY2VydC5wYXRocy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBcInR5cGluZ3MtZ2xvYmFsXCI7XG5pbXBvcnQgKiBhcyBwbHVnaW5zIGZyb20gXCIuL2NlcnQucGx1Z2luc1wiO1xuXG5leHBvcnQgbGV0IGNlcnRIb29rID0gcGx1Z2lucy5wYXRoLmpvaW4oX19kaXJuYW1lLFwiY2VydC5ob29rLmpzXCIpO1xuZXhwb3J0IGxldCBjb25maWcgPSBwbHVnaW5zLnBhdGguam9pbihfX2Rpcm5hbWUsXCJhc3NldHMvY29uZmlnLmpzb25cIik7XG5leHBvcnQgbGV0IGxldHNlbmNyeXB0U2ggPSBwbHVnaW5zLnBhdGguam9pbihfX2Rpcm5hbWUsXCJhc3NldHMvbGV0c2VuY3J5cHQuc2hcIik7XG5leHBvcnQgbGV0IGNlcnREaXIgPSBwbHVnaW5zLnBhdGguam9pbihfX2Rpcm5hbWUsXCIvYXNzZXRzL2NlcnRzXCIpOyJdfQ==
|
||||
|
24
dist/cert.plugins.d.ts
vendored
24
dist/cert.plugins.d.ts
vendored
@ -1,13 +1,11 @@
|
||||
import 'typings-global';
|
||||
import * as beautylog from 'beautylog';
|
||||
import * as cflare from 'cflare';
|
||||
declare let fs: any;
|
||||
import * as lik from 'lik';
|
||||
import * as path from 'path';
|
||||
import * as q from 'q';
|
||||
import * as shelljs from 'shelljs';
|
||||
import * as smartcli from 'smartcli';
|
||||
import * as smartfile from 'smartfile';
|
||||
import * as smartgit from 'smartgit';
|
||||
import * as smartstring from 'smartstring';
|
||||
export { beautylog, cflare, fs, lik, path, q, shelljs, smartcli, smartfile, smartgit, smartstring };
|
||||
import "typings-global";
|
||||
export import beautylog = require("beautylog");
|
||||
export import cflare = require("cflare");
|
||||
export declare let fs: any;
|
||||
export import path = require("path");
|
||||
export declare let q: any;
|
||||
export declare let shelljs: any;
|
||||
export import smartcli = require("smartcli");
|
||||
export import smartfile = require("smartfile");
|
||||
export import smartgit = require("smartgit");
|
||||
export import smartstring = require("smartstring");
|
||||
|
35
dist/cert.plugins.js
vendored
35
dist/cert.plugins.js
vendored
@ -1,25 +1,14 @@
|
||||
"use strict";
|
||||
require("typings-global");
|
||||
const beautylog = require("beautylog");
|
||||
exports.beautylog = beautylog;
|
||||
const cflare = require("cflare");
|
||||
exports.cflare = cflare;
|
||||
let fs = require('fs-extra');
|
||||
exports.fs = fs;
|
||||
const lik = require("lik");
|
||||
exports.lik = lik;
|
||||
const path = require("path");
|
||||
exports.path = path;
|
||||
const q = require("q");
|
||||
exports.q = q;
|
||||
const shelljs = require("shelljs");
|
||||
exports.shelljs = shelljs;
|
||||
const smartcli = require("smartcli");
|
||||
exports.smartcli = smartcli;
|
||||
const smartfile = require("smartfile");
|
||||
exports.smartfile = smartfile;
|
||||
const smartgit = require("smartgit");
|
||||
exports.smartgit = smartgit;
|
||||
const smartstring = require("smartstring");
|
||||
exports.smartstring = smartstring;
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VydC5wbHVnaW5zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY2VydC5wbHVnaW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwwQkFBdUI7QUFDdkIsdUNBQXNDO0FBYWxDLDhCQUFTO0FBWmIsaUNBQWdDO0FBYTVCLHdCQUFNO0FBWlYsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBYXhCLGdCQUFFO0FBWk4sMkJBQTBCO0FBYXRCLGtCQUFHO0FBWlAsNkJBQTRCO0FBYXhCLG9CQUFJO0FBWlIsdUJBQXNCO0FBYWxCLGNBQUM7QUFaTCxtQ0FBa0M7QUFhOUIsMEJBQU87QUFaWCxxQ0FBb0M7QUFhaEMsNEJBQVE7QUFaWix1Q0FBc0M7QUFhbEMsOEJBQVM7QUFaYixxQ0FBb0M7QUFhaEMsNEJBQVE7QUFaWiwyQ0FBMEM7QUFhdEMsa0NBQVcifQ==
|
||||
exports.beautylog = require("beautylog");
|
||||
exports.cflare = require("cflare");
|
||||
exports.fs = require("fs-extra");
|
||||
exports.path = require("path");
|
||||
exports.q = require("q");
|
||||
exports.shelljs = require("shelljs");
|
||||
exports.smartcli = require("smartcli");
|
||||
exports.smartfile = require("smartfile");
|
||||
exports.smartgit = require("smartgit");
|
||||
exports.smartstring = require("smartstring");
|
||||
|
||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNlcnQucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsUUFBTyxnQkFBZ0IsQ0FBQyxDQUFBO0FBQ1YsaUJBQVMsV0FBVyxXQUFXLENBQUMsQ0FBQztBQUNqQyxjQUFNLFdBQVcsUUFBUSxDQUFDLENBQUM7QUFDOUIsVUFBRSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUN0QixZQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFDMUIsU0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNqQixlQUFPLEdBQUcsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQzFCLGdCQUFRLFdBQVcsVUFBVSxDQUFDLENBQUM7QUFDL0IsaUJBQVMsV0FBVyxXQUFXLENBQUMsQ0FBQztBQUNqQyxnQkFBUSxXQUFXLFVBQVUsQ0FBQyxDQUFDO0FBQy9CLG1CQUFXLFdBQVcsYUFBYSxDQUFDLENBQUMiLCJmaWxlIjoiY2VydC5wbHVnaW5zLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy1nbG9iYWxcIjtcbmV4cG9ydCBpbXBvcnQgYmVhdXR5bG9nID0gcmVxdWlyZShcImJlYXV0eWxvZ1wiKTtcbmV4cG9ydCBpbXBvcnQgY2ZsYXJlID0gcmVxdWlyZShcImNmbGFyZVwiKTtcbmV4cG9ydCBsZXQgZnMgPSByZXF1aXJlKFwiZnMtZXh0cmFcIik7XG5leHBvcnQgaW1wb3J0IHBhdGggPSByZXF1aXJlKFwicGF0aFwiKTtcbmV4cG9ydCBsZXQgcSA9IHJlcXVpcmUoXCJxXCIpO1xuZXhwb3J0IGxldCBzaGVsbGpzID0gcmVxdWlyZShcInNoZWxsanNcIik7XG5leHBvcnQgaW1wb3J0IHNtYXJ0Y2xpID0gcmVxdWlyZShcInNtYXJ0Y2xpXCIpO1xuZXhwb3J0IGltcG9ydCBzbWFydGZpbGUgPSByZXF1aXJlKFwic21hcnRmaWxlXCIpO1xuZXhwb3J0IGltcG9ydCBzbWFydGdpdCA9IHJlcXVpcmUoXCJzbWFydGdpdFwiKTtcbmV4cG9ydCBpbXBvcnQgc21hcnRzdHJpbmcgPSByZXF1aXJlKFwic21hcnRzdHJpbmdcIik7XG5cbiJdfQ==
|
||||
|
24
dist/index.d.ts
vendored
24
dist/index.d.ts
vendored
@ -1 +1,23 @@
|
||||
export * from './cert.classes.cert';
|
||||
export declare class Cert {
|
||||
private _cfEmail;
|
||||
private _cfKey;
|
||||
private _sslDir;
|
||||
certificatesPresent: Certificate[];
|
||||
certificatesValid: Certificate[];
|
||||
gitOriginRepo: any;
|
||||
constructor(optionsArg: {
|
||||
cfEmail: string;
|
||||
cfKey: string;
|
||||
sslDir: string;
|
||||
gitOriginRepo?: string;
|
||||
});
|
||||
getDomainCert(domainNameArg: string, optionsArg?: {
|
||||
force: boolean;
|
||||
}): any;
|
||||
}
|
||||
export declare class Certificate {
|
||||
domainName: string;
|
||||
creationDate: Date;
|
||||
expiryDate: Date;
|
||||
constructor();
|
||||
}
|
||||
|
75
dist/index.js
vendored
75
dist/index.js
vendored
File diff suppressed because one or more lines are too long
1
dist/install.d.ts
vendored
Normal file
1
dist/install.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export declare let startInstall: () => any;
|
20
dist/install.js
vendored
Normal file
20
dist/install.js
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
"use strict";
|
||||
var plugins = require("./cert.plugins");
|
||||
var paths = require("./cert.paths");
|
||||
exports.startInstall = function () {
|
||||
var done = plugins.q.defer();
|
||||
plugins.beautylog.info("installing letsencrypt.sh locally...");
|
||||
plugins.fs.ensureDir(plugins.path.join(__dirname, "assets/"));
|
||||
plugins.smartfile.remote.toFs("https://raw.githubusercontent.com/lukas2511/letsencrypt.sh/master/letsencrypt.sh", paths.letsencryptSh).then(function () {
|
||||
plugins.beautylog.success("Done!");
|
||||
done.resolve();
|
||||
});
|
||||
return done.promise;
|
||||
};
|
||||
var smartcli = new plugins.smartcli.Smartcli();
|
||||
smartcli.addCommand({
|
||||
commandName: "install"
|
||||
}).then(exports.startInstall);
|
||||
smartcli.startParse();
|
||||
|
||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImluc3RhbGwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLElBQVksT0FBTyxXQUFNLGdCQUFnQixDQUFDLENBQUE7QUFDMUMsSUFBWSxLQUFLLFdBQU0sY0FBYyxDQUFDLENBQUE7QUFFM0Isb0JBQVksR0FBRztJQUN0QixJQUFJLElBQUksR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQzdCLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLHNDQUFzQyxDQUFDLENBQUM7SUFFL0QsT0FBTyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7SUFDOUQsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6QixrRkFBa0YsRUFDbEYsS0FBSyxDQUFDLGFBQWEsQ0FDdEIsQ0FBQyxJQUFJLENBQUM7UUFDSCxPQUFPLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUNuQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbkIsQ0FBQyxDQUFDLENBQUM7SUFDSCxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztBQUN4QixDQUFDLENBQUM7QUFFRixJQUFJLFFBQVEsR0FBRyxJQUFJLE9BQU8sQ0FBQyxRQUFRLENBQUMsUUFBUSxFQUFFLENBQUM7QUFDL0MsUUFBUSxDQUFDLFVBQVUsQ0FBQztJQUNoQixXQUFXLEVBQUMsU0FBUztDQUN4QixDQUFDLENBQUMsSUFBSSxDQUFDLG9CQUFZLENBQUMsQ0FBQztBQUN0QixRQUFRLENBQUMsVUFBVSxFQUFFLENBQUMiLCJmaWxlIjoiaW5zdGFsbC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIHBsdWdpbnMgZnJvbSBcIi4vY2VydC5wbHVnaW5zXCI7XG5pbXBvcnQgKiBhcyBwYXRocyBmcm9tIFwiLi9jZXJ0LnBhdGhzXCI7XG5cbmV4cG9ydCBsZXQgc3RhcnRJbnN0YWxsID0gKCkgPT4ge1xuICAgIGxldCBkb25lID0gcGx1Z2lucy5xLmRlZmVyKCk7XG4gICAgcGx1Z2lucy5iZWF1dHlsb2cuaW5mbyhcImluc3RhbGxpbmcgbGV0c2VuY3J5cHQuc2ggbG9jYWxseS4uLlwiKTtcblxuICAgIHBsdWdpbnMuZnMuZW5zdXJlRGlyKHBsdWdpbnMucGF0aC5qb2luKF9fZGlybmFtZSwgXCJhc3NldHMvXCIpKTtcbiAgICBwbHVnaW5zLnNtYXJ0ZmlsZS5yZW1vdGUudG9GcyhcbiAgICAgICAgXCJodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vbHVrYXMyNTExL2xldHNlbmNyeXB0LnNoL21hc3Rlci9sZXRzZW5jcnlwdC5zaFwiLFxuICAgICAgICBwYXRocy5sZXRzZW5jcnlwdFNoXG4gICAgKS50aGVuKCgpID0+IHtcbiAgICAgICAgcGx1Z2lucy5iZWF1dHlsb2cuc3VjY2VzcyhcIkRvbmUhXCIpO1xuICAgICAgICBkb25lLnJlc29sdmUoKTtcbiAgICB9KTtcbiAgICByZXR1cm4gZG9uZS5wcm9taXNlO1xufTtcblxubGV0IHNtYXJ0Y2xpID0gbmV3IHBsdWdpbnMuc21hcnRjbGkuU21hcnRjbGkoKTtcbnNtYXJ0Y2xpLmFkZENvbW1hbmQoe1xuICAgIGNvbW1hbmROYW1lOlwiaW5zdGFsbFwiXG59KS50aGVuKHN0YXJ0SW5zdGFsbCk7XG5zbWFydGNsaS5zdGFydFBhcnNlKCk7Il19
|
@ -1,5 +0,0 @@
|
||||
{
|
||||
"npmts": {
|
||||
"mode": "default"
|
||||
}
|
||||
}
|
38
package.json
38
package.json
@ -1,13 +1,11 @@
|
||||
{
|
||||
"name": "cert",
|
||||
"version": "1.0.8",
|
||||
"version": "0.0.10",
|
||||
"description": "Easily obain SSL certificates from LetsEncrypt. Supports DNS-01 challenge. TypeScript ready.",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"scripts": {
|
||||
"test": "(npm run cleanTest && npmts --nodocs)",
|
||||
"cleanTest": "(rm -rf ./test/assets)",
|
||||
"compile": "(npmts --notest)"
|
||||
"test": "(npmts)",
|
||||
"install": "node dist/install.js install"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@ -26,25 +24,21 @@
|
||||
},
|
||||
"homepage": "https://gitlab.com/pushrocks/cert#readme",
|
||||
"dependencies": {
|
||||
"@types/minimatch": "2.x.x",
|
||||
"@types/q": "0.0.32",
|
||||
"beautylog": "^6.0.0",
|
||||
"cflare": "0.0.10",
|
||||
"fs-extra": "^1.0.0",
|
||||
"lik": "^1.0.27",
|
||||
"beautylog": "^5.0.12",
|
||||
"cflare": "0.0.9",
|
||||
"fs-extra": "^0.30.0",
|
||||
"q": "^1.4.1",
|
||||
"smartacme": "^1.0.2",
|
||||
"smartcli": "^2.0.1",
|
||||
"smartfile": "^4.1.1",
|
||||
"smartgit": "1.0.5",
|
||||
"smartstring": "^2.0.22",
|
||||
"typings-global": "^1.0.14"
|
||||
"shelljs": "^0.7.0",
|
||||
"smartcli": "^1.0.4",
|
||||
"smartfile": "^4.0.8",
|
||||
"smartgit": "0.1.0",
|
||||
"smartstring": "^2.0.10",
|
||||
"typings-global": "^1.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/should": "^8.1.30",
|
||||
"npmts-g": "^5.2.10",
|
||||
"qenv": "^1.1.1",
|
||||
"should": "^11.1.2",
|
||||
"typings-test": "^1.0.3"
|
||||
"npmts-g": "^5.2.6",
|
||||
"qenv": "^1.0.8",
|
||||
"should": "^9.0.2",
|
||||
"typings-test": "^1.0.1"
|
||||
}
|
||||
}
|
||||
|
1656
pnpm-lock.yaml
generated
1656
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
3
test/test.d.ts
vendored
3
test/test.d.ts
vendored
@ -1 +1,2 @@
|
||||
import 'typings-test';
|
||||
import "typings-test";
|
||||
import "should";
|
||||
|
60
test/test.js
60
test/test.js
@ -1,43 +1,37 @@
|
||||
"use strict";
|
||||
require("typings-test");
|
||||
const should = require("should");
|
||||
const qenv_1 = require("qenv");
|
||||
const path = require("path");
|
||||
const q = require("q");
|
||||
const cert = require("../dist/index");
|
||||
let testQenv = new qenv_1.Qenv(process.cwd(), process.cwd() + '/.nogit');
|
||||
let testCert;
|
||||
describe('cert', function () {
|
||||
describe('Cert', function () {
|
||||
it('should create a new Cert object from class', function () {
|
||||
testCert = new cert.Cert({
|
||||
cfEmail: process.env.CF_EMAIL,
|
||||
cfKey: process.env.CF_KEY,
|
||||
sslDirPath: path.join(process.cwd(), 'test/assets'),
|
||||
gitOriginRepo: 'git@gitlab.com:sandboxzone/sandbox-sslorigin.git',
|
||||
leEnv: 'staging'
|
||||
});
|
||||
should(testCert).be.instanceof(cert.Cert);
|
||||
});
|
||||
it('should run class Cert.setup() successful', function (done) {
|
||||
this.timeout(40000);
|
||||
testCert.setup().then(() => {
|
||||
require("should");
|
||||
var qenv_1 = require("qenv");
|
||||
var path = require("path");
|
||||
var install_1 = require("../dist/install");
|
||||
var cert = require("../dist/index");
|
||||
var testQenv = new qenv_1.Qenv(process.cwd(), process.cwd() + "/.nogit");
|
||||
var testCert;
|
||||
describe("cert", function () {
|
||||
describe("install", function () {
|
||||
it("should download letsencrypt.sh", function (done) {
|
||||
this.timeout(5000);
|
||||
install_1.startInstall().then(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
it('should get a valid certificate', function (done) {
|
||||
this.timeout(1200000);
|
||||
let promiseArray = [];
|
||||
function getRandomArbitrary(min, max) {
|
||||
return Math.floor(Math.random() * (max - min) + min);
|
||||
}
|
||||
promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1, 100000)}.bleu.de`));
|
||||
// promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
|
||||
// promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
|
||||
q.all(promiseArray).then(() => {
|
||||
});
|
||||
describe("Cert", function () {
|
||||
it("should create a new Cert object from class", function () {
|
||||
testCert = new cert.Cert({
|
||||
cfEmail: process.env.CF_EMAIL,
|
||||
cfKey: process.env.CF_KEY,
|
||||
sslDir: path.join(process.cwd(), "test/assets")
|
||||
});
|
||||
testCert.should.be.instanceof(cert.Cert);
|
||||
});
|
||||
it("should get a valid certificate", function (done) {
|
||||
this.timeout(120000);
|
||||
testCert.getDomainCert("sub9.bleu.de").then(function () {
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFDaEMsK0JBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3Qix1QkFBdUI7QUFDdkIsc0NBQXFDO0FBR3JDLElBQUksUUFBUSxHQUFHLElBQUksV0FBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBRSxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUyxDQUFDLENBQUE7QUFFakUsSUFBSSxRQUFtQixDQUFBO0FBRXZCLFFBQVEsQ0FBQyxNQUFNLEVBQUM7SUFDWixRQUFRLENBQUMsTUFBTSxFQUFDO1FBQ1osRUFBRSxDQUFDLDRDQUE0QyxFQUFDO1lBQzVDLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVE7Z0JBQzdCLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU07Z0JBQ3pCLFVBQVUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBQyxhQUFhLENBQUM7Z0JBQ2xELGFBQWEsRUFBRSxrREFBa0Q7Z0JBQ2pFLEtBQUssRUFBRSxTQUFTO2FBQ25CLENBQUMsQ0FBQTtZQUNGLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUM3QyxDQUFDLENBQUMsQ0FBQTtRQUNGLEVBQUUsQ0FBQywwQ0FBMEMsRUFBRSxVQUFTLElBQUk7WUFDeEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUNuQixRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsSUFBSSxDQUFDO2dCQUNsQixJQUFJLEVBQUUsQ0FBQTtZQUNWLENBQUMsQ0FBQyxDQUFBO1FBQ04sQ0FBQyxDQUFDLENBQUE7UUFDRixFQUFFLENBQUMsZ0NBQWdDLEVBQUMsVUFBUyxJQUFJO1lBQzdDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUE7WUFDckIsSUFBSSxZQUFZLEdBQUcsRUFBRSxDQUFBO1lBQ3JCLDRCQUE0QixHQUFHLEVBQUUsR0FBRztnQkFDaEMsTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxDQUFBO1lBQ3hELENBQUM7WUFDRCxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsVUFBVSxrQkFBa0IsQ0FBQyxDQUFDLEVBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUE7WUFDNUYsK0ZBQStGO1lBQy9GLCtGQUErRjtZQUMvRixDQUFDLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDckIsSUFBSSxFQUFFLENBQUE7WUFDVixDQUFDLENBQUMsQ0FBQTtRQUNOLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQSJ9
|
||||
|
||||
//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLFFBQU8sY0FBYyxDQUFDLENBQUE7QUFDdEIsUUFBTyxRQUFRLENBQUMsQ0FBQTtBQUNoQixxQkFBbUIsTUFBTSxDQUFDLENBQUE7QUFDMUIsSUFBTyxJQUFJLFdBQVcsTUFBTSxDQUFDLENBQUM7QUFFOUIsd0JBQTJCLGlCQUFpQixDQUFDLENBQUE7QUFDN0MsSUFBWSxJQUFJLFdBQU0sZUFBZSxDQUFDLENBQUE7QUFHdEMsSUFBSSxRQUFRLEdBQUcsSUFBSSxXQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTLENBQUMsQ0FBQztBQUVsRSxJQUFJLFFBQWtCLENBQUM7QUFFdkIsUUFBUSxDQUFDLE1BQU0sRUFBQztJQUNaLFFBQVEsQ0FBQyxTQUFTLEVBQUM7UUFDZixFQUFFLENBQUMsZ0NBQWdDLEVBQUMsVUFBUyxJQUFJO1lBQzdDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDbkIsc0JBQVksRUFBRSxDQUFDLElBQUksQ0FBQztnQkFDaEIsSUFBSSxFQUFFLENBQUM7WUFDWCxDQUFDLENBQUMsQ0FBQTtRQUNOLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFDRixRQUFRLENBQUMsTUFBTSxFQUFDO1FBQ1osRUFBRSxDQUFDLDRDQUE0QyxFQUFDO1lBQzVDLFFBQVEsR0FBRyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFFBQVE7Z0JBQzdCLEtBQUssRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLE1BQU07Z0JBQ3pCLE1BQU0sRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsRUFBQyxhQUFhLENBQUM7YUFDakQsQ0FBQyxDQUFDO1lBQ0gsUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUM3QyxDQUFDLENBQUMsQ0FBQTtRQUNGLEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBQyxVQUFTLElBQUk7WUFDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNyQixRQUFRLENBQUMsYUFBYSxDQUFDLGNBQWMsQ0FBQyxDQUFDLElBQUksQ0FBQztnQkFDeEMsSUFBSSxFQUFFLENBQUM7WUFDWCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQyIsImZpbGUiOiJ0ZXN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IFwidHlwaW5ncy10ZXN0XCI7XG5pbXBvcnQgXCJzaG91bGRcIjtcbmltcG9ydCB7UWVudn0gZnJvbSBcInFlbnZcIjtcbmltcG9ydCBwYXRoID0gcmVxdWlyZShcInBhdGhcIik7XG5cbmltcG9ydCB7c3RhcnRJbnN0YWxsfSBmcm9tIFwiLi4vZGlzdC9pbnN0YWxsXCI7XG5pbXBvcnQgKiBhcyBjZXJ0IGZyb20gXCIuLi9kaXN0L2luZGV4XCI7XG5cblxubGV0IHRlc3RRZW52ID0gbmV3IFFlbnYocHJvY2Vzcy5jd2QoKSwgcHJvY2Vzcy5jd2QoKSArIFwiLy5ub2dpdFwiKTtcblxubGV0IHRlc3RDZXJ0OmNlcnQuQ2VydDtcblxuZGVzY3JpYmUoXCJjZXJ0XCIsZnVuY3Rpb24oKXtcbiAgICBkZXNjcmliZShcImluc3RhbGxcIixmdW5jdGlvbigpe1xuICAgICAgICBpdChcInNob3VsZCBkb3dubG9hZCBsZXRzZW5jcnlwdC5zaFwiLGZ1bmN0aW9uKGRvbmUpe1xuICAgICAgICAgICAgdGhpcy50aW1lb3V0KDUwMDApO1xuICAgICAgICAgICAgc3RhcnRJbnN0YWxsKCkudGhlbigoKSA9PiB7XG4gICAgICAgICAgICAgICAgZG9uZSgpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgfSlcbiAgICB9KVxuICAgIGRlc2NyaWJlKFwiQ2VydFwiLGZ1bmN0aW9uKCl7XG4gICAgICAgIGl0KFwic2hvdWxkIGNyZWF0ZSBhIG5ldyBDZXJ0IG9iamVjdCBmcm9tIGNsYXNzXCIsZnVuY3Rpb24oKXtcbiAgICAgICAgICAgIHRlc3RDZXJ0ID0gbmV3IGNlcnQuQ2VydCh7XG4gICAgICAgICAgICAgICAgY2ZFbWFpbDogcHJvY2Vzcy5lbnYuQ0ZfRU1BSUwsXG4gICAgICAgICAgICAgICAgY2ZLZXk6IHByb2Nlc3MuZW52LkNGX0tFWSxcbiAgICAgICAgICAgICAgICBzc2xEaXI6IHBhdGguam9pbihwcm9jZXNzLmN3ZCgpLFwidGVzdC9hc3NldHNcIilcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgdGVzdENlcnQuc2hvdWxkLmJlLmluc3RhbmNlb2YoY2VydC5DZXJ0KTtcbiAgICAgICAgfSlcbiAgICAgICAgaXQoXCJzaG91bGQgZ2V0IGEgdmFsaWQgY2VydGlmaWNhdGVcIixmdW5jdGlvbihkb25lKXtcbiAgICAgICAgICAgIHRoaXMudGltZW91dCgxMjAwMDApO1xuICAgICAgICAgICAgdGVzdENlcnQuZ2V0RG9tYWluQ2VydChcInN1YjkuYmxldS5kZVwiKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgICAgICBkb25lKCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSlcbiAgICB9KVxufSk7Il19
|
||||
|
70
test/test.ts
70
test/test.ts
@ -1,45 +1,39 @@
|
||||
import 'typings-test'
|
||||
import * as should from 'should'
|
||||
import {Qenv} from 'qenv'
|
||||
import path = require('path')
|
||||
import q = require('q')
|
||||
import * as cert from '../dist/index'
|
||||
import "typings-test";
|
||||
import "should";
|
||||
import {Qenv} from "qenv";
|
||||
import path = require("path");
|
||||
|
||||
import {startInstall} from "../dist/install";
|
||||
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(){
|
||||
it('should create a new Cert object from class',function(){
|
||||
testCert = new cert.Cert({
|
||||
cfEmail: process.env.CF_EMAIL,
|
||||
cfKey: process.env.CF_KEY,
|
||||
sslDirPath: path.join(process.cwd(),'test/assets'),
|
||||
gitOriginRepo: 'git@gitlab.com:sandboxzone/sandbox-sslorigin.git',
|
||||
leEnv: 'staging'
|
||||
})
|
||||
should(testCert).be.instanceof(cert.Cert)
|
||||
})
|
||||
it('should run class Cert.setup() successful', function(done){
|
||||
this.timeout(40000)
|
||||
testCert.setup().then(() => {
|
||||
done()
|
||||
})
|
||||
})
|
||||
it('should get a valid certificate',function(done){
|
||||
this.timeout(1200000)
|
||||
let promiseArray = []
|
||||
function getRandomArbitrary(min, max) {
|
||||
return Math.floor(Math.random() * (max - min) + min)
|
||||
}
|
||||
promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
|
||||
// promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
|
||||
// promiseArray.push(testCert.addCertificate(`testing${getRandomArbitrary(1,100000)}.bleu.de`))
|
||||
q.all(promiseArray).then(() => {
|
||||
done()
|
||||
describe("cert",function(){
|
||||
describe("install",function(){
|
||||
it("should download letsencrypt.sh",function(done){
|
||||
this.timeout(5000);
|
||||
startInstall().then(() => {
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
describe("Cert",function(){
|
||||
it("should create a new Cert object from class",function(){
|
||||
testCert = new cert.Cert({
|
||||
cfEmail: process.env.CF_EMAIL,
|
||||
cfKey: process.env.CF_KEY,
|
||||
sslDir: path.join(process.cwd(),"test/assets")
|
||||
});
|
||||
testCert.should.be.instanceof(cert.Cert);
|
||||
})
|
||||
it("should get a valid certificate",function(done){
|
||||
this.timeout(120000);
|
||||
testCert.getDomainCert("sub9.bleu.de").then(() => {
|
||||
done();
|
||||
});
|
||||
})
|
||||
})
|
||||
});
|
@ -1,98 +0,0 @@
|
||||
import * as q from 'q'
|
||||
import { Stringmap, Objectmap } from 'lik'
|
||||
|
||||
import * as plugins from './cert.plugins'
|
||||
import * as paths from './cert.paths'
|
||||
|
||||
// classes
|
||||
import { Certificate } from './cert.classes.certificate'
|
||||
import { CertRepo } from './cert.classes.certrepo'
|
||||
import { Letsencrypt, TLeEnv } from './cert.classes.letsencrypt'
|
||||
import { ChallengeHandler } from './cert.classes.challengehandler'
|
||||
|
||||
|
||||
export interface ICertConstructorOptions {
|
||||
cfEmail: string,
|
||||
cfKey: string,
|
||||
sslDirPath?: string,
|
||||
gitOriginRepo?: string,
|
||||
leEnv?: TLeEnv
|
||||
}
|
||||
|
||||
export class Cert {
|
||||
domainStringRequestMap = new Stringmap()
|
||||
certificateMap = new Objectmap<Certificate>()
|
||||
letsencrypt: Letsencrypt
|
||||
private _challengeHandler: ChallengeHandler
|
||||
private _certRepo: CertRepo
|
||||
|
||||
/**
|
||||
* Constructor for Cert object
|
||||
*/
|
||||
constructor(optionsArg: ICertConstructorOptions) {
|
||||
|
||||
// set up challengehandler
|
||||
this._challengeHandler = new ChallengeHandler({
|
||||
cfEmail: optionsArg.cfEmail,
|
||||
cfKey: optionsArg.cfKey
|
||||
})
|
||||
|
||||
// setup Letsencrypt
|
||||
this.letsencrypt = new Letsencrypt({
|
||||
leEnv: optionsArg.leEnv,
|
||||
sslDir: optionsArg.sslDirPath,
|
||||
challengeHandler: this._challengeHandler
|
||||
})
|
||||
|
||||
this._certRepo = new CertRepo({
|
||||
sslDirPath: optionsArg.sslDirPath,
|
||||
remoteGitUrl: optionsArg.gitOriginRepo,
|
||||
certInstance: this
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* setup the Cert instanceof
|
||||
* @executes ASYNC
|
||||
* @return Promise
|
||||
*/
|
||||
setup() {
|
||||
return this._certRepo.setup()
|
||||
}
|
||||
|
||||
/**
|
||||
* adds a Certificate for a given domain
|
||||
*/
|
||||
addCertificate(domainNameArg: string, optionsArg: { force: boolean } = { force: false }) {
|
||||
let done = q.defer()
|
||||
let certificateForDomain = this.certificateMap.find((certificate) => {
|
||||
return certificate.domainName === domainNameArg
|
||||
})
|
||||
if (certificateForDomain instanceof Certificate) {
|
||||
certificateForDomain.renew()
|
||||
.then(done.resolve)
|
||||
} else {
|
||||
certificateForDomain = new Certificate({
|
||||
certInstance: this,
|
||||
domainName: domainNameArg
|
||||
})
|
||||
certificateForDomain.renew()
|
||||
.then(done.resolve)
|
||||
}
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* cleans up old certificates
|
||||
*/
|
||||
cleanOldCertificates() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* executes the current batch of jobs
|
||||
*/
|
||||
deploy() {
|
||||
|
||||
}
|
||||
}
|
@ -1,129 +0,0 @@
|
||||
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() { }
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
import * as q from 'q'
|
||||
import { GitRepo } from 'smartgit'
|
||||
|
||||
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
|
||||
remoteGitUrl: string
|
||||
certInstance: Cert
|
||||
}
|
||||
|
||||
export class CertRepo {
|
||||
private _sslDirPath: string
|
||||
private _remoteGitUrl: string
|
||||
private gitRepo: GitRepo
|
||||
private _certInstance: Cert
|
||||
constructor(optionsArg: ICertRepoConstructorOptions) {
|
||||
this._sslDirPath = optionsArg.sslDirPath
|
||||
this._remoteGitUrl = optionsArg.remoteGitUrl
|
||||
this._certInstance = optionsArg.certInstance
|
||||
|
||||
// setup sslDir
|
||||
if (!this._sslDirPath) {
|
||||
this._sslDirPath = paths.defaultSslDir
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* setup the Cert instance
|
||||
*/
|
||||
setup() {
|
||||
// setup Git
|
||||
let done = q.defer()
|
||||
if (this._remoteGitUrl) {
|
||||
plugins.smartfile.fs.ensureEmptyDirSync(paths.defaultSslDir)
|
||||
plugins.smartgit.createRepoFromClone(this._remoteGitUrl, paths.defaultSslDir)
|
||||
.then(gitRepoArg => {
|
||||
this.gitRepo = gitRepoArg
|
||||
done.resolve()
|
||||
})
|
||||
}
|
||||
return done.promise
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.gitRepo) {
|
||||
this.gitRepo.pull('origin', 'master')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pushes all new requested certificates to git origin
|
||||
*/
|
||||
sslGitOriginAddCommitPush = () => {
|
||||
if (this._remoteGitUrl) {
|
||||
this.gitRepo.addAll()
|
||||
this.gitRepo.commit('added new SSL certificates and deleted obsolete ones.')
|
||||
this.gitRepo.push('origin', 'master')
|
||||
}
|
||||
}
|
||||
}
|
@ -1,84 +0,0 @@
|
||||
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
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
import * as q from 'q'
|
||||
let letsencrypt = require('letsencrypt')
|
||||
let leStore = require('le-store-certbot')
|
||||
|
||||
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 _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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* register a domain
|
||||
*/
|
||||
registerDomain(domainNameArg: string) {
|
||||
plugins.beautylog.log(`trying to register domain ${domainNameArg}`)
|
||||
let done = q.defer()
|
||||
plugins.smartfile.fs.ensureDirSync(plugins.path.join(paths.leConfigDir, 'live', domainNameArg))
|
||||
return done.promise
|
||||
}
|
||||
}
|
74
ts/cert.hook.ts
Normal file
74
ts/cert.hook.ts
Normal file
@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env node
|
||||
// the shebang line above makes sure this script will get interpreted by node
|
||||
|
||||
import "typings-global";
|
||||
import * as plugins from "./cert.plugins";
|
||||
import * as paths from "./cert.paths";
|
||||
|
||||
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");
|
||||
return done.promise;
|
||||
}
|
||||
|
||||
let cooldown = () => {
|
||||
let done = plugins.q.defer();
|
||||
let cooldowntime = 40000;
|
||||
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,9 +1,7 @@
|
||||
import * as plugins from './cert.plugins'
|
||||
import "typings-global";
|
||||
import * as plugins from "./cert.plugins";
|
||||
|
||||
// dirs
|
||||
export let projectDir = plugins.path.join(__dirname,'../')
|
||||
export let assetDir = plugins.path.join(projectDir,'assets')
|
||||
export let defaultSslDir = plugins.path.join(assetDir,'defaultSslDir')
|
||||
export let leConfigDir = plugins.path.join(assetDir,'letsencrypt')
|
||||
plugins.smartfile.fs.ensureDirSync(leConfigDir)
|
||||
plugins.smartfile.fs.ensureDirSync(defaultSslDir)
|
||||
export let certHook = plugins.path.join(__dirname,"cert.hook.js");
|
||||
export let config = plugins.path.join(__dirname,"assets/config.json");
|
||||
export let letsencryptSh = plugins.path.join(__dirname,"assets/letsencrypt.sh");
|
||||
export let certDir = plugins.path.join(__dirname,"/assets/certs");
|
@ -1,26 +1,12 @@
|
||||
import 'typings-global'
|
||||
import * as beautylog from 'beautylog'
|
||||
import * as cflare from 'cflare'
|
||||
let fs = require('fs-extra')
|
||||
import * as lik from 'lik'
|
||||
import * as path from 'path'
|
||||
import * as q from 'q'
|
||||
import * as shelljs from 'shelljs'
|
||||
import * as smartcli from 'smartcli'
|
||||
import * as smartfile from 'smartfile'
|
||||
import * as smartgit from 'smartgit'
|
||||
import * as smartstring from 'smartstring'
|
||||
import "typings-global";
|
||||
export import beautylog = require("beautylog");
|
||||
export import cflare = require("cflare");
|
||||
export let fs = require("fs-extra");
|
||||
export import path = require("path");
|
||||
export let q = require("q");
|
||||
export let shelljs = require("shelljs");
|
||||
export import smartcli = require("smartcli");
|
||||
export import smartfile = require("smartfile");
|
||||
export import smartgit = require("smartgit");
|
||||
export import smartstring = require("smartstring");
|
||||
|
||||
export {
|
||||
beautylog,
|
||||
cflare,
|
||||
fs,
|
||||
lik,
|
||||
path,
|
||||
q,
|
||||
shelljs,
|
||||
smartcli,
|
||||
smartfile,
|
||||
smartgit,
|
||||
smartstring
|
||||
}
|
||||
|
96
ts/index.ts
96
ts/index.ts
@ -1 +1,95 @@
|
||||
export * from './cert.classes.cert'
|
||||
import * as plugins from "./cert.plugins";
|
||||
import * as paths from "./cert.paths";
|
||||
|
||||
export class Cert {
|
||||
private _cfEmail: string;
|
||||
private _cfKey: string;
|
||||
private _sslDir: string;
|
||||
certificatesPresent:Certificate[];
|
||||
certificatesValid:Certificate[];
|
||||
gitOriginRepo;
|
||||
constructor(optionsArg: {
|
||||
cfEmail: string,
|
||||
cfKey: string,
|
||||
sslDir: string,
|
||||
gitOriginRepo?: string
|
||||
}) {
|
||||
this._cfEmail = optionsArg.cfEmail;
|
||||
this._cfKey = optionsArg.cfKey;
|
||||
this._sslDir = optionsArg.sslDir;
|
||||
this.gitOriginRepo = optionsArg.gitOriginRepo;
|
||||
let config = {
|
||||
cfEmail: this._cfEmail,
|
||||
cfKey: this._cfKey
|
||||
}
|
||||
plugins.smartfile.memory.toFsSync(JSON.stringify(config),plugins.path.join(__dirname, "assets/config.json"));
|
||||
};
|
||||
getDomainCert(domainNameArg: string,optionsArg?:{force:boolean}) {
|
||||
let done = plugins.q.defer();
|
||||
if (!checkDomainsStillValid(domainNameArg) || optionsArg.force) {
|
||||
plugins.shelljs.exec("chmod 700 " + paths.letsencryptSh);
|
||||
plugins.shelljs.exec("chmod 700 " + paths.certHook);
|
||||
plugins.shelljs.exec("bash -c \"" + paths.letsencryptSh + " -c -d " + domainNameArg + " -t dns-01 -k " + paths.certHook + " -o " + paths.certDir + "\"");
|
||||
let fetchedCertsArray:string[] = plugins.smartfile.fs.listFoldersSync(paths.certDir);
|
||||
if(fetchedCertsArray.indexOf(domainNameArg) != -1){
|
||||
updateSslDirSync(this._sslDir,domainNameArg);
|
||||
}
|
||||
done.resolve();
|
||||
} else {
|
||||
plugins.beautylog.info("certificate for " + domainNameArg + " is still valid! Not fetching new one!");
|
||||
done.resolve();
|
||||
}
|
||||
return done.promise;
|
||||
};
|
||||
}
|
||||
|
||||
export class Certificate {
|
||||
domainName: string;
|
||||
creationDate: Date;
|
||||
expiryDate: Date;
|
||||
constructor() {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
interface certConfig {
|
||||
domainName:string;
|
||||
created:number;
|
||||
expires:number;
|
||||
}
|
||||
|
||||
let checkDomainsStillValid = (domainNameArg: string): boolean => {
|
||||
return false;
|
||||
}
|
||||
|
||||
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.toFs(
|
||||
JSON.stringify(certConfig),
|
||||
plugins.path.join(sslDirArg,domainNameArg,"config.json")
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
let updateGitOrigin = () => {
|
||||
|
||||
}
|
23
ts/install.ts
Normal file
23
ts/install.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import * as plugins from "./cert.plugins";
|
||||
import * as paths from "./cert.paths";
|
||||
|
||||
export let startInstall = () => {
|
||||
let done = plugins.q.defer();
|
||||
plugins.beautylog.info("installing letsencrypt.sh locally...");
|
||||
|
||||
plugins.fs.ensureDir(plugins.path.join(__dirname, "assets/"));
|
||||
plugins.smartfile.remote.toFs(
|
||||
"https://raw.githubusercontent.com/lukas2511/letsencrypt.sh/master/letsencrypt.sh",
|
||||
paths.letsencryptSh
|
||||
).then(() => {
|
||||
plugins.beautylog.success("Done!");
|
||||
done.resolve();
|
||||
});
|
||||
return done.promise;
|
||||
};
|
||||
|
||||
let smartcli = new plugins.smartcli.Smartcli();
|
||||
smartcli.addCommand({
|
||||
commandName:"install"
|
||||
}).then(startInstall);
|
||||
smartcli.startParse();
|
Loading…
x
Reference in New Issue
Block a user