mirror of
https://github.com/wekan/wekan.git
synced 2025-09-22 01:50:48 +02:00
REST API - Meteor 1.4 - first step issue
This commit is contained in:
parent
a99218e2c7
commit
0319bcf7bb
9 changed files with 361 additions and 137 deletions
|
@ -52,8 +52,8 @@
|
||||||
"prefer-const": 2,
|
"prefer-const": 2,
|
||||||
"prefer-spread": 2,
|
"prefer-spread": 2,
|
||||||
"prefer-template": 2,
|
"prefer-template": 2,
|
||||||
"no-console":"off",
|
"no-console": 0,
|
||||||
"no-unused-vars":"warn"
|
"no-unused-vars" : "warn"
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"Meteor": false,
|
"Meteor": false,
|
||||||
|
@ -125,6 +125,10 @@
|
||||||
"Checklists": true,
|
"Checklists": true,
|
||||||
"Settings": true,
|
"Settings": true,
|
||||||
"InvitationCodes": true,
|
"InvitationCodes": true,
|
||||||
|
<<<<<<< HEAD
|
||||||
"Winston":true
|
"Winston":true
|
||||||
|
=======
|
||||||
|
"JsonRoutes" : true
|
||||||
|
>>>>>>> 3a5150f6eef86816471f7b0134d3d93cf6686413
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
3stack:presence@1.0.5
|
3stack:presence@1.0.5
|
||||||
accounts-base@1.2.15
|
accounts-base@1.2.16
|
||||||
accounts-password@1.3.4
|
accounts-password@1.3.5
|
||||||
aldeed:collection2@2.10.0
|
aldeed:collection2@2.10.0
|
||||||
aldeed:collection2-core@1.2.0
|
aldeed:collection2-core@1.2.0
|
||||||
aldeed:schema-deny@1.1.0
|
aldeed:schema-deny@1.1.0
|
||||||
|
@ -11,7 +11,7 @@ allow-deny@1.0.5
|
||||||
arillo:flow-router-helpers@0.5.2
|
arillo:flow-router-helpers@0.5.2
|
||||||
audit-argument-checks@1.0.7
|
audit-argument-checks@1.0.7
|
||||||
autoupdate@1.3.12
|
autoupdate@1.3.12
|
||||||
babel-compiler@6.14.1
|
babel-compiler@6.18.1
|
||||||
babel-runtime@1.0.1
|
babel-runtime@1.0.1
|
||||||
base64@1.0.10
|
base64@1.0.10
|
||||||
binary-heap@1.0.10
|
binary-heap@1.0.10
|
||||||
|
@ -44,16 +44,16 @@ coffeescript@1.12.3_1
|
||||||
cottz:publish-relations@2.0.7
|
cottz:publish-relations@2.0.7
|
||||||
dburles:collection-helpers@1.1.0
|
dburles:collection-helpers@1.1.0
|
||||||
ddp@1.2.5
|
ddp@1.2.5
|
||||||
ddp-client@1.3.3
|
ddp-client@1.3.4
|
||||||
ddp-common@1.2.8
|
ddp-common@1.2.8
|
||||||
ddp-rate-limiter@1.0.7
|
ddp-rate-limiter@1.0.7
|
||||||
ddp-server@1.3.13
|
ddp-server@1.3.14
|
||||||
deps@1.0.12
|
deps@1.0.12
|
||||||
diff-sequence@1.0.7
|
diff-sequence@1.0.7
|
||||||
ecmascript@0.6.3
|
ecmascript@0.7.2
|
||||||
ecmascript-runtime@0.3.15
|
ecmascript-runtime@0.3.15
|
||||||
ejson@1.0.13
|
ejson@1.0.13
|
||||||
email@1.1.18
|
email@1.2.0
|
||||||
es5-shim@4.6.15
|
es5-shim@4.6.15
|
||||||
fastclick@1.0.13
|
fastclick@1.0.13
|
||||||
fortawesome:fontawesome@4.7.0
|
fortawesome:fontawesome@4.7.0
|
||||||
|
@ -92,8 +92,8 @@ minifier-js@1.2.18
|
||||||
minifiers@1.1.8-faster-rebuild.0
|
minifiers@1.1.8-faster-rebuild.0
|
||||||
minimongo@1.0.21
|
minimongo@1.0.21
|
||||||
mobile-status-bar@1.0.14
|
mobile-status-bar@1.0.14
|
||||||
modules@0.7.9
|
modules@0.8.1
|
||||||
modules-runtime@0.7.9
|
modules-runtime@0.7.10
|
||||||
mongo@1.1.16
|
mongo@1.1.16
|
||||||
mongo-id@1.0.6
|
mongo-id@1.0.6
|
||||||
mongo-livedata@1.0.12
|
mongo-livedata@1.0.12
|
||||||
|
@ -123,7 +123,7 @@ raix:eventemitter@0.1.3
|
||||||
raix:handlebar-helpers@0.2.5
|
raix:handlebar-helpers@0.2.5
|
||||||
rajit:bootstrap3-datepicker@1.6.4
|
rajit:bootstrap3-datepicker@1.6.4
|
||||||
random@1.0.10
|
random@1.0.10
|
||||||
rate-limit@1.0.7
|
rate-limit@1.0.8
|
||||||
reactive-dict@1.1.8
|
reactive-dict@1.1.8
|
||||||
reactive-var@1.0.11
|
reactive-var@1.0.11
|
||||||
reload@1.1.11
|
reload@1.1.11
|
||||||
|
@ -134,7 +134,7 @@ service-configuration@1.0.11
|
||||||
session@1.1.7
|
session@1.1.7
|
||||||
sha@1.0.9
|
sha@1.0.9
|
||||||
shell-server@0.2.3
|
shell-server@0.2.3
|
||||||
simple:json-routes@1.0.4
|
simple:json-routes@2.1.0
|
||||||
softwarerero:accounts-t9n@1.3.9
|
softwarerero:accounts-t9n@1.3.9
|
||||||
spacebars@1.0.15
|
spacebars@1.0.15
|
||||||
spacebars-compiler@1.1.2
|
spacebars-compiler@1.1.2
|
||||||
|
@ -156,6 +156,6 @@ useraccounts:core@1.14.2
|
||||||
useraccounts:flow-routing@1.14.2
|
useraccounts:flow-routing@1.14.2
|
||||||
useraccounts:unstyled@1.14.2
|
useraccounts:unstyled@1.14.2
|
||||||
verron:autosize@3.0.8
|
verron:autosize@3.0.8
|
||||||
webapp@1.3.14
|
webapp@1.3.15
|
||||||
webapp-hashing@1.0.9
|
webapp-hashing@1.0.9
|
||||||
zimme:active-route@2.3.2
|
zimme:active-route@2.3.2
|
||||||
|
|
|
@ -15,17 +15,17 @@ Template.boardMenuPopup.events({
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
Template.boardMenuPopup.helpers({
|
// Template.boardMenuPopup.helpers({
|
||||||
exportUrl() {
|
// exportUrl() {
|
||||||
const boardId = Session.get('currentBoard');
|
// const boardId = Session.get('currentBoard');
|
||||||
const loginToken = Accounts._storedLoginToken();
|
// const loginToken = Accounts._storedLoginToken();
|
||||||
return FlowRouter.url(`api/boards/${boardId}?authToken=${loginToken}`);
|
// return FlowRouter.url(`api/boards/${boardId}?authToken=${loginToken}`);
|
||||||
},
|
// },
|
||||||
exportFilename() {
|
// exportFilename() {
|
||||||
const boardId = Session.get('currentBoard');
|
// const boardId = Session.get('currentBoard');
|
||||||
return `wekan-export-board-${boardId}.json`;
|
// return `wekan-export-board-${boardId}.json`;
|
||||||
},
|
// },
|
||||||
});
|
// });
|
||||||
|
|
||||||
Template.boardChangeTitlePopup.events({
|
Template.boardChangeTitlePopup.events({
|
||||||
submit(evt, tpl) {
|
submit(evt, tpl) {
|
||||||
|
|
101
models/boards.js
101
models/boards.js
|
@ -156,7 +156,7 @@ Boards.helpers({
|
||||||
* Is supplied user authorized to view this board?
|
* Is supplied user authorized to view this board?
|
||||||
*/
|
*/
|
||||||
isVisibleBy(user) {
|
isVisibleBy(user) {
|
||||||
if(this.isPublic()) {
|
if (this.isPublic()) {
|
||||||
// public boards are visible to everyone
|
// public boards are visible to everyone
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
|
@ -172,7 +172,7 @@ Boards.helpers({
|
||||||
* @returns {boolean} the member that matches, or undefined/false
|
* @returns {boolean} the member that matches, or undefined/false
|
||||||
*/
|
*/
|
||||||
isActiveMember(userId) {
|
isActiveMember(userId) {
|
||||||
if(userId) {
|
if (userId) {
|
||||||
return this.members.find((member) => (member.userId === userId && member.isActive));
|
return this.members.find((member) => (member.userId === userId && member.isActive));
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -184,23 +184,23 @@ Boards.helpers({
|
||||||
},
|
},
|
||||||
|
|
||||||
lists() {
|
lists() {
|
||||||
return Lists.find({ boardId: this._id, archived: false }, { sort: { sort: 1 }});
|
return Lists.find({ boardId: this._id, archived: false }, { sort: { sort: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
activities() {
|
activities() {
|
||||||
return Activities.find({ boardId: this._id }, { sort: { createdAt: -1 }});
|
return Activities.find({ boardId: this._id }, { sort: { createdAt: -1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
activeMembers() {
|
activeMembers() {
|
||||||
return _.where(this.members, {isActive: true});
|
return _.where(this.members, { isActive: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
activeAdmins() {
|
activeAdmins() {
|
||||||
return _.where(this.members, {isActive: true, isAdmin: true});
|
return _.where(this.members, { isActive: true, isAdmin: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
memberUsers() {
|
memberUsers() {
|
||||||
return Users.find({ _id: {$in: _.pluck(this.members, 'userId')} });
|
return Users.find({ _id: { $in: _.pluck(this.members, 'userId') } });
|
||||||
},
|
},
|
||||||
|
|
||||||
getLabel(name, color) {
|
getLabel(name, color) {
|
||||||
|
@ -216,15 +216,15 @@ Boards.helpers({
|
||||||
},
|
},
|
||||||
|
|
||||||
hasMember(memberId) {
|
hasMember(memberId) {
|
||||||
return !!_.findWhere(this.members, {userId: memberId, isActive: true});
|
return !!_.findWhere(this.members, { userId: memberId, isActive: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
hasAdmin(memberId) {
|
hasAdmin(memberId) {
|
||||||
return !!_.findWhere(this.members, {userId: memberId, isActive: true, isAdmin: true});
|
return !!_.findWhere(this.members, { userId: memberId, isActive: true, isAdmin: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
hasCommentOnly(memberId) {
|
hasCommentOnly(memberId) {
|
||||||
return !!_.findWhere(this.members, {userId: memberId, isActive: true, isAdmin: false, isCommentOnly: true});
|
return !!_.findWhere(this.members, { userId: memberId, isActive: true, isAdmin: false, isCommentOnly: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
absoluteUrl() {
|
absoluteUrl() {
|
||||||
|
@ -239,34 +239,34 @@ Boards.helpers({
|
||||||
// XXX waiting on https://github.com/mquandalle/meteor-collection-mutations/issues/1 to remove...
|
// XXX waiting on https://github.com/mquandalle/meteor-collection-mutations/issues/1 to remove...
|
||||||
pushLabel(name, color) {
|
pushLabel(name, color) {
|
||||||
const _id = Random.id(6);
|
const _id = Random.id(6);
|
||||||
Boards.direct.update(this._id, { $push: {labels: { _id, name, color }}});
|
Boards.direct.update(this._id, { $push: { labels: { _id, name, color } } });
|
||||||
return _id;
|
return _id;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
Boards.mutations({
|
Boards.mutations({
|
||||||
archive() {
|
archive() {
|
||||||
return { $set: { archived: true }};
|
return { $set: { archived: true } };
|
||||||
},
|
},
|
||||||
|
|
||||||
restore() {
|
restore() {
|
||||||
return { $set: { archived: false }};
|
return { $set: { archived: false } };
|
||||||
},
|
},
|
||||||
|
|
||||||
rename(title) {
|
rename(title) {
|
||||||
return { $set: { title }};
|
return { $set: { title } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setDescription(description) {
|
setDescription(description) {
|
||||||
return { $set: {description} };
|
return { $set: { description } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setColor(color) {
|
setColor(color) {
|
||||||
return { $set: { color }};
|
return { $set: { color } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setVisibility(visibility) {
|
setVisibility(visibility) {
|
||||||
return { $set: { permission: visibility }};
|
return { $set: { permission: visibility } };
|
||||||
},
|
},
|
||||||
|
|
||||||
addLabel(name, color) {
|
addLabel(name, color) {
|
||||||
|
@ -276,7 +276,7 @@ Boards.mutations({
|
||||||
// user).
|
// user).
|
||||||
if (!this.getLabel(name, color)) {
|
if (!this.getLabel(name, color)) {
|
||||||
const _id = Random.id(6);
|
const _id = Random.id(6);
|
||||||
return { $push: {labels: { _id, name, color }}};
|
return { $push: { labels: { _id, name, color } } };
|
||||||
}
|
}
|
||||||
return {};
|
return {};
|
||||||
},
|
},
|
||||||
|
@ -295,7 +295,7 @@ Boards.mutations({
|
||||||
},
|
},
|
||||||
|
|
||||||
removeLabel(labelId) {
|
removeLabel(labelId) {
|
||||||
return { $pull: { labels: { _id: labelId }}};
|
return { $pull: { labels: { _id: labelId } } };
|
||||||
},
|
},
|
||||||
|
|
||||||
addMember(memberId) {
|
addMember(memberId) {
|
||||||
|
@ -386,7 +386,7 @@ if (Meteor.isServer) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If there is more than one admin, it's ok to remove anyone
|
// If there is more than one admin, it's ok to remove anyone
|
||||||
const nbAdmins = _.where(doc.members, {isActive: true, isAdmin: true}).length;
|
const nbAdmins = _.where(doc.members, { isActive: true, isAdmin: true }).length;
|
||||||
if (nbAdmins > 1)
|
if (nbAdmins > 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -408,7 +408,7 @@ if (Meteor.isServer) {
|
||||||
if (board) {
|
if (board) {
|
||||||
const userId = Meteor.userId();
|
const userId = Meteor.userId();
|
||||||
const index = board.memberIndex(userId);
|
const index = board.memberIndex(userId);
|
||||||
if (index>=0) {
|
if (index >= 0) {
|
||||||
board.removeMember(userId);
|
board.removeMember(userId);
|
||||||
return true;
|
return true;
|
||||||
} else throw new Meteor.Error('error-board-notAMember');
|
} else throw new Meteor.Error('error-board-notAMember');
|
||||||
|
@ -424,7 +424,7 @@ if (Meteor.isServer) {
|
||||||
_id: 1,
|
_id: 1,
|
||||||
'members.userId': 1,
|
'members.userId': 1,
|
||||||
}, { unique: true });
|
}, { unique: true });
|
||||||
Boards._collection._ensureIndex({'members.userId': 1});
|
Boards._collection._ensureIndex({ 'members.userId': 1 });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Genesis: the first activity of the newly created board
|
// Genesis: the first activity of the newly created board
|
||||||
|
@ -553,3 +553,60 @@ if (Meteor.isServer) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//BOARDS REST API
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
JsonRoutes.add('GET', '/api/boards', function (req, res, next) {
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Boards.find({ permission: 'public' }).map(function (doc) {
|
||||||
|
return {
|
||||||
|
_id: doc._id,
|
||||||
|
title: doc.title,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('GET', '/api/boards/:id', function (req, res, next) {
|
||||||
|
const id = req.params.id;
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Boards.findOne({ _id: id }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('POST', '/api/boards', function (req, res, next) {
|
||||||
|
const id = Boards.insert({
|
||||||
|
title: req.body.title,
|
||||||
|
members: [
|
||||||
|
{
|
||||||
|
userId: req.body.owner,
|
||||||
|
isAdmin: true,
|
||||||
|
isActive: true,
|
||||||
|
isCommentOnly: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
permission: 'public',
|
||||||
|
color: 'belize',
|
||||||
|
});
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('DELETE', '/api/boards/:id', function (req, res, next) {
|
||||||
|
const id = req.params.id;
|
||||||
|
Boards.remove({ _id: id });
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data:{
|
||||||
|
_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -123,15 +123,15 @@ Cards.helpers({
|
||||||
},
|
},
|
||||||
|
|
||||||
activities() {
|
activities() {
|
||||||
return Activities.find({ cardId: this._id }, { sort: { createdAt: -1 }});
|
return Activities.find({ cardId: this._id }, { sort: { createdAt: -1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
comments() {
|
comments() {
|
||||||
return CardComments.find({ cardId: this._id }, { sort: { createdAt: -1 }});
|
return CardComments.find({ cardId: this._id }, { sort: { createdAt: -1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
attachments() {
|
attachments() {
|
||||||
return Attachments.find({ cardId: this._id }, { sort: { uploadedAt: -1 }});
|
return Attachments.find({ cardId: this._id }, { sort: { uploadedAt: -1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
cover() {
|
cover() {
|
||||||
|
@ -142,7 +142,7 @@ Cards.helpers({
|
||||||
},
|
},
|
||||||
|
|
||||||
checklists() {
|
checklists() {
|
||||||
return Checklists.find({ cardId: this._id }, { sort: { createdAt: 1 }});
|
return Checklists.find({ cardId: this._id }, { sort: { createdAt: 1 } });
|
||||||
},
|
},
|
||||||
|
|
||||||
checklistItemCount() {
|
checklistItemCount() {
|
||||||
|
@ -183,19 +183,19 @@ Cards.helpers({
|
||||||
|
|
||||||
Cards.mutations({
|
Cards.mutations({
|
||||||
archive() {
|
archive() {
|
||||||
return { $set: { archived: true }};
|
return { $set: { archived: true } };
|
||||||
},
|
},
|
||||||
|
|
||||||
restore() {
|
restore() {
|
||||||
return { $set: { archived: false }};
|
return { $set: { archived: false } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setTitle(title) {
|
setTitle(title) {
|
||||||
return { $set: { title }};
|
return { $set: { title } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setDescription(description) {
|
setDescription(description) {
|
||||||
return { $set: { description }};
|
return { $set: { description } };
|
||||||
},
|
},
|
||||||
|
|
||||||
move(listId, sortIndex) {
|
move(listId, sortIndex) {
|
||||||
|
@ -207,11 +207,11 @@ Cards.mutations({
|
||||||
},
|
},
|
||||||
|
|
||||||
addLabel(labelId) {
|
addLabel(labelId) {
|
||||||
return { $addToSet: { labelIds: labelId }};
|
return { $addToSet: { labelIds: labelId } };
|
||||||
},
|
},
|
||||||
|
|
||||||
removeLabel(labelId) {
|
removeLabel(labelId) {
|
||||||
return { $pull: { labelIds: labelId }};
|
return { $pull: { labelIds: labelId } };
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleLabel(labelId) {
|
toggleLabel(labelId) {
|
||||||
|
@ -223,11 +223,11 @@ Cards.mutations({
|
||||||
},
|
},
|
||||||
|
|
||||||
assignMember(memberId) {
|
assignMember(memberId) {
|
||||||
return { $addToSet: { members: memberId }};
|
return { $addToSet: { members: memberId } };
|
||||||
},
|
},
|
||||||
|
|
||||||
unassignMember(memberId) {
|
unassignMember(memberId) {
|
||||||
return { $pull: { members: memberId }};
|
return { $pull: { members: memberId } };
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleMember(memberId) {
|
toggleMember(memberId) {
|
||||||
|
@ -239,27 +239,27 @@ Cards.mutations({
|
||||||
},
|
},
|
||||||
|
|
||||||
setCover(coverId) {
|
setCover(coverId) {
|
||||||
return { $set: { coverId }};
|
return { $set: { coverId } };
|
||||||
},
|
},
|
||||||
|
|
||||||
unsetCover() {
|
unsetCover() {
|
||||||
return { $unset: { coverId: '' }};
|
return { $unset: { coverId: '' } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setStart(startAt) {
|
setStart(startAt) {
|
||||||
return { $set: { startAt }};
|
return { $set: { startAt } };
|
||||||
},
|
},
|
||||||
|
|
||||||
unsetStart() {
|
unsetStart() {
|
||||||
return { $unset: { startAt: '' }};
|
return { $unset: { startAt: '' } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setDue(dueAt) {
|
setDue(dueAt) {
|
||||||
return { $set: { dueAt }};
|
return { $set: { dueAt } };
|
||||||
},
|
},
|
||||||
|
|
||||||
unsetDue() {
|
unsetDue() {
|
||||||
return { $unset: { dueAt: '' }};
|
return { $unset: { dueAt: '' } };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -304,7 +304,7 @@ if (Meteor.isServer) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// New activity for card moves
|
// New activity for card moves
|
||||||
Cards.after.update(function(userId, doc, fieldNames) {
|
Cards.after.update(function (userId, doc, fieldNames) {
|
||||||
const oldListId = this.previous.listId;
|
const oldListId = this.previous.listId;
|
||||||
if (_.contains(fieldNames, 'listId') && doc.listId !== oldListId) {
|
if (_.contains(fieldNames, 'listId') && doc.listId !== oldListId) {
|
||||||
Activities.insert({
|
Activities.insert({
|
||||||
|
@ -370,3 +370,63 @@ if (Meteor.isServer) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
//LISTS REST API
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
const paramListId = req.params.listId;
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Cards.find({ boardId: paramBoardId, listId: paramListId, archived: false }).map(function (doc) {
|
||||||
|
return {
|
||||||
|
_id: doc._id,
|
||||||
|
title: doc.title,
|
||||||
|
description: doc.description,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
const paramListId = req.params.listId;
|
||||||
|
const paramCardId = req.params.cardId;
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Cards.findOne({ _id: paramCardId, listId: paramListId, boardId: paramBoardId, archived: false }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('POST', '/api/boards/:boardId/lists/:listId/cards', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
const paramListId = req.params.listId;
|
||||||
|
const id = Cards.insert({
|
||||||
|
title: req.body.title,
|
||||||
|
boardId: paramBoardId,
|
||||||
|
listId: paramListId,
|
||||||
|
description: req.body.description,
|
||||||
|
userId : req.body.authorId,
|
||||||
|
sort: 0,
|
||||||
|
members:[ req.body.authorId ],
|
||||||
|
});
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId/cards/:cardId', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
const paramListId = req.params.listId;
|
||||||
|
const paramCardId = req.params.cardId;
|
||||||
|
Cards.remove({ _id: paramCardId, listId: paramListId, boardId: paramBoardId });
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
_id: paramCardId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* global JsonRoutes */
|
/* global JsonRoutes */
|
||||||
if(Meteor.isServer) {
|
if (Meteor.isServer) {
|
||||||
// todo XXX once we have a real API in place, move that route there
|
// todo XXX once we have a real API in place, move that route there
|
||||||
// todo XXX also share the route definition between the client and the server
|
// todo XXX also share the route definition between the client and the server
|
||||||
// so that we could use something like
|
// so that we could use something like
|
||||||
|
@ -14,28 +14,28 @@ if(Meteor.isServer) {
|
||||||
* See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/
|
* See https://blog.kayla.com.au/server-side-route-authentication-in-meteor/
|
||||||
* for detailed explanations
|
* for detailed explanations
|
||||||
*/
|
*/
|
||||||
JsonRoutes.add('get', '/api/boards/:boardId', function (req, res) {
|
// JsonRoutes.add('get', '/api/boards/:boardId', function (req, res) {
|
||||||
const boardId = req.params.boardId;
|
// const boardId = req.params.boardId;
|
||||||
let user = null;
|
// let user = null;
|
||||||
// todo XXX for real API, first look for token in Authentication: header
|
// // todo XXX for real API, first look for token in Authentication: header
|
||||||
// then fallback to parameter
|
// // then fallback to parameter
|
||||||
const loginToken = req.query.authToken;
|
// const loginToken = req.query.authToken;
|
||||||
if (loginToken) {
|
// if (loginToken) {
|
||||||
const hashToken = Accounts._hashLoginToken(loginToken);
|
// const hashToken = Accounts._hashLoginToken(loginToken);
|
||||||
user = Meteor.users.findOne({
|
// user = Meteor.users.findOne({
|
||||||
'services.resume.loginTokens.hashedToken': hashToken,
|
// 'services.resume.loginTokens.hashedToken': hashToken,
|
||||||
});
|
// });
|
||||||
}
|
// }
|
||||||
|
|
||||||
const exporter = new Exporter(boardId);
|
// const exporter = new Exporter(boardId);
|
||||||
if(exporter.canExport(user)) {
|
// if(exporter.canExport(user)) {
|
||||||
JsonRoutes.sendResult(res, 200, exporter.build());
|
// JsonRoutes.sendResult(res, 200, exporter.build());
|
||||||
} else {
|
// } else {
|
||||||
// we could send an explicit error message, but on the other hand the only
|
// // 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.
|
// // way to get there is by hacking the UI so let's keep it raw.
|
||||||
JsonRoutes.sendResult(res, 403);
|
// JsonRoutes.sendResult(res, 403);
|
||||||
}
|
// }
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
class Exporter {
|
class Exporter {
|
||||||
|
@ -44,13 +44,13 @@ class Exporter {
|
||||||
}
|
}
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
const byBoard = {boardId: this._boardId};
|
const byBoard = { boardId: this._boardId };
|
||||||
// we do not want to retrieve boardId in related elements
|
// we do not want to retrieve boardId in related elements
|
||||||
const noBoardId = {fields: {boardId: 0}};
|
const noBoardId = { fields: { boardId: 0 } };
|
||||||
const result = {
|
const result = {
|
||||||
_format: 'wekan-board-1.0.0',
|
_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.lists = Lists.find(byBoard, noBoardId).fetch();
|
||||||
result.cards = Cards.find(byBoard, noBoardId).fetch();
|
result.cards = Cards.find(byBoard, noBoardId).fetch();
|
||||||
result.comments = CardComments.find(byBoard, noBoardId).fetch();
|
result.comments = CardComments.find(byBoard, noBoardId).fetch();
|
||||||
|
@ -69,29 +69,31 @@ class Exporter {
|
||||||
// 1- only exports users that are linked somehow to that board
|
// 1- only exports users that are linked somehow to that board
|
||||||
// 2- do not export any sensitive information
|
// 2- do not export any sensitive information
|
||||||
const users = {};
|
const users = {};
|
||||||
result.members.forEach((member) => {users[member.userId] = true;});
|
result.members.forEach((member) => { users[member.userId] = true; });
|
||||||
result.lists.forEach((list) => {users[list.userId] = true;});
|
result.lists.forEach((list) => { users[list.userId] = true; });
|
||||||
result.cards.forEach((card) => {
|
result.cards.forEach((card) => {
|
||||||
users[card.userId] = true;
|
users[card.userId] = true;
|
||||||
if (card.members) {
|
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.comments.forEach((comment) => { users[comment.userId] = true; });
|
||||||
result.activities.forEach((activity) => {users[activity.userId] = true;});
|
result.activities.forEach((activity) => { users[activity.userId] = true; });
|
||||||
const byUserIds = {_id: {$in: Object.getOwnPropertyNames(users)}};
|
const byUserIds = { _id: { $in: Object.getOwnPropertyNames(users) } };
|
||||||
// we use whitelist to be sure we do not expose inadvertently
|
// we use whitelist to be sure we do not expose inadvertently
|
||||||
// some secret fields that gets added to User later.
|
// some secret fields that gets added to User later.
|
||||||
const userFields = {fields: {
|
const userFields = {
|
||||||
_id: 1,
|
fields: {
|
||||||
username: 1,
|
_id: 1,
|
||||||
'profile.fullname': 1,
|
username: 1,
|
||||||
'profile.initials': 1,
|
'profile.fullname': 1,
|
||||||
'profile.avatarUrl': 1,
|
'profile.initials': 1,
|
||||||
}};
|
'profile.avatarUrl': 1,
|
||||||
|
},
|
||||||
|
};
|
||||||
result.users = Users.find(byUserIds, userFields).fetch().map((user) => {
|
result.users = Users.find(byUserIds, userFields).fetch().map((user) => {
|
||||||
// user avatar is stored as a relative url, we export absolute
|
// user avatar is stored as a relative url, we export absolute
|
||||||
if(user.profile.avatarUrl) {
|
if (user.profile.avatarUrl) {
|
||||||
user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
|
user.profile.avatarUrl = FlowRouter.url(user.profile.avatarUrl);
|
||||||
}
|
}
|
||||||
return user;
|
return user;
|
||||||
|
|
|
@ -76,15 +76,15 @@ Lists.helpers({
|
||||||
|
|
||||||
Lists.mutations({
|
Lists.mutations({
|
||||||
rename(title) {
|
rename(title) {
|
||||||
return { $set: { title }};
|
return { $set: { title } };
|
||||||
},
|
},
|
||||||
|
|
||||||
archive() {
|
archive() {
|
||||||
return { $set: { archived: true }};
|
return { $set: { archived: true } };
|
||||||
},
|
},
|
||||||
|
|
||||||
restore() {
|
restore() {
|
||||||
return { $set: { archived: false }};
|
return { $set: { archived: false } };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -128,3 +128,55 @@ if (Meteor.isServer) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//LISTS REST API
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
JsonRoutes.add('GET', '/api/boards/:boardId/lists', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Lists.find({ boardId: paramBoardId, archived: false }).map(function (doc) {
|
||||||
|
return {
|
||||||
|
_id: doc._id,
|
||||||
|
title: doc.title,
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('GET', '/api/boards/:boardId/lists/:listId', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
const paramListId = req.params.listId;
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Lists.findOne({ _id: paramListId, boardId: paramBoardId, archived: false }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('POST', '/api/boards/:boardId/lists', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
const id = Lists.insert({
|
||||||
|
title: req.body.title,
|
||||||
|
boardId: paramBoardId,
|
||||||
|
});
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('DELETE', '/api/boards/:boardId/lists/:listId', function (req, res, next) {
|
||||||
|
const paramBoardId = req.params.boardId;
|
||||||
|
const paramListId = req.params.listId;
|
||||||
|
Lists.remove({ _id: paramListId, boardId: paramBoardId });
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
_id: paramListId,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
104
models/users.js
104
models/users.js
|
@ -1,7 +1,7 @@
|
||||||
// Sandstorm context is detected using the METEOR_SETTINGS environment variable
|
// Sandstorm context is detected using the METEOR_SETTINGS environment variable
|
||||||
// in the package definition.
|
// in the package definition.
|
||||||
const isSandstorm = Meteor.settings && Meteor.settings.public &&
|
const isSandstorm = Meteor.settings && Meteor.settings.public &&
|
||||||
Meteor.settings.public.sandstorm;
|
Meteor.settings.public.sandstorm;
|
||||||
Users = Meteor.users;
|
Users = Meteor.users;
|
||||||
|
|
||||||
Users.attachSchema(new SimpleSchema({
|
Users.attachSchema(new SimpleSchema({
|
||||||
|
@ -148,32 +148,32 @@ Users.helpers({
|
||||||
},
|
},
|
||||||
|
|
||||||
starredBoards() {
|
starredBoards() {
|
||||||
const {starredBoards = []} = this.profile;
|
const { starredBoards = [] } = this.profile;
|
||||||
return Boards.find({archived: false, _id: {$in: starredBoards}});
|
return Boards.find({ archived: false, _id: { $in: starredBoards } });
|
||||||
},
|
},
|
||||||
|
|
||||||
hasStarred(boardId) {
|
hasStarred(boardId) {
|
||||||
const {starredBoards = []} = this.profile;
|
const { starredBoards = [] } = this.profile;
|
||||||
return _.contains(starredBoards, boardId);
|
return _.contains(starredBoards, boardId);
|
||||||
},
|
},
|
||||||
|
|
||||||
invitedBoards() {
|
invitedBoards() {
|
||||||
const {invitedBoards = []} = this.profile;
|
const { invitedBoards = [] } = this.profile;
|
||||||
return Boards.find({archived: false, _id: {$in: invitedBoards}});
|
return Boards.find({ archived: false, _id: { $in: invitedBoards } });
|
||||||
},
|
},
|
||||||
|
|
||||||
isInvitedTo(boardId) {
|
isInvitedTo(boardId) {
|
||||||
const {invitedBoards = []} = this.profile;
|
const { invitedBoards = [] } = this.profile;
|
||||||
return _.contains(invitedBoards, boardId);
|
return _.contains(invitedBoards, boardId);
|
||||||
},
|
},
|
||||||
|
|
||||||
hasTag(tag) {
|
hasTag(tag) {
|
||||||
const {tags = []} = this.profile;
|
const { tags = [] } = this.profile;
|
||||||
return _.contains(tags, tag);
|
return _.contains(tags, tag);
|
||||||
},
|
},
|
||||||
|
|
||||||
hasNotification(activityId) {
|
hasNotification(activityId) {
|
||||||
const {notifications = []} = this.profile;
|
const { notifications = [] } = this.profile;
|
||||||
return _.contains(notifications, activityId);
|
return _.contains(notifications, activityId);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ Users.helpers({
|
||||||
},
|
},
|
||||||
|
|
||||||
getEmailBuffer() {
|
getEmailBuffer() {
|
||||||
const {emailBuffer = []} = this.profile;
|
const { emailBuffer = [] } = this.profile;
|
||||||
return emailBuffer;
|
return emailBuffer;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ Users.mutations({
|
||||||
},
|
},
|
||||||
|
|
||||||
setAvatarUrl(avatarUrl) {
|
setAvatarUrl(avatarUrl) {
|
||||||
return { $set: { 'profile.avatarUrl': avatarUrl }};
|
return { $set: { 'profile.avatarUrl': avatarUrl } };
|
||||||
},
|
},
|
||||||
|
|
||||||
setShowCardsCountAt(limit) {
|
setShowCardsCountAt(limit) {
|
||||||
|
@ -323,7 +323,7 @@ Meteor.methods({
|
||||||
if (nUsersWithUsername > 0) {
|
if (nUsersWithUsername > 0) {
|
||||||
throw new Meteor.Error('username-already-taken');
|
throw new Meteor.Error('username-already-taken');
|
||||||
} else {
|
} else {
|
||||||
Users.update(this.userId, {$set: { username }});
|
Users.update(this.userId, { $set: { username } });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleSystemMessages() {
|
toggleSystemMessages() {
|
||||||
|
@ -346,19 +346,19 @@ if (Meteor.isServer) {
|
||||||
const inviter = Meteor.user();
|
const inviter = Meteor.user();
|
||||||
const board = Boards.findOne(boardId);
|
const board = Boards.findOne(boardId);
|
||||||
const allowInvite = inviter &&
|
const allowInvite = inviter &&
|
||||||
board &&
|
board &&
|
||||||
board.members &&
|
board.members &&
|
||||||
_.contains(_.pluck(board.members, 'userId'), inviter._id) &&
|
_.contains(_.pluck(board.members, 'userId'), inviter._id) &&
|
||||||
_.where(board.members, {userId: inviter._id})[0].isActive &&
|
_.where(board.members, { userId: inviter._id })[0].isActive &&
|
||||||
_.where(board.members, {userId: inviter._id})[0].isAdmin;
|
_.where(board.members, { userId: inviter._id })[0].isAdmin;
|
||||||
if (!allowInvite) throw new Meteor.Error('error-board-notAMember');
|
if (!allowInvite) throw new Meteor.Error('error-board-notAMember');
|
||||||
|
|
||||||
this.unblock();
|
this.unblock();
|
||||||
|
|
||||||
const posAt = username.indexOf('@');
|
const posAt = username.indexOf('@');
|
||||||
let user = null;
|
let user = null;
|
||||||
if (posAt>=0) {
|
if (posAt >= 0) {
|
||||||
user = Users.findOne({emails: {$elemMatch: {address: username}}});
|
user = Users.findOne({ emails: { $elemMatch: { address: username } } });
|
||||||
} else {
|
} else {
|
||||||
user = Users.findOne(username) || Users.findOne({ username });
|
user = Users.findOne(username) || Users.findOne({ username });
|
||||||
}
|
}
|
||||||
|
@ -409,7 +409,7 @@ if (Meteor.isServer) {
|
||||||
});
|
});
|
||||||
Accounts.onCreateUser((options, user) => {
|
Accounts.onCreateUser((options, user) => {
|
||||||
const userCount = Users.find().count();
|
const userCount = Users.find().count();
|
||||||
if (!isSandstorm && userCount === 0 ){
|
if (!isSandstorm && userCount === 0) {
|
||||||
user.isAdmin = true;
|
user.isAdmin = true;
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
@ -421,11 +421,11 @@ if (Meteor.isServer) {
|
||||||
if (!options || !options.profile) {
|
if (!options || !options.profile) {
|
||||||
throw new Meteor.Error('error-invitation-code-blank', 'The invitation code is required');
|
throw new Meteor.Error('error-invitation-code-blank', 'The invitation code is required');
|
||||||
}
|
}
|
||||||
const invitationCode = InvitationCodes.findOne({code: options.profile.invitationcode, email: options.email, valid: true});
|
const invitationCode = InvitationCodes.findOne({ code: options.profile.invitationcode, email: options.email, valid: true });
|
||||||
if (!invitationCode) {
|
if (!invitationCode) {
|
||||||
throw new Meteor.Error('error-invitation-code-not-exist', 'The invitation code doesn\'t exist');
|
throw new Meteor.Error('error-invitation-code-not-exist', 'The invitation code doesn\'t exist');
|
||||||
}else{
|
} else {
|
||||||
user.profile = {icode: options.profile.invitationcode};
|
user.profile = { icode: options.profile.invitationcode };
|
||||||
}
|
}
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
@ -445,7 +445,7 @@ if (Meteor.isServer) {
|
||||||
// counter.
|
// counter.
|
||||||
// We need to run this code on the server only, otherwise the incrementation
|
// We need to run this code on the server only, otherwise the incrementation
|
||||||
// will be done twice.
|
// will be done twice.
|
||||||
Users.after.update(function(userId, user, fieldNames) {
|
Users.after.update(function (userId, user, fieldNames) {
|
||||||
// The `starredBoards` list is hosted on the `profile` field. If this
|
// The `starredBoards` list is hosted on the `profile` field. If this
|
||||||
// field hasn't been modificated we don't need to run this hook.
|
// field hasn't been modificated we don't need to run this hook.
|
||||||
if (!_.contains(fieldNames, 'profile'))
|
if (!_.contains(fieldNames, 'profile'))
|
||||||
|
@ -464,7 +464,7 @@ if (Meteor.isServer) {
|
||||||
// direction and then in the other.
|
// direction and then in the other.
|
||||||
function incrementBoards(boardsIds, inc) {
|
function incrementBoards(boardsIds, inc) {
|
||||||
boardsIds.forEach((boardId) => {
|
boardsIds.forEach((boardId) => {
|
||||||
Boards.update(boardId, {$inc: {stars: inc}});
|
Boards.update(boardId, { $inc: { stars: inc } });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
incrementBoards(_.difference(oldIds, newIds), -1);
|
incrementBoards(_.difference(oldIds, newIds), -1);
|
||||||
|
@ -505,10 +505,10 @@ if (Meteor.isServer) {
|
||||||
//invite user to corresponding boards
|
//invite user to corresponding boards
|
||||||
const disableRegistration = Settings.findOne().disableRegistration;
|
const disableRegistration = Settings.findOne().disableRegistration;
|
||||||
if (disableRegistration) {
|
if (disableRegistration) {
|
||||||
const invitationCode = InvitationCodes.findOne({code: doc.profile.icode, valid:true});
|
const invitationCode = InvitationCodes.findOne({ code: doc.profile.icode, valid: true });
|
||||||
if (!invitationCode) {
|
if (!invitationCode) {
|
||||||
throw new Meteor.Error('error-invitation-code-not-exist');
|
throw new Meteor.Error('error-invitation-code-not-exist');
|
||||||
}else{
|
} else {
|
||||||
invitationCode.boardsToBeInvited.forEach((boardId) => {
|
invitationCode.boardsToBeInvited.forEach((boardId) => {
|
||||||
const board = Boards.findOne(boardId);
|
const board = Boards.findOne(boardId);
|
||||||
board.addMember(doc._id);
|
board.addMember(doc._id);
|
||||||
|
@ -517,9 +517,55 @@ if (Meteor.isServer) {
|
||||||
doc.profile = {};
|
doc.profile = {};
|
||||||
}
|
}
|
||||||
doc.profile.invitedBoards = invitationCode.boardsToBeInvited;
|
doc.profile.invitedBoards = invitationCode.boardsToBeInvited;
|
||||||
Users.update(doc._id, {$set:{profile: doc.profile}});
|
Users.update(doc._id, { $set: { profile: doc.profile } });
|
||||||
InvitationCodes.update(invitationCode._id, {$set: {valid:false}});
|
InvitationCodes.update(invitationCode._id, { $set: { valid: false } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// USERS REST API
|
||||||
|
if (Meteor.isServer) {
|
||||||
|
JsonRoutes.add('GET', '/api/users', function (req, res, next) {
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Meteor.users.find({}).map(function (doc) {
|
||||||
|
return { _id: doc._id, username: doc.username };
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
JsonRoutes.add('GET', '/api/users/:id', function (req, res, next) {
|
||||||
|
const id = req.params.id;
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: Meteor.users.findOne({ _id: id }),
|
||||||
|
});
|
||||||
|
});
|
||||||
|
JsonRoutes.add('POST', '/api/users/', function (req, res, next) {
|
||||||
|
const id = Accounts.createUser({
|
||||||
|
username: req.body.username,
|
||||||
|
email: req.body.email,
|
||||||
|
password: 'default',
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
JsonRoutes.add('DELETE', '/api/users/:id', function (req, res, next) {
|
||||||
|
const id = req.params.id;
|
||||||
|
Meteor.users.remove({ _id: id });
|
||||||
|
JsonRoutes.sendResult(res, {
|
||||||
|
code: 200,
|
||||||
|
data: {
|
||||||
|
_id: id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
"lint": "eslint --ignore-pattern 'packages/*' .",
|
"lint": "eslint --ignore-pattern 'packages/*' .",
|
||||||
"test": "npm run --silent lint"
|
"test": "npm run --silent lint"
|
||||||
},
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"extends": "@meteorjs/eslint-config-meteor"
|
||||||
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/wekan/wekan.git"
|
"url": "git+https://github.com/wekan/wekan.git"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue