roster-server 2.2.10 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/README.md +25 -2
  2. package/index.js +28 -38
  3. package/lib/resolve-site-app.js +42 -0
  4. package/lib/static-site-handler.js +122 -0
  5. package/package.json +12 -3
  6. package/skills/roster-server/SKILL.md +15 -4
  7. package/test/roster-server.test.js +87 -0
  8. package/vendor/greenlock/.prettierrc +8 -0
  9. package/vendor/greenlock/LICENSE +312 -0
  10. package/vendor/greenlock/MIGRATION_GUIDE.md +403 -0
  11. package/vendor/greenlock/README.md +667 -0
  12. package/vendor/greenlock/accounts.js +218 -0
  13. package/vendor/greenlock/bin/add.js +72 -0
  14. package/vendor/greenlock/bin/certonly.js +368 -0
  15. package/vendor/greenlock/bin/config.js +77 -0
  16. package/vendor/greenlock/bin/defaults.js +58 -0
  17. package/vendor/greenlock/bin/greenlock.js +26 -0
  18. package/vendor/greenlock/bin/init.js +159 -0
  19. package/vendor/greenlock/bin/lib/cli.js +230 -0
  20. package/vendor/greenlock/bin/lib/flags.js +385 -0
  21. package/vendor/greenlock/bin/remove.js +46 -0
  22. package/vendor/greenlock/bin/tmpl/app.tmpl.js +9 -0
  23. package/vendor/greenlock/bin/tmpl/cluster.tmpl.js +30 -0
  24. package/vendor/greenlock/bin/tmpl/greenlock.tmpl.js +13 -0
  25. package/vendor/greenlock/bin/tmpl/server.tmpl.js +20 -0
  26. package/vendor/greenlock/bin/update.js +62 -0
  27. package/vendor/greenlock/certificates.js +324 -0
  28. package/vendor/greenlock/errors.js +58 -0
  29. package/vendor/greenlock/greenlock.js +621 -0
  30. package/vendor/greenlock/greenlockrc.js +169 -0
  31. package/vendor/greenlock/lib/challenges-wrapper.js +88 -0
  32. package/vendor/greenlock/lib/directory-url.js +44 -0
  33. package/vendor/greenlock/lib/init.js +191 -0
  34. package/vendor/greenlock/lib/manager-wrapper.js +625 -0
  35. package/vendor/greenlock/lib/rc.js +70 -0
  36. package/vendor/greenlock/logo/beaker-browser-301x112.png +0 -0
  37. package/vendor/greenlock/logo/from-not-secure-to-secure-url-bar.png +0 -0
  38. package/vendor/greenlock/logo/greenlock-1063x250.png +0 -0
  39. package/vendor/greenlock/logo/greenlock-850x200.png +0 -0
  40. package/vendor/greenlock/logo/ibm-301x112.png +0 -0
  41. package/vendor/greenlock/logo/telebit-301x112.png +0 -0
  42. package/vendor/greenlock/order.js +63 -0
  43. package/vendor/greenlock/package-lock.json +140 -0
  44. package/vendor/greenlock/package.json +56 -0
  45. package/vendor/greenlock/plugins.js +270 -0
  46. package/vendor/greenlock/tests/cli.sh +31 -0
  47. package/vendor/greenlock/tests/index.js +53 -0
  48. package/vendor/greenlock/user-events.js +7 -0
  49. package/vendor/greenlock/utils.js +281 -0
  50. package/vendor/greenlock-express/greenlock-shim.js +3 -1
  51. package/vendor/greenlock-express/package.json +0 -1
  52. package/tasks/lessons.md +0 -4
