Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
74c6a423ee | ||
|
|
41c90bb69f | ||
|
|
68432541db | ||
|
|
c417c45db1 | ||
|
|
3f3caf63e4 | ||
|
|
49c5a1fcb1 | ||
|
|
9fb37148fa | ||
|
|
a67d7fb4ea | ||
|
|
8e0f19742b | ||
|
|
216e502c8a | ||
|
|
1a18d1f816 | ||
|
|
c099e3173b | ||
|
|
de93636c7c | ||
|
|
5e263443b3 | ||
|
|
8c3a891254 | ||
|
|
e737067990 | ||
|
|
465a61f80f | ||
|
|
bbf42aaf97 | ||
|
|
b20d086a24 | ||
|
|
52baf297ca | ||
|
|
45e9f491ff | ||
|
|
742b26b0de | ||
|
|
164ba78c81 | ||
|
|
e27211b24d | ||
|
|
30987752cc | ||
|
|
4e574c0f51 | ||
|
|
80b195b7f7 |
@@ -8,6 +8,6 @@ Getting started
|
||||
|
||||
`git clone https://github.com/ThaumRystra/DiceCloud1 dicecloud`
|
||||
`cd dicecloud`
|
||||
`cd rpg-docs`
|
||||
`cd app`
|
||||
`bower install`
|
||||
`meteor`
|
||||
|
||||
0
rpg-docs/.gitignore → app/.gitignore
vendored
0
rpg-docs/.gitignore → app/.gitignore
vendored
@@ -15,3 +15,4 @@ notices-for-facebook-graph-api-2
|
||||
1.4.1-add-shell-server-package
|
||||
1.4.3-split-account-service-packages
|
||||
1.5-add-dynamic-import-package
|
||||
1.7-split-underscore-from-meteor-base
|
||||
@@ -3,9 +3,9 @@
|
||||
# 'meteor add' and 'meteor remove' will edit this file for you,
|
||||
# but you can also edit it by hand.
|
||||
|
||||
accounts-password@1.5.0
|
||||
accounts-ui@1.2.0
|
||||
random@1.0.10
|
||||
accounts-password@1.5.1
|
||||
accounts-ui@1.3.0
|
||||
random@1.1.0
|
||||
dburles:collection-helpers
|
||||
reactive-var@1.0.11
|
||||
underscore@1.0.10
|
||||
@@ -17,40 +17,40 @@ dburles:mongo-collection-instances
|
||||
percolate:migrations
|
||||
ecwyne:mathjs
|
||||
useraccounts:polymer
|
||||
accounts-google@1.3.0
|
||||
accounts-google@1.3.1
|
||||
splendido:accounts-meld
|
||||
email@1.2.3
|
||||
meteorhacks:subs-manager
|
||||
chuangbo:marked
|
||||
reywood:iron-router-ga
|
||||
meteor-base@1.2.0
|
||||
meteor-base@1.4.0
|
||||
mobile-experience@1.0.5
|
||||
mongo@1.3.1
|
||||
mongo@1.5.0
|
||||
blaze-html-templates
|
||||
session@1.1.7
|
||||
jquery@1.11.10
|
||||
tracker@1.1.3
|
||||
logging@1.1.19
|
||||
reload@1.1.11
|
||||
tracker@1.2.0
|
||||
logging@1.1.20
|
||||
reload@1.2.0
|
||||
ejson@1.1.0
|
||||
spacebars
|
||||
check@1.2.5
|
||||
check@1.3.1
|
||||
useraccounts:iron-routing
|
||||
wizonesolutions:canonical
|
||||
standard-minifier-js@2.2.0
|
||||
shell-server@0.3.0
|
||||
standard-minifier-js@2.3.4
|
||||
shell-server@0.3.1
|
||||
seba:minifiers-autoprefixer
|
||||
nikogosovd:multiple-uihooks
|
||||
templates:array
|
||||
ecmascript@0.9.0
|
||||
es5-shim@4.6.15
|
||||
ecmascript@0.11.1
|
||||
es5-shim@4.8.0
|
||||
differential:vulcanize
|
||||
reactive-dict@1.2.0
|
||||
percolate:synced-cron
|
||||
ongoworks:speakingurl
|
||||
service-configuration@1.0.11
|
||||
google-config-ui@1.0.0
|
||||
dynamic-import@0.2.0
|
||||
dynamic-import@0.4.0
|
||||
ddp-rate-limiter@1.0.7
|
||||
rate-limit@1.0.8
|
||||
rate-limit@1.0.9
|
||||
iron:router
|
||||
1
app/.meteor/release
Normal file
1
app/.meteor/release
Normal file
@@ -0,0 +1 @@
|
||||
METEOR@1.7.0.3
|
||||
@@ -1,57 +1,57 @@
|
||||
accounts-base@1.4.2
|
||||
accounts-google@1.3.1
|
||||
accounts-oauth@1.1.15
|
||||
accounts-password@1.5.0
|
||||
accounts-ui@1.2.0
|
||||
accounts-ui-unstyled@1.3.0
|
||||
accounts-password@1.5.1
|
||||
accounts-ui@1.3.0
|
||||
accounts-ui-unstyled@1.4.1
|
||||
aldeed:collection2@2.10.0
|
||||
aldeed:collection2-core@1.2.0
|
||||
aldeed:schema-deny@1.1.0
|
||||
aldeed:schema-index@1.1.1
|
||||
aldeed:simple-schema@1.5.3
|
||||
aldeed:simple-schema@1.5.4
|
||||
allow-deny@1.1.0
|
||||
autoupdate@1.3.12
|
||||
babel-compiler@6.24.7
|
||||
babel-runtime@1.1.1
|
||||
base64@1.0.10
|
||||
autoupdate@1.4.1
|
||||
babel-compiler@7.1.1
|
||||
babel-runtime@1.2.2
|
||||
base64@1.0.11
|
||||
binary-heap@1.0.10
|
||||
blaze@2.3.2
|
||||
blaze-html-templates@1.1.2
|
||||
blaze-tools@1.0.10
|
||||
boilerplate-generator@1.3.1
|
||||
caching-compiler@1.1.11
|
||||
caching-html-compiler@1.1.2
|
||||
callback-hook@1.0.10
|
||||
check@1.2.5
|
||||
boilerplate-generator@1.5.0
|
||||
caching-compiler@1.1.12
|
||||
caching-html-compiler@1.1.3
|
||||
callback-hook@1.1.0
|
||||
check@1.3.1
|
||||
chuangbo:marked@0.3.5_1
|
||||
coffeescript@1.11.1_4
|
||||
coffeescript@1.0.17
|
||||
dburles:collection-helpers@1.1.0
|
||||
dburles:mongo-collection-instances@0.3.5
|
||||
ddp@1.4.0
|
||||
ddp-client@2.2.0
|
||||
ddp-common@1.3.0
|
||||
ddp-client@2.3.3
|
||||
ddp-common@1.4.0
|
||||
ddp-rate-limiter@1.0.7
|
||||
ddp-server@2.1.1
|
||||
ddp-server@2.2.0
|
||||
deps@1.0.12
|
||||
diff-sequence@1.0.7
|
||||
diff-sequence@1.1.0
|
||||
differential:vulcanize@3.0.0
|
||||
dynamic-import@0.2.1
|
||||
ecmascript@0.9.0
|
||||
ecmascript-runtime@0.5.0
|
||||
ecmascript-runtime-client@0.5.0
|
||||
ecmascript-runtime-server@0.5.0
|
||||
dynamic-import@0.4.1
|
||||
ecmascript@0.11.1
|
||||
ecmascript-runtime@0.7.0
|
||||
ecmascript-runtime-client@0.7.1
|
||||
ecmascript-runtime-server@0.7.0
|
||||
ecwyne:mathjs@0.25.0
|
||||
ejson@1.1.0
|
||||
email@1.2.3
|
||||
es5-shim@4.6.15
|
||||
es5-shim@4.8.0
|
||||
geojson-utils@1.0.10
|
||||
google-config-ui@1.0.0
|
||||
google-oauth@1.2.5
|
||||
hot-code-push@1.0.4
|
||||
html-tools@1.0.11
|
||||
htmljs@1.0.11
|
||||
http@1.3.0
|
||||
id-map@1.0.9
|
||||
http@1.4.1
|
||||
id-map@1.1.0
|
||||
iron:controller@1.0.12
|
||||
iron:core@1.0.11
|
||||
iron:dynamic-template@1.0.12
|
||||
@@ -60,74 +60,76 @@ iron:location@1.0.11
|
||||
iron:middleware-stack@1.1.0
|
||||
iron:router@1.1.2
|
||||
iron:url@1.1.0
|
||||
jquery@1.11.10
|
||||
jquery@1.11.11
|
||||
lai:collection-extensions@0.2.1_1
|
||||
launch-screen@1.1.1
|
||||
less@2.7.12
|
||||
livedata@1.0.18
|
||||
localstorage@1.2.0
|
||||
logging@1.1.19
|
||||
logging@1.1.20
|
||||
matb33:collection-hooks@0.8.4
|
||||
mdg:validation-error@0.5.1
|
||||
meteor@1.8.2
|
||||
meteor-base@1.2.0
|
||||
meteor@1.9.2
|
||||
meteor-base@1.4.0
|
||||
meteorhacks:subs-manager@1.6.4
|
||||
minifier-css@1.2.16
|
||||
minifier-js@2.2.2
|
||||
minimongo@1.4.3
|
||||
minifier-css@1.3.1
|
||||
minifier-js@2.3.5
|
||||
minimongo@1.4.4
|
||||
mobile-experience@1.0.5
|
||||
mobile-status-bar@1.0.14
|
||||
modules@0.11.3
|
||||
modules-runtime@0.9.2
|
||||
momentjs:moment@2.20.1
|
||||
mongo@1.3.1
|
||||
modern-browsers@0.1.2
|
||||
modules@0.12.2
|
||||
modules-runtime@0.10.2
|
||||
momentjs:moment@2.22.2
|
||||
mongo@1.5.1
|
||||
mongo-dev-server@1.1.0
|
||||
mongo-id@1.0.6
|
||||
mongo-id@1.0.7
|
||||
nikogosovd:multiple-uihooks@0.1.8
|
||||
npm-bcrypt@0.9.3
|
||||
npm-mongo@2.2.34
|
||||
oauth@1.2.1
|
||||
npm-mongo@3.0.11
|
||||
oauth@1.2.3
|
||||
oauth2@1.2.0
|
||||
observe-sequence@1.0.16
|
||||
ongoworks:speakingurl@9.0.0
|
||||
ordered-dict@1.0.9
|
||||
ordered-dict@1.1.0
|
||||
percolate:migrations@0.9.8
|
||||
percolate:synced-cron@1.3.2
|
||||
promise@0.10.1
|
||||
promise@0.11.1
|
||||
raix:eventemitter@0.1.3
|
||||
random@1.0.10
|
||||
rate-limit@1.0.8
|
||||
random@1.1.0
|
||||
rate-limit@1.0.9
|
||||
reactive-dict@1.2.0
|
||||
reactive-var@1.0.11
|
||||
reload@1.1.11
|
||||
retry@1.0.9
|
||||
reload@1.2.0
|
||||
retry@1.1.0
|
||||
reywood:iron-router-ga@0.7.1
|
||||
routepolicy@1.0.12
|
||||
routepolicy@1.0.13
|
||||
seba:minifiers-autoprefixer@1.0.1
|
||||
service-configuration@1.0.11
|
||||
session@1.1.7
|
||||
sha@1.0.9
|
||||
shell-server@0.3.1
|
||||
socket-stream-client@0.2.2
|
||||
softwarerero:accounts-t9n@1.3.11
|
||||
spacebars@1.0.15
|
||||
spacebars-compiler@1.1.3
|
||||
splendido:accounts-emails-field@1.2.0
|
||||
splendido:accounts-meld@1.3.1
|
||||
srp@1.0.10
|
||||
standard-minifier-js@2.2.3
|
||||
standard-minifier-js@2.3.4
|
||||
templates:array@1.0.3
|
||||
templating@1.3.2
|
||||
templating-compiler@1.3.3
|
||||
templating-runtime@1.3.2
|
||||
templating-tools@1.1.2
|
||||
tracker@1.1.3
|
||||
tracker@1.2.0
|
||||
ui@1.0.13
|
||||
underscore@1.0.10
|
||||
url@1.1.0
|
||||
url@1.2.0
|
||||
useraccounts:core@1.14.2
|
||||
useraccounts:iron-routing@1.14.2
|
||||
useraccounts:polymer@1.14.2
|
||||
webapp@1.4.0
|
||||
webapp@1.6.2
|
||||
webapp-hashing@1.0.9
|
||||
wizonesolutions:canonical@0.0.5
|
||||
zimme:collection-behaviours@1.1.3
|
||||
@@ -583,7 +583,7 @@ Characters.allow({
|
||||
|
||||
Characters.deny({
|
||||
update: function(userId, docs, fields, modifier) {
|
||||
// can't change owners
|
||||
return _.contains(fields, "owner");
|
||||
// can't change owners unless you are the current owner
|
||||
return _.contains(fields, "owner") && doc.owner !== userId;
|
||||
}
|
||||
});
|
||||
9
app/Model/Meta/Blacklist.js
Normal file
9
app/Model/Meta/Blacklist.js
Normal file
@@ -0,0 +1,9 @@
|
||||
Blacklist = new Mongo.Collection("blacklist");
|
||||
|
||||
Schemas.Blacklist = new SimpleSchema({
|
||||
userId: {
|
||||
type: String,
|
||||
},
|
||||
});
|
||||
|
||||
Blacklist.attachSchema(Schemas.Blacklist);
|
||||
91
app/Routes/API.js
Normal file
91
app/Routes/API.js
Normal file
@@ -0,0 +1,91 @@
|
||||
Router.map(function() {
|
||||
this.route("vmixCharacter", {
|
||||
path: "/vmix-character/:_id/",
|
||||
where: "server",
|
||||
action: function() {
|
||||
this.response.setHeader("Content-Type", "application/json");
|
||||
var query = this.params.query;
|
||||
var key = query && query.key;
|
||||
ifKeyValid(key, this.response, "vmixCharacter", () =>
|
||||
this.response.end(vMixCharacter(this.params._id))
|
||||
);
|
||||
},
|
||||
});
|
||||
this.route("vmixParty", {
|
||||
path: "/vmix-party/:_id/",
|
||||
where: "server",
|
||||
action: function() {
|
||||
this.response.setHeader("Content-Type", "application/json");
|
||||
var query = this.params.query;
|
||||
var key = query && query.key;
|
||||
ifKeyValid(key, this.response, "vmixParty", () =>
|
||||
this.response.end(vMixParty(this.params._id))
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
this.route("jsonCharacterSheet", {
|
||||
path: "/character/:_id/json",
|
||||
where: "server",
|
||||
action: function() {
|
||||
this.response.setHeader("Content-Type", "application/json");
|
||||
var query = this.params.query;
|
||||
var key = query && query.key;
|
||||
ifKeyValid(key, this.response, "jsonCharacterSheet", () => {
|
||||
if (canViewCharacter(this.params._id, userIdFromKey(key))){
|
||||
this.response.end(JSONExport(this.params._id))
|
||||
} else {
|
||||
this.response.writeHead(403, "You do not have permission to view this character");
|
||||
this.response.end();
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
var ifKeyValid = function(apiKey, response, method, callback){
|
||||
if (!apiKey){
|
||||
response.writeHead(403, "You must use an api key to access this api");
|
||||
response.end();
|
||||
} else if (!isKeyValid(apiKey)){
|
||||
response.writeHead(403, "API key is invalid");
|
||||
response.end();
|
||||
} else if (isRateLimited(apiKey, method)){
|
||||
response.writeHead(429, "Too many requests");
|
||||
response.end(JSON.stringify({
|
||||
"timeToReset": rateLimiter.check({apiKey: apiKey, method: method}).timeToReset
|
||||
}));
|
||||
} else {
|
||||
rateLimiter.increment({apiKey: apiKey, method: method})
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
var isKeyValid = function(apiKey){
|
||||
var user = Meteor.users.findOne({apiKey});
|
||||
if (!user) return false;
|
||||
var blackListed = Blacklist.findOne({userId: user._id});
|
||||
return !blackListed;
|
||||
};
|
||||
|
||||
var userIdFromKey = function(apiKey){
|
||||
var user = Meteor.users.findOne({apiKey}); // we know user exists from isKeyValid
|
||||
return user._id;
|
||||
}
|
||||
|
||||
var rateLimiter = new RateLimiter();
|
||||
rateLimiter.addRule({apiKey: String}, 5, 5000);
|
||||
rateLimiter.addRule({apiKey: String, method: "vmixCharacter"}, 2, 10000);
|
||||
rateLimiter.addRule({apiKey: String, method: "vmixParty"}, 2, 10000);
|
||||
rateLimiter.addRule({apiKey: String, method: "jsonCharacterSheet"}, 5, 5000);
|
||||
|
||||
var isRateLimited = function(apiKey, method){
|
||||
const limited = !rateLimiter.check({apiKey: apiKey, method: method}).allowed
|
||||
if (limited) {
|
||||
console.log(`Rate limit hit by API key ${apiKey}`);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -13,6 +13,11 @@ Router.plugin("ensureSignedIn", {
|
||||
|
||||
Router.plugin("dataNotFound", {notFoundTemplate: "notFound"});
|
||||
|
||||
var handleSubError = function(e){
|
||||
Session.set("error", {reason: e.reason, href: location.href});
|
||||
Router.go("/error");
|
||||
};
|
||||
|
||||
Router.map(function() {
|
||||
this.route("/", {
|
||||
name: "home",
|
||||
@@ -36,7 +41,9 @@ Router.map(function() {
|
||||
path: "/character/:_id/",
|
||||
waitOn: function(){
|
||||
return [
|
||||
subsManager.subscribe("singleCharacter", this.params._id),
|
||||
subsManager.subscribe(
|
||||
"singleCharacter", this.params._id, {onError: handleSubError}
|
||||
),
|
||||
];
|
||||
},
|
||||
action: function(){
|
||||
@@ -52,7 +59,9 @@ Router.map(function() {
|
||||
path: "/character/:_id/:urlName",
|
||||
waitOn: function(){
|
||||
return [
|
||||
subsManager.subscribe("singleCharacter", this.params._id),
|
||||
subsManager.subscribe(
|
||||
"singleCharacter", this.params._id, {onError: handleSubError}
|
||||
),
|
||||
];
|
||||
},
|
||||
data: function() {
|
||||
@@ -82,7 +91,9 @@ Router.map(function() {
|
||||
path: "/character/:_id/:urlName/print",
|
||||
waitOn: function(){
|
||||
return [
|
||||
subsManager.subscribe("singleCharacter", this.params._id),
|
||||
subsManager.subscribe(
|
||||
"singleCharacter", this.params._id, {onError: handleSubError}
|
||||
),
|
||||
];
|
||||
},
|
||||
data: function() {
|
||||
@@ -153,4 +164,11 @@ Router.map(function() {
|
||||
document.title = appName;
|
||||
},
|
||||
});
|
||||
|
||||
this.route("/error", {
|
||||
name: "error",
|
||||
onAfterAction: function() {
|
||||
document.title = `${appName} - Error`;
|
||||
},
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user