From f2ead46580ed25637469a41b202e72a7cf6f3db4 Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Mon, 7 Mar 2016 14:16:26 -0800 Subject: [PATCH 1/4] Remove .rawCollection method from DatabaseController. --- src/Adapters/Storage/Mongo/MongoCollection.js | 4 ++++ src/Controllers/DatabaseController.js | 6 +----- src/Controllers/PushController.js | 16 ++++++---------- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/src/Adapters/Storage/Mongo/MongoCollection.js b/src/Adapters/Storage/Mongo/MongoCollection.js index f19705c42f..78c90fefd0 100644 --- a/src/Adapters/Storage/Mongo/MongoCollection.js +++ b/src/Adapters/Storage/Mongo/MongoCollection.js @@ -64,6 +64,10 @@ export default class MongoCollection { return this._mongoCollection.update(query, update, { upsert: true }); } + updateMany(query, update) { + return this._mongoCollection.updateMany(query, update); + } + // Atomically find and delete an object based on query. // The result is the promise with an object that was in the database before deleting. // Postgres Note: Translates directly to `DELETE * FROM ... RETURNING *`, which will return data after delete is done. diff --git a/src/Controllers/DatabaseController.js b/src/Controllers/DatabaseController.js index 042a086d11..83c2703a34 100644 --- a/src/Controllers/DatabaseController.js +++ b/src/Controllers/DatabaseController.js @@ -35,7 +35,7 @@ DatabaseController.prototype.collection = function(className) { throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, 'invalid className: ' + className); } - return this.rawCollection(className); + return this.adapter.collection(this.collectionPrefix + className); }; DatabaseController.prototype.adaptiveCollection = function(className) { @@ -46,10 +46,6 @@ DatabaseController.prototype.collectionExists = function(className) { return this.adapter.collectionExists(this.collectionPrefix + className); }; -DatabaseController.prototype.rawCollection = function(className) { - return this.adapter.collection(this.collectionPrefix + className); -}; - DatabaseController.prototype.dropCollection = function(className) { return this.adapter.dropCollection(this.collectionPrefix + className); }; diff --git a/src/Controllers/PushController.js b/src/Controllers/PushController.js index 55cb609517..fb03ab52a3 100644 --- a/src/Controllers/PushController.js +++ b/src/Controllers/PushController.js @@ -63,23 +63,19 @@ export class PushController extends AdaptableController { let badgeUpdate = Promise.resolve(); if (body.badge) { - var op = {}; + let op = {}; if (body.badge == "Increment") { - op = {'$inc': {'badge': 1}} + op = { $inc: { badge: 1 } } } else if (Number(body.badge)) { - op = {'$set': {'badge': body.badge } } + op = { $set: { badge: body.badge } } } else { throw "Invalid value for badge, expected number or 'Increment'"; } let updateWhere = deepcopy(where); + updateWhere.deviceType = 'ios'; // Only on iOS! - // Only on iOS! - updateWhere.deviceType = 'ios'; - - // TODO: @nlutsenko replace with better thing - badgeUpdate = config.database.rawCollection("_Installation").then((coll) => { - return coll.update(updateWhere, op, { multi: true }); - }); + badgeUpdate = config.database.adaptiveCollection("_Installation") + .then(coll => coll.updateMany(updateWhere, op)); } return badgeUpdate.then(() => { From 47061d8e98c8dfa69125dc4cf5dd02ade29d61ed Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Mon, 7 Mar 2016 14:23:05 -0800 Subject: [PATCH 2/4] Migrate PushRouter to shared master-key middleware. --- spec/PushRouter.spec.js | 34 ------------------------- src/Routers/PushRouter.js | 52 ++++++++++++++------------------------- 2 files changed, 18 insertions(+), 68 deletions(-) diff --git a/spec/PushRouter.spec.js b/spec/PushRouter.spec.js index e7273dd508..d71f9f5cc6 100644 --- a/spec/PushRouter.spec.js +++ b/spec/PushRouter.spec.js @@ -2,40 +2,6 @@ var PushRouter = require('../src/Routers/PushRouter').PushRouter; var request = require('request'); describe('PushRouter', () => { - it('can check valid master key of request', (done) => { - // Make mock request - var request = { - info: { - masterKey: 'masterKey' - }, - config: { - masterKey: 'masterKey' - } - } - - expect(() => { - PushRouter.validateMasterKey(request); - }).not.toThrow(); - done(); - }); - - it('can check invalid master key of request', (done) => { - // Make mock request - var request = { - info: { - masterKey: 'masterKey' - }, - config: { - masterKey: 'masterKeyAgain' - } - } - - expect(() => { - PushRouter.validateMasterKey(request); - }).toThrow(); - done(); - }); - it('can get query condition when channels is set', (done) => { // Make mock request var request = { diff --git a/src/Routers/PushRouter.js b/src/Routers/PushRouter.js index f75d99985b..c3af0d28f5 100644 --- a/src/Routers/PushRouter.js +++ b/src/Routers/PushRouter.js @@ -1,57 +1,42 @@ -import PushController from '../Controllers/PushController' import PromiseRouter from '../PromiseRouter'; +import * as middleware from "../middlewares"; +import { Parse } from "parse/node"; export class PushRouter extends PromiseRouter { mountRoutes() { - this.route("POST", "/push", req => { return this.handlePOST(req); }); - } - - /** - * Check whether the api call has master key or not. - * @param {Object} request A request object - */ - static validateMasterKey(req) { - if (req.info.masterKey !== req.config.masterKey) { - throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, - 'Master key is invalid, you should only use master key to send push'); - } + this.route("POST", "/push", middleware.promiseEnforceMasterKeyAccess, PushRouter.handlePOST); } - handlePOST(req) { - // TODO: move to middlewares when support for Promise middlewares - PushRouter.validateMasterKey(req); - + static handlePOST(req) { const pushController = req.config.pushController; if (!pushController) { - throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, - 'Push controller is not set'); + throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, 'Push controller is not set'); } - var where = PushRouter.getQueryCondition(req); - + let where = PushRouter.getQueryCondition(req); pushController.sendPush(req.body, where, req.config, req.auth); return Promise.resolve({ - response: { - 'result': true - } + response: { + 'result': true + } }); } - - /** + + /** * Get query condition from the request body. - * @param {Object} request A request object + * @param {Object} req A request object * @returns {Object} The query condition, the where field in a query api call */ static getQueryCondition(req) { - var body = req.body || {}; - var hasWhere = typeof body.where !== 'undefined'; - var hasChannels = typeof body.channels !== 'undefined'; + let body = req.body || {}; + let hasWhere = typeof body.where !== 'undefined'; + let hasChannels = typeof body.channels !== 'undefined'; - var where; + let where; if (hasWhere && hasChannels) { throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, - 'Channels and query can not be set at the same time.'); + 'Channels and query can not be set at the same time.'); } else if (hasWhere) { where = body.where; } else if (hasChannels) { @@ -62,11 +47,10 @@ export class PushRouter extends PromiseRouter { } } else { throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, - 'Channels and query should be set at least one.'); + 'Channels and query should be set at least one.'); } return where; } - } export default PushRouter; From de0f71cc9e4f29a668b9d73aed4a1b459831196e Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Mon, 7 Mar 2016 14:25:04 -0800 Subject: [PATCH 3/4] Remove useless masterKey validation in PushController.sendPush. --- spec/PushController.spec.js | 25 ------------------------- src/Controllers/PushController.js | 14 +------------- 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/spec/PushController.spec.js b/spec/PushController.spec.js index 1821d1a3cf..64a7959a59 100644 --- a/spec/PushController.spec.js +++ b/spec/PushController.spec.js @@ -3,31 +3,6 @@ var PushController = require('../src/Controllers/PushController').PushController var Config = require('../src/Config'); describe('PushController', () => { - it('can check valid master key of request', (done) => { - // Make mock request - var auth = { - isMaster: true - } - - expect(() => { - PushController.validateMasterKey(auth); - }).not.toThrow(); - done(); - }); - - it('can check invalid master key of request', (done) => { - // Make mock request - var auth = { - isMaster: false - } - - expect(() => { - PushController.validateMasterKey(auth); - }).toThrow(); - done(); - }); - - it('can validate device type when no device type is set', (done) => { // Make query condition var where = { diff --git a/src/Controllers/PushController.js b/src/Controllers/PushController.js index fb03ab52a3..116c78ed1f 100644 --- a/src/Controllers/PushController.js +++ b/src/Controllers/PushController.js @@ -36,17 +36,6 @@ export class PushController extends AdaptableController { } } } - - /** - * Check whether the api call has master key or not. - * @param {Object} request A request object - */ - static validateMasterKey(auth = {}) { - if (!auth.isMaster) { - throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, - 'Master key is invalid, you should only use master key to send push'); - } - } sendPush(body = {}, where = {}, config, auth) { var pushAdapter = this.adapter; @@ -54,7 +43,6 @@ export class PushController extends AdaptableController { throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, 'Push adapter is not available'); } - PushController.validateMasterKey(auth); PushController.validatePushType(where, pushAdapter.getValidPushTypes()); // Replace the expiration_time with a valid Unix epoch milliseconds time body['expiration_time'] = PushController.getExpirationTime(body); @@ -140,6 +128,6 @@ export class PushController extends AdaptableController { expectedAdapterType() { return PushAdapter; } -}; +} export default PushController; From 654a540b6acf2e17806027699003f91ed4313581 Mon Sep 17 00:00:00 2001 From: Nikita Lutsenko Date: Mon, 7 Mar 2016 15:42:42 -0800 Subject: [PATCH 4/4] Fix race condition in GlobalConfig test. --- spec/ParseGlobalConfig.spec.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/ParseGlobalConfig.spec.js b/spec/ParseGlobalConfig.spec.js index 176c78609b..4b684553dc 100644 --- a/spec/ParseGlobalConfig.spec.js +++ b/spec/ParseGlobalConfig.spec.js @@ -5,11 +5,11 @@ var Parse = require('parse/node').Parse; let Config = require('../src/Config'); describe('a GlobalConfig', () => { - beforeEach(function (done) { + beforeEach(done => { let config = new Config('test'); config.database.adaptiveCollection('_GlobalConfig') .then(coll => coll.upsertOne({ '_id': 1 }, { $set: { params: { companies: ['US', 'DK'] } } })) - .then(done()); + .then(() => { done(); }); }); it('can be retrieved', (done) => {