diff --git a/API.md b/API.md
index b8b6c3ba..42eb5f78 100644
--- a/API.md
+++ b/API.md
@@ -6,33 +6,59 @@
| ------ | ----- | ------ | ----------- |
| GET | `/auth/login` | login home | Shows login options or redirects the user if he is already authenticated.
Optional parameter for redirect: `continue` |
| GET | `/auth/login/:method` | login | Creates a session.
Method can be `couch`, `github`, `google`, ... |
-| GET | `/auth/logout` | logout |
-| GET | `/auth/session` | get info on current session |
+| GET | `/auth/logout` | logout | |
+| GET | `/auth/session` | get info on current session | |
## Database
+### Entry
+
| Method | Route | Action | Description |
| ------ | ----- | ------ | ----------- |
| POST | `/db/:dbname/entry` | Insert / Update an entry | Based on _id or $id of the entry |
| GET | `/db/:dbname/entry/_all` | Get all entries | Returns an array of documents |
-| GET | `/db/:dbname/entry/:uuid` | Get an entry by UUID |
-| PUT | `/db/:dbname/entry/:uuid` | Update an entry by UUID |
-| DELETE | `/db/:dbname/entry/:uuid` | Delete an an entry by UUID |
-| GET | `/db/:dbname/entry/:uuid/_owner` | Get a list of owners |
-| PUT | `/db/:dbname/entry/:uuid/_owner/:owner` | Add an owner |
-| DELETE | `/db/:dbname/entry/:uuid/_owner/:owner` | Remove an owner |
-| GET | `/db/:dbname/entry/:uuid/:attachment+` | Get an attachment |
-| PUT | `/db/:dbname/entry/:uuid/:attachment+` | Save an attachment |
+| GET | `/db/:dbname/entry/:uuid` | Get an entry by UUID | |
+| PUT | `/db/:dbname/entry/:uuid` | Update an entry by UUID | |
+| DELETE | `/db/:dbname/entry/:uuid` | Delete an an entry by UUID | |
+| GET | `/db/:dbname/entry/:uuid/_owner` | Get a list of owners | |
+| PUT | `/db/:dbname/entry/:uuid/_owner/:owner` | Add an owner | |
+| DELETE | `/db/:dbname/entry/:uuid/_owner/:owner` | Remove an owner | |
+| GET | `/db/:dbname/entry/:uuid/:attachment+` | Get an attachment | |
+| PUT | `/db/:dbname/entry/:uuid/:attachment+` | Save an attachment | |
+
+### User
+
+| Method | Route | Action | Description |
+| ------ | ----- | ------ | ----------- |
| GET | `/db/:dbname/user/_me` | Get user preferences | Returns logged user's preferences entry |
| POST | `/db/:dbname/user/_me` | Update user preferences | Creates a merge of current preferences with sent preferences |
+
+### Queries
+
+| Method | Route | Action | Description |
+| ------ | ----- | ------ | ----------- |
| GET | `/db/:dbname/_view/:view` | Query a custom view | Returns an array of documents |
| GET | `/db/:dbname/_query/:view` | Query a custom view with owners | Returns an array of mapped results |
| POST | `/db/:dbname/_query/byKindAndId/:kind` | Search by kind and id | key, startkey and endkey can be set in the body of the request |
| POST | `/db/:dbname/_query/byOwnerAndId/:email` | Search by kind and owner | key, startkey and endkey can be set in the body of the request |
-| GET | `/db/:dbname/group/:name` | Get a group by name |
-| PUT | `/db/:dbname/group/:name` | Create or update a group |
-| DELETE | `/db/:dbname/group/:name` | Remove a group |
+
+### Groups
+
+| Method | Route | Action | Description |
+| ------ | ----- | ------ | ----------- |
+| GET | `/db/:dbname/group/:name` | Get a group by name | |
+| PUT | `/db/:dbname/group/:name` | Create or update a group | |
+| DELETE | `/db/:dbname/group/:name` | Remove a group | |
| PUT | `/db/:dbname/group/:name/user/:user` | Add a user to an existing group | Group must exist. No-op if user is already in group |
| DELETE | `/db/:dbname/group/:name/user/:user` | Remove a user from an existing group | Group must exist. No-op if user is not in group |
| PUT | `/db/:dbname/group/:name/right/:right` | Add a right to an existing group | Group must exist. No-op if group already has right |
| DELETE | `/db/:dbname/group/:name/right/:right` | Remove a right from an existing group | Group must exist. No-op if group does not have right |
+
+### Tokens
+
+| Method | Route | Action | Description |
+| ------ | ----- | ------ | ----------- |
+| POST | `/db/:dbname/entry/:uuid/_token` | Create a readonly token for this entry | User must have write rights on the entry |
+| GET | `/db/:dbname/token` | Get all tokens for current user | |
+| GET | `/db/:dbname/token/:tokenid` | Get information about a token | |
+| DELETE | `/db/:dbname/token/:tokenid` | Delete a token | |
diff --git a/src/server/middleware/couch.js b/src/server/middleware/couch.js
index dbcc8087..46b4fb87 100644
--- a/src/server/middleware/couch.js
+++ b/src/server/middleware/couch.js
@@ -259,6 +259,41 @@ exports.deleteGroup = function *() {
}
};
+exports.createEntryToken = function* () {
+ try {
+ const token = yield this.state.couch.createEntryToken(this.state.userEmail, this.params.uuid);
+ this.status = 201;
+ this.body = token;
+ } catch (e) {
+ onGetError(this, e);
+ }
+};
+
+exports.getTokens = function* () {
+ try {
+ this.body = yield this.state.couch.getTokens(this.state.userEmail);
+ } catch (e) {
+ onGetError(this, e);
+ }
+};
+
+exports.getTokenById = function* () {
+ try {
+ this.body = yield this.state.couch.getToken(this.params.tokenid);
+ } catch (e) {
+ onGetError(this, e);
+ }
+};
+
+exports.deleteTokenById = function* () {
+ try {
+ yield this.state.couch.deleteToken(this.state.userEmail, this.params.tokenid);
+ this.body = {ok: true};
+ } catch (e) {
+ onGetError(this, e);
+ }
+};
+
function onGetError(ctx, e, secure) {
switch (e.reason) {
case 'unauthorized':
diff --git a/src/server/routes/api.js b/src/server/routes/api.js
index 7abbe8f0..edf56f08 100644
--- a/src/server/routes/api.js
+++ b/src/server/routes/api.js
@@ -50,5 +50,11 @@ exports.init = function () {
//router.put('/:dbname/group/:name', parseJson1mb, couch.createOrUpdateGroup);
router.delete('/:dbname/group/:name', couch.deleteGroup);
+ // Tokens
+ router.post('/:dbname/entry/:uuid/_token', couch.createEntryToken);
+ router.get('/:dbname/token', couch.getTokens);
+ router.get('/:dbname/token/:tokenid', couch.getTokenById);
+ router.delete('/:dbname/token/:tokenid', couch.deleteTokenById);
+
return router;
};