Compare commits

...

48 Commits
1.7.0 ... 1.7.4

Author SHA1 Message Date
Stefan Zermatten
fcae3056de Merge branch 'bugfix-67' 2018-11-13 12:57:28 +02:00
Stefan Zermatten
7d364c80c0 Added hotfix to fix password button until the relevant package can be updated, fixes #67 2018-11-13 12:57:02 +02:00
Stefan Zermatten
0ff6c08abd Merge branch 'bugfix-150' 2018-11-13 12:01:52 +02:00
Stefan Zermatten
1c95336843 Spell slot bubbles are limited to 10, overflow is shown numerically
fixes #150
2018-11-13 12:01:40 +02:00
Stefan Zermatten
b36720511b Merge branch 'bugfix-155' 2018-11-13 10:39:26 +02:00
Stefan Zermatten
261220fdd5 Fixes #155, buffs can now only be applied if you have write access
refactored applying buffs to be a method, not a client side operation. You can now only applied if you have write access to the receiving character.
2018-11-13 10:39:14 +02:00
Stefan Zermatten
64edc52cca Merge branch 'bugfix-170' 2018-11-13 10:08:08 +02:00
Stefan Zermatten
56f1bd2829 Fixes #170 and maybe some other more subtle problems regarding soft removes not cascading properly, orphaning objects 2018-11-13 10:07:55 +02:00
Stefan Zermatten
3b669fd2f9 Merge branch 'bugfix-177' 2018-11-13 09:32:24 +02:00
Stefan Zermatten
933878e158 fixes #177 2018-11-13 09:31:57 +02:00
Stefan Zermatten
0e6ca56316 Merge branch 'bugfix-191' 2018-11-13 09:28:06 +02:00
Stefan Zermatten
6599fe1ef8 fixes #191 2018-11-13 09:26:36 +02:00
Stefan Zermatten
f39baf43a1 Merge branch 'bugfix-187' 2018-11-13 08:59:34 +02:00
Stefan Zermatten
96f4e35e25 fixes #187 2018-11-13 08:58:42 +02:00
Stefan Zermatten
e17dbf6601 Upgrade to meteor 1.8 2018-10-10 14:28:48 +02:00
Stefan Zermatten
3f81d419f7 updated meteor 2018-10-10 14:00:46 +02:00
Stefan Zermatten
1c00f5aa04 Hotfix iOS sign in issues (maybe) 2018-10-04 10:05:02 +02:00
Stefan Zermatten
f5a32cb50a Cobbled together some semblance of an item library UI 2018-10-02 15:43:10 +02:00
Stefan Zermatten
f4d3368fb4 Updated cron job to clean database of soft removed documents 2018-09-25 10:58:01 +02:00
Stefan Zermatten
1de9fb558a Merge pull request #182 from mommothazaz123/patch-1
fix error in Characters.deny()
2018-09-14 10:06:43 +02:00
Andrew Zhu
06ffc94b4c fix error in Characters.deny()
Renamed `docs` to `doc`, since `doc.owner` was undefined.
2018-09-07 14:07:55 -07:00
Stefan Zermatten
74c6a423ee Allowed owners to give their characters to new owners, no UI yet. 2018-08-28 09:59:10 +02:00
Stefan Zermatten
41c90bb69f Updated Meteor 2018-08-23 11:45:38 +02:00
Stefan Zermatten
68432541db Merge pull request #168 from Frogvall/master
Adding advantage/disadvantage arrows to initiative stat card
2018-08-23 11:34:02 +02:00
Frogvall
c417c45db1 Cleaned up a bit 2018-06-20 14:33:34 +02:00
Frogvall
3f3caf63e4 Add css and js implementation of previously naïve approach
Bonus: Learned some meteor :)
2018-06-20 14:25:18 +02:00
Jonas
49c5a1fcb1 Added adv class to skills in stat cards
Added arrows to initiative, for example
2018-06-18 00:51:20 +02:00
Stefan Zermatten
9fb37148fa Merge pull request #167 from mommothazaz123/master
Add raw character JSON output, improve ratelimiter rules of API
2018-06-08 09:26:52 +02:00
Andrew Zhu
a67d7fb4ea Merge branch 'master' into master 2018-06-07 02:06:34 -07:00
Andrew Zhu
8e0f19742b fix some branch conflicts 2018-06-07 02:03:12 -07:00
Andrew Zhu
216e502c8a add permission check to JSONcharacter 2018-06-07 01:38:29 -07:00
Andrew Zhu
1a18d1f816 update README to reflect dir name change 2018-06-07 01:08:41 -07:00
Andrew Zhu
c099e3173b rename /rpg-docs to /app 2018-06-07 01:07:49 -07:00
Andrew Zhu
de93636c7c Revert "add mixmax:smart-disconnect to reduce server load"
This reverts commit 465a61f80f.
2018-06-07 01:03:16 -07:00
Stefan Zermatten
5e263443b3 Updated dependencies 2018-06-04 15:42:23 +02:00
Stefan Zermatten
8c3a891254 Merge branch 'bugfix-163' 2018-06-04 15:29:14 +02:00
Stefan Zermatten
e737067990 Made sure empty party names take up some space so they can be edited 2018-06-04 15:28:08 +02:00
Andrew Zhu
465a61f80f add mixmax:smart-disconnect to reduce server load 2018-05-27 22:58:02 -07:00
Andrew Zhu
bbf42aaf97 make ratelimiter actually match, return time to reset on hitting ratelimit 2018-05-25 01:39:35 -07:00
Andrew Zhu
b20d086a24 add character JSON endpoint, improve ratelimit rules 2018-05-25 01:34:39 -07:00
Stefan Zermatten
52baf297ca Changed rpg-docs folder to app 2018-05-21 14:21:07 +02:00
Thaum Rystra
45e9f491ff Merge branch 'feature-blacklist' 2018-04-02 14:27:24 +02:00
Thaum Rystra
742b26b0de Added rate limiting logging and an error page for hitting the rate limit on opening characters 2018-04-02 14:26:55 +02:00
Stefan Zermatten
164ba78c81 Added blacklist checks and rate limit logging
Needs testing
2018-03-12 09:22:04 +02:00
Thaum Rystra
e27211b24d Merge branch 'enhancement-154' 2018-03-03 20:13:03 +02:00
Thaum Rystra
30987752cc Hotfix - Remove localhost from image link on printed character sheet 2018-03-03 17:28:42 +02:00
Jacob
4e574c0f51 Added "clear" (reset to 0) button to resource cards 2018-02-24 14:49:42 +00:00
Jacob
80b195b7f7 Added reset button to resource cards 2018-02-24 14:42:41 +00:00
439 changed files with 3558 additions and 2283 deletions

