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 367
/
methods.js
131 lines (109 loc) · 3.44 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
129
130
131
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { Meteor } from 'meteor/meteor';
import { _ } from 'meteor/underscore';
import { SimpleSchema } from 'meteor/aldeed:simple-schema';
import { DDPRateLimiter } from 'meteor/ddp-rate-limiter';
import { Lists } from './lists.js';
const LIST_ID_ONLY = new SimpleSchema({
listId: { type: String }
}).validator();
export const insert = new ValidatedMethod({
name: 'Lists.methods.insert',
validate: new SimpleSchema({}).validator(),
run() {
return Lists.insert({});
}
});
export const makePrivate = new ValidatedMethod({
name: 'Lists.methods.makePrivate',
validate: 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 }
});
}
});
export const makePublic = new ValidatedMethod({
name: 'Lists.methods.makePublic',
validate: 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
Lists.update(listId, {
$unset: { userId: true }
});
}
});
export const updateName = new ValidatedMethod({
name: 'Lists.methods.updateName',
validate: new SimpleSchema({
listId: { type: String },
newName: { type: String }
}).validator(),
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 }
});
}
});
export const remove = new ValidatedMethod({
name: 'Lists.methods.remove',
validate: 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()) {
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([
insert,
makePublic,
makePrivate,
updateName,
remove
], 'name');
if (Meteor.isServer) {
// 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);
}