diff --git a/spec/InstallationsRouter.spec.js b/spec/InstallationsRouter.spec.js index 46ac51ef..60965ff9 100644 --- a/spec/InstallationsRouter.spec.js +++ b/spec/InstallationsRouter.spec.js @@ -23,7 +23,8 @@ describe('InstallationsRouter', () => { deviceType: 'android' } }, - query: {} + query: {}, + info: {} }; var router = new InstallationsRouter(); @@ -56,7 +57,8 @@ describe('InstallationsRouter', () => { where: { deviceType: 'android' } - } + }, + info: {} }; var router = new InstallationsRouter(); @@ -87,7 +89,8 @@ describe('InstallationsRouter', () => { body: {}, query: { limit: 0 - } + }, + info: {} }; var router = new InstallationsRouter(); @@ -118,7 +121,8 @@ describe('InstallationsRouter', () => { body: {}, query: { count: 1 - } + }, + info: {} }; var router = new InstallationsRouter(); @@ -153,7 +157,8 @@ describe('InstallationsRouter', () => { query: { limit: 0, count: 1 - } + }, + info: {} }; var router = new InstallationsRouter(); diff --git a/spec/Middlewares.spec.js b/spec/Middlewares.spec.js index 45efc2fd..643506d8 100644 --- a/spec/Middlewares.spec.js +++ b/spec/Middlewares.spec.js @@ -66,4 +66,24 @@ describe('middlewares', () => { }); }); }); + + it('should properly parse the SDK versions', () => { + let clientSDKFromVersion = middlewares.clientSDKFromVersion; + expect(clientSDKFromVersion('i1.1.1')).toEqual({ + sdk: 'i', + version: '1.1.1' + }); + expect(clientSDKFromVersion('i1')).toEqual({ + sdk: 'i', + version: '1' + }); + expect(clientSDKFromVersion('apple-tv1.13.0')).toEqual({ + sdk: 'apple-tv', + version: '1.13.0' + }); + expect(clientSDKFromVersion('js1.9.0')).toEqual({ + sdk: 'js', + version: '1.9.0' + }); + }) }); \ No newline at end of file diff --git a/src/RestQuery.js b/src/RestQuery.js index 349e4e14..9c391ab0 100644 --- a/src/RestQuery.js +++ b/src/RestQuery.js @@ -14,12 +14,13 @@ import { default as FilesController } from './Controllers/FilesController'; // include // keys // redirectClassNameForKey -function RestQuery(config, auth, className, restWhere = {}, restOptions = {}) { +function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, clientSDK) { this.config = config; this.auth = auth; this.className = className; this.restWhere = restWhere; + this.clientSDK = clientSDK; this.response = null; this.findOptions = {}; if (!this.auth.isMaster) { diff --git a/src/RestWrite.js b/src/RestWrite.js index bc1ad2c0..cb438545 100644 --- a/src/RestWrite.js +++ b/src/RestWrite.js @@ -23,13 +23,13 @@ import _ from 'lodash'; // RestWrite will handle objectId, createdAt, and updatedAt for // everything. It also knows to use triggers and special modifications // for the _User class. -function RestWrite(config, auth, className, query, data, originalData) { +function RestWrite(config, auth, className, query, data, originalData, clientSDK) { this.config = config; this.auth = auth; this.className = className; + this.clientSDK = clientSDK; this.storage = {}; this.runOptions = {}; - if (!query && data.objectId) { throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId is an invalid field name.'); } diff --git a/src/Routers/ClassesRouter.js b/src/Routers/ClassesRouter.js index ed56ad6d..e1d186c1 100644 --- a/src/Routers/ClassesRouter.js +++ b/src/Routers/ClassesRouter.js @@ -46,7 +46,7 @@ export class ClassesRouter extends PromiseRouter { if (typeof body.where === 'string') { body.where = JSON.parse(body.where); } - return rest.find(req.config, req.auth, req.params.className, body.where, options) + return rest.find(req.config, req.auth, req.params.className, body.where, options, req.info.clientSDK) .then((response) => { if (response && response.results) { for (let result of response.results) { @@ -77,7 +77,7 @@ export class ClassesRouter extends PromiseRouter { options.include = String(body.include); } - return rest.get(req.config, req.auth, req.params.className, req.params.objectId, options) + return rest.get(req.config, req.auth, req.params.className, req.params.objectId, options, req.info.clientSDK) .then((response) => { if (!response.results || response.results.length == 0) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.'); @@ -99,15 +99,15 @@ export class ClassesRouter extends PromiseRouter { } handleCreate(req) { - return rest.create(req.config, req.auth, req.params.className, req.body); + return rest.create(req.config, req.auth, req.params.className, req.body, req.info.clientSDK); } handleUpdate(req) { - return rest.update(req.config, req.auth, req.params.className, req.params.objectId, req.body); + return rest.update(req.config, req.auth, req.params.className, req.params.objectId, req.body, req.info.clientSDK); } handleDelete(req) { - return rest.del(req.config, req.auth, req.params.className, req.params.objectId) + return rest.del(req.config, req.auth, req.params.className, req.params.objectId, req.info.clientSDK) .then(() => { return {response: {}}; }); diff --git a/src/Routers/IAPValidationRouter.js b/src/Routers/IAPValidationRouter.js index b9618532..70ba3ade 100644 --- a/src/Routers/IAPValidationRouter.js +++ b/src/Routers/IAPValidationRouter.js @@ -43,7 +43,7 @@ function validateWithAppStore(url, receipt) { } function getFileForProductIdentifier(productIdentifier, req) { - return rest.find(req.config, req.auth, '_Product', { productIdentifier: productIdentifier }).then(function(result){ + return rest.find(req.config, req.auth, '_Product', { productIdentifier: productIdentifier }, undefined, req.info.clientSDK).then(function(result){ const products = result.results; if (!products || products.length != 1) { // Error not found or too many diff --git a/src/Routers/InstallationsRouter.js b/src/Routers/InstallationsRouter.js index 4a9efc3f..792f4e20 100644 --- a/src/Routers/InstallationsRouter.js +++ b/src/Routers/InstallationsRouter.js @@ -26,7 +26,7 @@ export class InstallationsRouter extends ClassesRouter { } return rest.find(req.config, req.auth, - '_Installation', body.where, options) + '_Installation', body.where, options, req.info.clientSDK) .then((response) => { return {response: response}; }); diff --git a/src/Routers/SessionsRouter.js b/src/Routers/SessionsRouter.js index 1bae3344..c94b289d 100644 --- a/src/Routers/SessionsRouter.js +++ b/src/Routers/SessionsRouter.js @@ -36,7 +36,7 @@ export class SessionsRouter extends ClassesRouter { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'Session token required.'); } - return rest.find(req.config, Auth.master(req.config), '_Session', { sessionToken: req.info.sessionToken }) + return rest.find(req.config, Auth.master(req.config), '_Session', { sessionToken: req.info.sessionToken }, undefined, req.info.clientSDK) .then((response) => { if (!response.results || response.results.length == 0) { throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index f036a37b..02e9c3b4 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -47,7 +47,7 @@ export class UsersRouter extends ClassesRouter { let sessionToken = req.info.sessionToken; return rest.find(req.config, Auth.master(req.config), '_Session', { sessionToken }, - { include: 'user' }) + { include: 'user' }, req.info.clientSDK) .then((response) => { if (!response.results || response.results.length == 0 || @@ -145,7 +145,7 @@ export class UsersRouter extends ClassesRouter { let success = {response: {}}; if (req.info && req.info.sessionToken) { return rest.find(req.config, Auth.master(req.config), '_Session', - { sessionToken: req.info.sessionToken } + { sessionToken: req.info.sessionToken }, undefined, req.info.clientSDK ).then((records) => { if (records.results && records.results.length) { return rest.del(req.config, Auth.master(req.config), '_Session', diff --git a/src/batch.js b/src/batch.js index 4b710a17..bf61b9e9 100644 --- a/src/batch.js +++ b/src/batch.js @@ -52,7 +52,8 @@ function handleBatch(router, req) { body: restRequest.body, params: match.params, config: req.config, - auth: req.auth + auth: req.auth, + info: req.info }; promises.push(match.handler(request).then((response) => { diff --git a/src/middlewares.js b/src/middlewares.js index 91abea9e..cdf0f380 100644 --- a/src/middlewares.js +++ b/src/middlewares.js @@ -298,5 +298,6 @@ module.exports = { handleParseErrors: handleParseErrors, handleParseHeaders: handleParseHeaders, enforceMasterKeyAccess: enforceMasterKeyAccess, - promiseEnforceMasterKeyAccess + promiseEnforceMasterKeyAccess, + clientSDKFromVersion }; diff --git a/src/rest.js b/src/rest.js index 42595295..83cacd38 100644 --- a/src/rest.js +++ b/src/rest.js @@ -15,21 +15,21 @@ var RestWrite = require('./RestWrite'); var triggers = require('./triggers'); // Returns a promise for an object with optional keys 'results' and 'count'. -function find(config, auth, className, restWhere, restOptions) { +function find(config, auth, className, restWhere, restOptions, clientSDK) { enforceRoleSecurity('find', className, auth); - let query = new RestQuery(config, auth, className, restWhere, restOptions); + let query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK); return query.execute(); } // get is just like find but only queries an objectId. -const get = (config, auth, className, objectId, restOptions) => { +const get = (config, auth, className, objectId, restOptions, clientSDK) => { enforceRoleSecurity('get', className, auth); - let query = new RestQuery(config, auth, className, { objectId }, restOptions); + let query = new RestQuery(config, auth, className, { objectId }, restOptions, clientSDK); return query.execute(); } // Returns a promise that doesn't resolve to any useful value. -function del(config, auth, className, objectId) { +function del(config, auth, className, objectId, clientSDK) { if (typeof objectId !== 'string') { throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad objectId'); @@ -92,16 +92,16 @@ function del(config, auth, className, objectId) { } // Returns a promise for a {response, status, location} object. -function create(config, auth, className, restObject) { +function create(config, auth, className, restObject, clientSDK) { enforceRoleSecurity('create', className, auth); - var write = new RestWrite(config, auth, className, null, restObject); + var write = new RestWrite(config, auth, className, null, restObject, clientSDK); return write.execute(); } // Returns a promise that contains the fields of the update that the // REST API is supposed to return. // Usually, this is just updatedAt. -function update(config, auth, className, objectId, restObject) { +function update(config, auth, className, objectId, restObject, clientSDK) { enforceRoleSecurity('update', className, auth); return Promise.resolve().then(() => { @@ -117,7 +117,7 @@ function update(config, auth, className, objectId, restObject) { originalRestObject = response.results[0]; } - var write = new RestWrite(config, auth, className, {objectId: objectId}, restObject, originalRestObject); + var write = new RestWrite(config, auth, className, {objectId: objectId}, restObject, originalRestObject, clientSDK); return write.execute(); }); }