View File

@@ -8,6 +8,6 @@ Getting started
`git clone https://github.com/ThaumRystra/DiceCloud1 dicecloud`
`cd dicecloud`
`cd rpg-docs`
`cd app`
`bower install`
`meteor`

View File

@@ -4,6 +4,7 @@
settings.json
public/components
public/_imports.html
private/oldClient
nohup.out
node_modules
dump

View File

@@ -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

View File

@@ -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.1
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.2
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.6.0
blaze-html-templates
session@1.1.7
session@1.1.8
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.4.0
shell-server@0.4.0
seba:minifiers-autoprefixer
nikogosovd:multiple-uihooks
templates:array
ecmascript@0.9.0
es5-shim@4.6.15
ecmascript@0.12.0
es5-shim@4.8.0
differential:vulcanize
reactive-dict@1.2.0
percolate:synced-cron
reactive-dict@1.2.1
ongoworks:speakingurl
service-configuration@1.0.11
google-config-ui@1.0.0
dynamic-import@0.2.0
google-config-ui@1.0.1
dynamic-import@0.5.0
ddp-rate-limiter@1.0.7
rate-limit@1.0.8
rate-limit@1.0.9
iron:router
littledata:synced-cron

1
app/.meteor/release Normal file
View File

@@ -0,0 +1 @@
METEOR@1.8

