start better segregation of concerns
This commit is contained in:
		
							
								
								
									
										21
									
								
								dist/smartacme.classes.acmeaccount.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								dist/smartacme.classes.acmeaccount.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,22 @@
 | 
			
		||||
import 'typings-global';
 | 
			
		||||
/// <reference types="q" />
 | 
			
		||||
import * as q from 'q';
 | 
			
		||||
import { SmartAcme } from './smartacme.classes.smartacme';
 | 
			
		||||
/**
 | 
			
		||||
 * class AcmeAccount represents an AcmeAccount
 | 
			
		||||
 */
 | 
			
		||||
export declare class AcmeAccount {
 | 
			
		||||
    parentSmartAcme: SmartAcme;
 | 
			
		||||
    location: string;
 | 
			
		||||
    link: string;
 | 
			
		||||
    JWK: any;
 | 
			
		||||
    constructor(smartAcmeParentArg: SmartAcme);
 | 
			
		||||
    /**
 | 
			
		||||
     * register the account with letsencrypt
 | 
			
		||||
     */
 | 
			
		||||
    register(): q.Promise<{}>;
 | 
			
		||||
    /**
 | 
			
		||||
     * agree to letsencrypr terms of service
 | 
			
		||||
     */
 | 
			
		||||
    agreeTos(): q.Promise<{}>;
 | 
			
		||||
    createAcmeCert(domainNameArg: string): void;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										52
									
								
								dist/smartacme.classes.acmeaccount.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										52
									
								
								dist/smartacme.classes.acmeaccount.js
									
									
									
									
										vendored
									
									
								
							@@ -1,6 +1,54 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
require("typings-global");
 | 
			
		||||
const q = require("q");
 | 
			
		||||
/**
 | 
			
		||||
 * class AcmeAccount represents an AcmeAccount
 | 
			
		||||
 */
 | 
			
		||||
class AcmeAccount {
 | 
			
		||||
    constructor(smartAcmeParentArg) {
 | 
			
		||||
        this.parentSmartAcme = smartAcmeParentArg;
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * register the account with letsencrypt
 | 
			
		||||
     */
 | 
			
		||||
    register() {
 | 
			
		||||
        let done = q.defer();
 | 
			
		||||
        this.parentSmartAcme.rawacmeClient.newReg({
 | 
			
		||||
            contact: ['mailto:domains@lossless.org']
 | 
			
		||||
        }, (err, res) => {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.error('smartacme: something went wrong:');
 | 
			
		||||
                console.log(err);
 | 
			
		||||
                done.reject(err);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            this.JWK = res.body.key;
 | 
			
		||||
            this.link = res.headers.link;
 | 
			
		||||
            console.log(this.link);
 | 
			
		||||
            this.location = res.headers.location;
 | 
			
		||||
            done.resolve();
 | 
			
		||||
        });
 | 
			
		||||
        return done.promise;
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * agree to letsencrypr terms of service
 | 
			
		||||
     */
 | 
			
		||||
    agreeTos() {
 | 
			
		||||
        let done = q.defer();
 | 
			
		||||
        let tosPart = this.link.split(',')[1];
 | 
			
		||||
        let tosLinkPortion = tosPart.split(';')[0];
 | 
			
		||||
        let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '');
 | 
			
		||||
        this.parentSmartAcme.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.log(err);
 | 
			
		||||
                done.reject(err);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            done.resolve();
 | 
			
		||||
        });
 | 
			
		||||
        return done.promise;
 | 
			
		||||
    }
 | 
			
