Cleanup url handling
This commit is contained in:
parent
405bb84ca6
commit
d5bd65b4bc
@ -2,6 +2,10 @@ module.exports = {
|
||||
|
||||
log: {
|
||||
level: 'error'
|
||||
}
|
||||
},
|
||||
|
||||
server: {
|
||||
upgradeHTTP: true
|
||||
},
|
||||
|
||||
};
|
@ -22,6 +22,7 @@ const app = require('koa')();
|
||||
const log = require('npmlog');
|
||||
const config = require('config');
|
||||
const router = require('koa-router')();
|
||||
const util = require('./service/util');
|
||||
const Mongo = require('./dao/mongo');
|
||||
const Email = require('./email/email');
|
||||
const PGP = require('./service/pgp');
|
||||
@ -85,7 +86,7 @@ app.use(function *(next) {
|
||||
|
||||
// Redirect all http traffic to https
|
||||
app.use(function *(next) {
|
||||
if (process.env.NODE_ENV === 'production' && !this.secure && this.get('X-Forwarded-Proto') === 'http') {
|
||||
if (config.server.upgradeHTTP && util.checkHTTP(this)) {
|
||||
this.redirect('https://' + this.hostname + this.url);
|
||||
} else {
|
||||
yield next;
|
||||
|
@ -69,7 +69,7 @@ class Email {
|
||||
html: template.html,
|
||||
params: {
|
||||
name: userId.name,
|
||||
baseUrl: origin.protocol + '://' + origin.host,
|
||||
baseUrl: util.url(origin),
|
||||
keyId: encodeURIComponent(keyId),
|
||||
nonce: encodeURIComponent(userId.nonce)
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class HKP {
|
||||
if (!publicKeyArmored) {
|
||||
ctx.throw(400, 'Invalid request!');
|
||||
}
|
||||
let origin = util.getOrigin(ctx);
|
||||
let origin = util.origin(ctx);
|
||||
yield this._publicKey.put({ publicKeyArmored, origin });
|
||||
ctx.status = 201;
|
||||
}
|
||||
|
@ -1,23 +1,34 @@
|
||||
'use strict';
|
||||
|
||||
const util = require('../service/util');
|
||||
|
||||
module.exports = function () {
|
||||
let tls = this.secure || process.env.NODE_ENV === 'production' && this.get('X-Forwarded-Proto') === 'https';
|
||||
let hkp = (tls ? 'hkps://' : 'hkp://') + this.host;
|
||||
let del = (tls ? 'https://' : 'http://') + this.host + '/api/v1/removeKey?email=user@example.com';
|
||||
let hkpLink = util.hkpUrl(this);
|
||||
let removeLink = util.url(util.origin(this), '/api/v1/removeKey?email=user@example.com');
|
||||
this.body =
|
||||
`
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>OpenPGP key server</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
</head>
|
||||
<body>
|
||||
<h1>Welcome to the OpenPGP key server</h1>
|
||||
<p>This server verifies email address as well as private key ownership by sending an encrypted verification email.</p>
|
||||
<h2>Try it out</h2>
|
||||
<ol>
|
||||
<li>Configure this key server in your HKP compatible OpenPGP client using this url: <a href="${hkp}" target="_blank">${hkp}</a></li>
|
||||
<li>Configure this key server in your HKP compatible OpenPGP client using this url: <a href="${hkpLink}" target="_blank">${hkpLink}</a></li>
|
||||
<li>Now just upload a public key like you always do.</li>
|
||||
<li>Check your inbox and click on the verification link inside the encrypted message.</li>
|
||||
<li>You can delete all your data from the server at any time using this link: <a href="${del}" target="_blank">${del}</a></li>
|
||||
<li>You can delete all your data from the server at any time using this link: <a href="${removeLink}" target="_blank">${removeLink}</a></li>
|
||||
</ol>
|
||||
<h2>Documentation and code</h2>
|
||||
<p>Please refer to <a href="https://github.com/mailvelope/keyserver" target="_blank">the documentation</a> to learn more about the api.</p>
|
||||
<p>License AGPL v3.0</p>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
this.set('Content-Type', 'text/html; charset=utf-8');
|
||||
|
@ -44,7 +44,7 @@ class REST {
|
||||
if (!publicKeyArmored || (primaryEmail && !util.isEmail(primaryEmail))) {
|
||||
ctx.throw(400, 'Invalid request!');
|
||||
}
|
||||
let origin = util.getOrigin(ctx);
|
||||
let origin = util.origin(ctx);
|
||||
yield this._publicKey.put({ publicKeyArmored, primaryEmail, origin });
|
||||
ctx.status = 201;
|
||||
}
|
||||
@ -91,7 +91,7 @@ class REST {
|
||||
* @param {Object} ctx The koa request/response context
|
||||
*/
|
||||
*remove(ctx) {
|
||||
let q = { keyId:ctx.query.keyId, email:ctx.query.email, origin:util.getOrigin(ctx) };
|
||||
let q = { keyId:ctx.query.keyId, email:ctx.query.email, origin:util.origin(ctx) };
|
||||
if (!util.isKeyId(q.keyId) && !util.isEmail(q.email)) {
|
||||
ctx.throw(400, 'Invalid request!');
|
||||
}
|
||||
|
@ -102,6 +102,25 @@ exports.random = function(bytes) {
|
||||
return crypto.randomBytes(bytes).toString('hex');
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the user is connecting over a plaintext http connection.
|
||||
* This can be used as an indicator to upgrade their connection to https.
|
||||
* @param {Object} ctx The koa request/repsonse context
|
||||
* @return {boolean} If http is used
|
||||
*/
|
||||
exports.checkHTTP = function(ctx) {
|
||||
return !ctx.secure && ctx.get('X-Forwarded-Proto') === 'http';
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the user is connecting over a https connection.
|
||||
* @param {Object} ctx The koa request/repsonse context
|
||||
* @return {boolean} If https is used
|
||||
*/
|
||||
exports.checkHTTPS = function(ctx) {
|
||||
return ctx.secure || ctx.get('X-Forwarded-Proto') === 'https';
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the server's own origin host and protocol. Required for sending
|
||||
* verification links via email. If the PORT environmane variable
|
||||
@ -110,9 +129,29 @@ exports.random = function(bytes) {
|
||||
* @param {Object} ctx The koa request/repsonse context
|
||||
* @return {Object} The server origin
|
||||
*/
|
||||
exports.getOrigin = function(ctx) {
|
||||
exports.origin = function(ctx) {
|
||||
return {
|
||||
protocol: process.env.PORT ? 'https' : ctx.protocol,
|
||||
protocol: this.checkHTTPS(ctx) ? 'https' : ctx.protocol,
|
||||
host: ctx.host
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to create urls pointing to this server
|
||||
* @param {Object} origin The server's origin
|
||||
* @param {string} resource (optional) The resource to point to
|
||||
* @return {string} The complete url
|
||||
*/
|
||||
exports.url = function(origin, resource) {
|
||||
return origin.protocol + '://' + origin.host + (resource || '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to create a url for hkp clients to connect to this server via
|
||||
* the hkp protocol.
|
||||
* @param {Object} ctx The koa request/repsonse context
|
||||
* @return {string} The complete url
|
||||
*/
|
||||
exports.hkpUrl = function(ctx) {
|
||||
return (this.checkHTTPS(ctx) ? 'hkps://' : 'hkp://') + ctx.host;
|
||||
};
|
@ -135,9 +135,21 @@ describe('Util Unit Tests', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('getOrigin', () => {
|
||||
describe('origin', () => {
|
||||
it('should work', () => {
|
||||
expect(util.getOrigin({host:'h', protocol:'p'})).to.exist;
|
||||
expect(util.origin({ secure:true, host:'h', protocol:'p' })).to.exist;
|
||||
});
|
||||
});
|
||||
|
||||
describe('url', () => {
|
||||
it('should work with resource', () => {
|
||||
let url = util.url({ host:'localhost', protocol:'http'}, '/foo');
|
||||
expect(url).to.equal('http://localhost/foo');
|
||||
});
|
||||
|
||||
it('should work without resource', () => {
|
||||
let url = util.url({ host:'localhost', protocol:'http'});
|
||||
expect(url).to.equal('http://localhost');
|
||||
});
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user