| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 | 
							- const ACME = require('acme')
 
- const Keypairs = require('@root/keypairs')
 
- const _ = require('lodash')
 
- const moment = require('moment')
 
- const CSR = require('@root/csr')
 
- const PEM = require('@root/pem')
 
- // eslint-disable-next-line node/no-deprecated-api
 
- const punycode = require('punycode')
 
- /* global WIKI */
 
- module.exports = {
 
-   apiDirectory: WIKI.dev ? 'https://acme-staging-v02.api.letsencrypt.org/directory' : 'https://acme-v02.api.letsencrypt.org/directory',
 
-   acme: null,
 
-   async init () {
 
-     if (!_.get(WIKI.config, 'letsencrypt.payload', false)) {
 
-       await this.requestCertificate()
 
-     } else if (WIKI.config.letsencrypt.domain !== WIKI.config.ssl.domain) {
 
-       WIKI.logger.info(`(LETSENCRYPT) Domain has changed. Requesting new certificates...`)
 
-       await this.requestCertificate()
 
-     } else if (moment(WIKI.config.letsencrypt.payload.expires).isSameOrBefore(moment().add(5, 'days'))) {
 
-       WIKI.logger.info(`(LETSENCRYPT) Certificate is about to or has expired, requesting a new one...`)
 
-       await this.requestCertificate()
 
-     } else {
 
-       WIKI.logger.info(`(LETSENCRYPT) Using existing certificate for ${WIKI.config.ssl.domain}, expires on ${WIKI.config.letsencrypt.payload.expires}: [ OK ]`)
 
-     }
 
-     WIKI.config.ssl.format = 'pem'
 
-     WIKI.config.ssl.inline = true
 
-     WIKI.config.ssl.key = WIKI.config.letsencrypt.serverKey
 
-     WIKI.config.ssl.cert = WIKI.config.letsencrypt.payload.cert + '\n' + WIKI.config.letsencrypt.payload.chain
 
-     WIKI.config.ssl.passphrase = null
 
-     WIKI.config.ssl.dhparam = null
 
-   },
 
-   async requestCertificate () {
 
-     try {
 
-       WIKI.logger.info(`(LETSENCRYPT) Initializing Let's Encrypt client...`)
 
-       this.acme = ACME.create({
 
-         maintainerEmail: WIKI.config.maintainerEmail,
 
-         packageAgent: `wikijs/${WIKI.version}`,
 
-         notify: (ev, msg) => {
 
-           if (_.includes(['warning', 'error'], ev)) {
 
-             WIKI.logger.warn(`${ev}: ${msg}`)
 
-           } else {
 
-             WIKI.logger.debug(`${ev}: ${JSON.stringify(msg)}`)
 
-           }
 
-         }
 
-       })
 
-       await this.acme.init(this.apiDirectory)
 
-       // -> Create ACME Subscriber account
 
-       if (!_.get(WIKI.config, 'letsencrypt.account', false)) {
 
-         WIKI.logger.info(`(LETSENCRYPT) Setting up account for the first time...`)
 
-         const accountKeypair = await Keypairs.generate({ kty: 'EC', format: 'jwk' })
 
-         const account = await this.acme.accounts.create({
 
-           subscriberEmail: WIKI.config.ssl.subscriberEmail,
 
-           agreeToTerms: true,
 
-           accountKey: accountKeypair.private
 
-         })
 
-         WIKI.config.letsencrypt = {
 
-           accountKeypair: accountKeypair,
 
-           account: account,
 
-           domain: WIKI.config.ssl.domain
 
-         }
 
-         await WIKI.configSvc.saveToDb(['letsencrypt'])
 
-         WIKI.logger.info(`(LETSENCRYPT) Account was setup successfully [ OK ]`)
 
-       }
 
-       // -> Create Server Keypair
 
-       if (!WIKI.config.letsencrypt.serverKey) {
 
-         WIKI.logger.info(`(LETSENCRYPT) Generating server keypairs...`)
 
-         const serverKeypair = await Keypairs.generate({ kty: 'RSA', format: 'jwk' })
 
-         WIKI.config.letsencrypt.serverKey = await Keypairs.export({ jwk: serverKeypair.private })
 
-         WIKI.logger.info(`(LETSENCRYPT) Server keypairs generated successfully [ OK ]`)
 
-       }
 
-       // -> Create CSR
 
-       WIKI.logger.info(`(LETSENCRYPT) Generating certificate signing request (CSR)...`)
 
-       const domains = [ punycode.toASCII(WIKI.config.ssl.domain) ]
 
-       const serverKey = await Keypairs.import({ pem: WIKI.config.letsencrypt.serverKey })
 
-       const csrDer = await CSR.csr({ jwk: serverKey, domains, encoding: 'der' })
 
-       const csr = PEM.packBlock({ type: 'CERTIFICATE REQUEST', bytes: csrDer })
 
-       WIKI.logger.info(`(LETSENCRYPT) CSR generated successfully [ OK ]`)
 
-       // -> Verify Domain + Get Certificate
 
-       WIKI.logger.info(`(LETSENCRYPT) Requesting certificate from Let's Encrypt...`)
 
-       const certResp = await this.acme.certificates.create({
 
-         account: WIKI.config.letsencrypt.account,
 
-         accountKey: WIKI.config.letsencrypt.accountKeypair.private,
 
-         csr,
 
-         domains,
 
-         challenges: {
 
-           'http-01': {
 
-             init () {},
 
-             set (data) {
 
-               WIKI.logger.info(`(LETSENCRYPT) Setting HTTP challenge for ${data.challenge.hostname}: [ READY ]`)
 
-               WIKI.config.letsencrypt.challenge = data.challenge
 
-               WIKI.logger.info(`(LETSENCRYPT) Waiting for challenge to complete...`)
 
-               return null // <- this is needed, cannot be undefined
 
-             },
 
-             get (data) {
 
-               return WIKI.config.letsencrypt.challenge
 
-             },
 
-             async remove (data) {
 
-               WIKI.logger.info(`(LETSENCRYPT) Removing HTTP challenge: [ OK ]`)
 
-               WIKI.config.letsencrypt.challenge = null
 
-               return null // <- this is needed, cannot be undefined
 
-             }
 
-           }
 
-         }
 
-       })
 
-       WIKI.logger.info(`(LETSENCRYPT) New certifiate received successfully: [ COMPLETED ]`)
 
-       WIKI.config.letsencrypt.payload = certResp
 
-       WIKI.config.letsencrypt.domain = WIKI.config.ssl.domain
 
-       await WIKI.configSvc.saveToDb(['letsencrypt'])
 
-     } catch (err) {
 
-       WIKI.logger.warn(`(LETSENCRYPT) ${err}`)
 
-       throw err
 
-     }
 
-   }
 
- }
 
 
  |