challenges-underlay.js 3.63 KB
'use strict';

var Greenlock = require('./');

module.exports.wrap = function(greenlock) {
    greenlock.challenges = {};
    greenlock.challenges.get = function(chall) {
        // TODO pick one and warn on the others
        // (just here due to some backwards compat issues with early v3 plugins)
        var servername =
            chall.servername ||
            chall.altname ||
            (chall.identifier && chall.identifier.value);

        // TODO some sort of caching to prevent database hits?
        return greenlock
            ._config({ servername: servername })
            .then(function(site) {
                if (!site) {
                    return null;
                }

                // Hmm... this _should_ be impossible
                if (!site.challenges || !site.challenges['http-01']) {
                    var copy = JSON.parse(JSON.stringify(site));
                    sanitizeCopiedConf(copy);
                    sanitizeCopiedConf(copy.store);
                    if (site.challenges) {
                        sanitizeCopiedConf(copy.challenges['http-01']);
                        sanitizeCopiedConf(copy.challenges['dns-01']);
                        sanitizeCopiedConf(copy.challenges['tls-alpn-01']);
                    }
                    console.warn('[Bug] Please report this error:');
                    console.warn(
                        '\terror: http-01 challenge requested, but not even a default http-01 config exists'
                    );
                    console.warn('\tservername:', JSON.stringify(servername));
                    console.warn('\tsite:', JSON.stringify(copy));
                    return null;
                }

                return Greenlock._loadChallenge(site.challenges, 'http-01');
            })
            .then(function(plugin) {
                if (!plugin) {
                    return null;
                }
                return plugin
                    .get({
                        challenge: {
                            type: chall.type,
                            //hostname: chall.servername,
                            altname: chall.servername,
                            identifier: { value: chall.servername },
                            token: chall.token
                        }
                    })
                    .then(function(result) {
                        var keyAuth;
                        var keyAuthDigest;
                        if (result) {
                            // backwards compat that shouldn't be dropped
                            // because new v3 modules had to do this to be
                            // backwards compatible with Greenlock v2.7 at
                            // the time.
                            if (result.challenge) {
                                result = result.challenge;
                            }
                            keyAuth = result.keyAuthorization;
                            keyAuthDigest = result.keyAuthorizationDigest;
                        }
                        if (/dns/.test(chall.type)) {
                            return {
                                keyAuthorizationDigest: keyAuthDigest
                            };
                        }
                        return {
                            keyAuthorization: keyAuth
                        };
                    });
            });
    };
};

function sanitizeCopiedConf(copy) {
    if (!copy) {
        return;
    }

    Object.keys(copy).forEach(function(k) {
        if (/(api|key|token)/i.test(k) && 'string' === typeof copy[k]) {
            copy[k] = '**redacted**';
        }
    });

    return copy;
}