@@ -0,0 +1,169 @@
1
+ 'use strict';
2
+
3
+ var log = require('lemonlog')('greenlock-rc-file');
4
+ var fs = require('fs');
5
+ var path = require('path');
6
+
7
+ function saveFile(rcpath, data, enc) {
8
+ // because this may have a database url or some such
9
+ fs.writeFileSync(rcpath, data, enc);
10
+ return fs.chmodSync(rcpath, parseInt('0600', 8));
11
+ }
12
+
13
+ var GRC = (module.exports = function(pkgpath, manager, rc) {
14
+ // TODO when run from package
15
+ // Run from the package root (assumed) or exit
16
+ var pkgdir = path.dirname(pkgpath);
17
+
18
+ try {
19
+ require(pkgpath);
20
+ } catch (e) {
21
+ log.error('Run greenlock from package root (directory containing package.json)');
22
+ process.exit(1);
23
+ }
24
+
25
+ try {
26
+ return module.exports._defaults(pkgdir, manager, rc);
27
+ } catch (e) {
28
+ if ('package.json' === e.context) {
29
+ log.error(e.desc);
30
+ } else {
31
+ log.error(e.message);
32
+ }
33
+ process.exit(1);
34
+ }
35
+ });
36
+
37
+ // Figure out what to do between what's hard-coded,
38
+ // what's in the config file, and what's left unset
39
+ module.exports.resolve = function(gconf) {
40
+ var rc = GRC.read(gconf.packageRoot);
41
+ if (gconf.configFile) {
42
+ rc = { configFile: gconf.configFile };
43
+ }
44
+
45
+ var manager;
46
+ var updates;
47
+
48
+ if (rc.manager) {
49
+ if (gconf.manager && rc.manager !== gconf.manager) {
50
+ log.warn('Using manager from .greenlockrc (%s) instead of hard-coded %s', rc.manager, gconf.manager);
51
+ }
52
+ gconf.manager = rc.manager;
53
+ } else if (gconf.manager) {
54
+ manager = gconf.manager;
55
+ }
56
+
57
+ if (rc.configFile) {
58
+ if (gconf.configFile && rc.configFile !== gconf.configFile) {
59
+ log.warn('Using configFile from .greenlockrc instead of hard-coded value');
60
+ }
61
+ gconf.configFile = rc.configFile;
62
+ } else if (gconf.manager) {
63
+ updates = { configFile: gconf.configFile };
64
+ }
65
+
66
+ return GRC._defaults(gconf.packageRoot, manager, rc);
67
+ };
68
+
69
+ module.exports._defaults = function(pkgdir, manager, rc) {
70
+ var rcpath = path.join(pkgdir, '.greenlockrc');
71
+ var _rc;
72
+ var created = false;
73
+
74
+ if (manager) {
75
+ if ('.' === manager[0]) {
76
+ manager = path.resolve(pkgdir, manager);
77
+ }
78
+ try {
79
+ require(manager);
80
+ } catch (e) {
81
+ log.error('Could not load manager %s from %s', manager, pkgdir);
82
+ throw e;
83
+ }
84
+ }
85
+
86
+ var stuff = module.exports._read(pkgdir);
87
+ _rc = stuff.rc;
88
+ created = stuff.created;
89
+
90
+ var changed;
91
+ if (manager) {
92
+ if (!_rc.manager) {
93
+ _rc.manager = manager;
94
+ }
95
+ if (_rc.manager !== manager) {
96
+ var older = _rc.manager;
97
+ var newer = manager;
98
+ if ('/' === (older || '')[0]) older = path.relative(pkgdir, older);
99
+ if ('/' === (newer || '')[0]) newer = path.relative(pkgdir, newer);
100
+ log.info('Switching manager: %s -> %s', older, newer);
101
+ changed = true;
102
+ }
103
+ }
104
+
105
+ if (rc) {
106
+ changed = true;
107
+ Object.keys(rc).forEach(function(k) {
108
+ _rc[k] = rc[k];
109
+ });
110
+ }
111
+
112
+ if (['@greenlock/manager', 'greenlock-manager-fs'].includes(_rc.manager)) {
113
+ if (!_rc.configFile) {
114
+ changed = true;
115
+ _rc.configFile = path.join(pkgdir, 'greenlock.json');
116
+ }
117
+ }
118
+
119
+ if (!changed) {
120
+ return _rc;
121
+ }
122
+
123
+ var data = JSON.stringify(_rc, null, 2);
124
+ if (created) log.info('Created %s', rcpath);
125
+ saveFile(rcpath, data, 'utf8');
126
+ return _rc;
127
+ };
128
+
129
+ module.exports.read = function(pkgdir) {
130
+ return module.exports._read(pkgdir).rc;
131
+ };
132
+
133
+ module.exports._read = function(pkgdir) {
134
+ var created;
135
+ var rcpath = path.join(pkgdir, '.greenlockrc');
136
+ var _data;
137
+ try {
138
+ _data = fs.readFileSync(rcpath, 'utf8');
139
+ } catch (err) {
140
+ if ('ENOENT' !== err.code) {
141
+ throw err;
142
+ }
143
+ try {
144
+ require(path.resolve(path.join(pkgdir, './package.json')));
145
+ } catch (e) {
146
+ e.context = 'package.json';
147
+ e.desc =
148
+ 'run `greenlock` from the same directory as `package.json`, or specify `packageRoot` of `.greenlockrc`';
149
+ throw e;
150
+ }
151
+ log.info('Creating %s', rcpath);
152
+ created = true;
153
+ _data = '{}';
154
+ saveFile(rcpath, _data, 'utf8');
155
+ }
156
+
157
+ var rc;
158
+ try {
159
+ rc = JSON.parse(_data);
160
+ } catch (e) {
161
+ log.error("Invalid JSON in %s (delete and retry?)", rcpath, e.message);
162
+ process.exit(1);
163
+ }
164
+
165
+ return {
166
+ created: created,
167
+ rc: rc
168
+ };
169
+ };
@@ -0,0 +1,88 @@
1
+ 'use strict';
2
+
3
+ var Greenlock = require('../');
4
+ var log = require('lemonlog')('greenlock-challenges');
5
+
6
+ module.exports.wrap = function(greenlock) {
7
+ greenlock.challenges = {};
8
+ greenlock.challenges.get = async function(chall) {
9
+ // TODO pick one and warn on the others
10
+ // (just here due to some backwards compat issues with early v3 plugins)
11
+ var servername =
12
+ chall.servername ||
13
+ chall.altname ||
14
+ (chall.identifier && chall.identifier.value);
15
+
16
+ // TODO some sort of caching to prevent database hits?
17
+ var site = await greenlock._config({ servername: servername });
18
+ if (!site) {
19
+ return null;
20
+ }
21
+
22
+ // Hmm... this _should_ be impossible
23
+ if (!site.challenges || !site.challenges['http-01']) {
24
+ var copy = JSON.parse(JSON.stringify(site));
25
+ sanitizeCopiedConf(copy);
26
+ sanitizeCopiedConf(copy.store);
27
+ if (site.challenges) {
28
+ sanitizeCopiedConf(copy.challenges['http-01']);
29
+ sanitizeCopiedConf(copy.challenges['dns-01']);
30
+ sanitizeCopiedConf(copy.challenges['tls-alpn-01']);
31
+ }
32
+ log.warn(
33
+ 'http-01 challenge requested but no http-01 config; servername=%s',
34
+ servername,
35
+ copy
36
+ );
37
+ return null;
38
+ }
39
+
40
+ var plugin = await Greenlock._loadChallenge(site.challenges, 'http-01');
41
+ if (!plugin) {
42
+ return null;
43
+ }
44
+
45
+ var keyAuth;
46
+ var keyAuthDigest;
47
+ var result = await plugin.get({
48
+ challenge: {
49
+ type: chall.type,
50
+ //hostname: chall.servername,
51
+ altname: chall.servername,
52
+ identifier: { value: chall.servername },
53
+ token: chall.token
54
+ }
55
+ });
56
+ if (result) {
57
+ // backwards compat that shouldn't be dropped
58
+ // because new v3 modules had to do this to be
59
+ // backwards compatible with Greenlock v2.7 at
60
+ // the time.
61
+ if (result.challenge) {
62
+ result = result.challenge;
63
+ }
64
+ keyAuth = result.keyAuthorization;
65
+ keyAuthDigest = result.keyAuthorizationDigest;
66
+ }
67
+
68
+ if (/dns/.test(chall.type)) {
69
+ return { keyAuthorizationDigest: keyAuthDigest };
70
+ }
71
+
72
+ return { keyAuthorization: keyAuth };
73
+ };
74
+ };
75
+
76
+ function sanitizeCopiedConf(copy) {
77
+ if (!copy) {
78
+ return;
79
+ }
80
+
81
+ Object.keys(copy).forEach(function(k) {
82
+ if (/(api|key|token)/i.test(k) && 'string' === typeof copy[k]) {
83
+ copy[k] = '**redacted**';
84
+ }
85
+ });
86
+
87
+ return copy;
88
+ }
@@ -0,0 +1,44 @@
1
+ var DIR = module.exports;
2
+ var log = require('lemonlog')('greenlock-dir');
3
+
4
+ DIR._getDirectoryUrl = function(dirUrl, domain) {
5
+ var liveUrl = 'https://acme-v02.api.letsencrypt.org/directory';
6
+ dirUrl = DIR._getDefaultDirectoryUrl(dirUrl, '', domain);
7
+ if (!dirUrl) {
8
+ dirUrl = liveUrl;
9
+ if (!DIR._shownDirectoryUrl) {
10
+ DIR._shownDirectoryUrl = true;
11
+ log.info('ACME directory URL:', dirUrl);
12
+ }
13
+ }
14
+ return dirUrl;
15
+ };
16
+
17
+ // Handle staging URLs, pebble test server, etc
18
+ DIR._getDefaultDirectoryUrl = function(dirUrl, staging, domain) {
19
+ var stagingUrl = 'https://acme-staging-v02.api.letsencrypt.org/directory';
20
+ var stagingRe = /(^http:|staging|^127\.0\.|^::|localhost)/;
21
+ var env = '';
22
+ var args = [];
23
+ if ('undefined' !== typeof process) {
24
+ env = (process.env && process.env.ENV) || '';
25
+ args = (process.argv && process.argv.slice(1)) || [];
26
+ }
27
+
28
+ if (
29
+ staging ||
30
+ stagingRe.test(dirUrl) ||
31
+ args.includes('--staging') ||
32
+ /DEV|STAG/i.test(env)
33
+ ) {
34
+ if (!stagingRe.test(dirUrl)) {
35
+ dirUrl = stagingUrl;
36
+ }
37
+ log.info('Staging ACME directory:', dirUrl, env);
38
+ log.warn('Staging mode: fake certificates for testing only', env, domain);
39
+ }
40
+
41
+ return dirUrl;
42
+ };
43
+
44
+ DIR._shownDirectoryUrl = false;
@@ -0,0 +1,191 @@
1
+ 'use strict';
2
+
3
+ var Init = module.exports;
4
+ var log = require('lemonlog')('greenlock-init');
5
+
6
+ var fs = require('fs');
7
+ var path = require('path');
8
+ //var promisify = require("util").promisify;
9
+
10
+ Init._init = function(opts) {
11
+ //var Rc = require("@root/greenlock/rc");
12
+ var Rc = require('./rc.js');
13
+ var pkgText;
14
+ var pkgErr;
15
+ var msgErr;
16
+ //var emailErr;
17
+ var realPkg;
18
+ var userPkg;
19
+ var myPkg = {};
20
+ // we want to be SUPER transparent that we're reading from package.json
21
+ // we don't want anything unexpected
22
+ var implicitConfig = [];
23
+ var rc;
24
+
25
+ if (opts.packageRoot) {
26
+ try {
27
+ pkgText = fs.readFileSync(
28
+ path.resolve(opts.packageRoot, 'package.json'),
29
+ 'utf8'
30
+ );
31
+ opts._hasPackage = true;
32
+ } catch (e) {
33
+ pkgErr = e;
34
+ if (opts._mustPackage) {
35
+ log.error('Must be run from package root (directory containing package.json)');
36
+ process.exit(1);
37
+ return;
38
+ }
39
+ log.warn('packageRoot should be the package root (e.g. __dirname)');
40
+ }
41
+ }
42
+
43
+ if (pkgText) {
44
+ try {
45
+ realPkg = JSON.parse(pkgText);
46
+ } catch (e) {
47
+ pkgErr = e;
48
+ }
49
+ }
50
+
51
+ userPkg = opts.package;
52
+
53
+ if (realPkg || userPkg) {
54
+ userPkg = userPkg || {};
55
+ realPkg = realPkg || {};
56
+
57
+ // build package agent
58
+ if (!opts.packageAgent) {
59
+ // name
60
+ myPkg.name = userPkg.name;
61
+ if (!myPkg.name) {
62
+ myPkg.name = realPkg.name;
63
+ implicitConfig.push('name');
64
+ }
65
+
66
+ // version
67
+ myPkg.version = userPkg.version;
68
+ if (!myPkg.version) {
69
+ myPkg.version = realPkg.version;
70
+ implicitConfig.push('version');
71
+ }
72
+ if (myPkg.name && myPkg.version) {
73
+ opts.packageAgent = myPkg.name + '/' + myPkg.version;
74
+ }
75
+ }
76
+
77
+ // build author
78
+ myPkg.author = opts.maintainerEmail;
79
+ if (!myPkg.author) {
80
+ myPkg.author =
81
+ (userPkg.author && userPkg.author.email) || userPkg.author;
82
+ }
83
+ if (!myPkg.author) {
84
+ implicitConfig.push('author');
85
+ myPkg.author =
86
+ (realPkg.author && realPkg.author.email) || realPkg.author;
87
+ }
88
+ if (!opts._init) {
89
+ opts.maintainerEmail = myPkg.author;
90
+ }
91
+ }
92
+
93
+ if (!opts.packageAgent) {
94
+ msgErr =
95
+ 'missing `packageAgent` and also failed to read `name` and/or `version` from `package.json`';
96
+ if (pkgErr) {
97
+ msgErr += ': ' + pkgErr.message;
98
+ }
99
+ throw new Error(msgErr);
100
+ }
101
+
102
+ if (!opts._init) {
103
+ opts.maintainerEmail = parseMaintainer(opts.maintainerEmail);
104
+ if (!opts.maintainerEmail) {
105
+ msgErr =
106
+ 'missing or malformed `maintainerEmail` (or `author` from `package.json`), which is used as the contact for support notices';
107
+ throw new Error(msgErr);
108
+ }
109
+ }
110
+
111
+ if (opts.packageRoot) {
112
+ // Place the rc file in the packageroot
113
+ rc = Rc._initSync(opts.packageRoot, opts.manager, opts.configDir);
114
+ opts.configDir = rc.configDir;
115
+ opts.manager = rc.manager;
116
+ }
117
+
118
+ if (!opts.configDir && !opts.manager) {
119
+ throw new Error(
120
+ 'missing `packageRoot` and `configDir`, but no `manager` was supplied'
121
+ );
122
+ }
123
+
124
+ opts.configFile = path.join(
125
+ path.resolve(opts.packageRoot, opts.configDir),
126
+ 'config.json'
127
+ );
128
+ var config;
129
+ try {
130
+ config = JSON.parse(fs.readFileSync(opts.configFile));
131
+ } catch (e) {
132
+ if ('ENOENT' !== e.code) {
133
+ throw e;
134
+ }
135
+ config = { defaults: {} };
136
+ }
137
+
138
+ opts.manager =
139
+ rc.manager ||
140
+ (config.defaults && config.defaults.manager) ||
141
+ config.manager;
142
+ if (!opts.manager) {
143
+ opts.manager = '@greenlock/manager';
144
+ }
145
+ if ('string' === typeof opts.manager) {
146
+ opts.manager = {
147
+ module: opts.manager
148
+ };
149
+ }
150
+ opts.manager = JSON.parse(JSON.stringify(opts.manager));
151
+
152
+ var confconf = ['configDir', 'configFile', 'staging', 'directoryUrl'];
153
+ Object.keys(opts).forEach(function(k) {
154
+ if (!confconf.includes(k)) {
155
+ return;
156
+ }
157
+ if ('undefined' !== typeof opts.manager[k]) {
158
+ return;
159
+ }
160
+ opts.manager[k] = opts[k];
161
+ });
162
+
163
+ /*
164
+ var ignore = ["packageRoot", "maintainerEmail", "packageAgent", "staging", "directoryUrl", "manager"];
165
+ Object.keys(opts).forEach(function(k) {
166
+ if (ignore.includes(k)) {
167
+ return;
168
+ }
169
+ opts.manager[k] = opts[k];
170
+ });
171
+ */
172
+
173
+ // Place the rc file in the configDir itself
174
+ //Rc._initSync(opts.configDir, opts.configDir);
175
+ return opts;
176
+ };
177
+
178
+ // ex: "John Doe <john@example.com> (https://john.doe)"
179
+ // ex: "John Doe <john@example.com>"
180
+ // ex: "<john@example.com>"
181
+ // ex: "john@example.com"
182
+ var looseEmailRe = /(^|[\s<])([^'" <>:;`]+@[^'" <>:;`]+\.[^'" <>:;`]+)/;
183
+ function parseMaintainer(maintainerEmail) {
184
+ try {
185
+ maintainerEmail = maintainerEmail.match(looseEmailRe)[2];
186
+ } catch (e) {
187
+ maintainerEmail = null;
188
+ }
189
+
190
+ return maintainerEmail;
191
+ }