log cleanup
This commit is contained in:
		
							parent
							
								
									d9da4c0989
								
							
						
					
					
						commit
						1998c3d119
					
				@ -218,6 +218,10 @@
 | 
				
			|||||||
                  <div class="js-acme-ver-txt-value">loading...</div>
 | 
					                  <div class="js-acme-ver-txt-value">loading...</div>
 | 
				
			||||||
                  <br>
 | 
					                  <br>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					                <p><strong>Warning</strong>:
 | 
				
			||||||
 | 
					                  You should wait at least 30 seconds after setting DNS records before continuing.</p>
 | 
				
			||||||
 | 
					                <p><strong>Google DNS Users</strong>:
 | 
				
			||||||
 | 
					                  You may need to wait up to 5 minutes.</p>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -231,6 +235,10 @@
 | 
				
			|||||||
                  <div class="js-acme-ver-txt-value">loading...</div>
 | 
					                  <div class="js-acme-ver-txt-value">loading...</div>
 | 
				
			||||||
                  <br>
 | 
					                  <br>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
 | 
					                <p><strong>Warning</strong>:
 | 
				
			||||||
 | 
					                  You should wait at least 30 seconds after setting DNS records before continuing.</p>
 | 
				
			||||||
 | 
					                <p><strong>Google DNS</strong>:
 | 
				
			||||||
 | 
					                  You may need to wait up to 5 minutes.</p>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
				
			|||||||