View File

@@ -1,57 +1,59 @@
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-base@1.4.3
accounts-google@1.3.2
accounts-oauth@1.1.16
accounts-password@1.5.1
accounts-ui@1.3.1
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
binary-heap@1.0.10
blaze@2.3.2
autoupdate@1.5.0
babel-compiler@7.2.0
babel-runtime@1.3.0
base64@1.0.11
binary-heap@1.0.11
blaze@2.3.3
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.6.0
caching-compiler@1.2.0
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.5.0
ecmascript@0.12.0
ecmascript-runtime@0.7.0
ecmascript-runtime-client@0.8.0
ecmascript-runtime-server@0.7.1
ecwyne:mathjs@0.25.0
ejson@1.1.0
email@1.2.3
es5-shim@4.6.15
es5-shim@4.8.0
fetch@0.1.0
geojson-utils@1.0.10
google-config-ui@1.0.0
google-oauth@1.2.5
google-config-ui@1.0.1
google-oauth@1.2.6
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
inter-process-messaging@0.1.0
iron:controller@1.0.12
iron:core@1.0.11
iron:dynamic-template@1.0.12
@@ -60,74 +62,77 @@ 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
less@2.8.0
littledata:synced-cron@1.5.1
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.4.0
minifier-js@2.4.0
minimongo@1.4.5
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.13.0
modules-runtime@0.10.2
momentjs:moment@2.22.2
mongo@1.6.0
mongo-decimal@0.1.0
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
oauth2@1.2.0
npm-mongo@3.1.1
oauth@1.2.3
oauth2@1.2.1
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
reactive-dict@1.2.0
random@1.1.0
rate-limit@1.0.9
reactive-dict@1.2.1
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
seba:minifiers-autoprefixer@1.0.1
routepolicy@1.1.0
seba:minifiers-autoprefixer@1.1.1
service-configuration@1.0.11
session@1.1.7
session@1.1.8
sha@1.0.9
shell-server@0.3.1
shell-server@0.4.0
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
srp@1.0.12
standard-minifier-js@2.4.0
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.7.0
webapp-hashing@1.0.9
wizonesolutions:canonical@0.0.5
zimme:collection-behaviours@1.1.3

View File

@@ -65,3 +65,37 @@ makeParent(Buffs, ["name", "enabled"]); //parents of effects, attacks, proficien
Buffs.allow(CHARACTER_SUBSCHEMA_ALLOW);
Buffs.deny(CHARACTER_SUBSCHEMA_DENY);
Meteor.methods({
applyBuff: function(buffId, targetId){
if (!Meteor.call("canWriteCharacter", targetId)){
throw new Meteor.Error(
"Access denied",
"You do not have permission to buff this character"
);
}
let buff = CustomBuffs.findOne(buffId);
if (!buff) return;
var parentCol = Meteor.isClient ?
window[buff.parent.collection] : global[buff.parent.collection]
var parent = parentCol.findOne(buff.parent.id);
//insert new buff
newBuffId = Buffs.insert({
charId: targetId,
name: buff.name,
description: buff.description,
lifeTime: {total: buff.lifeTime.total},
type: "custom",
appliedBy: buff.charId,
appliedByDetails: {
name: parent && parent.name || "",
collection: buff.parent.collection,
},
});
Meteor.call("cloneChildren", buffId, {id: newBuffId, collection: "Buffs"})
}
})

View File

