summaryrefslogtreecommitdiffstats
path: root/models
diff options
context:
space:
mode:
Diffstat (limited to 'models')
-rw-r--r--models/boards.js27
-rw-r--r--models/export.js59
2 files changed, 86 insertions, 0 deletions
diff --git a/models/boards.js b/models/boards.js
index 9c792674..cdf83ce0 100644
--- a/models/boards.js
+++ b/models/boards.js
@@ -79,6 +79,33 @@ Boards.attachSchema(new SimpleSchema({
Boards.helpers({
+ /**
+ * Is current logged-in user authorized to view this board?
+ */
+ isVisibleByUser() {
+ if(this.isPublic()) {
+ // public boards are visible to everyone
+ return true;
+ } else {
+ // otherwise you have to be logged-in and active member
+ return this.isActiveMember(Meteor.userId());
+ }
+ },
+
+ /**
+ * Is the user one of the active members of the board?
+ *
+ * @param userId
+ * @returns {boolean} the member that matches, or undefined/false
+ */
+ isActiveMember(userId) {
+ if(userId) {
+ return this.members.find((member) => (member.userId === userId && member.isActive));
+ } else {
+ return false;
+ }
+ },
+
isPublic() {
return this.permission === 'public';
},
diff --git a/models/export.js b/models/export.js
new file mode 100644
index 00000000..20b1186a
--- /dev/null
+++ b/models/export.js
@@ -0,0 +1,59 @@
+
+
+Meteor.methods({
+ exportBoard(boardId) {
+ check(boardId, String);
+ const board = Boards.findOne(boardId);
+ if(board.isVisibleByUser()) {
+ const exporter = new Exporter(boardId);
+ return exporter.build();
+ } else {
+ throw new Meteor.Error('error-board-notAMember');
+ }
+ }
+});
+
+class Exporter {
+ constructor(boardId) {
+ this._boardId = boardId;
+ }
+
+ build() {
+ const byBoard = {boardId: this._boardId};
+ const fields = {fields: {boardId: 0}};
+ const result = Boards.findOne(this._boardId);
+ result.lists = Lists.find(byBoard, fields).fetch();
+ result.cards = Cards.find(byBoard, fields).fetch();
+ result.comments = CardComments.find(byBoard, fields).fetch();
+ result.activities = Activities.find(byBoard, fields).fetch();
+
+ // we also have to export some user data - as the other elements only include id
+ // but we have to be careful:
+ // 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.cards.forEach((card) => {
+ users[card.userId] = true;
+ if (card.members) {
+ card.members.forEach((memberId) => {users[memberId] = true;});
+ }
+ });
+ result.comments.forEach((comment) => {users[comment.userId] = true;});
+ result.activities.forEach((activity) => {users[activity.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 = {fields: {
+ _id: 1,
+ username: 1,
+ 'profile.fullname': 1,
+ 'profile.initials': 1,
+ 'profile.avatarUrl': 1,
+ }};
+ result.users = Users.find(byUserIds, userFields).fetch();
+ //return JSON.stringify(result);
+ return result;
+ }
+}