mirror of
https://github.com/nodemailer/wildduck.git
synced 2024-12-27 02:10:52 +08:00
80 lines
2.7 KiB
JavaScript
80 lines
2.7 KiB
JavaScript
'use strict';
|
|
|
|
const config = require('wild-config');
|
|
const log = require('npmlog');
|
|
const Joi = require('joi');
|
|
const AcmeChallenge = require('../acme/acme-challenge');
|
|
const { responseWrapper, validationErrors, getHostname, normalizeIp } = require('../tools');
|
|
|
|
module.exports = (db, server, routeOptions) => {
|
|
routeOptions = routeOptions || {};
|
|
|
|
const acmeChallenge = AcmeChallenge.create({ db: db.database });
|
|
|
|
server.get(
|
|
{ name: 'acmeToken', path: '/.well-known/acme-challenge/:token' },
|
|
responseWrapper(async (req, res) => {
|
|
res.charSet('utf-8');
|
|
|
|
const ip = normalizeIp(res.socket.remoteAddress);
|
|
const domain = getHostname(req);
|
|
|
|
const schema = Joi.object().keys({
|
|
token: Joi.string().empty('').max(256).required()
|
|
});
|
|
|
|
const result = schema.validate(req.params, {
|
|
abortEarly: false,
|
|
convert: true,
|
|
allowUnknown: true
|
|
});
|
|
|
|
if (result.error) {
|
|
res.status(400);
|
|
return res.json({
|
|
error: result.error.message,
|
|
code: 'InputValidationError',
|
|
details: validationErrors(result)
|
|
});
|
|
}
|
|
|
|
const token = result.value.token;
|
|
|
|
let challenge;
|
|
try {
|
|
challenge = await acmeChallenge.get({
|
|
challenge: {
|
|
token,
|
|
identifier: { value: domain }
|
|
}
|
|
});
|
|
} catch (err) {
|
|
log.error('ACME', `Error verifying challenge ${domain}: ${token} (${ip}, ${req.url}) ${err.message}`);
|
|
|
|
let resErr = new Error(`Failed to verify authentication token`);
|
|
resErr.responseCode = 500;
|
|
throw resErr;
|
|
}
|
|
|
|
if (!challenge || !challenge.keyAuthorization) {
|
|
log.error('ACME', `Unknown challenge ${domain}: ${token} (${ip}, ${req.url})`);
|
|
|
|
let err = new Error(`Unknown challenge`);
|
|
err.responseCode = 404;
|
|
throw err;
|
|
}
|
|
|
|
res.statusCode = 200;
|
|
res.setHeader('Content-Type', 'text/plain');
|
|
res.send(challenge.keyAuthorization);
|
|
})
|
|
);
|
|
|
|
if (!routeOptions.disableRedirect) {
|
|
server.on('NotFound', (req, res, err, cb) => {
|
|
let remoteAddress = ((req.socket || req.connection).remoteAddress || '').replace(/^::ffff:/, '');
|
|
log.http('ACME', `${remoteAddress} ${req.method} ${req.url} 302 [redirect=${config.acme.agent.redirect}]`);
|
|
res.redirect(302, config.acme.agent.redirect, cb);
|
|
});
|
|
}
|
|
};
|