index.js
1.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
'use strict'
var path = require('path')
var LE = require('greenlock-express')
var DEFAULT_DIR = path.join(require('os').homedir(), '/letsencrypt/etc')
var concat = Array.prototype.concat
var noop = function () {}
// Expose lib to the world.
module.exports = createServer
/**
* Like nodes https.createServer but will automatically generate certificates from letsencrypt
* falling back to self signed.
*
* @param {Object} opts
* @param {Function} handler
* @return {Server}
*/
function createServer (opts, app) {
opts = opts || {}
app = app || noop
var handler = null
var approveDomains = opts.domains
var ports = opts.ports = opts.ports || {}
if (!('http' in ports)) ports.http = 80
if (!('https' in ports)) ports.https = 443
if (!opts.email) throw new TypeError('AutoSNI: Email is required.')
if (!opts.agreeTos) throw new TypeError('AutoSNI: Must agree to LE TOS.')
if (Array.isArray(approveDomains)) {
// Flatten nested domains.
approveDomains = concat.apply([], opts.domains || [])
if (!approveDomains.length) {
throw new TypeError('AutoSNI: You must specify at least one domain.')
}
} else if (typeof approveDomains !== 'function') {
throw new TypeError('AutoSNI: Domains option must be an array or a function.')
}
if (typeof app === 'function') {
// Allow passing in handler function directly.
handler = app
} else if (typeof app.emit === 'function') {
// Allow passing in another node server (forwards requests).
handler = function (req, res) {
app.emit('request', req, res)
}
} else {
throw new TypeError('AutoSNI: Invalid app provided.')
}
return LE.create({
app: handler,
debug: opts.debug,
email: opts.email,
agreeTos: opts.agreeTos,
approveDomains: approveDomains,
configDir: opts.dir || DEFAULT_DIR,
server: opts.debug ? 'staging' : 'production'
}).listen(opts.ports.http, opts.ports.https)
}