@ -1907,6 +1907,9 @@ ACME._registerAccount = function (me, options) {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return Promise.resolve().then(function () {
 | 
					  return Promise.resolve().then(function () {
 | 
				
			||||||
 | 
					    if (true === options.agreeToTerms) {
 | 
				
			||||||
 | 
					      options.agreeToTerms = function (tos) { return tos; };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return options.agreeToTerms(me._tos);
 | 
					    return options.agreeToTerms(me._tos);
 | 
				
			||||||
  }).then(agree);
 | 
					  }).then(agree);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
@ -1977,7 +1980,7 @@ ACME._testChallengeOptions = function () {
 | 
				
			|||||||
  ];
 | 
					  ];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
ACME._testChallenges = function (me, reals) {
 | 
					ACME._testChallenges = function (me, reals) {
 | 
				
			||||||
  console.log('[DEBUG] testChallenges');
 | 
					  //#console.log('[DEBUG] testChallenges');
 | 
				
			||||||
  if (me.skipDryRun || me.skipChallengeTest) {
 | 
					  if (me.skipDryRun || me.skipChallengeTest) {
 | 
				
			||||||
    return Promise.resolve();
 | 
					    return Promise.resolve();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@ -2043,7 +2046,7 @@ ACME._chooseType = function(options, auths) {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
ACME._challengesMap = {'http-01':0,'dns-01':0,'tls-alpn-01':0};
 | 
					ACME._challengesMap = {'http-01':0,'dns-01':0,'tls-alpn-01':0};
 | 
				
			||||||
ACME._computeAuths = function (me, options, request, dryrun) {
 | 
					ACME._computeAuths = function (me, options, request, dryrun) {
 | 
				
			||||||
  console.log('[DEBUG] computeAuths');
 | 
					  //#console.log('[DEBUG] computeAuths');
 | 
				
			||||||
  // we don't poison the dns cache with our dummy request
 | 
					  // we don't poison the dns cache with our dummy request
 | 
				
			||||||
  var dnsPrefix = ACME.challengePrefixes['dns-01'];
 | 
					  var dnsPrefix = ACME.challengePrefixes['dns-01'];
 | 
				
			||||||
  if (dryrun) {
 | 
					  if (dryrun) {
 | 
				
			||||||
@ -2226,7 +2229,7 @@ ACME._postChallenge = function (me, options, auth) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// options = { domains, claims, challenges, challengePriority }
 | 
					// options = { domains, claims, challenges, challengePriority }
 | 
				
			||||||
ACME._setChallengesAll = function (me, options) {
 | 
					ACME._setChallengesAll = function (me, options) {
 | 
				
			||||||
  console.log("[DEBUG] setChallengesAll");
 | 
					  //#console.log("[DEBUG] setChallengesAll");
 | 
				
			||||||
  var claims = options.order.claims.slice(0);
 | 
					  var claims = options.order.claims.slice(0);
 | 
				
			||||||
  var valids = [];
 | 
					  var valids = [];
 | 
				
			||||||
  var auths = [];
 | 
					  var auths = [];
 | 
				
			||||||
@ -2331,8 +2334,8 @@ ACME._finalizeOrder = function (me, options) {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      return challengeNext().then(function () {
 | 
					      return challengeNext().then(function () {
 | 
				
			||||||
        //#console.debug("[getCertificate] next.then");
 | 
					        //#console.debug("[getCertificate] next.then");
 | 
				
			||||||
        console.log('DEBUG 1 order:');
 | 
					        //#console.log('DEBUG order:');
 | 
				
			||||||
        console.log(options.order);
 | 
					        //#console.log(options.order);
 | 
				
			||||||
        return options.order.identifiers.map(function (ident) {
 | 
					        return options.order.identifiers.map(function (ident) {
 | 
				
			||||||
          return ident.value;
 | 
					          return ident.value;
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
				
			|||||||
@ -4,18 +4,18 @@
 | 
				
			|||||||
  /*global URLSearchParams,Headers*/
 | 
					  /*global URLSearchParams,Headers*/
 | 
				
			||||||
  var PromiseA = window.Promise;
 | 
					  var PromiseA = window.Promise;
 | 
				
			||||||
  var VERSION = '2';
 | 
					  var VERSION = '2';
 | 
				
			||||||
	// ACME recommends ECDSA P-256, but RSA 2048 is still required by some old servers (like what replicated.io uses )
 | 
					  // ACME recommends ECDSA P-256, but RSA 2048 is still required by some old servers (like what replicated.io uses )
 | 
				
			||||||
	// ECDSA P-384, P-521, and RSA 3072, 4096 are NOT recommend standards (and not properly supported)
 | 
					  // ECDSA P-384, P-521, and RSA 3072, 4096 are NOT recommend standards (and not properly supported)
 | 
				
			||||||
  var BROWSER_SUPPORTS_RSA;
 | 
					  var BROWSER_SUPPORTS_RSA = false;
 | 
				
			||||||
	var ECDSA_OPTS = { kty: 'EC', namedCurve: 'P-256' };
 | 
					  var ECDSA_OPTS = { kty: 'EC', namedCurve: 'P-256' };
 | 
				
			||||||
	var RSA_OPTS = { kty: 'RSA', modulusLength: 2048 };
 | 
					  var RSA_OPTS = { kty: 'RSA', modulusLength: 2048 };
 | 
				
			||||||
  var Promise = window.Promise;
 | 
					  var Promise = window.Promise;
 | 
				
			||||||
  var Keypairs = window.Keypairs;
 | 
					  var Keypairs = window.Keypairs;
 | 
				
			||||||
  var ACME = window.ACME;
 | 
					  var ACME = window.ACME;
 | 
				
			||||||
  var CSR = window.CSR;
 | 
					  var CSR = window.CSR;
 | 
				
			||||||
  var $qs = function (s) { return window.document.querySelector(s); };
 | 
					  var $qs = function (s) { return window.document.querySelector(s); };
 | 
				
			||||||
  var $qsa = function (s) { return window.document.querySelectorAll(s); };
 | 
					  var $qsa = function (s) { return window.document.querySelectorAll(s); };
 | 
				
			||||||
	var acme;
 | 
					  var acme;
 | 
				
			||||||
  var info = {};
 | 
					  var info = {};
 | 
				
			||||||
  var steps = {};
 | 
					  var steps = {};
 | 
				
			||||||
  var i = 1;
 | 
					  var i = 1;
 | 
				
			||||||
@ -29,36 +29,12 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  localStorage.setItem('version', VERSION);
 | 
					  localStorage.setItem('version', VERSION);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var challenges = {
 | 
					 | 
				
			||||||
    'http-01': {
 | 
					 | 
				
			||||||
      set: function (auth) {
 | 
					 | 
				
			||||||
        console.log('Chose http-01 for', auth.altname, auth);
 | 
					 | 
				
			||||||
        return Promise.resolve();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    , remove: function (auth) {
 | 
					 | 
				
			||||||
        console.log('Can remove http-01 for', auth.altname, auth);
 | 
					 | 
				
			||||||
        return Promise.resolve();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  , 'dns-01': {
 | 
					 | 
				
			||||||
      set: function (auth) {
 | 
					 | 
				
			||||||
        console.log('Chose dns-01 for', auth.altname, auth);
 | 
					 | 
				
			||||||
        return Promise.resolve();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    , remove: function (auth) {
 | 
					 | 
				
			||||||
        console.log('Can remove dns-01 for', auth.altname, auth);
 | 
					 | 
				
			||||||
        return Promise.resolve();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  function updateApiType() {
 | 
					  function updateApiType() {
 | 
				
			||||||
    console.log("type updated");
 | 
					 | 
				
			||||||
    /*jshint validthis: true */
 | 
					    /*jshint validthis: true */
 | 
				
			||||||
    var input = this || Array.prototype.filter.call(
 | 
					    var input = this || Array.prototype.filter.call(
 | 
				
			||||||
      $qsa('.js-acme-api-type'), function ($el) { return $el.checked; }
 | 
					      $qsa('.js-acme-api-type'), function ($el) { return $el.checked; }
 | 
				
			||||||
    )[0];
 | 
					    )[0];
 | 
				
			||||||
    console.log('ACME api type radio:', input.value);
 | 
					    //#console.log('ACME api type radio:', input.value);
 | 
				
			||||||
    $qs('.js-acme-directory-url').value = apiUrl.replace(/{{env}}/g, input.value);
 | 
					    $qs('.js-acme-directory-url').value = apiUrl.replace(/{{env}}/g, input.value);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -70,7 +46,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  function updateProgress(currentStep) {
 | 
					  function updateProgress(currentStep) {
 | 
				
			||||||
    var progressSteps = $qs("#js-progress-bar").children;
 | 
					    var progressSteps = $qs("#js-progress-bar").children;
 | 
				
			||||||
		var j;
 | 
					    var j;
 | 
				
			||||||
    for (j = 0; j < progressSteps.length; j += 1) {
 | 
					    for (j = 0; j < progressSteps.length; j += 1) {
 | 
				
			||||||
      if (j < currentStep) {
 | 
					      if (j < currentStep) {
 | 
				
			||||||
        progressSteps[j].classList.add("js-progress-step-complete");
 | 
					        progressSteps[j].classList.add("js-progress-step-complete");
 | 
				
			||||||
@ -116,28 +92,18 @@
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function testEcdsaSupport() {
 | 
					 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
			var opts = {
 | 
					 | 
				
			||||||
				kty: $('input[name="kty"]:checked').value
 | 
					 | 
				
			||||||
			, namedCurve: $('input[name="ec-crv"]:checked').value
 | 
					 | 
				
			||||||
			, modulusLength: $('input[name="rsa-len"]:checked').value
 | 
					 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
		*/
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  function testRsaSupport() {
 | 
					 | 
				
			||||||
		return Keypairs.generate(RSA_OPTS);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  function testKeypairSupport() {
 | 
					  function testKeypairSupport() {
 | 
				
			||||||
 | 
					    return Keypairs.generate(RSA_OPTS).then(function () {
 | 
				
			||||||
    return testRsaSupport().then(function () {
 | 
					 | 
				
			||||||
      console.info("[crypto] RSA is supported");
 | 
					      console.info("[crypto] RSA is supported");
 | 
				
			||||||
      BROWSER_SUPPORTS_RSA = true;
 | 
					      BROWSER_SUPPORTS_RSA = true;
 | 
				
			||||||
      return BROWSER_SUPPORTS_RSA;
 | 
					 | 
				
			||||||
    }).catch(function () {
 | 
					    }).catch(function () {
 | 
				
			||||||
      console.warn("[crypto] RSA is NOT fully supported");
 | 
					      console.warn("[crypto] RSA is NOT supported");
 | 
				
			||||||
      BROWSER_SUPPORTS_RSA = false;
 | 
					      return Keypairs.generate(ECDSA_OPTS).then(function () {
 | 
				
			||||||
      return BROWSER_SUPPORTS_RSA;
 | 
					        console.info('[crypto] ECDSA is supported');
 | 
				
			||||||
 | 
					      }).catch(function (e) {
 | 
				
			||||||
 | 
					        console.warn("[crypto] EC is NOT supported");
 | 
				
			||||||
 | 
					        throw e;
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -159,36 +125,35 @@
 | 
				
			|||||||
    return Keypairs.generate(RSA_OPTS).catch(function (err) {
 | 
					    return Keypairs.generate(RSA_OPTS).catch(function (err) {
 | 
				
			||||||
      console.error("[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):");
 | 
					      console.error("[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):");
 | 
				
			||||||
      throw err;
 | 
					      throw err;
 | 
				
			||||||
		}).then(function (pair) {
 | 
					    }).then(function (pair) {
 | 
				
			||||||
			localStorage.setItem('server:'+sortedAltnames, JSON.stringify(pair.private));
 | 
					      localStorage.setItem('server:'+sortedAltnames, JSON.stringify(pair.private));
 | 
				
			||||||
			return pair.private;
 | 
					      return pair.private;
 | 
				
			||||||
		});
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function getAccountKeypair(email) {
 | 
					  function getAccountKeypair(email) {
 | 
				
			||||||
		var json = localStorage.getItem('account:'+email);
 | 
					    var json = localStorage.getItem('account:'+email);
 | 
				
			||||||
		if (json) {
 | 
					    if (json) {
 | 
				
			||||||
			return Promise.resolve(JSON.parse(json));
 | 
					      return Promise.resolve(JSON.parse(json));
 | 
				
			||||||
		}
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return Keypairs.generate(ECDSA_OPTS).catch(function (err) {
 | 
					    return Keypairs.generate(ECDSA_OPTS).catch(function (err) {
 | 
				
			||||||
			console.warn("[Error] Keypairs.generate(" + JSON.stringify(ECDSA_OPTS) + "):\n", err);
 | 
					      console.warn("[Error] Keypairs.generate(" + JSON.stringify(ECDSA_OPTS) + "):\n", err);
 | 
				
			||||||
			return Keypairs.generate(RSA_OPTS).catch(function (err) {
 | 
					      return Keypairs.generate(RSA_OPTS).catch(function (err) {
 | 
				
			||||||
				console.error("[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):");
 | 
					        console.error("[Error] Keypairs.generate(" + JSON.stringify(RSA_OPTS) + "):");
 | 
				
			||||||
				throw err;
 | 
					        throw err;
 | 
				
			||||||
			});
 | 
					      });
 | 
				
			||||||
		}).then(function (pair) {
 | 
					    }).then(function (pair) {
 | 
				
			||||||
			localStorage.setItem('account:'+email, JSON.stringify(pair.private));
 | 
					      localStorage.setItem('account:'+email, JSON.stringify(pair.private));
 | 
				
			||||||
			return pair.private;
 | 
					      return pair.private;
 | 
				
			||||||
		});
 | 
					    });
 | 
				
			||||||
	}
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  function updateChallengeType() {
 | 
					  function updateChallengeType() {
 | 
				
			||||||
    /*jshint validthis: true*/
 | 
					    /*jshint validthis: true*/
 | 
				
			||||||
    var input = this || Array.prototype.filter.call(
 | 
					    var input = this || Array.prototype.filter.call(
 | 
				
			||||||
      $qsa('.js-acme-challenge-type'), function ($el) { return $el.checked; }
 | 
					      $qsa('.js-acme-challenge-type'), function ($el) { return $el.checked; }
 | 
				
			||||||
    )[0];
 | 
					    )[0];
 | 
				
			||||||
    console.log('ch type radio:', input.value);
 | 
					 | 
				
			||||||
    $qs('.js-acme-verification-wildcard').hidden = true;
 | 
					    $qs('.js-acme-verification-wildcard').hidden = true;
 | 
				
			||||||
    $qs('.js-acme-verification-http-01').hidden = true;
 | 
					    $qs('.js-acme-verification-http-01').hidden = true;
 | 
				
			||||||
    $qs('.js-acme-verification-dns-01').hidden = true;
 | 
					    $qs('.js-acme-verification-dns-01').hidden = true;
 | 
				
			||||||
@ -209,7 +174,7 @@
 | 
				
			|||||||
    , body: JSON.stringify({
 | 
					    , body: JSON.stringify({
 | 
				
			||||||
        address: email
 | 
					        address: email
 | 
				
			||||||
      , project: 'greenlock-domains@rootprojects.org'
 | 
					      , project: 'greenlock-domains@rootprojects.org'
 | 
				
			||||||
			, timezone: new Intl.DateTimeFormat().resolvedOptions().timeZone
 | 
					      , timezone: new Intl.DateTimeFormat().resolvedOptions().timeZone
 | 
				
			||||||
      , domain: domains.join(',')
 | 
					      , domain: domains.join(',')
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
    }).catch(function (err) {
 | 
					    }).catch(function (err) {
 | 
				
			||||||
@ -218,12 +183,17 @@
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  steps[1] = function () {
 | 
					  steps[1] = function () {
 | 
				
			||||||
 | 
					    console.info("1. Show domains form");
 | 
				
			||||||
    updateProgress(0);
 | 
					    updateProgress(0);
 | 
				
			||||||
    hideForms();
 | 
					    hideForms();
 | 
				
			||||||
    $qs('.js-acme-form-domains').hidden = false;
 | 
					    $qs('.js-acme-form-domains').hidden = false;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  steps[1].submit = function () {
 | 
					  steps[1].submit = function () {
 | 
				
			||||||
    info.domains = $qs('.js-acme-domains').value.replace(/https?:\/\//g, ' ').replace(/[,+]/g, ' ').trim().split(/\s+/g);
 | 
					    console.info("[submit] 1. Process domains, create ACME client", info.domains);
 | 
				
			||||||
 | 
					    info.domains = $qs('.js-acme-domains').value
 | 
				
			||||||
 | 
					      .replace(/https?:\/\//g, ' ').replace(/[,+]/g, ' ').trim().split(/\s+/g);
 | 
				
			||||||
 | 
					    console.info("[domains]", info.domains.join(' '));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info.identifiers = info.domains.map(function (hostname) {
 | 
					    info.identifiers = info.domains.map(function (hostname) {
 | 
				
			||||||
      return { type: 'dns', value: hostname.toLowerCase().trim() };
 | 
					      return { type: 'dns', value: hostname.toLowerCase().trim() };
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@ -233,90 +203,77 @@
 | 
				
			|||||||
      if (a > b) { return -1; }
 | 
					      if (a > b) { return -1; }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var acmeDirectoryUrl = $qs('.js-acme-directory-url').value;
 | 
					    var acmeDirectoryUrl = $qs('.js-acme-directory-url').value;
 | 
				
			||||||
		acme = ACME.create({ Keypairs: Keypairs, CSR: CSR });
 | 
					    acme = ACME.create({ Keypairs: Keypairs, CSR: CSR });
 | 
				
			||||||
		return acme.init(acmeDirectoryUrl).then(function (directory) {
 | 
					    return acme.init(acmeDirectoryUrl).then(function (directory) {
 | 
				
			||||||
      $qs('.js-acme-tos-url').href = directory.meta.termsOfService;
 | 
					      $qs('.js-acme-tos-url').href = directory.meta.termsOfService;
 | 
				
			||||||
			console.log("MAGIC STEP NUMBER in 1 is:", i);
 | 
					      steps[i]();
 | 
				
			||||||
			steps[i]();
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  steps[2] = function () {
 | 
					  steps[2] = function () {
 | 
				
			||||||
 | 
					    console.info("2. Show account (email, ToS) form");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateProgress(0);
 | 
					    updateProgress(0);
 | 
				
			||||||
    hideForms();
 | 
					    hideForms();
 | 
				
			||||||
    $qs('.js-acme-form-account').hidden = false;
 | 
					    $qs('.js-acme-form-account').hidden = false;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  steps[2].submit = function () {
 | 
					  steps[2].submit = function () {
 | 
				
			||||||
    var email = $qs('.js-acme-account-email').value.toLowerCase().trim();
 | 
					    console.info("[submit] 2. Create ACME account (get Key ID)");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var email = $qs('.js-acme-account-email').value.toLowerCase().trim();
 | 
				
			||||||
    info.email = email;
 | 
					    info.email = email;
 | 
				
			||||||
    info.contact = [ 'mailto:' + email ];
 | 
					    info.contact = [ 'mailto:' + email ];
 | 
				
			||||||
    info.agree = $qs('.js-acme-account-tos').checked;
 | 
					    info.agree = $qs('.js-acme-account-tos').checked;
 | 
				
			||||||
    //info.greenlockAgree = $qs('.js-gl-tos').checked;
 | 
					    //info.greenlockAgree = $qs('.js-gl-tos').checked;
 | 
				
			||||||
    info.domains = info.identifiers.map(function (ident) { return ident.value; });
 | 
					 | 
				
			||||||
    console.log("domains:");
 | 
					 | 
				
			||||||
    console.log(info.domains);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // TODO ping with version and account creation
 | 
					    // TODO ping with version and account creation
 | 
				
			||||||
    setTimeout(saveContact, 100, email, info.domains);
 | 
					    setTimeout(saveContact, 100, email, info.domains);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		function checkTos(tos) {
 | 
					 | 
				
			||||||
			if (info.agree) {
 | 
					 | 
				
			||||||
				return tos;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				return '';
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $qs('.js-account-next').disabled = true;
 | 
					    $qs('.js-account-next').disabled = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return getAccountKeypair(email).then(function (jwk) {
 | 
					    return info.cryptoCheck.then(function () {
 | 
				
			||||||
      // TODO save account id rather than always retrieving it?
 | 
					      return getAccountKeypair(email).then(function (jwk) {
 | 
				
			||||||
			return acme.accounts.create({
 | 
					        // TODO save account id rather than always retrieving it?
 | 
				
			||||||
				email: email
 | 
					        console.info("[accounts] upsert for", email);
 | 
				
			||||||
			, agreeToTerms: checkTos
 | 
					        return acme.accounts.create({
 | 
				
			||||||
			, accountKeypair: { privateKeyJwk: jwk }
 | 
					          email: email
 | 
				
			||||||
			}).then(function (account) {
 | 
					        , agreeToTerms: info.agree && true
 | 
				
			||||||
				console.log("account created result:", account);
 | 
					        , accountKeypair: { privateKeyJwk: jwk }
 | 
				
			||||||
				info.account = account;
 | 
					        }).then(function (account) {
 | 
				
			||||||
				info.privateJwk = jwk;
 | 
					          console.info("[accounts] result:", account);
 | 
				
			||||||
				info.email = email;
 | 
					          info.account = account;
 | 
				
			||||||
				info.acme = acme; // TODO XXX remove
 | 
					          info.privateJwk = jwk;
 | 
				
			||||||
			}).catch(function (err) {
 | 
					          info.email = email;
 | 
				
			||||||
				console.error("A bad thing happened:");
 | 
					        }).catch(function (err) {
 | 
				
			||||||
				console.error(err);
 | 
					          console.error("[accounts] failed to upsert account:");
 | 
				
			||||||
				window.alert(err.message || JSON.stringify(err, null, 2));
 | 
					          console.error(err);
 | 
				
			||||||
				return new Promise(function () {
 | 
					          window.alert(err.message || JSON.stringify(err, null, 2));
 | 
				
			||||||
 					// stop the process cold
 | 
					          return new Promise(function () {
 | 
				
			||||||
					console.warn('TODO: resume at ask email?');
 | 
					            if (window.confirm("Start over?")) {
 | 
				
			||||||
				});
 | 
					              document.location.reload();
 | 
				
			||||||
			});
 | 
					            }
 | 
				
			||||||
		}).then(function () {
 | 
					          });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }).then(function () {
 | 
				
			||||||
      var jwk = info.privateJwk;
 | 
					      var jwk = info.privateJwk;
 | 
				
			||||||
      var account = info.account;
 | 
					      var account = info.account;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return acme.orders.request({
 | 
					      console.info("[orders] requesting");
 | 
				
			||||||
			  account: account
 | 
					      return acme.orders.request({
 | 
				
			||||||
			, accountKeypair: { privateKeyJwk: jwk }
 | 
					        account: account
 | 
				
			||||||
			, domains: info.domains
 | 
					      , accountKeypair: { privateKeyJwk: jwk }
 | 
				
			||||||
      , challenges: challenges
 | 
					      , domains: info.domains
 | 
				
			||||||
			}).then(function (order) {
 | 
					      }).then(function (order) {
 | 
				
			||||||
        info.order = order;
 | 
					        info.order = order;
 | 
				
			||||||
 | 
					        console.info("[orders] created ", order);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var claims = order.claims;
 | 
					        var claims = order.claims;
 | 
				
			||||||
        console.log('claims:');
 | 
					 | 
				
			||||||
        console.log(claims);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        var obj = { 'dns-01': [], 'http-01': [], 'wildcard': [] };
 | 
					        var obj = { 'dns-01': [], 'http-01': [], 'wildcard': [] };
 | 
				
			||||||
        info.challenges = obj;
 | 
					        info.challenges = obj;
 | 
				
			||||||
        /*
 | 
					
 | 
				
			||||||
        var map = {
 | 
					 | 
				
			||||||
          'http-01': '.js-acme-verification-http-01'
 | 
					 | 
				
			||||||
        , 'dns-01': '.js-acme-verification-dns-01'
 | 
					 | 
				
			||||||
        , 'wildcard': '.js-acme-verification-wildcard'
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        */
 | 
					 | 
				
			||||||
        var $httpList = $qs('.js-acme-http');
 | 
					        var $httpList = $qs('.js-acme-http');
 | 
				
			||||||
        var $dnsList = $qs('.js-acme-dns');
 | 
					        var $dnsList = $qs('.js-acme-dns');
 | 
				
			||||||
        var $wildList = $qs('.js-acme-wildcard');
 | 
					        var $wildList = $qs('.js-acme-wildcard');
 | 
				
			||||||
@ -328,8 +285,7 @@
 | 
				
			|||||||
        $wildList.innerHTML = '';
 | 
					        $wildList.innerHTML = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        claims.forEach(function (claim) {
 | 
					        claims.forEach(function (claim) {
 | 
				
			||||||
          console.log("Challenge (claim):");
 | 
					          //#console.log("claims[i]", claim);
 | 
				
			||||||
          console.log(claim);
 | 
					 | 
				
			||||||
          var hostname = claim.identifier.value;
 | 
					          var hostname = claim.identifier.value;
 | 
				
			||||||
          claim.challenges.forEach(function (c) {
 | 
					          claim.challenges.forEach(function (c) {
 | 
				
			||||||
            var auth = c;
 | 
					            var auth = c;
 | 
				
			||||||
@ -344,41 +300,33 @@
 | 
				
			|||||||
            , dnsHost: auth.dnsHost
 | 
					            , dnsHost: auth.dnsHost
 | 
				
			||||||
            , dnsAnswer: auth.keyAuthorizationDigest
 | 
					            , dnsAnswer: auth.keyAuthorizationDigest
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					            //#console.log("claims[i].challenge", data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            console.log('');
 | 
					            var $tpl = document.createElement("div");
 | 
				
			||||||
            console.log('CHALLENGE');
 | 
					 | 
				
			||||||
            console.log(claim);
 | 
					 | 
				
			||||||
            console.log(c);
 | 
					 | 
				
			||||||
            console.log(data);
 | 
					 | 
				
			||||||
            console.log('');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            var verification = document.createElement("div");
 | 
					 | 
				
			||||||
            if (claim.wildcard) {
 | 
					            if (claim.wildcard) {
 | 
				
			||||||
              obj.wildcard.push(data);
 | 
					              obj.wildcard.push(data);
 | 
				
			||||||
              verification.innerHTML = wildTpl;
 | 
					              $tpl.innerHTML = wildTpl;
 | 
				
			||||||
              //verification.querySelector(".js-acme-ver-hostname").innerHTML = data.hostname;
 | 
					              $tpl.querySelector(".js-acme-ver-txt-host").innerHTML = data.dnsHost;
 | 
				
			||||||
              verification.querySelector(".js-acme-ver-txt-host").innerHTML = data.dnsHost;
 | 
					              $tpl.querySelector(".js-acme-ver-txt-value").innerHTML = data.dnsAnswer;
 | 
				
			||||||
              verification.querySelector(".js-acme-ver-txt-value").innerHTML = data.dnsAnswer;
 | 
					              $wildList.appendChild($tpl);
 | 
				
			||||||
              $wildList.appendChild(verification);
 | 
					 | 
				
			||||||
            } else if(obj[data.type]) {
 | 
					            } else if(obj[data.type]) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              obj[data.type].push(data);
 | 
					              obj[data.type].push(data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
              if ('dns-01' === data.type) {
 | 
					              if ('dns-01' === data.type) {
 | 
				
			||||||
                verification.innerHTML = dnsTpl;
 | 
					                $tpl.innerHTML = dnsTpl;
 | 
				
			||||||
                //verification.querySelector(".js-acme-ver-hostname").innerHTML = data.hostname;
 | 
					                $tpl.querySelector(".js-acme-ver-txt-host").innerHTML = data.dnsHost;
 | 
				
			||||||
                verification.querySelector(".js-acme-ver-txt-host").innerHTML = data.dnsHost;
 | 
					                $tpl.querySelector(".js-acme-ver-txt-value").innerHTML = data.dnsAnswer;
 | 
				
			||||||
                verification.querySelector(".js-acme-ver-txt-value").innerHTML = data.dnsAnswer;
 | 
					                $dnsList.appendChild($tpl);
 | 
				
			||||||
                $dnsList.appendChild(verification);
 | 
					 | 
				
			||||||
              } else if ('http-01' === data.type) {
 | 
					              } else if ('http-01' === data.type) {
 | 
				
			||||||
                verification.innerHTML = httpTpl;
 | 
					                $tpl.innerHTML = httpTpl;
 | 
				
			||||||
                verification.querySelector(".js-acme-ver-file-location").innerHTML = data.httpPath.split("/").slice(-1);
 | 
					                $tpl.querySelector(".js-acme-ver-file-location").innerHTML = data.httpPath.split("/").slice(-1);
 | 
				
			||||||
                verification.querySelector(".js-acme-ver-content").innerHTML = data.httpAuth;
 | 
					                $tpl.querySelector(".js-acme-ver-content").innerHTML = data.httpAuth;
 | 
				
			||||||
                verification.querySelector(".js-acme-ver-uri").innerHTML = data.httpPath;
 | 
					                $tpl.querySelector(".js-acme-ver-uri").innerHTML = data.httpPath;
 | 
				
			||||||
                verification.querySelector(".js-download-verify-link").href =
 | 
					                $tpl.querySelector(".js-download-verify-link").href =
 | 
				
			||||||
                  "data:text/octet-stream;base64," + window.btoa(data.httpAuth);
 | 
					                  "data:text/octet-stream;base64," + window.btoa(data.httpAuth);
 | 
				
			||||||
                verification.querySelector(".js-download-verify-link").download = data.httpPath.split("/").slice(-1);
 | 
					                $tpl.querySelector(".js-download-verify-link").download = data.httpPath.split("/").slice(-1);
 | 
				
			||||||
                $httpList.appendChild(verification);
 | 
					                $httpList.appendChild($tpl);
 | 
				
			||||||
              }
 | 
					              }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          });
 | 
					          });
 | 
				
			||||||
@ -393,9 +341,9 @@
 | 
				
			|||||||
          $qs('.js-acme-challenges').hidden = true;
 | 
					          $qs('.js-acme-challenges').hidden = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        updateChallengeType();
 | 
					        console.info("[housekeeping] challenges", info.challenges);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        console.log("MAGIC STEP NUMBER in 2 is:", i);
 | 
					        updateChallengeType();
 | 
				
			||||||
        steps[i]();
 | 
					        steps[i]();
 | 
				
			||||||
      });
 | 
					      });
 | 
				
			||||||
    }).catch(function (err) {
 | 
					    }).catch(function (err) {
 | 
				
			||||||
@ -407,23 +355,28 @@
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  steps[3] = function () {
 | 
					  steps[3] = function () {
 | 
				
			||||||
 | 
					    console.info("3. Present challenge options");
 | 
				
			||||||
    updateProgress(1);
 | 
					    updateProgress(1);
 | 
				
			||||||
    hideForms();
 | 
					    hideForms();
 | 
				
			||||||
    $qs('.js-acme-form-challenges').hidden = false;
 | 
					    $qs('.js-acme-form-challenges').hidden = false;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  steps[3].submit = function () {
 | 
					  steps[3].submit = function () {
 | 
				
			||||||
 | 
					    console.info("[submit] 3. Fulfill challenges, fetch certificate");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    var challengePriority = [ 'dns-01' ];
 | 
					    var challengePriority = [ 'dns-01' ];
 | 
				
			||||||
    if ('http-01' === $qs('.js-acme-challenge-type:checked').value) {
 | 
					    if ('http-01' === $qs('.js-acme-challenge-type:checked').value) {
 | 
				
			||||||
      challengePriority.unshift('http-01');
 | 
					      challengePriority.unshift('http-01');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    console.log('primary challenge type is:', challengePriority[0]);
 | 
					    console.info("[challenge] selected ", challengePriority[0]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // for now just show the next page immediately (its a spinner)
 | 
				
			||||||
    steps[i]();
 | 
					    steps[i]();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return getAccountKeypair(info.email).then(function (jwk) {
 | 
					    return getAccountKeypair(info.email).then(function (jwk) {
 | 
				
			||||||
      // for now just show the next page immediately (its a spinner)
 | 
					 | 
				
			||||||
      // TODO put a test challenge in the list
 | 
					      // TODO put a test challenge in the list
 | 
				
			||||||
 | 
					      // info.order.claims.push(...)
 | 
				
			||||||
      // TODO warn about wait-time if DNS
 | 
					      // TODO warn about wait-time if DNS
 | 
				
			||||||
		  return getServerKeypair().then(function (serverJwk) {
 | 
					      return getServerKeypair().then(function (serverJwk) {
 | 
				
			||||||
        return acme.orders.complete({
 | 
					        return acme.orders.complete({
 | 
				
			||||||
          account: info.account
 | 
					          account: info.account
 | 
				
			||||||
        , accountKeypair: { privateKeyJwk: jwk }
 | 
					        , accountKeypair: { privateKeyJwk: jwk }
 | 
				
			||||||
@ -431,10 +384,10 @@
 | 
				
			|||||||
        , domains: info.domains
 | 
					        , domains: info.domains
 | 
				
			||||||
        , domainKeypair: { privateKeyJwk: serverJwk }
 | 
					        , domainKeypair: { privateKeyJwk: serverJwk }
 | 
				
			||||||
        , challengePriority: challengePriority
 | 
					        , challengePriority: challengePriority
 | 
				
			||||||
        , challenges: challenges
 | 
					        , challenges: false
 | 
				
			||||||
        }).then(function (certs) {
 | 
					        }).then(function (certs) {
 | 
				
			||||||
          return Keypairs.export({ jwk: serverJwk }).then(function (keyPem) {
 | 
					          return Keypairs.export({ jwk: serverJwk }).then(function (keyPem) {
 | 
				
			||||||
            console.log('WINNING!');
 | 
					            console.info('WINNING!');
 | 
				
			||||||
            console.log(certs);
 | 
					            console.log(certs);
 | 
				
			||||||
            $qs('#js-fullchain').innerHTML = [
 | 
					            $qs('#js-fullchain').innerHTML = [
 | 
				
			||||||
              certs.cert.trim() + "\n"
 | 
					              certs.cert.trim() + "\n"
 | 
				
			||||||
@ -455,76 +408,76 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  // spinner
 | 
					  // spinner
 | 
				
			||||||
  steps[4] = function () {
 | 
					  steps[4] = function () {
 | 
				
			||||||
 | 
					    console.info('4. Show loading spinner');
 | 
				
			||||||
    updateProgress(1);
 | 
					    updateProgress(1);
 | 
				
			||||||
    hideForms();
 | 
					    hideForms();
 | 
				
			||||||
    $qs('.js-acme-form-poll').hidden = false;
 | 
					    $qs('.js-acme-form-poll').hidden = false;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
  steps[4].submit = function () {
 | 
					  steps[4].submit = function () {
 | 
				
			||||||
    console.log('Congrats! Auto advancing...');
 | 
					    console.info('[submit] 4. Order complete');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    steps[i]();
 | 
					    steps[i]();
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  steps[5] = function () {
 | 
					  steps[5] = function () {
 | 
				
			||||||
 | 
					    console.info('5. Present certificates (yay!)');
 | 
				
			||||||
    updateProgress(2);
 | 
					    updateProgress(2);
 | 
				
			||||||
    hideForms();
 | 
					    hideForms();
 | 
				
			||||||
    $qs('.js-acme-form-download').hidden = false;
 | 
					    $qs('.js-acme-form-download').hidden = false;
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  var params = new URLSearchParams(window.location.search);
 | 
					  function init() {
 | 
				
			||||||
  var apiType = params.get('acme-api-type') || "staging-v02";
 | 
					    var params = new URLSearchParams(window.location.search);
 | 
				
			||||||
 | 
					    var apiType = params.get('acme-api-type') || "staging-v02";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $qsa('.js-acme-api-type').forEach(function ($el) {
 | 
					    $qsa('.js-acme-api-type').forEach(function ($el) {
 | 
				
			||||||
    $el.addEventListener('change', updateApiType);
 | 
					      $el.addEventListener('change', updateApiType);
 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  updateApiType();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  $qsa('.js-acme-form').forEach(function ($el) {
 | 
					 | 
				
			||||||
    $el.addEventListener('submit', function (ev) {
 | 
					 | 
				
			||||||
      ev.preventDefault();
 | 
					 | 
				
			||||||
      submitForm(ev);
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  $qsa('.js-acme-challenge-type').forEach(function ($el) {
 | 
					 | 
				
			||||||
    $el.addEventListener('change', updateChallengeType);
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (params.has('acme-domains')) {
 | 
					 | 
				
			||||||
    console.log("acme-domains param: ", params.get('acme-domains'));
 | 
					 | 
				
			||||||
    $qs('.js-acme-domains').value = params.get('acme-domains');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $qsa('.js-acme-api-type').forEach(function(ele) {
 | 
					 | 
				
			||||||
      if(ele.value === apiType) {
 | 
					 | 
				
			||||||
        ele.checked = true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    updateApiType();
 | 
					    updateApiType();
 | 
				
			||||||
    steps[2]();
 | 
					 | 
				
			||||||
    submitForm();
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  $qs('body').hidden = false;
 | 
					    $qsa('.js-acme-form').forEach(function ($el) {
 | 
				
			||||||
 | 
					      $el.addEventListener('submit', function (ev) {
 | 
				
			||||||
 | 
					        ev.preventDefault();
 | 
				
			||||||
 | 
					        submitForm(ev);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    $qsa('.js-acme-challenge-type').forEach(function ($el) {
 | 
				
			||||||
 | 
					      $el.addEventListener('change', updateChallengeType);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (params.has('acme-domains')) {
 | 
				
			||||||
 | 
					      $qs('.js-acme-domains').value = params.get('acme-domains');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      $qsa('.js-acme-api-type').forEach(function(ele) {
 | 
				
			||||||
 | 
					        if(ele.value === apiType) {
 | 
				
			||||||
 | 
					          ele.checked = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      updateApiType();
 | 
				
			||||||
 | 
					      steps[2]();
 | 
				
			||||||
 | 
					      submitForm();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // The kickoff
 | 
					  // The kickoff
 | 
				
			||||||
  steps[1]();
 | 
					  steps[1]();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return testKeypairSupport().then(function (rsaSupport) {
 | 
					  init();
 | 
				
			||||||
    if (rsaSupport) {
 | 
					  $qs('body').hidden = false;
 | 
				
			||||||
      return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return testEcdsaSupport().then(function () {
 | 
					  // in the background
 | 
				
			||||||
      console.info('[crypto] ECDSA is supported');
 | 
					  info.cryptoCheck = testKeypairSupport().then(function () {
 | 
				
			||||||
    }).catch(function (err) {
 | 
					    console.info("[crypto] self-check: passed");
 | 
				
			||||||
      console.error('[crypto] could not use either RSA nor EC.');
 | 
					  }).catch(function (err) {
 | 
				
			||||||
      console.error(err);
 | 
					    console.error('[crypto] could not use either RSA nor EC.');
 | 
				
			||||||
      window.alert("Generating secure certificates requires a browser with cryptography support."
 | 
					    console.error(err);
 | 
				
			||||||
				+ "Please consider a recent version of Chrome, Firefox, or Safari.");
 | 
					    window.alert("Generating secure certificates requires a browser with cryptography support."
 | 
				
			||||||
			throw err;
 | 
					      + "Please consider a recent version of Chrome, Firefox, or Safari.");
 | 
				
			||||||
    });
 | 
					    throw err;
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
}());
 | 
					}());
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user