From d1d22c0d89b2c0d341db5a6c9a8caad6fda5d3ed Mon Sep 17 00:00:00 2001 From: Andrew Zhu Date: Tue, 5 Feb 2019 13:09:56 -0800 Subject: [PATCH] formatting, add helper func for POST endpoints --- app/Routes/API.js | 167 +++++++++++++++++++++++++--------------------- 1 file changed, 91 insertions(+), 76 deletions(-) diff --git a/app/Routes/API.js b/app/Routes/API.js index e375c4f0..b9cb005a 100644 --- a/app/Routes/API.js +++ b/app/Routes/API.js @@ -1,47 +1,47 @@ -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)) - ); - }, - }); +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(); - } - } - ); - }, - }); + 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(); + } + } + ); + }, + }); this.route("getUserId", { // GET /api/user?username=:un path: "/api/user", @@ -67,35 +67,50 @@ Router.map(function() { }); }); -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 ifPostOK = function (router, endpoint, callback) { + router.response.setHeader("Content-Type", "application/json"); + var header = router.request.headers; + var key = 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 isKeyValid = function(apiKey){ - var user = Meteor.users.findOne({apiKey}); - if (!user) return false; - var blackListed = Blacklist.findOne({userId: user._id}); - return !blackListed; +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 userIdFromKey = function(apiKey){ - var user = Meteor.users.findOne({apiKey}); // we know user exists from isKeyValid - return user._id; -} +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); @@ -103,12 +118,12 @@ 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; - } +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; + } };