summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.eslintrc.json3
-rw-r--r--.meteor/packages1
-rw-r--r--.meteor/versions4
-rw-r--r--models/boards.js4
-rw-r--r--models/cardComments.js62
-rw-r--r--models/cards.js4
-rw-r--r--models/checklists.js100
-rw-r--r--models/lists.js4
-rw-r--r--models/users.js4
-rw-r--r--server/authentication.js21
-rw-r--r--server/logger.js25
11 files changed, 207 insertions, 25 deletions
diff --git a/.eslintrc.json b/.eslintrc.json
index 7aa16f4d..5fa05a38 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -126,6 +126,7 @@
"Settings": true,
"InvitationCodes": true,
"Winston":true,
- "JsonRoutes": true
+ "JsonRoutes": true,
+ "Authentication": true
}
}
diff --git a/.meteor/packages b/.meteor/packages
index 67678ccb..f5fce1f6 100644
--- a/.meteor/packages
+++ b/.meteor/packages
@@ -77,3 +77,4 @@ simple:json-routes
rajit:bootstrap3-datepicker
kadira:flow-router
shell-server@0.2.3
+simple:rest-accounts-password
diff --git a/.meteor/versions b/.meteor/versions
index 1a040534..4c1fccf4 100644
--- a/.meteor/versions
+++ b/.meteor/versions
@@ -134,7 +134,11 @@ service-configuration@1.0.11
session@1.1.7
sha@1.0.9
shell-server@0.2.3
+simple:authenticate-user-by-token@1.0.1
simple:json-routes@2.1.0
+simple:rest-accounts-password@1.1.2
+simple:rest-bearer-token-parser@1.0.1
+simple:rest-json-error-handler@1.0.1
softwarerero:accounts-t9n@1.3.9
spacebars@1.0.15
spacebars-compiler@1.1.2
diff --git a/models/boards.js b/models/boards.js
index 9cbb5b63..879dde84 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -557,6 +557,7 @@ if (Meteor.isServer) {
//BOARDS REST API
if (Meteor.isServer) {
JsonRoutes.add('GET', '/api/boards', function (req, res, next) {
+ Authentication.checkUserId(req.userId);
JsonRoutes.sendResult(res, {
code: 200,
data: Boards.find({ permission: 'public' }).map(function (doc) {
@@ -569,6 +570,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('GET', '/api/boards/:id', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const id = req.params.id;
JsonRoutes.sendResult(res, {
code: 200,
@@ -577,6 +579,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('POST', '/api/boards', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const id = Boards.insert({
title: req.body.title,
members: [
@@ -599,6 +602,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('DELETE', '/api/boards/:id', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const id = req.params.id;
Boards.remove({ _id: id });
JsonRoutes.sendResult(res, {
diff --git a/models/cardComments.js b/models/cardComments.js
index 070c148e..e51275a4 100644
--- a/models/cardComments.js
+++ b/models/cardComments.js
@@ -80,3 +80,65 @@ if (Meteor.isServer) {
}
});
}
+
+//CARD COMMENT REST API
+if (Meteor.isServer) {
+ JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/comments', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramBoardId = req.params.boardId;
+ const paramCardId = req.params.cardId;
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: CardComments.find({ boardId: paramBoardId, cardId: paramCardId}).map(function (doc) {
+ return {
+ _id: doc._id,
+ comment: doc.text,
+ authorId: doc.userId,
+ };
+ }),
+ });
+ });
+
+ JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/comments/:commentId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramBoardId = req.params.boardId;
+ const paramCommentId = req.params.commentId;
+ const paramCardId = req.params.cardId;
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: CardComments.findOne({ _id: paramCommentId, cardId: paramCardId, boardId: paramBoardId }),
+ });
+ });
+
+ JsonRoutes.add('POST', '/api/boards/:boardId/cards/:cardId/comments', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramBoardId = req.params.boardId;
+ const paramCardId = req.params.cardId;
+ const id = CardComments.insert({
+ userId: req.body.authorId,
+ text: req.body.comment,
+ cardId: paramCardId,
+ boardId: paramBoardId,
+ });
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: {
+ _id: id,
+ },
+ });
+ });
+
+ JsonRoutes.add('DELETE', '/api/boards/:boardId/cards/:cardId/comments/:commentId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramBoardId = req.params.boardId;
+ const paramCommentId = req.params.commentId;
+ const paramCardId = req.params.cardId;
+ CardComments.remove({ _id: paramCommentId, cardId: paramCardId, boardId: paramBoardId });
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: {
+ _id: paramCardId,
+ },
+ });
+ });
+}
diff --git a/models/cards.js b/models/cards.js
index 2d585825..bbe46b55 100644
--- a/models/cards.js
+++ b/models/cards.js
@@ -373,6 +373,7 @@ if (Meteor.isServer) {
//LISTS REST API
if (Meteor.isServer) {
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
JsonRoutes.sendResult(res, {
@@ -388,6 +389,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
const paramCardId = req.params.cardId;
@@ -398,6 +400,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
const id = Cards.insert({
@@ -418,6 +421,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
const paramCardId = req.params.cardId;
diff --git a/models/checklists.js b/models/checklists.js
index 3425f230..537aecb0 100644
--- a/models/checklists.js
+++ b/models/checklists.js
@@ -28,22 +28,29 @@ Checklists.attachSchema(new SimpleSchema({
createdAt: {
type: Date,
denyUpdate: false,
+ autoValue() { // eslint-disable-line consistent-return
+ if (this.isInsert) {
+ return new Date();
+ } else {
+ this.unset();
+ }
+ },
},
}));
Checklists.helpers({
- itemCount () {
+ itemCount() {
return this.items.length;
},
- finishedCount () {
+ finishedCount() {
return this.items.filter((item) => {
return item.isFinished;
}).length;
},
- isFinished () {
+ isFinished() {
return 0 !== this.itemCount() && this.itemCount() === this.finishedCount();
},
- getItem (_id) {
+ getItem(_id) {
return _.findWhere(this.items, { _id });
},
itemIndex(itemId) {
@@ -73,17 +80,17 @@ Checklists.before.insert((userId, doc) => {
Checklists.mutations({
//for checklist itself
- setTitle(title){
- return { $set: { title }};
+ setTitle(title) {
+ return { $set: { title } };
},
//for items in checklist
addItem(title) {
const itemCount = this.itemCount();
const _id = `${this._id}${itemCount}`;
- return { $addToSet: {items: {_id, title, isFinished: false}} };
+ return { $addToSet: { items: { _id, title, isFinished: false } } };
},
removeItem(itemId) {
- return {$pull: {items: {_id : itemId}}};
+ return { $pull: { items: { _id: itemId } } };
},
editItem(itemId, title) {
if (this.getItem(itemId)) {
@@ -150,13 +157,13 @@ if (Meteor.isServer) {
//TODO: so there will be no activity for adding item into checklist, maybe will be implemented in the future.
// Checklists.after.update((userId, doc) => {
// console.log('update:', doc)
- // Activities.insert({
- // userId,
- // activityType: 'addChecklist',
- // boardId: doc.boardId,
- // cardId: doc.cardId,
- // checklistId: doc._id,
- // });
+ // Activities.insert({
+ // userId,
+ // activityType: 'addChecklist',
+ // boardId: doc.boardId,
+ // cardId: doc.cardId,
+ // checklistId: doc._id,
+ // });
// });
Checklists.before.remove((userId, doc) => {
@@ -166,3 +173,66 @@ if (Meteor.isServer) {
}
});
}
+
+//CARD COMMENT REST API
+if (Meteor.isServer) {
+ JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/checklists', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramCardId = req.params.cardId;
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: Checklists.find({ cardId: paramCardId }).map(function (doc) {
+ return {
+ _id: doc._id,
+ title: doc.title,
+ };
+ }),
+ });
+ });
+
+ JsonRoutes.add('GET', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramChecklistId = req.params.checklistId;
+ const paramCardId = req.params.cardId;
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: Checklists.findOne({ _id: paramChecklistId, cardId: paramCardId }),
+ });
+ });
+
+ JsonRoutes.add('POST', '/api/boards/:boardId/cards/:cardId/checklists', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramCardId = req.params.cardId;
+
+ const checklistToSend = {};
+ checklistToSend.cardId = paramCardId;
+ checklistToSend.title = req.body.title;
+ checklistToSend.items = [];
+ const id = Checklists.insert(checklistToSend);
+ const checklist = Checklists.findOne({_id: id});
+ req.body.items.forEach(function (item) {
+ checklist.addItem(item);
+ }, this);
+
+
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: {
+ _id: id,
+ },
+ });
+ });
+
+ JsonRoutes.add('DELETE', '/api/boards/:boardId/cards/:cardId/checklists/:checklistId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
+ const paramCommentId = req.params.commentId;
+ const paramCardId = req.params.cardId;
+ Checklists.remove({ _id: paramCommentId, cardId: paramCardId });
+ JsonRoutes.sendResult(res, {
+ code: 200,
+ data: {
+ _id: paramCardId,
+ },
+ });
+ });
+}
diff --git a/models/lists.js b/models/lists.js
index a10e23b6..7dbdc9f2 100644
--- a/models/lists.js
+++ b/models/lists.js
@@ -132,6 +132,7 @@ if (Meteor.isServer) {
//LISTS REST API
if (Meteor.isServer) {
JsonRoutes.add('GET', '/api/boards/:boardId/lists', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
JsonRoutes.sendResult(res, {
code: 200,
@@ -145,6 +146,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
JsonRoutes.sendResult(res, {
@@ -154,6 +156,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('POST', '/api/boards/:boardId/lists', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const id = Lists.insert({
title: req.body.title,
@@ -168,6 +171,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const paramBoardId = req.params.boardId;
const paramListId = req.params.listId;
Lists.remove({ _id: paramListId, boardId: paramBoardId });
diff --git a/models/users.js b/models/users.js
index c1ce146a..aa870dca 100644
--- a/models/users.js
+++ b/models/users.js
@@ -528,6 +528,7 @@ if (Meteor.isServer) {
// USERS REST API
if (Meteor.isServer) {
JsonRoutes.add('GET', '/api/users', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
JsonRoutes.sendResult(res, {
code: 200,
data: Meteor.users.find({}).map(function (doc) {
@@ -536,6 +537,7 @@ if (Meteor.isServer) {
});
});
JsonRoutes.add('GET', '/api/users/:id', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const id = req.params.id;
JsonRoutes.sendResult(res, {
code: 200,
@@ -543,6 +545,7 @@ if (Meteor.isServer) {
});
});
JsonRoutes.add('POST', '/api/users/', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const id = Accounts.createUser({
username: req.body.username,
email: req.body.email,
@@ -558,6 +561,7 @@ if (Meteor.isServer) {
});
JsonRoutes.add('DELETE', '/api/users/:id', function (req, res, next) {
+ Authentication.checkUserId( req.userId);
const id = req.params.id;
Meteor.users.remove({ _id: id });
JsonRoutes.sendResult(res, {
diff --git a/server/authentication.js b/server/authentication.js
new file mode 100644
index 00000000..816c4d4c
--- /dev/null
+++ b/server/authentication.js
@@ -0,0 +1,21 @@
+Meteor.startup(() => {
+ Authentication = {};
+
+ Authentication.checkUserId = function (userId) {
+ if (userId === undefined) {
+ const error = new Meteor.Error('Unauthorized', 'Unauthorized');
+ error.statusCode = 401;
+ throw error;
+ }
+ const admin = Users.findOne({ _id: userId, isAdmin: true });
+
+ if (admin === undefined) {
+ const error = new Meteor.Error('Forbidden', 'Forbidden');
+ error.statusCode = 403;
+ throw error;
+ }
+
+ };
+
+});
+
diff --git a/server/logger.js b/server/logger.js
index 376e30aa..70caa292 100644
--- a/server/logger.js
+++ b/server/logger.js
@@ -3,22 +3,21 @@ Meteor.startup(() => {
require('winston-zulip');
const fs = require('fs');
- //remove default logger
- Winston.remove(Winston.transports.Console);
-
-
const loggerEnable = process.env.LOGGER_ENABLE || false;
- console.log('here1');
- console.log(loggerEnable);
if (loggerEnable) {
- console.log('here2');
+
+ Winston.log('info', 'logger is enable');
const loggers = process.env.LOGGERS.split(',') || 'console';
+ Winston.log('info', `Loggers selected : ${ process.env.LOGGERS }, if empty default is console`);
if (loggers.includes('console')) {
Winston.add(Winston.transports.Console, {
json: true,
timestamp: true,
});
+ } else {
+ //remove default logger
+ Winston.remove(Winston.transports.Console);
}
if (loggers.includes('file')) {
@@ -45,15 +44,23 @@ Meteor.startup(() => {
const loggerZulipTo = process.env.LOGGER_ZULIP_TO || 'logs';
const loggerZulipSubject = process.env.LOGGER_ZULIP_SUBJECT || 'wekan';
- Winston.add(Winston.transports.Zulip, {
+ const zulipConfig = {
zulipUsername: loggerZulipUsername,
zulipApikey: loggerZulipApikey,
zulipRealm: loggerZulipRealm,
zulipTo: loggerZulipTo,
zulipSubject: loggerZulipSubject,
- });
+ };
+
+ Winston.add(Winston.transports.Zulip, zulipConfig);
+
+ Winston.log('info', `zulipconfig ${zulipConfig}`);
}
+ } else {
+ //remove default logger
+ Winston.remove(Winston.transports.Console);
}
+ Winston.log('info', 'Logger is completly instanciate');
});