@postalsys/certs 1.0.1 → 1.0.3

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.
package/lib/certs.js CHANGED
@@ -274,13 +274,43 @@ class Certs {
274
274
  values[dataKey] = Object.assign(currendData || {}, updates);
275
275
  }
276
276
 
277
+ let run = this.redis.multi();
278
+
279
+ if ('cert' in updates) {
280
+ run = run.sadd(this.getKey('certlist'), domain);
281
+ }
282
+
277
283
  if (incrVersion) {
278
- await this.redis.hincrby(this.settings.getKey('settings'), versionKey, 1);
284
+ run = run.hincrby(this.settings.getKey('settings'), versionKey, 1);
279
285
  }
280
286
 
281
287
  if (Object.keys(values).length) {
282
- return await this.settings.set(values);
288
+ run = this.settings.getSet(run, values);
283
289
  }
290
+
291
+ await run.exec();
292
+ }
293
+
294
+ async deleteCertificateData(domain) {
295
+ let dataKey = `domain:${domain}:data`;
296
+ let lastCheckKey = `domain:${domain}:lastCheck`;
297
+ let privateKeyKey = `domain:${domain}:privateKey`;
298
+ let lastErrorKey = `domain:${domain}:lastError`;
299
+ let versionKey = `domain:${domain}:certVersion`;
300
+
301
+ return await this.redis
302
+ .multi()
303
+ .hdel(this.settings.getKey('settings'), dataKey)
304
+ .hdel(this.settings.getKey('settings'), lastCheckKey)
305
+ .hdel(this.settings.getKey('settings'), privateKeyKey)
306
+ .hdel(this.settings.getKey('settings'), lastErrorKey)
307
+ .hdel(this.settings.getKey('settings'), versionKey)
308
+ .srem(this.getKey('certlist'), domain)
309
+ .exec();
310
+ }
311
+
312
+ async listCertificateDomains() {
313
+ return (await this.redis.smembers(this.getKey('certlist'))).sort((a, b) => a.toLowerCase().trim().localeCompare(b.toLowerCase().trim()));
284
314
  }
285
315
 
286
316
  async acquireCert(domain) {
@@ -313,21 +343,21 @@ class Certs {
313
343
  return existingCertificateData;
314
344
  }
315
345
 
316
- try {
317
- // reload from db, maybe already renewed
318
- if (existingCertificateData.validTo && existingCertificateData.validTo > new Date(Date.now() + RENEW_AFTER_REMAINING)) {
319
- // no need to renew
320
- return existingCertificateData;
321
- }
346
+ // reload from db, maybe already renewed
347
+ if (existingCertificateData && existingCertificateData.validTo && existingCertificateData.validTo > new Date(Date.now() + RENEW_AFTER_REMAINING)) {
348
+ // no need to renew
349
+ return existingCertificateData;
350
+ }
322
351
 
323
- let privateKey = existingCertificateData.privateKey;
324
- if (!privateKey) {
325
- // generate new key
326
- this.logger.trace({ msg: 'Provision new private key', domain });
327
- privateKey = await generateKey(this.acmeOptions.keyBits, this.acmeOptions.keyExponent);
328
- await this.setCertificateData(domain, { domain, privateKey, status: 'pending', lastError: null });
329
- }
352
+ let privateKey = existingCertificateData && existingCertificateData.privateKey;
353
+ if (!privateKey) {
354
+ // generate new key
355
+ this.logger.trace({ msg: 'Provision new private key', domain });
356
+ privateKey = await generateKey(this.acmeOptions.keyBits, this.acmeOptions.keyExponent);
357
+ await this.setCertificateData(domain, { domain, privateKey, status: 'pending', lastError: null });
358
+ }
330
359
 
360
+ try {
331
361
  const jwkPrivateKey = pem2jwk(privateKey);
332
362
  const csr = await CSR.csr({
333
363
  jwk: jwkPrivateKey,
@@ -397,6 +427,19 @@ class Certs {
397
427
  } catch (err) {
398
428
  this.logger.error({ msg: 'Failed to update certificate record', domain, err });
399
429
  }
430
+ } else if (privateKey) {
431
+ try {
432
+ await this.setCertificateData(domain, {
433
+ status: 'failed',
434
+ lastError: {
435
+ err: err.message,
436
+ code: err.code,
437
+ time: new Date()
438
+ }
439
+ });
440
+ } catch (err) {
441
+ this.logger.error({ msg: 'Failed to update certificate record', domain, err });
442
+ }
400
443
  }
401
444
 
402
445
  if (existingCertificateData && existingCertificateData.cert) {
@@ -471,12 +514,13 @@ class Certs {
471
514
  async getCertificate(domain, skipAcquire) {
472
515
  domain = normalizeDomain(domain);
473
516
  let certificateData = await this.loadCertificateData(domain);
517
+
474
518
  if (certificateData && certificateData.status === 'valid' && certificateData.validTo && certificateData.validTo >= new Date()) {
475
519
  return certificateData;
476
520
  }
477
521
 
478
522
  if (skipAcquire) {
479
- return false;
523
+ return certificateData || false;
480
524
  }
481
525
 
482
526
  return await this.acquireCert(domain);
package/lib/settings.js CHANGED
@@ -20,6 +20,26 @@ class Settings {
20
20
  return `${this.ns}certs:${name}`;
21
21
  }
22
22
 
23
+ getSet(run, ...args) {
24
+ let settingsKey = this.getKey('settings');
25
+
26
+ let props = false;
27
+
28
+ if (args.length === 1 && typeof args[0] === 'object' && args[0]) {
29
+ props = {};
30
+ for (let key of Object.keys(args[0])) {
31
+ props[key] = msgpack.encode(args[0][key]);
32
+ }
33
+ } else if (args.length === 2 && typeof args[0] === 'string') {
34
+ props = {
35
+ [args[0]]: msgpack.encode(args[1])
36
+ };
37
+ } else {
38
+ return false;
39
+ }
40
+ return run.hmset(settingsKey, props);
41
+ }
42
+
23
43
  async set(...args) {
24
44
  let settingsKey = this.getKey('settings');
25
45
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@postalsys/certs",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Manage Let's Encrypt certificates",
5
5
  "main": "lib/certs.js",
6
6
  "scripts": {
@@ -15,17 +15,17 @@
15
15
  "devDependencies": {
16
16
  "eslint-config-nodemailer": "1.2.0",
17
17
  "eslint-config-prettier": "8.5.0",
18
- "express": "4.18.1",
19
- "ioredis": "5.1.0"
18
+ "express": "4.18.2",
19
+ "ioredis": "5.2.4"
20
20
  },
21
21
  "dependencies": {
22
22
  "@root/acme": "3.1.0",
23
23
  "ioredfour": "1.2.0-ioredis-06",
24
- "joi": "17.6.0",
25
- "msgpack5": "6.0.1",
24
+ "joi": "17.7.0",
25
+ "msgpack5": "6.0.2",
26
26
  "pem-jwk": "2.0.0",
27
- "pino": "8.1.0",
27
+ "pino": "8.7.0",
28
28
  "punycode": "2.1.1",
29
- "uuid": "8.3.2"
29
+ "uuid": "9.0.0"
30
30
  }
31
31
  }