move everything to Meteor methods
This commit is contained in:
@@ -69,266 +69,144 @@ Router.map(function () {
|
|||||||
this.route("addSpellsToCharacter", { // POST /api/character/:_id/spellList/:listId
|
this.route("addSpellsToCharacter", { // POST /api/character/:_id/spellList/:listId
|
||||||
path: "/api/character/:_id/spellList/:listId",
|
path: "/api/character/:_id/spellList/:listId",
|
||||||
where: "server"
|
where: "server"
|
||||||
}).post(
|
}).post(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
ifPostOK(this, "addSpellsToList", () => {
|
const spells = this.request.body;
|
||||||
const spells = this.request.body;
|
const charId = this.params._id;
|
||||||
const charId = this.params._id;
|
const listId = this.params.listId;
|
||||||
const listId = this.params.listId;
|
Meteor.call("insertSpells", key, charId, listId, spells, (err, res) => {
|
||||||
let spellIds = [];
|
if (err) {
|
||||||
let error;
|
console.log(err);
|
||||||
for (let spell of spells) {
|
this.response.writeHead(err.error, err.reason);
|
||||||
spell.parent = {id: listId, collection: "SpellLists"};
|
this.response.end(err.details);
|
||||||
spell.charId = charId;
|
} else {
|
||||||
let id = Spells.insert(spell, (err, _id) => {
|
this.response.end(JSON.stringify(res));
|
||||||
if (err) {
|
}
|
||||||
error = err.message;
|
});
|
||||||
}
|
});
|
||||||
});
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
spellIds.push(id);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to insert one or more spells");
|
|
||||||
this.response.end(JSON.stringify({err: error, inserted: spellIds}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify(spellIds));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.route("createCharacter", { // POST /api/character
|
this.route("createCharacter", { // POST /api/character
|
||||||
path: "/api/character",
|
path: "/api/character",
|
||||||
where: "server"
|
where: "server"
|
||||||
}).post(
|
}).post(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
this.response.setHeader("Content-Type", "application/json");
|
const character = this.request.body;
|
||||||
const header = this.request.headers;
|
Meteor.call("insertCharacter", key, character, (err, res) => {
|
||||||
const key = header && header['authorization'];
|
if (err) {
|
||||||
ifKeyValid(key, this.response, "createCharacter", () => {
|
this.response.writeHead(err.error, err.reason);
|
||||||
const character = this.request.body;
|
this.response.end(err.details);
|
||||||
let error;
|
} else {
|
||||||
|
this.response.end(JSON.stringify(res));
|
||||||
character.owner = userIdFromKey(key);
|
}
|
||||||
let id = Characters.insert(character, (err) => {
|
});
|
||||||
if (err)
|
});
|
||||||
error = err.message;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to insert character");
|
|
||||||
this.response.end(JSON.stringify({err: error}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify({id: id}));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.route("deleteCharacter", { // DELETE /api/character/:_id
|
this.route("deleteCharacter", { // DELETE /api/character/:_id
|
||||||
path: "/api/character/:_id",
|
path: "/api/character/:_id",
|
||||||
where: "server"
|
where: "server"
|
||||||
}).delete(
|
}).delete(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
this.response.setHeader("Content-Type", "application/json");
|
const charId = this.params._id;
|
||||||
const header = this.request.headers;
|
Meteor.call("deleteCharacter", key, charId, (err, res) => {
|
||||||
const key = header && header['authorization'];
|
if (err) {
|
||||||
const charId = this.params._id;
|
this.response.writeHead(err.error, err.reason);
|
||||||
ifKeyValid(key, this.response, "deleteCharacter", () => {
|
this.response.end(err.details);
|
||||||
if (isOwner(charId, userIdFromKey(key))) {
|
} else {
|
||||||
let error;
|
this.response.end(JSON.stringify(res));
|
||||||
Characters.remove({_id: charId}, (err) => {
|
}
|
||||||
if (err)
|
});
|
||||||
error = err.message;
|
});
|
||||||
});
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to delete character");
|
|
||||||
this.response.end(JSON.stringify({err: error}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify({success: true}));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.response.writeHead(403, "You do not have permission to delete this character");
|
|
||||||
this.response.end();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.route("transferCharacterOwnership", { // PUT /api/character/:_id/owner
|
this.route("transferCharacterOwnership", { // PUT /api/character/:_id/owner
|
||||||
path: "/api/character/:_id/owner",
|
path: "/api/character/:_id/owner",
|
||||||
where: "server"
|
where: "server"
|
||||||
}).put(
|
}).put(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
this.response.setHeader("Content-Type", "application/json");
|
const charId = this.params._id;
|
||||||
const header = this.request.headers;
|
const ownerId = this.request.body['id'];
|
||||||
const key = header && header['authorization'];
|
Meteor.call("transferCharacterOwnership", key, charId, ownerId, (err, res) => {
|
||||||
const charId = this.params._id;
|
if (err) {
|
||||||
ifKeyValid(key, this.response, "transferCharacterOwnership", () => {
|
this.response.writeHead(err.error, err.reason);
|
||||||
if (isOwner(charId, userIdFromKey(key))) {
|
this.response.end(err.details);
|
||||||
const newOwner = this.request.body['id'];
|
} else {
|
||||||
let error;
|
this.response.end(JSON.stringify(res));
|
||||||
Characters.update({_id: charId}, {"$set": {owner: newOwner}}, null,
|
}
|
||||||
(err) => {
|
});
|
||||||
if (err)
|
});
|
||||||
error = err.message;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to update character");
|
|
||||||
this.response.end(JSON.stringify({err: error}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify({success: true}));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.response.writeHead(403, "You do not have permission to transfer this character");
|
|
||||||
this.response.end();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.route("insertFeatures", { // POST /api/character/:_id/feature
|
this.route("insertFeatures", { // POST /api/character/:_id/feature
|
||||||
path: "/api/character/:_id/feature",
|
path: "/api/character/:_id/feature",
|
||||||
where: "server",
|
where: "server",
|
||||||
}).post(
|
}).post(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
ifPostOK(this, "insertFeatures", () => {
|
const charId = this.params._id;
|
||||||
const features = this.request.body;
|
const features = this.request.body;
|
||||||
const charId = this.params._id;
|
Meteor.call("insertFeatures", key, charId, features, (err, res) => {
|
||||||
let ids = [];
|
if (err) {
|
||||||
let error;
|
this.response.writeHead(err.error, err.reason);
|
||||||
for (let feature of features) {
|
this.response.end(err.details);
|
||||||
feature.charId = charId;
|
} else {
|
||||||
let id = Features.insert(feature, (err) => {
|
this.response.end(JSON.stringify(res));
|
||||||
if (err) {
|
}
|
||||||
error = err.message;
|
});
|
||||||
}
|
});
|
||||||
});
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
ids.push(id);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to insert one or more features");
|
|
||||||
this.response.end(JSON.stringify({err: error, inserted: ids}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify(ids));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.route("insertProfs", { // POST /api/character/:_id/prof
|
this.route("insertProfs", { // POST /api/character/:_id/prof
|
||||||
path: "/api/character/:_id/prof",
|
path: "/api/character/:_id/prof",
|
||||||
where: "server",
|
where: "server",
|
||||||
}).post(
|
}).post(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
ifPostOK(this, "insertProfs", () => {
|
const charId = this.params._id;
|
||||||
const profs = this.request.body;
|
const profs = this.request.body;
|
||||||
const charId = this.params._id;
|
Meteor.call("insertProfs", key, charId, profs, (err, res) => {
|
||||||
let ids = [];
|
if (err) {
|
||||||
let error;
|
this.response.writeHead(err.error, err.reason);
|
||||||
for (let prof of profs) {
|
this.response.end(err.details);
|
||||||
prof.charId = charId; // we currently rely on the client to supply parent
|
} else {
|
||||||
let id = Proficiencies.insert(prof, (err) => {
|
this.response.end(JSON.stringify(res));
|
||||||
if (err) {
|
}
|
||||||
error = err.message;
|
});
|
||||||
}
|
});
|
||||||
});
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
ids.push(id);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to insert one or more profs");
|
|
||||||
this.response.end(JSON.stringify({err: error, inserted: ids}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify(ids));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.route("insertEffects", { // POST /api/character/:_id/effect
|
this.route("insertEffects", { // POST /api/character/:_id/effect
|
||||||
path: "/api/character/:_id/effect",
|
path: "/api/character/:_id/effect",
|
||||||
where: "server",
|
where: "server",
|
||||||
}).post(
|
}).post(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
ifPostOK(this, "insertEffects", () => {
|
const charId = this.params._id;
|
||||||
const effects = this.request.body;
|
const effects = this.request.body;
|
||||||
const charId = this.params._id;
|
Meteor.call("insertEffects", key, charId, effects, (err, res) => {
|
||||||
let ids = [];
|
if (err) {
|
||||||
let error;
|
this.response.writeHead(err.error, err.reason);
|
||||||
for (let effect of effects) {
|
this.response.end(err.details);
|
||||||
effect.charId = charId; // we currently rely on the client to supply parent
|
} else {
|
||||||
let id = Effects.insert(effect, (err) => {
|
this.response.end(JSON.stringify(res));
|
||||||
if (err) {
|
}
|
||||||
error = err.message;
|
});
|
||||||
}
|
});
|
||||||
});
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
ids.push(id);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to insert one or more effects");
|
|
||||||
this.response.end(JSON.stringify({err: error, inserted: ids}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify(ids));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
this.route("insertClasses", { // POST /api/character/:_id/class
|
this.route("insertClasses", { // POST /api/character/:_id/class
|
||||||
path: "/api/character/:_id/class",
|
path: "/api/character/:_id/class",
|
||||||
where: "server",
|
where: "server",
|
||||||
}).post(
|
}).post(function () {
|
||||||
function () {
|
const key = startPOSTResponse(this);
|
||||||
ifPostOK(this, "insertClasses", () => {
|
const charId = this.params._id;
|
||||||
const klasses = this.request.body;
|
const classes = this.request.body;
|
||||||
const charId = this.params._id;
|
Meteor.call("insertClasses", key, charId, classes, (err, res) => {
|
||||||
let ids = [];
|
if (err) {
|
||||||
let error;
|
this.response.writeHead(err.error, err.reason);
|
||||||
for (let klass of klasses) {
|
this.response.end(err.details);
|
||||||
klass.charId = charId; // we currently rely on the client to supply parent
|
} else {
|
||||||
let id = Classes.insert(klass, (err) => {
|
this.response.end(JSON.stringify(res));
|
||||||
if (err) {
|
}
|
||||||
error = err.message;
|
});
|
||||||
}
|
});
|
||||||
});
|
|
||||||
if (error)
|
|
||||||
break;
|
|
||||||
ids.push(id);
|
|
||||||
}
|
|
||||||
if (error) {
|
|
||||||
this.response.writeHead(400, "Failed to insert one or more classes");
|
|
||||||
this.response.end(JSON.stringify({err: error, inserted: ids}));
|
|
||||||
} else {
|
|
||||||
this.response.end(JSON.stringify(ids));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
var ifPostOK = function (router, endpoint, callback) {
|
const startPOSTResponse = function (request) {
|
||||||
router.response.setHeader("Content-Type", "application/json");
|
request.response.setHeader("Content-Type", "application/json");
|
||||||
var header = router.request.headers;
|
const header = request.request.headers;
|
||||||
var key = header && header['authorization'];
|
return header && header['authorization'];
|
||||||
ifKeyValid(key, router.response, endpoint, () => {
|
|
||||||
if (canEditCharacter(router.params._id, userIdFromKey(key))) {
|
|
||||||
callback();
|
|
||||||
} else {
|
|
||||||
router.response.writeHead(403, "You do not have permission to edit this character");
|
|
||||||
router.response.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
var ifKeyValid = function (apiKey, response, method, callback) {
|
var ifKeyValid = function (apiKey, response, method, callback) {
|
||||||
@@ -349,19 +227,19 @@ var ifKeyValid = function (apiKey, response, method, callback) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var isKeyValid = function (apiKey) {
|
isKeyValid = function (apiKey) {
|
||||||
var user = Meteor.users.findOne({apiKey});
|
var user = Meteor.users.findOne({apiKey});
|
||||||
if (!user) return false;
|
if (!user) return false;
|
||||||
var blackListed = Blacklist.findOne({userId: user._id});
|
var blackListed = Blacklist.findOne({userId: user._id});
|
||||||
return !blackListed;
|
return !blackListed;
|
||||||
};
|
};
|
||||||
|
|
||||||
var userIdFromKey = function (apiKey) {
|
userIdFromKey = function (apiKey) {
|
||||||
var user = Meteor.users.findOne({apiKey}); // we know user exists from isKeyValid
|
var user = Meteor.users.findOne({apiKey}); // we know user exists from isKeyValid
|
||||||
return user._id;
|
return user._id;
|
||||||
};
|
};
|
||||||
|
|
||||||
var rateLimiter = new RateLimiter();
|
rateLimiter = new RateLimiter();
|
||||||
// global limit
|
// global limit
|
||||||
rateLimiter.addRule({apiKey: String}, 10, 1000);
|
rateLimiter.addRule({apiKey: String}, 10, 1000);
|
||||||
|
|
||||||
@@ -380,7 +258,7 @@ rateLimiter.addRule({apiKey: String, method: "insertProfs"}, 5, 5000);
|
|||||||
rateLimiter.addRule({apiKey: String, method: "insertEffects"}, 5, 5000);
|
rateLimiter.addRule({apiKey: String, method: "insertEffects"}, 5, 5000);
|
||||||
rateLimiter.addRule({apiKey: String, method: "insertClasses"}, 5, 5000);
|
rateLimiter.addRule({apiKey: String, method: "insertClasses"}, 5, 5000);
|
||||||
|
|
||||||
var isRateLimited = function (apiKey, method) {
|
isRateLimited = function (apiKey, method) {
|
||||||
const limited = !rateLimiter.check({apiKey: apiKey, method: method}).allowed;
|
const limited = !rateLimiter.check({apiKey: apiKey, method: method}).allowed;
|
||||||
if (limited) {
|
if (limited) {
|
||||||
console.log(`Rate limit hit by API key ${apiKey}`);
|
console.log(`Rate limit hit by API key ${apiKey}`);
|
||||||
|
|||||||
241
app/lib/functions/api.js
Normal file
241
app/lib/functions/api.js
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
/**
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
JSONExport = function (charId) {
|
||||||
|
const character = {
|
||||||
|
"attacks": Attacks.find({charId: charId}).fetch(),
|
||||||
|
"characters": Characters.find({_id: charId}).fetch(),
|
||||||
|
"classes": Classes.find({charId: charId}).fetch(),
|
||||||
|
"containers": Containers.find({charId: charId}).fetch(),
|
||||||
|
"effects": Effects.find({charId: charId}).fetch(),
|
||||||
|
"experience": Experiences.find({charId: charId}).fetch(),
|
||||||
|
"features": Features.find({charId: charId}).fetch(),
|
||||||
|
"items": Items.find({charId: charId}).fetch(),
|
||||||
|
"notes": Notes.find({charId: charId}).fetch(),
|
||||||
|
"proficiencies": Proficiencies.find({charId: charId}).fetch(),
|
||||||
|
"spellLists": SpellLists.find({charId: charId}).fetch(),
|
||||||
|
"spells": Spells.find({charId: charId}).fetch()
|
||||||
|
};
|
||||||
|
return JSON.stringify(character);
|
||||||
|
};
|
||||||
|
|
||||||
|
Meteor.methods({
|
||||||
|
"insertSpells": function (key, charId, listId, spells) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifCanEdit(key, charId, "addSpellsToCharacter", () => {
|
||||||
|
let ids = [];
|
||||||
|
let error;
|
||||||
|
for (let spell of spells) {
|
||||||
|
spell.parent = {id: listId, collection: "SpellLists"};
|
||||||
|
spell.charId = charId;
|
||||||
|
let id = Spells.insert(spell, (err) => {
|
||||||
|
if (err) {
|
||||||
|
error = err.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to insert one or more spells", JSON.stringify({
|
||||||
|
err: error,
|
||||||
|
inserted: ids
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"insertCharacter": function (key, character) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifAuthorized(key, "createCharacter", () => {
|
||||||
|
let error;
|
||||||
|
|
||||||
|
character.owner = userIdFromKey(key);
|
||||||
|
let id = Characters.insert(character, (err) => {
|
||||||
|
if (err)
|
||||||
|
error = err.message;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to insert character", JSON.stringify({err: error}));
|
||||||
|
} else {
|
||||||
|
return {id: id};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"deleteCharacter": function (key, charId) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifAuthorized(key, "deleteCharacter", () => {
|
||||||
|
if (isOwner(charId, userIdFromKey(key))) {
|
||||||
|
let error;
|
||||||
|
|
||||||
|
Characters.remove({_id: charId}, (err) => {
|
||||||
|
if (err)
|
||||||
|
error = err.message;
|
||||||
|
});
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to delete character", JSON.stringify({err: error}));
|
||||||
|
} else {
|
||||||
|
return {success: true};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Meteor.Error(403, "You do not have permission to delete the requested character");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"transferCharacterOwnership": function (key, charId, newOwner) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifAuthorized(key, "transferCharacterOwnership", () => {
|
||||||
|
if (isOwner(charId, userIdFromKey(key))) {
|
||||||
|
let error;
|
||||||
|
Characters.update({_id: charId}, {"$set": {owner: newOwner}}, null,
|
||||||
|
(err) => {
|
||||||
|
if (err)
|
||||||
|
error = err.message;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to update character", JSON.stringify({err: error}));
|
||||||
|
} else {
|
||||||
|
return {success: true};
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Meteor.Error(403, "You do not have permission to transfer the requested character");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"insertFeatures": function (key, charId, features) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifCanEdit(key, charId, "insertFeatures", () => {
|
||||||
|
let ids = [];
|
||||||
|
let error;
|
||||||
|
for (let feature of features) {
|
||||||
|
feature.charId = charId;
|
||||||
|
let id = Features.insert(feature, (err) => {
|
||||||
|
if (err) {
|
||||||
|
error = err.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to insert one or more features", JSON.stringify({
|
||||||
|
err: error,
|
||||||
|
inserted: ids
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"insertProfs": function (key, charId, profs) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifCanEdit(key, charId, "insertProfs", () => {
|
||||||
|
let ids = [];
|
||||||
|
let error;
|
||||||
|
for (let prof of profs) {
|
||||||
|
prof.charId = charId; // we currently rely on the client to supply parent
|
||||||
|
let id = Proficiencies.insert(prof, (err) => {
|
||||||
|
if (err) {
|
||||||
|
error = err.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to insert one or more profs", JSON.stringify({
|
||||||
|
err: error,
|
||||||
|
inserted: ids
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"insertEffects": function (key, charId, effects) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifCanEdit(key, charId, "insertEffects", () => {
|
||||||
|
let ids = [];
|
||||||
|
let error;
|
||||||
|
for (let effect of effects) {
|
||||||
|
effect.charId = charId; // we currently rely on the client to supply parent
|
||||||
|
let id = Effects.insert(effect, (err) => {
|
||||||
|
if (err) {
|
||||||
|
error = err.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to insert one or more effects", JSON.stringify({
|
||||||
|
err: error,
|
||||||
|
inserted: ids
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
"insertClasses": function (key, charId, klasses) {
|
||||||
|
if (Meteor.isClient) return;
|
||||||
|
ifCanEdit(key, charId, "insertClasses", () => {
|
||||||
|
let ids = [];
|
||||||
|
let error;
|
||||||
|
for (let klass of klasses) {
|
||||||
|
klass.charId = charId; // we currently rely on the client to supply parent
|
||||||
|
let id = Classes.insert(klass, (err) => {
|
||||||
|
if (err) {
|
||||||
|
error = err.message;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (error)
|
||||||
|
break;
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
throw new Meteor.Error(400, "Failed to insert one or more classes", JSON.stringify({
|
||||||
|
err: error,
|
||||||
|
inserted: ids
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var ifCanEdit = function (key, charId, method, callback) {
|
||||||
|
if (canEditCharacter(charId, userIdFromKey(key))) {
|
||||||
|
ifAuthorized(key, method, callback);
|
||||||
|
} else {
|
||||||
|
throw new Meteor.Error(403, "You do not have permission to edit the requested character");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var ifAuthorized = function (apiKey, method, callback) {
|
||||||
|
if (!apiKey) {
|
||||||
|
throw new Meteor.Error(403, "You must use an api key to access this api");
|
||||||
|
} else if (!isKeyValid(apiKey)) {
|
||||||
|
throw new Meteor.Error(403, "API key is invalid");
|
||||||
|
} else if (isRateLimited(apiKey, method)) {
|
||||||
|
throw new Meteor.Error(429, "Too many requests", JSON.stringify({
|
||||||
|
"timeToReset": rateLimiter.check({apiKey: apiKey, method: method}).timeToReset
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
rateLimiter.increment({apiKey: apiKey, method: method});
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
JSONExport = function(charId) {
|
|
||||||
var character = {
|
|
||||||
"attacks": Attacks.find({charId: charId}).fetch(),
|
|
||||||
"characters": Characters.find({_id: charId}).fetch(),
|
|
||||||
"classes": Classes.find({charId: charId}).fetch(),
|
|
||||||
"containers": Containers.find({charId: charId}).fetch(),
|
|
||||||
"effects": Effects.find({charId: charId}).fetch(),
|
|
||||||
"experience": Experiences.find({charId: charId}).fetch(),
|
|
||||||
"features": Features.find({charId: charId}).fetch(),
|
|
||||||
"items": Items.find({charId: charId}).fetch(),
|
|
||||||
"notes": Notes.find({charId: charId}).fetch(),
|
|
||||||
"proficiencies": Proficiencies.find({charId: charId}).fetch(),
|
|
||||||
"spellLists": SpellLists.find({charId: charId}).fetch(),
|
|
||||||
"spells": Spells.find({charId: charId}).fetch()
|
|
||||||
};
|
|
||||||
return JSON.stringify(character);
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user