This repository has been archived by the owner on Sep 27, 2022. It is now read-only.
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Build 2.0: Database now accessed by APIs; WebSocket interfaces added
- Loading branch information
Showing
84 changed files
with
5,124 additions
and
723 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
---------------------------------------------------------------------------- | ||
| qewd-conduit: QEWD Implementation of the Conduit Back-end | | ||
| | | ||
| Copyright (c) 2017 M/Gateway Developments Ltd, | | ||
| Reigate, Surrey UK. | | ||
| All rights reserved. | | ||
| | | ||
| http://www.mgateway.com | | ||
| Email: rtweed@mgateway.com | | ||
| | | ||
| | | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | | ||
| you may not use this file except in compliance with the License. | | ||
| You may obtain a copy of the License at | | ||
| | | ||
| http://www.apache.org/licenses/LICENSE-2.0 | | ||
| | | ||
| Unless required by applicable law or agreed to in writing, software | | ||
| distributed under the License is distributed on an "AS IS" BASIS, | | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | ||
| See the License for the specific language governing permissions and | | ||
| limitations under the License. | | ||
---------------------------------------------------------------------------- | ||
28 April 2017 | ||
*/ | ||
|
||
var validation = require('../utilities/validation'); | ||
var errorHandler = require('../utilities/errorHandler'); | ||
var getArticleIdBySlug = require('./getArticleIdBySlug'); | ||
var getComment = require('./getComment'); | ||
|
||
function addComments(args, callback) { | ||
|
||
// Add comment to an article | ||
|
||
// first, validate request object... | ||
|
||
// check for requuest body and required field ('body') | ||
|
||
var errors = validation.bodyAndFields(args, 'comment', ['body']); | ||
if (errorHandler.hasErrors(errors)) return errorHandler.errorResponse(errors, callback); | ||
|
||
// validate JWT and if OK, get the user database pointer | ||
|
||
var status = validation.jwt.call(this, args); | ||
if (status.error) return callback(status); | ||
var id = status.payload.id; | ||
|
||
// if slug exists, get pointer to article | ||
|
||
var slug = args.slug; | ||
var articleId = getArticleIdBySlug.call(this, slug); | ||
if (!articleId) { | ||
return errorHandler.notFound(callback); | ||
} | ||
|
||
// create comment database record | ||
|
||
var commentsDoc = new this.documentStore.DocumentNode('conduitComments'); | ||
var commentId = commentsDoc.$('nextId').increment(); | ||
var commentDoc = commentsDoc.$(['byId', commentId]); | ||
|
||
var iso = new Date().toISOString(); | ||
|
||
var comment = { | ||
id: commentId, | ||
articleId: articleId, | ||
body: args.req.body.comment.body, | ||
author: id, | ||
createdAt: iso, | ||
updatedAt: iso | ||
}; | ||
|
||
commentDoc.setDocument(comment); | ||
|
||
// link it to its article record | ||
|
||
var articlesDoc = new this.documentStore.DocumentNode('conduitArticles', ['byId', articleId, 'comments', commentId]); | ||
articlesDoc.value = commentId; | ||
|
||
// fetch and return the comment document, with author profile | ||
|
||
comment = getComment.call(this, commentId, id); | ||
|
||
callback({comment: comment}); | ||
} | ||
|
||
module.exports = addComments; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
/* | ||
---------------------------------------------------------------------------- | ||
| qewd-conduit: QEWD Implementation of the Conduit Back-end | | ||
| | | ||
| Copyright (c) 2017 M/Gateway Developments Ltd, | | ||
| Reigate, Surrey UK. | | ||
| All rights reserved. | | ||
| | | ||
| http://www.mgateway.com | | ||
| Email: rtweed@mgateway.com | | ||
| | | ||
| | | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | | ||
| you may not use this file except in compliance with the License. | | ||
| You may obtain a copy of the License at | | ||
| | | ||
| http://www.apache.org/licenses/LICENSE-2.0 | | ||
| | | ||
| Unless required by applicable law or agreed to in writing, software | | ||
| distributed under the License is distributed on an "AS IS" BASIS, | | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | ||
| See the License for the specific language governing permissions and | | ||
| limitations under the License. | | ||
---------------------------------------------------------------------------- | ||
3 May 2017 | ||
*/ | ||
|
||
var validation = require('../utilities/validation'); | ||
var errorHandler = require('../utilities/errorHandler'); | ||
var getArticle = require('./getArticle'); | ||
var slugify = require('slugify'); | ||
|
||
function create(args, callback) { | ||
|
||
// Create Article | ||
|
||
// first, validate request object... | ||
|
||
// check for body and optional fields | ||
|
||
var errors = validation.bodyAndFields(args, 'article', ['title', 'description', 'body']); | ||
var article = args.req.body.article; | ||
|
||
// validate title | ||
|
||
if (article.title !== '' && article.title.length > 255) { | ||
errors = errorHandler.add('title', "must be no longer than 255 characters", errors); | ||
} | ||
|
||
// validate description | ||
|
||
if (article.description !== '' && article.description.length > 255) { | ||
errors = errorHandler.add('description', "must be no longer than 255 characters", errors); | ||
} | ||
|
||
// validate tagList | ||
|
||
var tagList = article.tagList; | ||
//if (tagList !== 'undefined' && (!Array.isArray(tagList) || tagList.length === 0)) { | ||
if (tagList !== 'undefined' && !Array.isArray(tagList)) { | ||
errors = errorHandler.add('tagList', "must be an array", errors); | ||
} | ||
|
||
if (errorHandler.hasErrors(errors)) return errorHandler.errorResponse(errors, callback); | ||
|
||
// validate JWT and if OK, get the user database pointer | ||
|
||
var status = validation.jwt.call(this, args); | ||
if (status.error) return callback(status); | ||
var id = status.payload.id; | ||
|
||
// create article object | ||
|
||
var slug = slugify(article.title).toLowerCase(); | ||
var articlesDoc = new this.documentStore.DocumentNode('conduitArticles'); | ||
var articleId = articlesDoc.$('nextId').increment(); | ||
|
||
if (articlesDoc.$(['bySlug', slug]).exists) { | ||
slug = slug + '-x' + articleId; | ||
} | ||
|
||
var now = new Date(); | ||
var iso = now.toISOString(); | ||
var ts = 100000000000000 - now.getTime(); | ||
article.createdAt = iso; | ||
article.updatedAt = iso; | ||
article.timestampIndex = ts; | ||
article.favoritesCount = 0; | ||
article.author = id; | ||
article.slug = slug; | ||
|
||
// save to database and save indices | ||
|
||
articlesDoc.$(['byId', articleId]).setDocument(article); | ||
articlesDoc.$(['bySlug', slug]).value = articleId; | ||
articlesDoc.$(['byAuthor', id, articleId]).value = articleId; | ||
articlesDoc.$(['byTimestamp', ts]).value = articleId; | ||
|
||
if (article.tagList) { | ||
article.tagList.forEach(function(tag) { | ||
articlesDoc.$(['byTag', tag, articleId]).value = articleId; | ||
}); | ||
} | ||
|
||
// output article object | ||
|
||
var article = getArticle.call(this, articleId, id); | ||
|
||
callback({article: article}); | ||
} | ||
|
||
module.exports = create; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
---------------------------------------------------------------------------- | ||
| qewd-conduit: QEWD Implementation of the Conduit Back-end | | ||
| | | ||
| Copyright (c) 2017 M/Gateway Developments Ltd, | | ||
| Reigate, Surrey UK. | | ||
| All rights reserved. | | ||
| | | ||
| http://www.mgateway.com | | ||
| Email: rtweed@mgateway.com | | ||
| | | ||
| | | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | | ||
| you may not use this file except in compliance with the License. | | ||
| You may obtain a copy of the License at | | ||
| | | ||
| http://www.apache.org/licenses/LICENSE-2.0 | | ||
| | | ||
| Unless required by applicable law or agreed to in writing, software | | ||
| distributed under the License is distributed on an "AS IS" BASIS, | | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | ||
| See the License for the specific language governing permissions and | | ||
| limitations under the License. | | ||
---------------------------------------------------------------------------- | ||
28 April 2017 | ||
*/ | ||
|
||
var validation = require('../utilities/validation'); | ||
var errorHandler = require('../utilities/errorHandler'); | ||
var getArticleIdBySlug = require('./getArticleIdBySlug'); | ||
var getArticle = require('./getArticle'); | ||
|
||
function deleteArticle(args, callback) { | ||
|
||
// Delete Article | ||
|
||
// validate JWT | ||
|
||
var errors; | ||
var status = validation.jwt.call(this, args); | ||
if (status.error) return callback(status); | ||
var username = status.payload.username; | ||
var id = status.payload.id; | ||
|
||
// check that the slug exists | ||
|
||
var slug = args.slug; | ||
var articleId = getArticleIdBySlug.call(this, slug); | ||
if (!articleId) { | ||
return errorHandler.notFound(callback); | ||
} | ||
|
||
//check that the user is the author | ||
|
||
var article = getArticle.call(this, articleId); | ||
if (article.author.username !== username) { | ||
errors = errorHandler.add('article', "not owned by author", errors); | ||
return errorHandler.errorResponse(errors, callback, 403); | ||
} | ||
|
||
// delete article indices | ||
|
||
var articlesDoc = new this.documentStore.DocumentNode('conduitArticles'); | ||
articlesDoc.$(['bySlug', slug]).delete(); | ||
articlesDoc.$(['byAuthor', id, articleId]).delete(); | ||
var ts = articlesDoc.$(['byId', articleId, 'timestampIndex']).value; | ||
articlesDoc.$(['byTimestamp', ts]).delete(); | ||
if (article.tagList) { | ||
article.tagList.forEach(function(tag) { | ||
articlesDoc.$(['byTag', tag, articleId]).delete(); | ||
}); | ||
} | ||
|
||
// delete any associated comment records | ||
|
||
var commentsDoc = new this.documentStore.DocumentNode('conduitComments', ['byId']); | ||
articlesDoc.$(['byId', articleId, 'comments']).forEachChild(function(commentId) { | ||
commentsDoc.$(commentId).delete(); | ||
}); | ||
|
||
// finally, delete article record | ||
|
||
articlesDoc.$(['byId', articleId]).delete(); | ||
|
||
callback({}); | ||
} | ||
|
||
module.exports = deleteArticle; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
/* | ||
---------------------------------------------------------------------------- | ||
| qewd-conduit: QEWD Implementation of the Conduit Back-end | | ||
| | | ||
| Copyright (c) 2017 M/Gateway Developments Ltd, | | ||
| Reigate, Surrey UK. | | ||
| All rights reserved. | | ||
| | | ||
| http://www.mgateway.com | | ||
| Email: rtweed@mgateway.com | | ||
| | | ||
| | | ||
| Licensed under the Apache License, Version 2.0 (the "License"); | | ||
| you may not use this file except in compliance with the License. | | ||
| You may obtain a copy of the License at | | ||
| | | ||
| http://www.apache.org/licenses/LICENSE-2.0 | | ||
| | | ||
| Unless required by applicable law or agreed to in writing, software | | ||
| distributed under the License is distributed on an "AS IS" BASIS, | | ||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | | ||
| See the License for the specific language governing permissions and | | ||
| limitations under the License. | | ||
---------------------------------------------------------------------------- | ||
3 May 2017 | ||
*/ | ||
|
||
var validation = require('../utilities/validation'); | ||
var errorHandler = require('../utilities/errorHandler'); | ||
var getArticleIdBySlug = require('./getArticleIdBySlug'); | ||
var getComment = require('./getComment'); | ||
|
||
function deleteComment(args, callback) { | ||
|
||
// Delete Comment | ||
|
||
// validate JWT and if OK, get the user database pointer | ||
|
||
var errors; | ||
var status = validation.jwt.call(this, args); | ||
if (status.error) return callback(status); | ||
var id = status.payload.id; | ||
|
||
// if slug exists, get pointer to article | ||
|
||
var slug = args.slug; | ||
var articleId = getArticleIdBySlug.call(this, slug); | ||
if (!articleId) { | ||
// no article with that slug | ||
return errorHandler.notFound(callback); | ||
} | ||
|
||
// next get the pointer to the comment within that article | ||
|
||
var commentId = args.id; | ||
|
||
var articleCommentDoc = new this.documentStore.DocumentNode('conduitArticles', ['byId', articleId, 'comments', commentId]); | ||
if (!articleCommentDoc.exists) { | ||
// no comment with that Id in the article | ||
return errorHandler.notFound(callback); | ||
} | ||
|
||
// is the current user the author of the comment? | ||
|
||
var commentDoc = new this.documentStore.DocumentNode('conduitComments', ['byId', commentId]); | ||
|
||
if (commentDoc.$('author').value.toString() !== id.toString()) { | ||
errors = errorHandler.add('comment', "not owned by author", errors); | ||
return errorHandler.errorResponse(errors, callback, 403); | ||
} | ||
|
||
// ok, delete the comment | ||
|
||
commentDoc.delete(); | ||
|
||
// and delete the reference to it in the article | ||
|
||
articleCommentDoc.delete(); | ||
|
||
// that's it done! | ||
|
||
callback({}); | ||
} | ||
|
||
module.exports = deleteComment; |
Oops, something went wrong.