		||||
    createAcmeCert(domainNameArg) {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
exports.AcmeAccount = AcmeAccount;
 | 
			
		||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWFjY291bnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEJBQXVCO0FBRXZCO0NBRUM7QUFGRCxrQ0FFQyJ9
 | 
			
		||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuYWNtZWFjY291bnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuY2xhc3Nlcy5hY21lYWNjb3VudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsdUJBQXNCO0FBUXRCOztHQUVHO0FBQ0g7SUFLSSxZQUFZLGtCQUE2QjtRQUNyQyxJQUFJLENBQUMsZUFBZSxHQUFHLGtCQUFrQixDQUFBO0lBQzdDLENBQUM7SUFFRDs7T0FFRztJQUNILFFBQVE7UUFDSixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDcEIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUNyQztZQUNJLE9BQU8sRUFBRSxDQUFDLDZCQUE2QixDQUFDO1NBQzNDLEVBQ0QsQ0FBQyxHQUFHLEVBQUUsR0FBRztZQUNMLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7Z0JBQ04sT0FBTyxDQUFDLEtBQUssQ0FBQyxrQ0FBa0MsQ0FBQyxDQUFBO2dCQUNqRCxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixNQUFNLENBQUE7WUFDVixDQUFDO1lBQ0QsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQTtZQUN2QixJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFBO1lBQzVCLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFBO1lBQ3RCLElBQUksQ0FBQyxRQUFRLEdBQUcsR0FBRyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUE7WUFDcEMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ04sTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztJQUVEOztPQUVHO0lBQ0gsUUFBUTtRQUNKLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUNwQixJQUFJLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQTtRQUNyQyxJQUFJLGNBQWMsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzFDLElBQUksR0FBRyxHQUFHLGNBQWMsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUNsRSxJQUFJLENBQUMsZUFBZSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLFNBQVMsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxFQUFFLEdBQUc7WUFDakcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDTixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNoQixNQUFNLENBQUE7WUFDVixDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FBQyxDQUFBO1FBQ0YsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztJQUVELGNBQWMsQ0FBQyxhQUFxQjtJQUVwQyxDQUFDO0NBQ0o7QUF4REQsa0NBd0RDIn0=
 | 
			
		||||
							
								
								
									
										72
									
								
								dist/smartacme.classes.acmecert.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										72
									
								
								dist/smartacme.classes.acmecert.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -1,3 +1,71 @@
 | 
			
		||||
import 'typings-global';
 | 
			
		||||
export declare class AcmeCert {
 | 
			
		||||
/// <reference types="q" />
 | 
			
		||||
import * as q from 'q';
 | 
			
		||||
import { IRsaKeypair } from './smartacme.classes.smartacme';
 | 
			
		||||
import { AcmeAccount } from './smartacme.classes.acmeaccount';
 | 
			
		||||
/**
 | 
			
		||||
 * types of challenges supported by letsencrypt and this module
 | 
			
		||||
 */
 | 
			
		||||
export declare type TChallengeType = 'dns-01' | 'http-01';
 | 
			
		||||
/**
 | 
			
		||||
 * values that a challenge's status can have
 | 
			
		||||
 */
 | 
			
		||||
export declare type TChallengeStatus = 'pending';
 | 
			
		||||
export interface ISmartAcmeChallenge {
 | 
			
		||||
    uri: string;
 | 
			
		||||
    status: TChallengeStatus;
 | 
			
		||||
    type: TChallengeType;
 | 
			
		||||
    token: string;
 | 
			
		||||
    keyAuthorization: string;
 | 
			
		||||
}
 | 
			
		||||
export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
 | 
			
		||||
    keyHash: string;
 | 
			
		||||
}
 | 
			
		||||
export interface IAcmeCsrConstructorOptions {
 | 
			
		||||
    bit: number;
 | 
			
		||||
    key: string;
 | 
			
		||||
    domain: string;
 | 
			
		||||
    country: string;
 | 
			
		||||
    country_short: string;
 | 
			
		||||
    locality: string;
 | 
			
		||||
    organization: string;
 | 
			
		||||
    organization_short: string;
 | 
			
		||||
    password: string;
 | 
			
		||||
    unstructured: string;
 | 
			
		||||
    subject_alt_names: string[];
 | 
			
		||||
}
 | 
			
		||||
/**
 | 
			
		||||
 * class AcmeCert represents a cert for domain
 | 
			
		||||
 */
 | 
			
		||||
export declare class AcmeCert {
 | 
			
		||||
    attributes: any;
 | 
			
		||||
    fullchain: string;
 | 
			
		||||
    parentAcmeAccount: AcmeAccount;
 | 
			
		||||
    csr: any;
 | 
			
		||||
    validFrom: Date;
 | 
			
		||||
    validTo: Date;
 | 
			
		||||
    keypair: IRsaKeypair;
 | 
			
		||||
    keyPairFinal: IRsaKeypair;
 | 
			
		||||
    constructor(optionsArg: IAcmeCsrConstructorOptions, parentSmartAcmeArg: any);
 | 
			
		||||
    /**
 | 
			
		||||
     * requests a challenge for a domain
 | 
			
		||||
     * @param domainNameArg - the domain name to request a challenge for
 | 
			
		||||
     * @param challengeType - the challenge type to request
 | 
			
		||||
     */
 | 
			
		||||
    requestChallenge(domainNameArg: string, challengeTypeArg?: TChallengeType): q.Promise<ISmartAcmeChallengeAccepted>;
 | 
			
		||||
    /**
 | 
			
		||||
     * validates a challenge, only call after you have set the challenge at the expected location
 | 
			
		||||
     */
 | 
			
		||||
    validate(challenge: ISmartAcmeChallengeAccepted): q.Promise<{}>;
 | 
			
		||||
    /**
 | 
			
		||||
     * requests a certificate
 | 
			
		||||
     */
 | 
			
		||||
    requestCert(): q.Promise<{}>;
 | 
			
		||||
    /**
 | 
			
		||||
     * getCertificate - takes care of cooldown, validation polling and certificate retrieval
 | 
			
		||||
     */
 | 
			
		||||
    getCertificate(): void;
 | 
			
		||||
    /**
 | 
			
		||||
     * accept a challenge - for private use only
 | 
			
		||||
     */
 | 
			
		||||
    private acceptChallenge(challenge);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										142
									
								
								dist/smartacme.classes.acmecert.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										142
									
								
								dist/smartacme.classes.acmecert.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										21
									
								
								dist/smartacme.classes.helper.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								dist/smartacme.classes.helper.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -1,21 +0,0 @@
 | 
			
		||||
/// <reference types="q" />
 | 
			
		||||
import 'typings-global';
 | 
			
		||||
import * as q from 'q';
 | 
			
		||||
import { SmartAcme } from './smartacme.classes.smartacme';
 | 
			
		||||
export interface IRsaKeypair {
 | 
			
		||||
    publicKey: string;
 | 
			
		||||
    privateKey: string;
 | 
			
		||||
}
 | 
			
		||||
export declare class SmartacmeHelper {
 | 
			
		||||
    parentSmartAcme: SmartAcme;
 | 
			
		||||
    constructor(smartAcmeArg: SmartAcme);
 | 
			
		||||
    /**
 | 
			
		||||
     * creates a keypair to use with requests and to generate JWK from
 | 
			
		||||
     */
 | 
			
		||||
    createKeypair(bit?: number): IRsaKeypair;
 | 
			
		||||
    /**
 | 
			
		||||
     * gets an existing registration
 | 
			
		||||
     * @executes ASYNC
 | 
			
		||||
     */
 | 
			
		||||
    getReg(): q.Promise<{}>;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								dist/smartacme.classes.helper.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										40
									
								
								dist/smartacme.classes.helper.js
									
									
									
									
										vendored
									
									
								
							@@ -1,40 +0,0 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
require("typings-global");
 | 
			
		||||
const q = require("q");
 | 
			
		||||
let rsaKeygen = require('rsa-keygen');
 | 
			
		||||
class SmartacmeHelper {
 | 
			
		||||
    constructor(smartAcmeArg) {
 | 
			
		||||
        this.parentSmartAcme = smartAcmeArg;
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * creates a keypair to use with requests and to generate JWK from
 | 
			
		||||
     */
 | 
			
		||||
    createKeypair(bit = 2048) {
 | 
			
		||||
        let result = rsaKeygen.generate(bit);
 | 
			
		||||
        return {
 | 
			
		||||
            publicKey: result.public_key,
 | 
			
		||||
            privateKey: result.private_key
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * gets an existing registration
 | 
			
		||||
     * @executes ASYNC
 | 
			
		||||
     */
 | 
			
		||||
    getReg() {
 | 
			
		||||
        let done = q.defer();
 | 
			
		||||
        let body = { resource: 'reg' };
 | 
			
		||||
        this.parentSmartAcme.rawacmeClient.post(this.parentSmartAcme.location, body, this.parentSmartAcme.keyPair, (err, res) => {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.error('smartacme: something went wrong:');
 | 
			
		||||
                console.log(err);
 | 
			
		||||
                done.reject(err);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            console.log(JSON.stringify(res.body));
 | 
			
		||||
            done.resolve();
 | 
			
		||||
        });
 | 
			
		||||
        return done.promise;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
exports.SmartacmeHelper = SmartacmeHelper;
 | 
			
		||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmNsYXNzZXMuaGVscGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvc21hcnRhY21lLmNsYXNzZXMuaGVscGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSwwQkFBdUI7QUFDdkIsdUJBQXNCO0FBQ3RCLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQTtBQVNyQztJQUdJLFlBQVksWUFBdUI7UUFDL0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxZQUFZLENBQUE7SUFDdkMsQ0FBQztJQUVEOztPQUVHO0lBQ0gsYUFBYSxDQUFDLEdBQUcsR0FBRyxJQUFJO1FBQ3BCLElBQUksTUFBTSxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDcEMsTUFBTSxDQUFDO1lBQ0gsU0FBUyxFQUFFLE1BQU0sQ0FBQyxVQUFVO1lBQzVCLFVBQVUsRUFBRSxNQUFNLENBQUMsV0FBVztTQUNqQyxDQUFBO0lBQ0wsQ0FBQztJQUVEOzs7T0FHRztJQUNILE1BQU07UUFDRixJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7UUFDcEIsSUFBSSxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUE7UUFDOUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUNuQyxJQUFJLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFDN0IsSUFBSSxFQUFFLElBQUksQ0FBQyxlQUFlLENBQUMsT0FBTyxFQUNsQyxDQUFDLEdBQUcsRUFBRSxHQUFHO1lBQ0wsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztnQkFDTixPQUFPLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7Z0JBQ2pELE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLE1BQU0sQ0FBQTtZQUNWLENBQUM7WUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7WUFDckMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO1FBQ2xCLENBQUMsQ0FDSixDQUFBO1FBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7SUFDdkIsQ0FBQztDQUNKO0FBekNELDBDQXlDQyJ9
 | 
			
		||||
							
								
								
									
										51
									
								
								dist/smartacme.classes.smartacme.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										51
									
								
								dist/smartacme.classes.smartacme.d.ts
									
									
									
									
										vendored
									
									
								
							@@ -1,57 +1,34 @@
 | 
			
		||||
/// <reference types="q" />
 | 
			
		||||
import 'typings-global';
 | 
			
		||||
import * as q from 'q';
 | 
			
		||||
import { SmartacmeHelper, IRsaKeypair } from './smartacme.classes.helper';
 | 
			
		||||
export declare type TChallengeType = 'dns-01' | 'http-01';
 | 
			
		||||
export declare type TChallengeStatus = 'pending';
 | 
			
		||||
export interface ISmartAcmeChallenge {
 | 
			
		||||
    uri: string;
 | 
			
		||||
    status: TChallengeStatus;
 | 
			
		||||
    type: TChallengeType;
 | 
			
		||||
    token: string;
 | 
			
		||||
    keyAuthorization: string;
 | 
			
		||||
}
 | 
			
		||||
export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
 | 
			
		||||
    keyHash: string;
 | 
			
		||||
import { AcmeAccount } from './smartacme.classes.acmeaccount';
 | 
			
		||||
/**
 | 
			
		||||
 * a rsa keypair needed for account creation and subsequent requests
 | 
			
		||||
 */
 | 
			
		||||
export interface IRsaKeypair {
 | 
			
		||||
    publicKey: string;
 | 
			
		||||
    privateKey: string;
 | 
			
		||||
}
 | 
			
		||||
export { AcmeAccount } from './smartacme.classes.acmeaccount';
 | 
			
		||||
export { AcmeCert, ISmartAcmeChallenge, ISmartAcmeChallengeAccepted } from './smartacme.classes.acmecert';
 | 
			
		||||
/**
 | 
			
		||||
 * class SmartAcme exports methods for maintaining SSL Certificates
 | 
			
		||||
 */
 | 
			
		||||
export declare class SmartAcme {
 | 
			
		||||
    helper: SmartacmeHelper;
 | 
			
		||||
    acmeUrl: string;
 | 
			
		||||
    productionBool: boolean;
 | 
			
		||||
    keyPair: IRsaKeypair;
 | 
			
		||||
    location: string;
 | 
			
		||||
    link: string;
 | 
			
		||||
    rawacmeClient: any;
 | 
			
		||||
    JWK: any;
 | 
			
		||||
    /**
 | 
			
		||||
     * the constructor for class SmartAcme
 | 
			
		||||
     */
 | 
			
		||||
    constructor(productionArg?: boolean);
 | 
			
		||||
    /**
 | 
			
		||||
     * init the smartacme instance
 | 
			
		||||
     */
 | 
			
		||||
    init(): q.Promise<{}>;
 | 
			
		||||
    /**
 | 
			
		||||
     * creates an account if not currently present in module
 | 
			
		||||
     * @executes ASYNC
 | 
			
		||||
     */
 | 
			
		||||
    createAccount(): q.Promise<{}>;
 | 
			
		||||
    agreeTos(): q.Promise<{}>;
 | 
			
		||||
    /**
 | 
			
		||||
     * requests a challenge for a domain
 | 
			
		||||
     * @param domainNameArg - the domain name to request a challenge for
 | 
			
		||||
     * @param challengeType - the challenge type to request
 | 
			
		||||
     */
 | 
			
		||||
    requestChallenge(domainNameArg: string, challengeTypeArg?: TChallengeType): q.Promise<ISmartAcmeChallengeAccepted>;
 | 
			
		||||
    /**
 | 
			
		||||
     * getCertificate - takes care of cooldown, validation polling and certificate retrieval
 | 
			
		||||
     */
 | 
			
		||||
    getCertificate(): void;
 | 
			
		||||
    /**
 | 
			
		||||
     * validates a challenge
 | 
			
		||||
     */
 | 
			
		||||
    validate(challenge: ISmartAcmeChallengeAccepted): q.Promise<{}>;
 | 
			
		||||
    /**
 | 
			
		||||
     * accept a challenge - for private use only
 | 
			
		||||
     */
 | 
			
		||||
    private acceptChallenge(challenge);
 | 
			
		||||
    createAccount(): q.Promise<AcmeAccount>;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										146
									
								
								dist/smartacme.classes.smartacme.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										146
									
								
								dist/smartacme.classes.smartacme.js
									
									
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										6
									
								
								dist/smartacme.helpers.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								dist/smartacme.helpers.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
import 'typings-global';
 | 
			
		||||
import { IRsaKeypair } from './smartacme.classes.smartacme';
 | 
			
		||||
/**
 | 
			
		||||
 * creates a keypair to use with requests and to generate JWK from
 | 
			
		||||
 */
 | 
			
		||||
export declare let createKeypair: (bit?: number) => IRsaKeypair;
 | 
			
		||||
							
								
								
									
										34
									
								
								dist/smartacme.helpers.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								dist/smartacme.helpers.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,34 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
require("typings-global");
 | 
			
		||||
const q = require("q");
 | 
			
		||||
const plugins = require("./smartacme.plugins");
 | 
			
		||||
/**
 | 
			
		||||
 * creates a keypair to use with requests and to generate JWK from
 | 
			
		||||
 */
 | 
			
		||||
exports.createKeypair = (bit = 2048) => {
 | 
			
		||||
    let result = plugins.rsaKeygen.generate(bit);
 | 
			
		||||
    return {
 | 
			
		||||
        publicKey: result.public_key,
 | 
			
		||||
        privateKey: result.private_key
 | 
			
		||||
    };
 | 
			
		||||
};
 | 
			
		||||
/**
 | 
			
		||||
 * gets an existing registration
 | 
			
		||||
 * @executes ASYNC
 | 
			
		||||
 */
 | 
			
		||||
let getReg = (SmartAcmeArg, location) => {
 | 
			
		||||
    let done = q.defer();
 | 
			
		||||
    let body = { resource: 'reg' };
 | 
			
		||||
    SmartAcmeArg.rawacmeClient.post(location, body, SmartAcmeArg.keyPair, (err, res) => {
 | 
			
		||||
        if (err) {
 | 
			
		||||
            console.error('smartacme: something went wrong:');
 | 
			
		||||
            console.log(err);
 | 
			
		||||
            done.reject(err);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        console.log(JSON.stringify(res.body));
 | 
			
		||||
        done.resolve();
 | 
			
		||||
    });
 | 
			
		||||
    return done.promise;
 | 
			
		||||
};
 | 
			
		||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLmhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUuaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEJBQXVCO0FBQ3ZCLHVCQUFzQjtBQUV0QiwrQ0FBOEM7QUFLOUM7O0dBRUc7QUFDUSxRQUFBLGFBQWEsR0FBRyxDQUFDLEdBQUcsR0FBRyxJQUFJO0lBQ2xDLElBQUksTUFBTSxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFBO0lBQzVDLE1BQU0sQ0FBQztRQUNILFNBQVMsRUFBRSxNQUFNLENBQUMsVUFBVTtRQUM1QixVQUFVLEVBQUUsTUFBTSxDQUFDLFdBQVc7S0FDakMsQ0FBQTtBQUNMLENBQUMsQ0FBQTtBQUVEOzs7R0FHRztBQUNILElBQUksTUFBTSxHQUFHLENBQUMsWUFBdUIsRUFBRSxRQUFnQjtJQUNuRCxJQUFJLElBQUksR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUE7SUFDcEIsSUFBSSxJQUFJLEdBQUcsRUFBRSxRQUFRLEVBQUUsS0FBSyxFQUFFLENBQUE7SUFDOUIsWUFBWSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQzNCLFFBQVEsRUFDUixJQUFJLEVBQ0osWUFBWSxDQUFDLE9BQU8sRUFDcEIsQ0FBQyxHQUFHLEVBQUUsR0FBRztRQUNMLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDTixPQUFPLENBQUMsS0FBSyxDQUFDLGtDQUFrQyxDQUFDLENBQUE7WUFDakQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNoQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLE1BQU0sQ0FBQTtRQUNWLENBQUM7UUFDRCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUE7UUFDckMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFBO0lBQ2xCLENBQUMsQ0FDSixDQUFBO0lBQ0QsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUE7QUFDdkIsQ0FBQyxDQUFBIn0=
 | 
			
		||||
							
								
								
									
										8
									
								
								dist/smartacme.plugins.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								dist/smartacme.plugins.d.ts
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
import 'typings-global';
 | 
			
		||||
declare let rsaKeygen: any;
 | 
			
		||||
declare let rawacme: any;
 | 
			
		||||
declare let nodeForge: any;
 | 
			
		||||
import * as smartfile from 'smartfile';
 | 
			
		||||
import * as smartstring from 'smartstring';
 | 
			
		||||
import * as paths from './smartacme.paths';
 | 
			
		||||
export { rsaKeygen, rawacme, nodeForge, smartfile, smartstring, paths };
 | 
			
		||||
							
								
								
									
										16
									
								
								dist/smartacme.plugins.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								dist/smartacme.plugins.js
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,16 @@
 | 
			
		||||
"use strict";
 | 
			
		||||
require("typings-global"); // typings for node
 | 
			
		||||
let rsaKeygen = require('rsa-keygen'); // rsa keygen
 | 
			
		||||
exports.rsaKeygen = rsaKeygen;
 | 
			
		||||
let rawacme = require('rawacme'); // acme helper functions
 | 
			
		||||
exports.rawacme = rawacme;
 | 
			
		||||
let nodeForge = require('node-forge');
 | 
			
		||||
exports.nodeForge = nodeForge;
 | 
			
		||||
// push.rocks modules here
 | 
			
		||||
const smartfile = require("smartfile");
 | 
			
		||||
exports.smartfile = smartfile;
 | 
			
		||||
const smartstring = require("smartstring");
 | 
			
		||||
exports.smartstring = smartstring;
 | 
			
		||||
const paths = require("./smartacme.paths");
 | 
			
		||||
exports.paths = paths;
 | 
			
		||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic21hcnRhY21lLnBsdWdpbnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9zbWFydGFjbWUucGx1Z2lucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEsMEJBQXVCLENBQUMsbUJBQW1CO0FBRzNDLElBQUksU0FBUyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsQ0FBQSxDQUFDLGFBQWE7QUFVL0MsOEJBQVM7QUFUYixJQUFJLE9BQU8sR0FBRyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUEsQ0FBQyx3QkFBd0I7QUFVckQsMEJBQU87QUFUWCxJQUFJLFNBQVMsR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFDLENBQUE7QUFVakMsOEJBQVM7QUFSYiwwQkFBMEI7QUFDMUIsdUNBQXNDO0FBUWxDLDhCQUFTO0FBUGIsMkNBQTBDO0FBUXRDLGtDQUFXO0FBUGYsMkNBQTBDO0FBUXRDLHNCQUFLIn0=
 | 
			
		||||
@@ -35,6 +35,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "devDependencies": {
 | 
			
		||||
    "@types/should": "^8.1.30",
 | 
			
		||||
    "cflare": "0.0.10",
 | 
			
		||||
    "should": "^11.1.1",
 | 
			
		||||
    "typings-test": "^1.0.3"
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								test/test.js
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								test/test.js
									
									
									
									
									
								
							@@ -4,44 +4,42 @@ const should = require("should");
 | 
			
		||||
// import the module to test
 | 
			
		||||
const smartacme = require("../dist/index");
 | 
			
		||||
describe('smartacme', function () {
 | 
			
		||||
    let testAcme;
 | 
			
		||||
    let testSmartAcme;
 | 
			
		||||
    let testAcmeAccount;
 | 
			
		||||
    let testChallenge;
 | 
			
		||||
    it('should create a valid instance', function () {
 | 
			
		||||
    it('should create a valid instance', function (done) {
 | 
			
		||||
        this.timeout(10000);
 | 
			
		||||
        testAcme = new smartacme.SmartAcme();
 | 
			
		||||
        should(testAcme).be.instanceOf(smartacme.SmartAcme);
 | 
			
		||||
        testSmartAcme = new smartacme.SmartAcme();
 | 
			
		||||
        testSmartAcme.init().then(() => {
 | 
			
		||||
            should(testSmartAcme).be.instanceOf(smartacme.SmartAcme);
 | 
			
		||||
            done();
 | 
			
		||||
        }).catch(err => { done(err); });
 | 
			
		||||
    });
 | 
			
		||||
    it('should have created keyPair', function () {
 | 
			
		||||
        should(testAcme.acmeUrl).be.of.type('string');
 | 
			
		||||
        should(testSmartAcme.acmeUrl).be.of.type('string');
 | 
			
		||||
    });
 | 
			
		||||
    it('should register a new account', function (done) {
 | 
			
		||||
        this.timeout(10000);
 | 
			
		||||
        testAcme.createAccount().then(x => {
 | 
			
		||||
        testSmartAcme.createAccount().then(x => {
 | 
			
		||||
            done();
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
            console.log(err);
 | 
			
		||||
            done(err);
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    it('should agree to ToS', function (done) {
 | 
			
		||||
    it.skip('should request a cert for a domain', function (done) {
 | 
			
		||||
        this.timeout(10000);
 | 
			
		||||
        testAcme.agreeTos().then(() => {
 | 
			
		||||
            done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    it('should request a challenge for a domain', function (done) {
 | 
			
		||||
        this.timeout(10000);
 | 
			
		||||
        testAcme.requestChallenge('bleu.de').then((challengeAccepted) => {
 | 
			
		||||
        testAcmeAccount.requestChallenge('bleu.de').then((challengeAccepted) => {
 | 
			
		||||
            console.log(challengeAccepted);
 | 
			
		||||
            testChallenge = challengeAccepted;
 | 
			
		||||
            done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
    it('should poll for validation of a challenge', function (done) {
 | 
			
		||||
    it.skip('should poll for validation of a challenge', function (done) {
 | 
			
		||||
        this.timeout(10000);
 | 
			
		||||
        testAcme.validate(testChallenge).then(x => {
 | 
			
		||||
        testSmartAcme.validate(testChallenge).then(x => {
 | 
			
		||||
            done();
 | 
			
		||||
        });
 | 
			
		||||
    });
 | 
			
		||||
});
 | 
			
		||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFFaEMsNEJBQTRCO0FBQzVCLDJDQUEwQztBQUUxQyxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ2xCLElBQUksUUFBNkIsQ0FBQTtJQUNqQyxJQUFJLGFBQW9ELENBQUE7SUFDeEQsRUFBRSxDQUFDLGdDQUFnQyxFQUFFO1FBQ2pDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxHQUFHLElBQUksU0FBUyxDQUFDLFNBQVMsRUFBRSxDQUFBO1FBQ3BDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUN2RCxDQUFDLENBQUMsQ0FBQTtJQUVGLEVBQUUsQ0FBQyw2QkFBNkIsRUFBRTtRQUM5QixNQUFNLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBQ2pELENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLCtCQUErQixFQUFFLFVBQVUsSUFBSTtRQUM5QyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLFFBQVEsQ0FBQyxhQUFhLEVBQUUsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUMzQixJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHO1lBQ1IsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQTtZQUNoQixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUE7UUFDYixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHFCQUFxQixFQUFFLFVBQVMsSUFBSTtRQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxJQUFJLENBQUM7WUFDckIsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLHlDQUF5QyxFQUFFLFVBQVMsSUFBSTtRQUN2RCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLFFBQVEsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxpQkFBaUI7WUFDeEQsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1lBQzlCLGFBQWEsR0FBRyxpQkFBaUIsQ0FBQTtZQUNqQyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsMkNBQTJDLEVBQUMsVUFBUyxJQUFJO1FBQ3hELElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsUUFBUSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNuQyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7QUFDTixDQUFDLENBQUMsQ0FBQSJ9
 | 
			
		||||
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLHdCQUFxQjtBQUNyQixpQ0FBZ0M7QUFHaEMsNEJBQTRCO0FBQzVCLDJDQUEwQztBQUUxQyxRQUFRLENBQUMsV0FBVyxFQUFFO0lBQ2xCLElBQUksYUFBa0MsQ0FBQTtJQUN0QyxJQUFJLGVBQXNDLENBQUE7SUFDMUMsSUFBSSxhQUFvRCxDQUFBO0lBQ3hELEVBQUUsQ0FBQyxnQ0FBZ0MsRUFBRSxVQUFVLElBQUk7UUFDL0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUNuQixhQUFhLEdBQUcsSUFBSSxTQUFTLENBQUMsU0FBUyxFQUFFLENBQUE7UUFDekMsYUFBYSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQztZQUN0QixNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUE7WUFDeEQsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsR0FBRyxNQUFNLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQSxDQUFDLENBQUMsQ0FBQyxDQUFBO0lBQ2xDLENBQUMsQ0FBQyxDQUFBO0lBRUYsRUFBRSxDQUFDLDZCQUE2QixFQUFFO1FBQzlCLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUE7SUFDdEQsQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsK0JBQStCLEVBQUUsVUFBVSxJQUFJO1FBQzlDLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDbkIsYUFBYSxDQUFDLGFBQWEsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2hDLElBQUksRUFBRSxDQUFBO1FBQ1YsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUc7WUFDUixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1lBQ2hCLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNiLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsSUFBSSxDQUFDLG9DQUFvQyxFQUFFLFVBQVUsSUFBSTtRQUN4RCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxTQUFTLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxpQkFBaUI7WUFDL0QsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1lBQzlCLGFBQWEsR0FBRyxpQkFBaUIsQ0FBQTtZQUNqQyxJQUFJLEVBQUUsQ0FBQTtRQUNWLENBQUMsQ0FBQyxDQUFBO0lBQ04sQ0FBQyxDQUFDLENBQUE7SUFFRixFQUFFLENBQUMsSUFBSSxDQUFDLDJDQUEyQyxFQUFFLFVBQVUsSUFBSTtRQUMvRCxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ25CLGFBQWEsQ0FBQyxRQUFRLENBQUMsYUFBYSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEMsSUFBSSxFQUFFLENBQUE7UUFDVixDQUFDLENBQUMsQ0FBQTtJQUNOLENBQUMsQ0FBQyxDQUFBO0FBQ04sQ0FBQyxDQUFDLENBQUEifQ==
 | 
			
		||||
							
								
								
									
										32
									
								
								test/test.ts
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								test/test.ts
									
									
									
									
									
								
							@@ -1,25 +1,30 @@
 | 
			
		||||
import 'typings-test'
 | 
			
		||||
import * as should from 'should'
 | 
			
		||||
import * as cflare from 'cflare'
 | 
			
		||||
 | 
			
		||||
// import the module to test
 | 
			
		||||
import * as smartacme from '../dist/index'
 | 
			
		||||
 | 
			
		||||
describe('smartacme', function () {
 | 
			
		||||
    let testAcme: smartacme.SmartAcme
 | 
			
		||||
    let testSmartAcme: smartacme.SmartAcme
 | 
			
		||||
    let testAcmeAccount: smartacme.AcmeAccount
 | 
			
		||||
    let testChallenge: smartacme.ISmartAcmeChallengeAccepted
 | 
			
		||||
    it('should create a valid instance', function () {
 | 
			
		||||
    it('should create a valid instance', function (done) {
 | 
			
		||||
        this.timeout(10000)
 | 
			
		||||
        testAcme = new smartacme.SmartAcme()
 | 
			
		||||
        should(testAcme).be.instanceOf(smartacme.SmartAcme)
 | 
			
		||||
        testSmartAcme = new smartacme.SmartAcme()
 | 
			
		||||
        testSmartAcme.init().then(() => {
 | 
			
		||||
            should(testSmartAcme).be.instanceOf(smartacme.SmartAcme)
 | 
			
		||||
            done()
 | 
			
		||||
        }).catch(err => { done(err) })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('should have created keyPair', function () {
 | 
			
		||||
        should(testAcme.acmeUrl).be.of.type('string')
 | 
			
		||||
        should(testSmartAcme.acmeUrl).be.of.type('string')
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('should register a new account', function (done) {
 | 
			
		||||
        this.timeout(10000)
 | 
			
		||||
        testAcme.createAccount().then(x => {
 | 
			
		||||
        testSmartAcme.createAccount().then(x => {
 | 
			
		||||
            done()
 | 
			
		||||
        }).catch(err => {
 | 
			
		||||
            console.log(err)
 | 
			
		||||
@@ -27,25 +32,18 @@ describe('smartacme', function () {
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('should agree to ToS', function(done) {
 | 
			
		||||
    it.skip('should request a cert for a domain', function (done) {
 | 
			
		||||
        this.timeout(10000)
 | 
			
		||||
        testAcme.agreeTos().then(() => {
 | 
			
		||||
            done()
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('should request a challenge for a domain', function(done) {
 | 
			
		||||
        this.timeout(10000)
 | 
			
		||||
        testAcme.requestChallenge('bleu.de').then((challengeAccepted) => {
 | 
			
		||||
        testAcmeAccount.requestChallenge('bleu.de').then((challengeAccepted) => {
 | 
			
		||||
            console.log(challengeAccepted)
 | 
			
		||||
            testChallenge = challengeAccepted
 | 
			
		||||
            done()
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    it('should poll for validation of a challenge',function(done) {
 | 
			
		||||
    it.skip('should poll for validation of a challenge', function (done) {
 | 
			
		||||
        this.timeout(10000)
 | 
			
		||||
        testAcme.validate(testChallenge).then(x => {
 | 
			
		||||
        testSmartAcme.validate(testChallenge).then(x => {
 | 
			
		||||
            done()
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,68 @@
 | 
			
		||||
import 'typings-global'
 | 
			
		||||
import * as q from 'q'
 | 
			
		||||
 | 
			
		||||
import * as plugins from './smartacme.plugins'
 | 
			
		||||
import * as helpers from './smartacme.helpers'
 | 
			
		||||
 | 
			
		||||
import { SmartAcme, IRsaKeypair } from './smartacme.classes.smartacme'
 | 
			
		||||
import { AcmeCert } from './smartacme.classes.acmecert'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * class AcmeAccount represents an AcmeAccount
 | 
			
		||||
 */
 | 
			
		||||
export class AcmeAccount {
 | 
			
		||||
    
 | 
			
		||||
}
 | 
			
		||||
    parentSmartAcme: SmartAcme
 | 
			
		||||
    location: string
 | 
			
		||||
    link: string
 | 
			
		||||
    JWK
 | 
			
		||||
    constructor(smartAcmeParentArg: SmartAcme) {
 | 
			
		||||
        this.parentSmartAcme = smartAcmeParentArg
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * register the account with letsencrypt
 | 
			
		||||
     */
 | 
			
		||||
    register() {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
        this.parentSmartAcme.rawacmeClient.newReg(
 | 
			
		||||
            {
 | 
			
		||||
                contact: ['mailto:domains@lossless.org']
 | 
			
		||||
            },
 | 
			
		||||
            (err, res) => {
 | 
			
		||||
                if (err) {
 | 
			
		||||
                    console.error('smartacme: something went wrong:')
 | 
			
		||||
                    console.log(err)
 | 
			
		||||
                    done.reject(err)
 | 
			
		||||
                    return
 | 
			
		||||
                }
 | 
			
		||||
                this.JWK = res.body.key
 | 
			
		||||
                this.link = res.headers.link
 | 
			
		||||
                console.log(this.link)
 | 
			
		||||
                this.location = res.headers.location
 | 
			
		||||
                done.resolve()
 | 
			
		||||
            })
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * agree to letsencrypr terms of service
 | 
			
		||||
     */
 | 
			
		||||
    agreeTos() {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
        let tosPart = this.link.split(',')[1]
 | 
			
		||||
        let tosLinkPortion = tosPart.split(';')[0]
 | 
			
		||||
        let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '')
 | 
			
		||||
        this.parentSmartAcme.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.log(err)
 | 
			
		||||
                done.reject(err)
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
            done.resolve()
 | 
			
		||||
        })
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    createAcmeCert(domainNameArg: string) {
 | 
			
		||||
        
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,226 @@
 | 
			
		||||
import 'typings-global'
 | 
			
		||||
import * as q from 'q'
 | 
			
		||||
 | 
			
		||||
import * as plugins from './smartacme.plugins'
 | 
			
		||||
import * as helpers from './smartacme.helpers'
 | 
			
		||||
 | 
			
		||||
import { SmartAcme, IRsaKeypair } from './smartacme.classes.smartacme'
 | 
			
		||||
import { AcmeAccount } from './smartacme.classes.acmeaccount'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * types of challenges supported by letsencrypt and this module
 | 
			
		||||
 */
 | 
			
		||||
export type TChallengeType = 'dns-01' | 'http-01'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * values that a challenge's status can have
 | 
			
		||||
 */
 | 
			
		||||
export type TChallengeStatus = 'pending'
 | 
			
		||||
 | 
			
		||||
export interface ISmartAcmeChallenge {
 | 
			
		||||
    uri: string
 | 
			
		||||
    status: TChallengeStatus
 | 
			
		||||
    type: TChallengeType
 | 
			
		||||
    token: string
 | 
			
		||||
    keyAuthorization: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
 | 
			
		||||
    keyHash: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface IAcmeCsrConstructorOptions {
 | 
			
		||||
    bit: number,
 | 
			
		||||
    key: string,
 | 
			
		||||
    domain: string,
 | 
			
		||||
    country: string,
 | 
			
		||||
    country_short: string,
 | 
			
		||||
    locality: string,
 | 
			
		||||
    organization: string,
 | 
			
		||||
    organization_short: string,
 | 
			
		||||
    password: string,
 | 
			
		||||
    unstructured: string,
 | 
			
		||||
    subject_alt_names: string[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * class AcmeCert represents a cert for domain
 | 
			
		||||
 */
 | 
			
		||||
export class AcmeCert {
 | 
			
		||||
    attributes
 | 
			
		||||
    fullchain: string
 | 
			
		||||
}
 | 
			
		||||
    parentAcmeAccount: AcmeAccount
 | 
			
		||||
    csr
 | 
			
		||||
    validFrom: Date
 | 
			
		||||
    validTo: Date
 | 
			
		||||
    keypair: IRsaKeypair
 | 
			
		||||
    keyPairFinal: IRsaKeypair
 | 
			
		||||
    constructor(optionsArg: IAcmeCsrConstructorOptions, parentSmartAcmeArg) {
 | 
			
		||||
        this.parentAcmeAccount = parentSmartAcmeArg
 | 
			
		||||
        this.keypair = helpers.createKeypair(optionsArg.bit)
 | 
			
		||||
        let privateKeyForged = plugins.nodeForge.pki.privateKeyFromPem(this.keypair.privateKey)
 | 
			
		||||
        let publicKeyForged = plugins.nodeForge.pki.publicKeyToPem(
 | 
			
		||||
            plugins.nodeForge.pki.setRsaPublicKey(privateKeyForged.n, privateKeyForged.e)
 | 
			
		||||
        )
 | 
			
		||||
        this.keyPairFinal = {
 | 
			
		||||
            privateKey: privateKeyForged,
 | 
			
		||||
            publicKey: publicKeyForged
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // set dates
 | 
			
		||||
        this.validFrom = new Date()
 | 
			
		||||
        this.validTo = new Date()
 | 
			
		||||
        this.validTo.setDate(this.validFrom.getDate() + 90)
 | 
			
		||||
 | 
			
		||||
        // set attributes
 | 
			
		||||
        this.attributes = [
 | 
			
		||||
            { name: 'commonName', value: optionsArg.domain },
 | 
			
		||||
            { name: 'countryName', value: optionsArg.country },
 | 
			
		||||
            { shortName: 'ST', value: optionsArg.country_short },
 | 
			
		||||
            { name: 'localityName', value: optionsArg.locality },
 | 
			
		||||
            { name: 'organizationName', value: optionsArg.organization },
 | 
			
		||||
            { shortName: 'OU', value: optionsArg.organization_short },
 | 
			
		||||
            { name: 'challengePassword', value: optionsArg.password },
 | 
			
		||||
            { name: 'unstructuredName', value: optionsArg.unstructured }
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
        // set up csr
 | 
			
		||||
        this.csr = plugins.nodeForge.pki.createCertificationRequest()
 | 
			
		||||
        this.csr.setSubject(this.attributes)
 | 
			
		||||
        this.csr.setAttributes(this.attributes)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * requests a challenge for a domain
 | 
			
		||||
     * @param domainNameArg - the domain name to request a challenge for
 | 
			
		||||
     * @param challengeType - the challenge type to request
 | 
			
		||||
     */
 | 
			
		||||
    requestChallenge(domainNameArg: string, challengeTypeArg: TChallengeType = 'dns-01') {
 | 
			
		||||
        let done = q.defer<ISmartAcmeChallengeAccepted>()
 | 
			
		||||
        this.parentAcmeAccount.parentSmartAcme.rawacmeClient.newAuthz(
 | 
			
		||||
            {
 | 
			
		||||
                identifier: {
 | 
			
		||||
                    type: 'dns',
 | 
			
		||||
                    value: domainNameArg
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            this.parentAcmeAccount.parentSmartAcme.keyPair,
 | 
			
		||||
            (err, res) => {
 | 
			
		||||
                if (err) {
 | 
			
		||||
                    console.error('smartacme: something went wrong:')
 | 
			
		||||
                    console.log(err)
 | 
			
		||||
                    done.reject(err)
 | 
			
		||||
                }
 | 
			
		||||
                console.log(JSON.stringify(res.body))
 | 
			
		||||
                let dnsChallenge = res.body.challenges.filter(x => {
 | 
			
		||||
                    return x.type === challengeTypeArg
 | 
			
		||||
                })[0]
 | 
			
		||||
                this.acceptChallenge(dnsChallenge)
 | 
			
		||||
                    .then((x: ISmartAcmeChallengeAccepted) => {
 | 
			
		||||
                        done.resolve(x)
 | 
			
		||||
                    })
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * validates a challenge, only call after you have set the challenge at the expected location
 | 
			
		||||
     */
 | 
			
		||||
    validate(challenge: ISmartAcmeChallengeAccepted) {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
        this.parentAcmeAccount.parentSmartAcme.rawacmeClient.poll(challenge.uri, function (err, res) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.log(err)
 | 
			
		||||
                done.reject(err)
 | 
			
		||||
            }
 | 
			
		||||
            console.log(res.status)
 | 
			
		||||
            console.log(JSON.stringify(res.body))
 | 
			
		||||
            done.resolve()
 | 
			
		||||
        })
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * requests a certificate
 | 
			
		||||
     */
 | 
			
		||||
    requestCert() {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
        let payload = {
 | 
			
		||||
            csr: plugins.rawacme.base64.encode(
 | 
			
		||||
                plugins.rawacme.toDer(
 | 
			
		||||
                    plugins.nodeForge.pki.certificationRequestToPem(
 | 
			
		||||
                        this.csr
 | 
			
		||||
                    )
 | 
			
		||||
                )
 | 
			
		||||
            ),
 | 
			
		||||
            notBefore: this.validFrom.toISOString(),
 | 
			
		||||
            notAfter: this.validTo.toISOString()
 | 
			
		||||
        }
 | 
			
		||||
        this.parentAcmeAccount.parentSmartAcme.rawacmeClient.newCert(
 | 
			
		||||
            payload,
 | 
			
		||||
            helpers.createKeypair(),
 | 
			
		||||
            (err, res) => {
 | 
			
		||||
                if (err) {
 | 
			
		||||
                    console.log(err)
 | 
			
		||||
                    done.reject(err)
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * getCertificate - takes care of cooldown, validation polling and certificate retrieval
 | 
			
		||||
     */
 | 
			
		||||
    getCertificate() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * accept a challenge - for private use only
 | 
			
		||||
     */
 | 
			
		||||
    private acceptChallenge(challenge: ISmartAcmeChallenge) {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * the key is needed to accept the challenge
 | 
			
		||||
         */
 | 
			
		||||
        let authKey: string = plugins.rawacme.keyAuthz(
 | 
			
		||||
            challenge.token,
 | 
			
		||||
            this.parentAcmeAccount.parentSmartAcme.keyPair.publicKey
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * needed in case selected challenge is of type dns-01
 | 
			
		||||
         */
 | 
			
		||||
        let keyHash: string = plugins.rawacme.dnsKeyAuthzHash(authKey) // needed if dns challenge is chosen
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * the return challenge
 | 
			
		||||
         */
 | 
			
		||||
        let returnDNSChallenge: ISmartAcmeChallengeAccepted = {
 | 
			
		||||
            uri: challenge.uri,
 | 
			
		||||
            type: challenge.type,
 | 
			
		||||
            token: challenge.token,
 | 
			
		||||
            keyAuthorization: challenge.keyAuthorization,
 | 
			
		||||
            keyHash: keyHash,
 | 
			
		||||
            status: challenge.status
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.parentAcmeAccount.parentSmartAcme.rawacmeClient.post(
 | 
			
		||||
            challenge.uri,
 | 
			
		||||
            {
 | 
			
		||||
                resource: 'challenge',
 | 
			
		||||
                keyAuthorization: authKey
 | 
			
		||||
            },
 | 
			
		||||
            this.parentAcmeAccount.parentSmartAcme.keyPair,
 | 
			
		||||
            (err, res) => {
 | 
			
		||||
                if (err) {
 | 
			
		||||
                    console.log(err)
 | 
			
		||||
                    done.reject(err)
 | 
			
		||||
                }
 | 
			
		||||
                done.resolve(returnDNSChallenge)
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,52 +0,0 @@
 | 
			
		||||
import * as plugins from './smartacme.plugins'
 | 
			
		||||
import * as helpers from './smartacme.helpers'
 | 
			
		||||
 | 
			
		||||
import { IRsaKeypair } from './smartacme.classes.smartacme'
 | 
			
		||||
 | 
			
		||||
export interface IAcmeCsrConstructorOptions {
 | 
			
		||||
    bit: number,
 | 
			
		||||
    key: string,
 | 
			
		||||
    domain: string,
 | 
			
		||||
    country: string,
 | 
			
		||||
    country_short: string,
 | 
			
		||||
    locality: string,
 | 
			
		||||
    organization: string,
 | 
			
		||||
    organization_short: string,
 | 
			
		||||
    password: string,
 | 
			
		||||
    unstructured: string,
 | 
			
		||||
    subject_alt_names: string[]
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class AcmeCsr {
 | 
			
		||||
    validFrom: Date
 | 
			
		||||
    validTo: Date
 | 
			
		||||
    keypair: IRsaKeypair
 | 
			
		||||
    keyPairForged: IRsaKeypair
 | 
			
		||||
    constructor(optionsArg: IAcmeCsrConstructorOptions) {
 | 
			
		||||
        this.keypair = helpers.createKeypair(optionsArg.bit)
 | 
			
		||||
        let privateKeyForged = plugins.nodeForge.pki.privateKeyFromPem(this.keypair.privateKey)
 | 
			
		||||
        let publicKeyForged = plugins.nodeForge.pki.publicKeyToPem(
 | 
			
		||||
            plugins.nodeForge.pki.setRsaPublicKey(privateKeyForged.n, privateKeyForged.e)
 | 
			
		||||
        )
 | 
			
		||||
        this.keyPairForged = {
 | 
			
		||||
            privateKey: privateKeyForged,
 | 
			
		||||
            publicKey: publicKeyForged
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // set dates
 | 
			
		||||
        this.validFrom = new Date()
 | 
			
		||||
        this.validTo = new Date()
 | 
			
		||||
        this.validTo.setDate(this.validFrom.getDate() + 90)
 | 
			
		||||
 | 
			
		||||
        // create the csr
 | 
			
		||||
        let attributes = [
 | 
			
		||||
            { name: "commonName", value: domain },
 | 
			
		||||
            { name: "countryName", value: country },
 | 
			
		||||
            { shortName: "ST", value: country_short },
 | 
			
		||||
            { name: "localityName", value: locality },
 | 
			
		||||
            { name: "organizationName", value: organization },
 | 
			
		||||
            { shortName: "OU", value: organization_short }
 | 
			
		||||
        ]
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -3,37 +3,27 @@ import * as q from 'q' // promises
 | 
			
		||||
import * as plugins from './smartacme.plugins'
 | 
			
		||||
import * as helpers from './smartacme.helpers'
 | 
			
		||||
 | 
			
		||||
import { AcmeAccount } from './smartacme.classes.acmeaccount'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * a rsa keypair needed for account creation and subsequent requests
 | 
			
		||||
 */
 | 
			
		||||
export interface IRsaKeypair {
 | 
			
		||||
    publicKey: string
 | 
			
		||||
    privateKey: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export type TChallengeType = 'dns-01' | 'http-01'
 | 
			
		||||
export type TChallengeStatus = 'pending'
 | 
			
		||||
 | 
			
		||||
export interface ISmartAcmeChallenge {
 | 
			
		||||
    uri: string
 | 
			
		||||
    status: TChallengeStatus
 | 
			
		||||
    type: TChallengeType
 | 
			
		||||
    token: string
 | 
			
		||||
    keyAuthorization: string
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export interface ISmartAcmeChallengeAccepted extends ISmartAcmeChallenge {
 | 
			
		||||
    keyHash: string
 | 
			
		||||
}
 | 
			
		||||
export { AcmeAccount } from './smartacme.classes.acmeaccount'
 | 
			
		||||
export { AcmeCert, ISmartAcmeChallenge, ISmartAcmeChallengeAccepted } from './smartacme.classes.acmecert'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * class SmartAcme exports methods for maintaining SSL Certificates
 | 
			
		||||
 */
 | 
			
		||||
export class SmartAcme {
 | 
			
		||||
    acmeUrl: string // the acme url to use
 | 
			
		||||
    acmeUrl: string // the acme url to use for this instance
 | 
			
		||||
    productionBool: boolean // a boolean to quickly know wether we are in production or not
 | 
			
		||||
    keyPair: IRsaKeypair // the keyPair needed for account creation
 | 
			
		||||
    location: string
 | 
			
		||||
    link: string
 | 
			
		||||
    rawacmeClient
 | 
			
		||||
    JWK
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * the constructor for class SmartAcme
 | 
			
		||||
@@ -49,10 +39,9 @@ export class SmartAcme {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * creates an account if not currently present in module
 | 
			
		||||
     * @executes ASYNC
 | 
			
		||||
     * init the smartacme instance
 | 
			
		||||
     */
 | 
			
		||||
    createAccount() {
 | 
			
		||||
    init() {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
        plugins.rawacme.createClient(
 | 
			
		||||
            {
 | 
			
		||||
@@ -70,151 +59,24 @@ export class SmartAcme {
 | 
			
		||||
 | 
			
		||||
                // make client available in class 
 | 
			
		||||
                this.rawacmeClient = client
 | 
			
		||||
 | 
			
		||||
                // create the registration
 | 
			
		||||
                client.newReg(
 | 
			
		||||
                    {
 | 
			
		||||
                        contact: ['mailto:domains@lossless.org']
 | 
			
		||||
                    },
 | 
			
		||||
                    (err, res) => {
 | 
			
		||||
                        if (err) {
 | 
			
		||||
                            console.error('smartacme: something went wrong:')
 | 
			
		||||
                            console.log(err)
 | 
			
		||||
                            done.reject(err)
 | 
			
		||||
                            return
 | 
			
		||||
                        }
 | 
			
		||||
                        this.JWK = res.body.key
 | 
			
		||||
                        this.link = res.headers.link
 | 
			
		||||
                        console.log(this.link)
 | 
			
		||||
                        this.location = res.headers.location
 | 
			
		||||
                        done.resolve()
 | 
			
		||||
                    })
 | 
			
		||||
 | 
			
		||||
                done.resolve()
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    agreeTos() {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
        let tosPart = this.link.split(',')[1]
 | 
			
		||||
        let tosLinkPortion = tosPart.split(';')[0]
 | 
			
		||||
        let url = tosLinkPortion.split(';')[0].trim().replace(/[<>]/g, '')
 | 
			
		||||
        this.rawacmeClient.post(this.location, { Agreement: url, resource: 'reg' }, (err, res) => {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.log(err)
 | 
			
		||||
                done.reject(err)
 | 
			
		||||
                return
 | 
			
		||||
            }
 | 
			
		||||
            done.resolve()
 | 
			
		||||
    /**
 | 
			
		||||
     * creates an account if not currently present in module
 | 
			
		||||
     * @executes ASYNC
 | 
			
		||||
     */
 | 
			
		||||
    createAccount() {
 | 
			
		||||
        let done = q.defer<AcmeAccount>()
 | 
			
		||||
        let acmeAccount = new AcmeAccount(this)
 | 
			
		||||
        acmeAccount.register().then(() => {
 | 
			
		||||
            return acmeAccount.agreeTos()
 | 
			
		||||
        }).then(() => {
 | 
			
		||||
            done.resolve(acmeAccount)
 | 
			
		||||
        })
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * requests a challenge for a domain
 | 
			
		||||
     * @param domainNameArg - the domain name to request a challenge for
 | 
			
		||||
     * @param challengeType - the challenge type to request
 | 
			
		||||
     */
 | 
			
		||||
    requestChallenge(domainNameArg: string, challengeTypeArg: TChallengeType = 'dns-01') {
 | 
			
		||||
        let done = q.defer<ISmartAcmeChallengeAccepted>()
 | 
			
		||||
        this.rawacmeClient.newAuthz(
 | 
			
		||||
            {
 | 
			
		||||
                identifier: {
 | 
			
		||||
                    type: 'dns',
 | 
			
		||||
                    value: domainNameArg
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            this.keyPair,
 | 
			
		||||
            (err, res) => {
 | 
			
		||||
                if (err) {
 | 
			
		||||
                    console.error('smartacme: something went wrong:')
 | 
			
		||||
                    console.log(err)
 | 
			
		||||
                    done.reject(err)
 | 
			
		||||
                }
 | 
			
		||||
                console.log(JSON.stringify(res.body))
 | 
			
		||||
                let dnsChallenge = res.body.challenges.filter(x => {
 | 
			
		||||
                    return x.type === challengeTypeArg
 | 
			
		||||
                })[0]
 | 
			
		||||
                this.acceptChallenge(dnsChallenge)
 | 
			
		||||
                    .then((x: ISmartAcmeChallengeAccepted) => {
 | 
			
		||||
                        done.resolve(x)
 | 
			
		||||
                    })
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * getCertificate - takes care of cooldown, validation polling and certificate retrieval
 | 
			
		||||
     */
 | 
			
		||||
    getCertificate() {
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * validates a challenge
 | 
			
		||||
     */
 | 
			
		||||
    validate(challenge: ISmartAcmeChallengeAccepted) {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
        this.rawacmeClient.poll(challenge.uri, function(err, res) {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.log(err)
 | 
			
		||||
                done.reject(err)
 | 
			
		||||
            }
 | 
			
		||||
            console.log(res.status)
 | 
			
		||||
            console.log(JSON.stringify(res.body))
 | 
			
		||||
            done.resolve()
 | 
			
		||||
        })
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * accept a challenge - for private use only
 | 
			
		||||
     */
 | 
			
		||||
    private acceptChallenge(challenge: ISmartAcmeChallenge) {
 | 
			
		||||
        let done = q.defer()
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * the key is needed to accept the challenge
 | 
			
		||||
         */
 | 
			
		||||
        let authKey: string = plugins.rawacme.keyAuthz(challenge.token, this.keyPair.publicKey)
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * needed in case selected challenge is of type dns-01
 | 
			
		||||
         */
 | 
			
		||||
        let keyHash: string = plugins.rawacme.dnsKeyAuthzHash(authKey) // needed if dns challenge is chosen
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * the return challenge
 | 
			
		||||
         */
 | 
			
		||||
        let returnDNSChallenge: ISmartAcmeChallengeAccepted = {
 | 
			
		||||
            uri: challenge.uri,
 | 
			
		||||
            type: challenge.type,
 | 
			
		||||
            token: challenge.token,
 | 
			
		||||
            keyAuthorization: challenge.keyAuthorization,
 | 
			
		||||
            keyHash: keyHash,
 | 
			
		||||
            status: challenge.status
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.rawacmeClient.post(
 | 
			
		||||
            challenge.uri,
 | 
			
		||||
            {
 | 
			
		||||
                resource: 'challenge',
 | 
			
		||||
                keyAuthorization: authKey
 | 
			
		||||
            },
 | 
			
		||||
            this.keyPair,
 | 
			
		||||
            (err, res) => {
 | 
			
		||||
                if (err) {
 | 
			
		||||
                    console.log(err)
 | 
			
		||||
                    done.reject(err)
 | 
			
		||||
                }
 | 
			
		||||
                done.resolve(returnDNSChallenge)
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
        return done.promise
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,7 @@ import * as q from 'q'
 | 
			
		||||
import * as plugins from './smartacme.plugins'
 | 
			
		||||
 | 
			
		||||
import { SmartAcme, IRsaKeypair } from './smartacme.classes.smartacme'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
import { AcmeAccount } from './smartacme.classes.acmeaccount'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * creates a keypair to use with requests and to generate JWK from
 | 
			
		||||
@@ -22,12 +21,13 @@ export let createKeypair = (bit = 2048): IRsaKeypair => {
 | 
			
		||||
 * gets an existing registration
 | 
			
		||||
 * @executes ASYNC
 | 
			
		||||
 */
 | 
			
		||||
let getReg = (smartAcmeArg: SmartAcme) => {
 | 
			
		||||
let getReg = (SmartAcmeArg: SmartAcme, location: string) => {
 | 
			
		||||
    let done = q.defer()
 | 
			
		||||
    let body = { resource: 'reg' }
 | 
			
		||||
    smartAcmeArg.rawacmeClient.post(
 | 
			
		||||
        smartAcmeArg.location,
 | 
			
		||||
        body, smartAcmeArg.keyPair,
 | 
			
		||||
    SmartAcmeArg.rawacmeClient.post(
 | 
			
		||||
        location,
 | 
			
		||||
        body,
 | 
			
		||||
        SmartAcmeArg.keyPair,
 | 
			
		||||
        (err, res) => {
 | 
			
		||||
            if (err) {
 | 
			
		||||
                console.error('smartacme: something went wrong:')
 | 
			
		||||
 
 | 
			
		||||
@@ -17,4 +17,4 @@ export {
 | 
			
		||||
    smartfile,
 | 
			
		||||
    smartstring,
 | 
			
		||||
    paths
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user