Cleanup REST api and use 'op' query param for verbs
This commit is contained in:
parent
b29c8308a8
commit
a60d8b86a9
14
README.md
14
README.md
@ -131,27 +131,19 @@ POST /api/v1/key
|
|||||||
### Verify uploaded key
|
### Verify uploaded key
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /api/v1/verify?keyId=b8e4105cc9dedc77&nonce=6a314915c09368224b11df0feedbc53c
|
GET /api/v1/key?op=verify&keyId=b8e4105cc9dedc77&nonce=6a314915c09368224b11df0feedbc53c
|
||||||
```
|
```
|
||||||
|
|
||||||
### Request key removal
|
### Request key removal
|
||||||
|
|
||||||
#### Via delete request
|
|
||||||
|
|
||||||
```
|
```
|
||||||
DELETE /api/v1/key?keyId=b8e4105cc9dedc77 OR ?email=user@example.com
|
GET /api/v1/key?op=remove&keyId=b8e4105cc9dedc77 OR ?email=user@example.com
|
||||||
```
|
|
||||||
|
|
||||||
#### Via link
|
|
||||||
|
|
||||||
```
|
|
||||||
GET /api/v1/removeKey?keyId=b8e4105cc9dedc77 OR ?email=user@example.com
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Verify key removal
|
### Verify key removal
|
||||||
|
|
||||||
```
|
```
|
||||||
GET /api/v1/verifyRemove?keyId=b8e4105cc9dedc77&nonce=6a314915c09368224b11df0feedbc53c
|
GET /api/v1/key?op=verifyRemove&keyId=b8e4105cc9dedc77&nonce=6a314915c09368224b11df0feedbc53c
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
16
src/app.js
16
src/app.js
@ -49,21 +49,7 @@ router.post('/api/v1/key', function *() {
|
|||||||
yield rest.create(this);
|
yield rest.create(this);
|
||||||
});
|
});
|
||||||
router.get('/api/v1/key', function *() {
|
router.get('/api/v1/key', function *() {
|
||||||
yield rest.read(this);
|
yield rest.query(this);
|
||||||
});
|
|
||||||
router.del('/api/v1/key', function *() {
|
|
||||||
yield rest.remove(this);
|
|
||||||
});
|
|
||||||
|
|
||||||
// links for verification, removal and sharing
|
|
||||||
router.get('/api/v1/verify', function *() {
|
|
||||||
yield rest.verify(this);
|
|
||||||
});
|
|
||||||
router.get('/api/v1/removeKey', function *() {
|
|
||||||
yield rest.remove(this);
|
|
||||||
});
|
|
||||||
router.get('/api/v1/verifyRemove', function *() {
|
|
||||||
yield rest.verifyRemove(this);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Redirect all http traffic to https
|
// Redirect all http traffic to https
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"verifyKey": {
|
"verifyKey": {
|
||||||
"subject": "Verify Your Key",
|
"subject": "Verify Your Key",
|
||||||
"text": "Hello {{name}},\n\nplease click here to verify your key:\n\n{{baseUrl}}/api/v1/verify?keyId={{keyId}}&nonce={{nonce}}",
|
"text": "Hello {{name}},\n\nplease click here to verify your key:\n\n{{baseUrl}}/api/v1/key?op=verify&keyId={{keyId}}&nonce={{nonce}}",
|
||||||
"html": "<p>Hello {{name}},</p><p>please <a href=\"{{baseUrl}}/api/v1/verify?keyId={{keyId}}&nonce={{nonce}}\">click here to verify</a> your key.</p>"
|
"html": "<p>Hello {{name}},</p><p>please <a href=\"{{baseUrl}}/api/v1/key?op=verify&keyId={{keyId}}&nonce={{nonce}}\">click here to verify</a> your key.</p>"
|
||||||
},
|
},
|
||||||
"verifyRemove": {
|
"verifyRemove": {
|
||||||
"subject": "Verify Key Removal",
|
"subject": "Verify Key Removal",
|
||||||
"text": "Hello {{name}},\n\nplease click here to verify the removal of your key:\n\n{{baseUrl}}/api/v1/verifyRemove?keyId={{keyId}}&nonce={{nonce}}",
|
"text": "Hello {{name}},\n\nplease click here to verify the removal of your key:\n\n{{baseUrl}}/api/v1/key?op=verifyRemove&keyId={{keyId}}&nonce={{nonce}}",
|
||||||
"html": "<p>Hello {{name}},</p><p>please <a href=\"{{baseUrl}}/api/v1/verifyRemove?keyId={{keyId}}&nonce={{nonce}}\">click here to verify</a> the removal of your key.</p>"
|
"html": "<p>Hello {{name}},</p><p>please <a href=\"{{baseUrl}}/api/v1/key?op=verifyRemove&keyId={{keyId}}&nonce={{nonce}}\">click here to verify</a> the removal of your key.</p>"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -50,6 +50,23 @@ class REST {
|
|||||||
ctx.status = 201;
|
ctx.status = 201;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public key query via http GET
|
||||||
|
* @param {Object} ctx The koa request/response context
|
||||||
|
*/
|
||||||
|
*query(ctx) {
|
||||||
|
let op = ctx.query.op;
|
||||||
|
if (this[op]) {
|
||||||
|
return yield this[op](ctx); // delegate operation
|
||||||
|
}
|
||||||
|
// do READ if no 'op' provided
|
||||||
|
let q = { keyId:ctx.query.keyId, fingerprint:ctx.query.fingerprint, email:ctx.query.email };
|
||||||
|
if (!util.isKeyId(q.keyId) && !util.isFingerPrint(q.fingerprint) && !util.isEmail(q.email)) {
|
||||||
|
ctx.throw(400, 'Invalid request!');
|
||||||
|
}
|
||||||
|
ctx.body = yield this._publicKey.get(q);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify a public key's user id via http GET
|
* Verify a public key's user id via http GET
|
||||||
* @param {Object} ctx The koa request/response context
|
* @param {Object} ctx The koa request/response context
|
||||||
@ -66,18 +83,6 @@ class REST {
|
|||||||
ctx.set('Content-Type', 'text/html; charset=utf-8');
|
ctx.set('Content-Type', 'text/html; charset=utf-8');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Public key fetch via http GET
|
|
||||||
* @param {Object} ctx The koa request/response context
|
|
||||||
*/
|
|
||||||
*read(ctx) {
|
|
||||||
let q = { keyId:ctx.query.keyId, fingerprint:ctx.query.fingerprint, email:ctx.query.email };
|
|
||||||
if (!util.isKeyId(q.keyId) && !util.isFingerPrint(q.fingerprint) && !util.isEmail(q.email)) {
|
|
||||||
ctx.throw(400, 'Invalid request!');
|
|
||||||
}
|
|
||||||
ctx.body = yield this._publicKey.get(q);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request public key removal via http DELETE
|
* Request public key removal via http DELETE
|
||||||
* @param {Object} ctx The koa request/response context
|
* @param {Object} ctx The koa request/response context
|
||||||
|
@ -53,7 +53,8 @@
|
|||||||
|
|
||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h2>OpenPGP key removal</h2>
|
<h2>OpenPGP key removal</h2>
|
||||||
<form action="/api/v1/removeKey" method="get">
|
<form action="/api/v1/key" method="get">
|
||||||
|
<input class="hidden" type="radio" name="op" value="remove" checked="checked">
|
||||||
<div class="input-group input-group-lg">
|
<div class="input-group input-group-lg">
|
||||||
<input class="form-control" name="email" type="email" spellcheck="false" placeholder="Email address" required>
|
<input class="form-control" name="email" type="email" spellcheck="false" placeholder="Email address" required>
|
||||||
<span class="input-group-btn">
|
<span class="input-group-btn">
|
||||||
|
@ -97,7 +97,7 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /api/v1/verify', () => {
|
describe('GET /api/v1/key?op=verify', () => {
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.post('/api/v1/key')
|
.post('/api/v1/key')
|
||||||
@ -108,21 +108,21 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
|
|
||||||
it('should return 200 for valid params', done => {
|
it('should return 200 for valid params', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verify?keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
.get('/api/v1/key?op=verify&keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 400 for missing keyid and', done => {
|
it('should return 400 for missing keyid and', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verify?nonce=' + emailParams.nonce)
|
.get('/api/v1/key?op=verify&nonce=' + emailParams.nonce)
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 400 for missing nonce', done => {
|
it('should return 400 for missing nonce', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verify?keyId=' + emailParams.keyId)
|
.get('/api/v1/key?op=verify&keyId=' + emailParams.keyId)
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
@ -148,7 +148,7 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
describe('Verified', () => {
|
describe('Verified', () => {
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verify?keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
.get('/api/v1/key?op=verify&keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
@ -190,7 +190,7 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('DELETE /api/v1/key', () => {
|
describe('GET /api/v1/key?op=remove', () => {
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.post('/api/v1/key')
|
.post('/api/v1/key')
|
||||||
@ -201,51 +201,34 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
|
|
||||||
it('should return 202 for key id', done => {
|
it('should return 202 for key id', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.del('/api/v1/key?keyId=' + emailParams.keyId)
|
.get('/api/v1/key?op=remove&keyId=' + emailParams.keyId)
|
||||||
.expect(202)
|
.expect(202)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 202 for email address', done => {
|
it('should return 202 for email address', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.del('/api/v1/key?email=' + primaryEmail)
|
.get('/api/v1/key?op=remove&email=' + primaryEmail)
|
||||||
.expect(202)
|
.expect(202)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 400 for invalid params', done => {
|
it('should return 400 for invalid params', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.del('/api/v1/key')
|
.get('/api/v1/key?op=remove')
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 404 for unknown email address', done => {
|
it('should return 404 for unknown email address', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.del('/api/v1/key?email=a@foo.com')
|
.get('/api/v1/key?op=remove&email=a@foo.com')
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('GET /api/v1/removeKey', () => {
|
describe('GET /api/v1/key?op=verifyRemove', () => {
|
||||||
beforeEach(done => {
|
|
||||||
request(app.listen())
|
|
||||||
.post('/api/v1/key')
|
|
||||||
.send({ publicKeyArmored, primaryEmail })
|
|
||||||
.expect(201)
|
|
||||||
.end(done);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should return 202 for key id', done => {
|
|
||||||
request(app.listen())
|
|
||||||
.get('/api/v1/removeKey?keyId=' + emailParams.keyId)
|
|
||||||
.expect(202)
|
|
||||||
.end(done);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('GET /api/v1/verifyRemove', () => {
|
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.post('/api/v1/key')
|
.post('/api/v1/key')
|
||||||
@ -253,7 +236,7 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
.expect(201)
|
.expect(201)
|
||||||
.end(function() {
|
.end(function() {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.del('/api/v1/key?keyId=' + emailParams.keyId)
|
.get('/api/v1/key?op=remove&keyId=' + emailParams.keyId)
|
||||||
.expect(202)
|
.expect(202)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
@ -261,21 +244,21 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
|
|
||||||
it('should return 200 for key id', done => {
|
it('should return 200 for key id', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verifyRemove?keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
.get('/api/v1/key?op=verifyRemove&keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 400 for invalid params', done => {
|
it('should return 400 for invalid params', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verifyRemove')
|
.get('/api/v1/key?op=verifyRemove')
|
||||||
.expect(400)
|
.expect(400)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return 404 for unknown key id', done => {
|
it('should return 404 for unknown key id', done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verifyRemove?keyId=0123456789ABCDEF&nonce=' + emailParams.nonce)
|
.get('/api/v1/key?op=verifyRemove&keyId=0123456789ABCDEF&nonce=' + emailParams.nonce)
|
||||||
.expect(404)
|
.expect(404)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
@ -325,7 +308,7 @@ describe('Koa App (HTTP Server) Integration Tests', function() {
|
|||||||
describe('Verified', () => {
|
describe('Verified', () => {
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
request(app.listen())
|
request(app.listen())
|
||||||
.get('/api/v1/verify?keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
.get('/api/v1/key?op=verify&keyId=' + emailParams.keyId + '&nonce=' + emailParams.nonce)
|
||||||
.expect(200)
|
.expect(200)
|
||||||
.end(done);
|
.end(done);
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user