@@ -582,8 +582,8 @@ Characters.allow({
});
Characters.deny({
update: function(userId, docs, fields, modifier) {
// can't change owners
return _.contains(fields, "owner");
update: function(userId, doc, fields, modifier) {
// can't change owners unless you are the current owner
return _.contains(fields, "owner") && doc.owner !== userId;
}
});

View File

@@ -2,14 +2,38 @@ Libraries = new Mongo.Collection("library");
Schemas.Library = new SimpleSchema({
name: {type: String},
owner: {type: String, regEx: SimpleSchema.RegEx.Id},
readers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: []},
writers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: []},
public: {type: Boolean, defaultValue: false},
owner: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
readers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: [], index: 1},
writers: {type: [String], regEx: SimpleSchema.RegEx.Id, defaultValue: [], index: 1},
public: {type: Boolean, defaultValue: false, index: 1},
});
Libraries.attachSchema(Schemas.Library);
Libraries.after.remove(function(userId, library) {
LibraryItems.remove({library: library._id});
LibrarySpells.remove({library: library._id});
});
Meteor.methods({
removeLibrary: function(libraryId) {
let library = Libraries.findOne(libraryId);
let userId = Meteor.userId();
if (!library) return;
if (library.owner === userId){
Libraries.remove(libraryId);
} else {
if (_.contains(library.readers, userId)){
Libraries.update(libraryId, {$pull: {"readers": userId}});
}
if (_.contains(library.writers, userId)){
Libraries.update(libraryId, {$pull: {"writers": userId}});
}
}
},
});
Libraries.allow({
insert(userId, doc) {
return userId && doc.owner === userId;
@@ -18,16 +42,14 @@ Libraries.allow({
return canEdit(userId, doc);
},
remove(userId, doc) {
return canEdit(userId, doc);
return userId && doc.owner === userId;
},
fetch: ["owner", "writers"],
});
Libraries.deny({
// For now, only admins can manage libraries
insert(userId, doc){
var user = Meteor.users.findOne(userId);
return !user || !_.contains(user.roles, "admin");
return !Meteor.users.findOne(userId);
},
update(userId, doc, fields, modifier) {
// Can't change owners

View File

@@ -1,7 +1,7 @@
Schemas.LibraryAttacks = new SimpleSchema({
name: {
type: String,
defaultValue: "New Attack",
optional: true,
trim: false,
},
details: {

View File

@@ -9,7 +9,6 @@ Schemas.LibraryEffects = new SimpleSchema({
defaultValue: "add",
allowedValues: [
"base",
"proficiency",
"add",
"mul",
"min",

View File

@@ -0,0 +1,91 @@
LibraryItems = new Mongo.Collection("libraryItems");
Schemas.LibraryItems = new SimpleSchema({
libraryName:{type: String, optional: true, trim: false},
name: {type: String, defaultValue: "New Item", trim: false},
plural: {type: String, optional: true, trim: false},
description:{type: String, optional: true, trim: false},
quantity: {type: Number, min: 0, defaultValue: 1},
weight: {type: Number, min: 0, defaultValue: 0, decimal: true},
value: {type: Number, min: 0, defaultValue: 0, decimal: true},
requiresAttunement: {type: Boolean, defaultValue: false},
library: {type: String, regEx: SimpleSchema.RegEx.Id, index: 1},
"settings.category": {
type: String,
optional: true,
allowedValues: [
"adventuringGear", "armor", "weapons", "tools",
],
},
"settings.showIncrement": {
type: Boolean,
defaultValue: false,
},
effects: {type: [Schemas.LibraryEffects], defaultValue: []},
attacks: {type: [Schemas.LibraryAttacks], defaultValue: []},
});
LibraryItems.attachSchema(Schemas.LibraryItems);
LibraryItems.allow({
insert(userId, doc) {
return Libraries.canEdit(userId, doc.library);
},
update(userId, doc, fields, modifier) {
return Libraries.canEdit(userId, doc.library);
},
remove(userId, doc) {
return Libraries.canEdit(userId, doc.library);
},
fetch: ["library"],
});
Meteor.methods({
updateLibraryItemEffect: function({itemId, effectIndex, field, value, unsetField}){
let libraryId = LibraryItems.findOne(itemId).library;
let userId = Meteor.userId();
if (!Libraries.canEdit(userId, libraryId)) return;
let modifier = {
$set: {
[`effects.${effectIndex}.${field}`]: value,
}
};
if (unsetField){
modifier.$unset = {
[`effects.${effectIndex}.${unsetField}`]: 1,
}
}
LibraryItems.update(itemId, modifier);
},
removeLibraryItemEffect: function({itemId, effectIndex}){
let libraryId = LibraryItems.findOne(itemId).library;
let userId = Meteor.userId();
if (!Libraries.canEdit(userId, libraryId)) return;
LibraryItems.update(itemId, {$unset : {
[`effects.${effectIndex}`] : 1,
}});
LibraryItems.update(itemId, {$pull : {"effects" : null}});
},
updateLibraryItemAttack: function({itemId, attackIndex, field, value}){
let libraryId = LibraryItems.findOne(itemId).library;
let userId = Meteor.userId();
if (!Libraries.canEdit(userId, libraryId)) return;
LibraryItems.update(itemId, {
$set: {
[`attacks.${attackIndex}.${field}`]: value,
}
});
},
removeLibraryItemAttack: function({itemId, attackIndex}){
let libraryId = LibraryItems.findOne(itemId).library;
let userId = Meteor.userId();
if (!Libraries.canEdit(userId, libraryId)) return;
LibraryItems.update(itemId, {$unset : {
[`attacks.${attackIndex}`] : 1,
}});
LibraryItems.update(itemId, {$pull : {"attacks" : null}});
},
})

View File

@@ -0,0 +1,9 @@
Blacklist = new Mongo.Collection("blacklist");
Schemas.Blacklist = new SimpleSchema({
userId: {
type: String,
},
});
Blacklist.attachSchema(Schemas.Blacklist);

View File

@@ -3,6 +3,10 @@ Schemas.UserProfile = new SimpleSchema({
type: String,
optional: true,
},
librarySubscriptions: {
type: [String],
defaultValue: [],
},
});
Schemas.User = new SimpleSchema({

91
app/Routes/API.js Normal file
View 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;
}
};

View File

@@ -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() {
@@ -110,7 +121,7 @@ Router.map(function() {
this.route("library", {
path: "/library",
waitOn: function(){
return subsManager.subscribe("standardLibraries");
return subsManager.subscribe("customLibraries");
},
onAfterAction: function() {
document.title = appName + " - Library";
@@ -153,4 +164,11 @@ Router.map(function() {
document.title = appName;
},
});
this.route("/error", {
name: "error",
onAfterAction: function() {
document.title = `${appName} - Error`;
},
});
});

View File

@@ -1,6 +1,6 @@
{
"name": "RPG Docs",
"version": "0.0.0",
"name": "dicecloud",
"version": "1",
"homepage": "",
"authors": [
"Stefan Zermatten"

View File

@@ -0,0 +1,5 @@
let pwdFormSubmit = AccountsTemplates.atPwdFormEvents["submit #at-pwd-form"]
Template.atPwdForm.events({
"click .at-btn.submit": pwdFormSubmit,
});

View File

@@ -0,0 +1,8 @@
/*
* iOS doens't believe in click events for some elements.
* This is here to convince it to allow buttons to be clickable
*/
button {
cursor: pointer;
}

View File

@@ -0,0 +1,40 @@
const applyBuff = function(targetId, buff) {
Meteor.call("applyBuff", buff._id, targetId)
let target;
if (targetId == buff.charId) {
target = "self";
} else {
target = Characters.findOne(targetId) || {};
target = target && target.name || "target"
}
GlobalUI.toast(`${buff.name || "Buff"} applied to ${target}`);
};
Template.customBuffView.helpers({
toSelf: function() {
if (this.buff.target === "self") {
return " to self";
} else {
return "";
}
}
});
Template.customBuffView.events({
"click .apply-buff-button": function(){
if (this.buff.target !== "self") {
pushDialogStack({
template: "applyBuffDialog",
data: {buff: this.buff},
element: event.currentTarget,
callback: (targetId) => {
if (!targetId) return;
applyBuff(targetId, this.buff);
},
});
} else {
var targetId = this.buff.charId;
applyBuff(targetId, this.buff);
}
},
});

Some files were not shown because too many files have changed in this diff Show More