diff --git a/src/ctrl/public-key.js b/src/ctrl/public-key.js
index 704f025..2c2b6d4 100644
--- a/src/ctrl/public-key.js
+++ b/src/ctrl/public-key.js
@@ -17,6 +17,16 @@
'use strict';
+/**
+ * Database documents have the format:
+ * {
+ * _id: "02C134D079701934", // the 16 byte key id
+ * email: "jon@example.com", // the primary and verified email address
+ * publicKeyArmored: "-----BEGIN PGP PUBLIC KEY BLOCK----- ... -----END PGP PUBLIC KEY BLOCK-----"
+ * }
+ */
+const DB_TYPE = 'publickey';
+
/**
* A controller that handlers PGP public keys queries to the database
*/
@@ -30,6 +40,38 @@ class PublicKey {
this._mongo = mongo;
}
+ //
+ // Create/Update
+ //
+
+ put(options) {
+
+ }
+
+ verify(options) {
+
+ }
+
+ //
+ // Read
+ //
+
+ get(options) {
+
+ }
+
+ //
+ // Delete
+ //
+
+ remove(options) {
+
+ }
+
+ verifyRemove(options) {
+
+ }
+
}
module.exports = PublicKey;
\ No newline at end of file
diff --git a/src/dao/email.js b/src/dao/email.js
new file mode 100644
index 0000000..eb1e30d
--- /dev/null
+++ b/src/dao/email.js
@@ -0,0 +1,29 @@
+/**
+ * Mailvelope - secure email with OpenPGP encryption for Webmail
+ * Copyright (C) 2016 Mailvelope GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+'use strict';
+
+/**
+ * A simple wrapper around Nodemailer to send verification emails
+ */
+class Email {
+
+ send(options) {
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/routes/hkp.js b/src/routes/hkp.js
index e8cdf00..e3bae3e 100644
--- a/src/routes/hkp.js
+++ b/src/routes/hkp.js
@@ -31,30 +31,35 @@ class HKP {
this._publicKey = publicKey;
}
- /**
- * Public key lookup via http GET
- * @param {Object} ctx The koa request/response context
- */
- *lookup(ctx) {
- var params = this.parseQueryString(ctx);
- if (!params) {
- return; // invalid request
- }
-
- this.setHeaders(ctx);
- if (params.mr) {
- this.setGetMRHEaders(ctx);
- }
- ctx.body = yield Promise.resolve('----- BEGIN PUBLIC PGP KEY -----');
- }
-
/**
* Public key upload via http POST
* @param {Object} ctx The koa request/response context
*/
*add(ctx) {
ctx.throw(501, 'Not implemented!');
- return yield Promise.resolve();
+ yield;
+ }
+
+ /**
+ * Public key lookup via http GET
+ * @param {Object} ctx The koa request/response context
+ */
+ *lookup(ctx) {
+ let params = this.parseQueryString(ctx);
+ if (!params) {
+ return; // invalid request
+ }
+
+ let key = yield this._publicKey.get(params);
+ if (key) {
+ ctx.body = key.publicKeyArmored;
+ if (params.mr) {
+ this.setGetMRHEaders(ctx);
+ }
+ } else {
+ ctx.status = 404;
+ ctx.body = 'Not found!';
+ }
}
/**
@@ -64,20 +69,22 @@ class HKP {
* @return {Object} The query parameters or undefined for an invalid request
*/
parseQueryString(ctx) {
- let q = ctx.query;
let params = {
- op: q.op, // operation ... only 'get' is supported
- mr: q.options === 'mr', // machine readable
- keyid: this.checkId(q.search) ? q.search.replace('0x', '') : null,
- email: this.checkEmail(q.search) ? q.search : null,
+ op: ctx.query.op, // operation ... only 'get' is supported
+ mr: ctx.query.options === 'mr' // machine readable
};
+ if (this.checkId(ctx.query.search)) {
+ params._id = ctx.query.search.replace(/^0x/, '');
+ } else if(this.checkEmail(ctx.query.search)) {
+ params.email = ctx.query.search;
+ }
if (params.op !== 'get') {
ctx.status = 501;
ctx.body = 'Not implemented!';
return;
- } else if (!params.keyid && !params.email) {
- ctx.status = 404;
+ } else if (!params._id && !params.email) {
+ ctx.status = 400;
ctx.body = 'Invalid request!';
return;
}
@@ -101,18 +108,7 @@ class HKP {
* @return {Boolean} If the key id is valid
*/
checkId(keyid) {
- return /^0x[a-fA-F0-9]{8,40}/.test(keyid);
- }
-
- /**
- * Set HTTP headers for the HKP requests.
- * @param {Object} ctx The koa request/response context
- */
- setHeaders(ctx) {
- ctx.set('Access-Control-Allow-Origin', '*');
- ctx.set('Cache-Control', 'no-cache');
- ctx.set('Pragma', 'no-cache');
- ctx.set('Connection', 'keep-alive');
+ return /^0x[a-fA-F0-9]{8,40}$/.test(keyid);
}
/**
diff --git a/src/routes/rest.js b/src/routes/rest.js
new file mode 100644
index 0000000..d42299b
--- /dev/null
+++ b/src/routes/rest.js
@@ -0,0 +1,56 @@
+/**
+ * Mailvelope - secure email with OpenPGP encryption for Webmail
+ * Copyright (C) 2016 Mailvelope GmbH
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License version 3
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ */
+
+'use strict';
+
+/**
+ * The REST api to provide additional functionality on top of HKP
+ */
+class REST {
+
+ constructor(publicKey) {
+ this._publicKey = publicKey;
+ }
+
+ *create(ctx) {
+ ctx.throw(501, 'Not implemented!');
+ yield;
+ }
+
+ *verify(ctx) {
+ ctx.throw(501, 'Not implemented!');
+ yield;
+ }
+
+ *read(ctx) {
+ ctx.throw(501, 'Not implemented!');
+ yield;
+ }
+
+ *remove(ctx) {
+ ctx.throw(501, 'Not implemented!');
+ yield;
+ }
+
+ *verifyRemove(ctx) {
+ ctx.throw(501, 'Not implemented!');
+ yield;
+ }
+
+}
+
+module.exports = REST;
\ No newline at end of file
diff --git a/src/worker.js b/src/worker.js
index 45fe4e1..52e70bf 100644
--- a/src/worker.js
+++ b/src/worker.js
@@ -25,18 +25,53 @@ const router = require('koa-router')();
const Mongo = require('./dao/mongo');
const PublicKey = require('./ctrl/public-key');
const HKP = require('./routes/hkp');
+const REST = require('./routes/rest');
-let mongo, publicKey, hkp;
+let mongo, publicKey, hkp, rest;
//
-// Configure koa router
+// Configure koa HTTP server
//
-router.get('/pks/lookup', function *() {
+// HKP routes
+router.post('/pks/add', function *() { // no query params
+ yield hkp.add(this);
+});
+router.get('/pks/lookup', function *() { // ?op=get&search=0x1234567890123456
yield hkp.lookup(this);
});
-router.post('/pks/add', function *() {
- yield hkp.add(this);
+
+// REST api routes
+router.post('/api/key', function *() { // no query params
+ yield rest.create(this);
+});
+router.get('/api/key', function *() { // ?id=keyid OR ?email=email
+ yield rest.read(this);
+});
+router.del('/api/key', function *() { // ?id=keyid OR ?email=email
+ yield rest.remove(this);
+});
+
+// links for verification and sharing
+router.get('/api/verify', function *() { // ?id=keyid&nonce=nonce
+ yield rest.verify(this);
+});
+router.get('/api/verifyRemove', function *() { // ?id=keyid&nonce=nonce
+ yield rest.verifyRemove(this);
+});
+router.get('/:email', function *() { // shorthand link for sharing
+ yield rest.read(this);
+});
+
+// Set HTTP response headers
+app.use(function *(next) {
+ this.set('Access-Control-Allow-Origin', '*');
+ this.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
+ this.set('Access-Control-Allow-Headers', 'Content-Type');
+ this.set('Cache-Control', 'no-cache');
+ this.set('Pragma', 'no-cache');
+ this.set('Connection', 'keep-alive');
+ yield next;
});
app.use(router.routes());
@@ -56,6 +91,7 @@ function injectDependencies() {
});
publicKey = new PublicKey(mongo);
hkp = new HKP(publicKey);
+ rest = new REST(publicKey);
}
function readCredentials() {