Merge branch 'feature-rules' of https://github.com/Angtrim/wekan into Angtrim-feature-rules

This commit is contained in:
Lauri Ojansivu 2018-09-16 00:10:40 +03:00
commit 6673b79738
60 changed files with 3074 additions and 259 deletions

View file

@ -14,7 +14,7 @@ if (Meteor.isServer) {
* See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/
* for detailed explanations
*/
JsonRoutes.add('get', '/api/boards/:boardId/export', function (req, res) {
JsonRoutes.add('get', '/api/boards/:boardId/export', function(req, res) {
const boardId = req.params.boardId;
let user = null;
// todo XXX for real API, first look for token in Authentication: header
@ -28,8 +28,11 @@ if (Meteor.isServer) {
}
const exporter = new Exporter(boardId);
if(exporter.canExport(user)) {
JsonRoutes.sendResult(res, { code: 200, data: exporter.build() });
if (exporter.canExport(user)) {
JsonRoutes.sendResult(res, {
code: 200,
data: exporter.build()
});
} else {
// we could send an explicit error message, but on the other hand the only
// way to get there is by hacking the UI so let's keep it raw.
@ -47,24 +50,49 @@ class Exporter {
const byBoard = { boardId: this._boardId };
const byBoardNoLinked = { boardId: this._boardId, linkedId: '' };
// we do not want to retrieve boardId in related elements
const noBoardId = { fields: { boardId: 0 } };
const noBoardId = {
fields: {
boardId: 0
}
};
const result = {
_format: 'wekan-board-1.0.0',
};
_.extend(result, Boards.findOne(this._boardId, { fields: { stars: 0 } }));
_.extend(result, Boards.findOne(this._boardId, {
fields: {
stars: 0
}
}));
result.lists = Lists.find(byBoard, noBoardId).fetch();
result.cards = Cards.find(byBoardNoLinked, noBoardId).fetch();
result.swimlanes = Swimlanes.find(byBoard, noBoardId).fetch();
result.customFields = CustomFields.find(byBoard, noBoardId).fetch();
result.comments = CardComments.find(byBoard, noBoardId).fetch();
result.activities = Activities.find(byBoard, noBoardId).fetch();
result.rules = Rules.find(byBoard, noBoardId).fetch();
result.checklists = [];
result.checklistItems = [];
result.subtaskItems = [];
result.triggers = [];
result.actions = [];
result.cards.forEach((card) => {
result.checklists.push(...Checklists.find({ cardId: card._id }).fetch());
result.checklistItems.push(...ChecklistItems.find({ cardId: card._id }).fetch());
result.subtaskItems.push(...Cards.find({ parentid: card._id }).fetch());
result.checklists.push(...Checklists.find({
cardId: card._id
}).fetch());
result.checklistItems.push(...ChecklistItems.find({
cardId: card._id
}).fetch());
result.subtaskItems.push(...Cards.find({
parentid: card._id
}).fetch());
});
result.rules.forEach((rule) => {
result.triggers.push(...Triggers.find({
_id: rule.triggerId
}, noBoardId).fetch());
result.actions.push(...Actions.find({
_id: rule.actionId
}, noBoardId).fetch());
});
// [Old] for attachments we only export IDs and absolute url to original doc
@ -101,18 +129,34 @@ class Exporter {
// 1- only exports users that are linked somehow to that board
// 2- do not export any sensitive information
const users = {};
result.members.forEach((member) => { users[member.userId] = true; });
result.lists.forEach((list) => { users[list.userId] = true; });
result.members.forEach((member) => {
users[member.userId] = true;
});
result.lists.forEach((list) => {
users[list.userId] = true;
});
result.cards.forEach((card) => {
users[card.userId] = true;
if (card.members) {
card.members.forEach((memberId) => { users[memberId] = true; });
card.members.forEach((memberId) => {
users[memberId] = true;
});
}
});
result.comments.forEach((comment) => { users[comment.userId] = true; });
result.activities.forEach((activity) => { users[activity.userId] = true; });
result.checklists.forEach((checklist) => { users[checklist.userId] = true; });
const byUserIds = { _id: { $in: Object.getOwnPropertyNames(users) } };
result.comments.forEach((comment) => {
users[comment.userId] = true;
});
result.activities.forEach((activity) => {
users[activity.userId] = true;
});
result.checklists.forEach((checklist) => {
users[checklist.userId] = true;
});
const byUserIds = {
_id: {
$in: Object.getOwnPropertyNames(users)
}
};
// we use whitelist to be sure we do not expose inadvertently
// some secret fields that gets added to User later.
const userFields = {