This repository has been archived by the owner on Feb 26, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 364
/
Copy pathmethods.js
128 lines (103 loc) · 3.29 KB
/
methods.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* global Lists SimpleSchema Method Todos */
Lists.methods = {};
const LIST_ID_ONLY = new SimpleSchema({
listId: { type: String }
});
Lists.methods.insert = new Method({
name: 'Lists.methods.insert',
schema: new SimpleSchema({}),
run() {
return Lists.insert({});
}
});
Lists.methods.makePrivate = new Method({
name: 'Lists.methods.makePrivate',
schema: LIST_ID_ONLY,
run({ listId }) {
if (!this.userId) {
throw new Meteor.Error('Lists.methods.makePrivate.notLoggedIn',
'Must be logged in to make private lists.');
}
const list = Lists.findOne(listId);
if (list.isLastPublicList()) {
throw new Meteor.Error('Lists.methods.makePrivate.lastPublicList',
'Cannot make the last public list private.');
}
Lists.update(listId, {
$set: { userId: this.userId }
});
Lists.userIdDenormalizer.set(listId, this.userId);
}
});
Lists.methods.makePublic = new Method({
name: 'Lists.methods.makePublic',
schema: LIST_ID_ONLY,
run({ listId }) {
if (!this.userId) {
throw new Meteor.Error('Lists.methods.makePublic.notLoggedIn',
'Must be logged in.');
}
const list = Lists.findOne(listId);
if (!list.editableBy(this.userId)) {
throw new Meteor.Error('Lists.methods.makePublic.accessDenied',
'You don\'t have permission to edit this list.');
}
// XXX the security check above is not atomic, so in theory a race condition could
// result in exposing private data
const numUpdated = Lists.update(listId, {
$unset: { userId: true }
});
if (numUpdated) {
// Only denormalize if the list was actually updated
Lists.userIdDenormalizer.unset(listId);
}
}
});
Lists.methods.updateName = new Method({
name: 'Lists.methods.updateName',
schema: new SimpleSchema({
listId: { type: String },
newName: { type: String }
}),
run({ listId, newName }) {
const list = Lists.findOne(listId);
if (!list.editableBy(this.userId)) {
throw new Meteor.Error('Lists.methods.updateName.accessDenied',
'You don\'t have permission to edit this list.');
}
// XXX the security check above is not atomic, so in theory a race condition could
// result in exposing private data
Lists.update(listId, {
$set: { name: newName }
});
}
});
Lists.methods.remove = new Method({
name: 'Lists.methods.remove',
schema: LIST_ID_ONLY,
run({ listId }) {
const list = Lists.findOne(listId);
if (!list.editableBy(this.userId)) {
throw new Meteor.Error('Lists.methods.remove.accessDenied',
'You don\'t have permission to remove this list.');
}
// XXX the security check above is not atomic, so in theory a race condition could
// result in exposing private data
if (list.isLastPublicList()) {
// XXX what's our error i18n strategy here?
throw new Meteor.Error('Lists.methods.remove.lastPublicList',
'Cannot delete the last public list.');
}
Lists.remove(listId);
}
});
// Get list of all method names on Lists
const LISTS_METHODS = _.pluck(Lists.methods, 'name');
// Only allow 5 list operations per connection per second
DDPRateLimiter.addRule({
name(name) {
return _.contains(LISTS_METHODS, name);
},
// Rate limit per connection ID
connectionId() { return true; }
}, 5, 1000);