| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  | 'use strict'; | 
					
						
							| 
									
										
										
										
											2019-06-03 09:12:11 +00:00
										 |  |  | require('./compat.js'); | 
					
						
							| 
									
										
										
										
											2015-12-15 15:21:27 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-19 11:59:50 -08:00
										 |  |  | var path = require('path'); | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | var homeRe = new RegExp('^~(\\/|\\\\|\\' + path.sep + ')'); | 
					
						
							| 
									
										
										
										
											2018-04-27 11:38:15 -06:00
										 |  |  | // very basic check. Allows *.example.com.
 | 
					
						
							| 
									
										
										
										
											2018-04-27 11:44:49 -06:00
										 |  |  | var re = /^(\*\.)?[a-zA-Z0-9\.\-]+$/; | 
					
						
							| 
									
										
										
										
											2015-12-19 02:18:32 -08:00
										 |  |  | var punycode = require('punycode'); | 
					
						
							| 
									
										
										
										
											2019-06-03 09:12:11 +00:00
										 |  |  | var dnsResolveMxAsync = require('util').promisify(require('dns').resolveMx); | 
					
						
							| 
									
										
										
										
											2015-12-19 02:18:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | module.exports.attachCertInfo = function(results) { | 
					
						
							|  |  |  | 	var certInfo = require('cert-info').info(results.cert); | 
					
						
							| 
									
										
										
										
											2016-08-06 01:32:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	// subject, altnames, issuedAt, expiresAt
 | 
					
						
							|  |  |  | 	Object.keys(certInfo).forEach(function(key) { | 
					
						
							|  |  |  | 		results[key] = certInfo[key]; | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2016-08-06 01:32:59 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	return results; | 
					
						
							| 
									
										
										
										
											2016-08-06 01:32:59 -04:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | module.exports.certHasDomain = function(certInfo, _domain) { | 
					
						
							|  |  |  | 	var names = (certInfo.altnames || []).slice(0); | 
					
						
							|  |  |  | 	names.push(certInfo.subject); | 
					
						
							|  |  |  | 	return names.some(function(name) { | 
					
						
							|  |  |  | 		var domain = _domain.toLowerCase(); | 
					
						
							|  |  |  | 		name = name.toLowerCase(); | 
					
						
							|  |  |  | 		if ('*.' === name.substr(0, 2)) { | 
					
						
							|  |  |  | 			name = name.substr(2); | 
					
						
							|  |  |  | 			domain = domain | 
					
						
							|  |  |  | 				.split('.') | 
					
						
							|  |  |  | 				.slice(1) | 
					
						
							|  |  |  | 				.join('.'); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		return name === domain; | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2019-04-01 00:36:59 -06:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | module.exports.isValidDomain = function(domain) { | 
					
						
							|  |  |  | 	if (re.test(domain)) { | 
					
						
							|  |  |  | 		return domain; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-19 02:18:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	domain = punycode.toASCII(domain); | 
					
						
							| 
									
										
										
										
											2015-12-19 02:18:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	if (re.test(domain)) { | 
					
						
							|  |  |  | 		return domain; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-19 02:18:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	return ''; | 
					
						
							| 
									
										
										
										
											2015-12-19 02:18:32 -08:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | module.exports.merge = function(/*defaults, args*/) { | 
					
						
							|  |  |  | 	var allDefaults = Array.prototype.slice.apply(arguments); | 
					
						
							|  |  |  | 	var args = allDefaults.shift(); | 
					
						
							|  |  |  | 	var copy = {}; | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	allDefaults.forEach(function(defaults) { | 
					
						
							|  |  |  | 		Object.keys(defaults).forEach(function(key) { | 
					
						
							|  |  |  | 			/* | 
					
						
							| 
									
										
										
										
											2019-06-03 09:12:11 +00:00
										 |  |  |       if ('challenges' === key && copy[key] && defaults[key]) { | 
					
						
							|  |  |  |         Object.keys(defaults[key]).forEach(function (k) { | 
					
						
							|  |  |  |           copy[key][k] = defaults[key][k]; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |       } else { | 
					
						
							|  |  |  |         copy[key] = defaults[key]; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2019-06-14 03:21:03 -06:00
										 |  |  |     */ | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 			copy[key] = defaults[key]; | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2016-08-04 18:49:35 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	Object.keys(args).forEach(function(key) { | 
					
						
							|  |  |  | 		/* | 
					
						
							| 
									
										
										
										
											2019-06-03 09:12:11 +00:00
										 |  |  |     if ('challenges' === key && copy[key] && args[key]) { | 
					
						
							|  |  |  |         Object.keys(args[key]).forEach(function (k) { | 
					
						
							|  |  |  |           copy[key][k] = args[key][k]; | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |       copy[key] = args[key]; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2019-06-14 03:21:03 -06:00
										 |  |  |     */ | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 		copy[key] = args[key]; | 
					
						
							|  |  |  | 	}); | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | 	return copy; | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | module.exports.tplCopy = function(copy) { | 
					
						
							|  |  |  | 	var homedir = require('os').homedir(); | 
					
						
							|  |  |  | 	var tplKeys; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	copy.hostnameGet = function(copy) { | 
					
						
							|  |  |  | 		return copy.subject || (copy.domains || [])[0] || copy.domain; | 
					
						
							|  |  |  | 	}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	Object.keys(copy).forEach(function(key) { | 
					
						
							|  |  |  | 		var newName; | 
					
						
							|  |  |  | 		if (!/Get$/.test(key)) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newName = key.replace(/Get$/, ''); | 
					
						
							|  |  |  | 		copy[newName] = copy[newName] || copy[key](copy); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tplKeys = Object.keys(copy); | 
					
						
							|  |  |  | 	tplKeys.sort(function(a, b) { | 
					
						
							|  |  |  | 		return b.length - a.length; | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tplKeys.forEach(function(key) { | 
					
						
							|  |  |  | 		if ('string' !== typeof copy[key]) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		copy[key] = copy[key].replace(homeRe, homedir + path.sep); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	tplKeys.forEach(function(key) { | 
					
						
							|  |  |  | 		if ('string' !== typeof copy[key]) { | 
					
						
							|  |  |  | 			return; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		tplKeys.forEach(function(tplname) { | 
					
						
							|  |  |  | 			if (!copy[tplname]) { | 
					
						
							|  |  |  | 				// what can't be templated now may be templatable later
 | 
					
						
							|  |  |  | 				return; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			copy[key] = copy[key].replace(':' + tplname, copy[tplname]); | 
					
						
							|  |  |  | 		}); | 
					
						
							|  |  |  | 	}); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return copy; | 
					
						
							| 
									
										
										
										
											2015-12-17 08:46:40 +00:00
										 |  |  | }; | 
					
						
							| 
									
										
										
										
											2016-08-08 15:17:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-10-08 04:51:15 -06:00
										 |  |  | module.exports.testEmail = function(email) { | 
					
						
							|  |  |  | 	var parts = (email || '').split('@'); | 
					
						
							|  |  |  | 	var err; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (2 !== parts.length || !parts[0] || !parts[1]) { | 
					
						
							|  |  |  | 		err = new Error("malformed email address '" + email + "'"); | 
					
						
							|  |  |  | 		err.code = 'E_EMAIL'; | 
					
						
							|  |  |  | 		return Promise.reject(err); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return dnsResolveMxAsync(parts[1]).then( | 
					
						
							|  |  |  | 		function(records) { | 
					
						
							|  |  |  | 			// records only returns when there is data
 | 
					
						
							|  |  |  | 			if (!records.length) { | 
					
						
							|  |  |  | 				throw new Error( | 
					
						
							|  |  |  | 					'sanity check fail: success, but no MX records returned' | 
					
						
							|  |  |  | 				); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			return email; | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		function(err) { | 
					
						
							|  |  |  | 			if ('ENODATA' === err.code) { | 
					
						
							|  |  |  | 				err = new Error("no MX records found for '" + parts[1] + "'"); | 
					
						
							|  |  |  | 				err.code = 'E_EMAIL'; | 
					
						
							|  |  |  | 				return Promise.reject(err); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	); | 
					
						
							| 
									
										
										
										
											2016-08-08 15:17:09 -04:00
										 |  |  | }; |