Merge pull request #2259 from ParsePlatform/client-sdk-info
Exposes the ClientSDK infos if available
This commit is contained in:
@@ -23,7 +23,8 @@ describe('InstallationsRouter', () => {
|
|||||||
deviceType: 'android'
|
deviceType: 'android'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
query: {}
|
query: {},
|
||||||
|
info: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
var router = new InstallationsRouter();
|
var router = new InstallationsRouter();
|
||||||
@@ -56,7 +57,8 @@ describe('InstallationsRouter', () => {
|
|||||||
where: {
|
where: {
|
||||||
deviceType: 'android'
|
deviceType: 'android'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
info: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
var router = new InstallationsRouter();
|
var router = new InstallationsRouter();
|
||||||
@@ -87,7 +89,8 @@ describe('InstallationsRouter', () => {
|
|||||||
body: {},
|
body: {},
|
||||||
query: {
|
query: {
|
||||||
limit: 0
|
limit: 0
|
||||||
}
|
},
|
||||||
|
info: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
var router = new InstallationsRouter();
|
var router = new InstallationsRouter();
|
||||||
@@ -118,7 +121,8 @@ describe('InstallationsRouter', () => {
|
|||||||
body: {},
|
body: {},
|
||||||
query: {
|
query: {
|
||||||
count: 1
|
count: 1
|
||||||
}
|
},
|
||||||
|
info: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
var router = new InstallationsRouter();
|
var router = new InstallationsRouter();
|
||||||
@@ -153,7 +157,8 @@ describe('InstallationsRouter', () => {
|
|||||||
query: {
|
query: {
|
||||||
limit: 0,
|
limit: 0,
|
||||||
count: 1
|
count: 1
|
||||||
}
|
},
|
||||||
|
info: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
var router = new InstallationsRouter();
|
var router = new InstallationsRouter();
|
||||||
|
|||||||
@@ -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'
|
||||||
|
});
|
||||||
|
})
|
||||||
});
|
});
|
||||||
@@ -14,12 +14,13 @@ import { default as FilesController } from './Controllers/FilesController';
|
|||||||
// include
|
// include
|
||||||
// keys
|
// keys
|
||||||
// redirectClassNameForKey
|
// redirectClassNameForKey
|
||||||
function RestQuery(config, auth, className, restWhere = {}, restOptions = {}) {
|
function RestQuery(config, auth, className, restWhere = {}, restOptions = {}, clientSDK) {
|
||||||
|
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.restWhere = restWhere;
|
this.restWhere = restWhere;
|
||||||
|
this.clientSDK = clientSDK;
|
||||||
this.response = null;
|
this.response = null;
|
||||||
this.findOptions = {};
|
this.findOptions = {};
|
||||||
if (!this.auth.isMaster) {
|
if (!this.auth.isMaster) {
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ import _ from 'lodash';
|
|||||||
// RestWrite will handle objectId, createdAt, and updatedAt for
|
// RestWrite will handle objectId, createdAt, and updatedAt for
|
||||||
// everything. It also knows to use triggers and special modifications
|
// everything. It also knows to use triggers and special modifications
|
||||||
// for the _User class.
|
// 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.config = config;
|
||||||
this.auth = auth;
|
this.auth = auth;
|
||||||
this.className = className;
|
this.className = className;
|
||||||
|
this.clientSDK = clientSDK;
|
||||||
this.storage = {};
|
this.storage = {};
|
||||||
this.runOptions = {};
|
this.runOptions = {};
|
||||||
|
|
||||||
if (!query && data.objectId) {
|
if (!query && data.objectId) {
|
||||||
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId is an invalid field name.');
|
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId is an invalid field name.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export class ClassesRouter extends PromiseRouter {
|
|||||||
if (typeof body.where === 'string') {
|
if (typeof body.where === 'string') {
|
||||||
body.where = JSON.parse(body.where);
|
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) => {
|
.then((response) => {
|
||||||
if (response && response.results) {
|
if (response && response.results) {
|
||||||
for (let result of response.results) {
|
for (let result of response.results) {
|
||||||
@@ -77,7 +77,7 @@ export class ClassesRouter extends PromiseRouter {
|
|||||||
options.include = String(body.include);
|
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) => {
|
.then((response) => {
|
||||||
if (!response.results || response.results.length == 0) {
|
if (!response.results || response.results.length == 0) {
|
||||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.');
|
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Object not found.');
|
||||||
@@ -99,15 +99,15 @@ export class ClassesRouter extends PromiseRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
handleCreate(req) {
|
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) {
|
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) {
|
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(() => {
|
.then(() => {
|
||||||
return {response: {}};
|
return {response: {}};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ function validateWithAppStore(url, receipt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFileForProductIdentifier(productIdentifier, req) {
|
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;
|
const products = result.results;
|
||||||
if (!products || products.length != 1) {
|
if (!products || products.length != 1) {
|
||||||
// Error not found or too many
|
// Error not found or too many
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ export class InstallationsRouter extends ClassesRouter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rest.find(req.config, req.auth,
|
return rest.find(req.config, req.auth,
|
||||||
'_Installation', body.where, options)
|
'_Installation', body.where, options, req.info.clientSDK)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
return {response: response};
|
return {response: response};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export class SessionsRouter extends ClassesRouter {
|
|||||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN,
|
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN,
|
||||||
'Session token required.');
|
'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) => {
|
.then((response) => {
|
||||||
if (!response.results || response.results.length == 0) {
|
if (!response.results || response.results.length == 0) {
|
||||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN,
|
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN,
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export class UsersRouter extends ClassesRouter {
|
|||||||
let sessionToken = req.info.sessionToken;
|
let sessionToken = req.info.sessionToken;
|
||||||
return rest.find(req.config, Auth.master(req.config), '_Session',
|
return rest.find(req.config, Auth.master(req.config), '_Session',
|
||||||
{ sessionToken },
|
{ sessionToken },
|
||||||
{ include: 'user' })
|
{ include: 'user' }, req.info.clientSDK)
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (!response.results ||
|
if (!response.results ||
|
||||||
response.results.length == 0 ||
|
response.results.length == 0 ||
|
||||||
@@ -145,7 +145,7 @@ export class UsersRouter extends ClassesRouter {
|
|||||||
let success = {response: {}};
|
let success = {response: {}};
|
||||||
if (req.info && req.info.sessionToken) {
|
if (req.info && req.info.sessionToken) {
|
||||||
return rest.find(req.config, Auth.master(req.config), '_Session',
|
return rest.find(req.config, Auth.master(req.config), '_Session',
|
||||||
{ sessionToken: req.info.sessionToken }
|
{ sessionToken: req.info.sessionToken }, undefined, req.info.clientSDK
|
||||||
).then((records) => {
|
).then((records) => {
|
||||||
if (records.results && records.results.length) {
|
if (records.results && records.results.length) {
|
||||||
return rest.del(req.config, Auth.master(req.config), '_Session',
|
return rest.del(req.config, Auth.master(req.config), '_Session',
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ function handleBatch(router, req) {
|
|||||||
body: restRequest.body,
|
body: restRequest.body,
|
||||||
params: match.params,
|
params: match.params,
|
||||||
config: req.config,
|
config: req.config,
|
||||||
auth: req.auth
|
auth: req.auth,
|
||||||
|
info: req.info
|
||||||
};
|
};
|
||||||
|
|
||||||
promises.push(match.handler(request).then((response) => {
|
promises.push(match.handler(request).then((response) => {
|
||||||
|
|||||||
@@ -6,6 +6,17 @@ var Parse = require('parse/node').Parse;
|
|||||||
var auth = require('./Auth');
|
var auth = require('./Auth');
|
||||||
var Config = require('./Config');
|
var Config = require('./Config');
|
||||||
|
|
||||||
|
function clientSDKFromVersion(version) {
|
||||||
|
let versionRE = /([-a-zA-Z]+)([0-9\.]+)/;
|
||||||
|
let match = version.toLowerCase().match(versionRE);
|
||||||
|
if (match && match.length === 3) {
|
||||||
|
return {
|
||||||
|
sdk: match[1],
|
||||||
|
version: match[2]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Checks that the request is authorized for this app and checks user
|
// Checks that the request is authorized for this app and checks user
|
||||||
// auth too.
|
// auth too.
|
||||||
// The bodyparser should run before this middleware.
|
// The bodyparser should run before this middleware.
|
||||||
@@ -25,7 +36,8 @@ function handleParseHeaders(req, res, next) {
|
|||||||
clientKey: req.get('X-Parse-Client-Key'),
|
clientKey: req.get('X-Parse-Client-Key'),
|
||||||
javascriptKey: req.get('X-Parse-Javascript-Key'),
|
javascriptKey: req.get('X-Parse-Javascript-Key'),
|
||||||
dotNetKey: req.get('X-Parse-Windows-Key'),
|
dotNetKey: req.get('X-Parse-Windows-Key'),
|
||||||
restAPIKey: req.get('X-Parse-REST-API-Key')
|
restAPIKey: req.get('X-Parse-REST-API-Key'),
|
||||||
|
clientVersion: req.get('X-Parse-Client-Version')
|
||||||
};
|
};
|
||||||
|
|
||||||
var basicAuth = httpAuth(req);
|
var basicAuth = httpAuth(req);
|
||||||
@@ -93,6 +105,10 @@ function handleParseHeaders(req, res, next) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (info.clientVersion) {
|
||||||
|
info.clientSDK = clientSDKFromVersion(info.clientVersion);
|
||||||
|
}
|
||||||
|
|
||||||
if (fileViaJSON) {
|
if (fileViaJSON) {
|
||||||
// We need to repopulate req.body with a buffer
|
// We need to repopulate req.body with a buffer
|
||||||
var base64 = req.body.base64;
|
var base64 = req.body.base64;
|
||||||
@@ -283,5 +299,6 @@ module.exports = {
|
|||||||
handleParseErrors: handleParseErrors,
|
handleParseErrors: handleParseErrors,
|
||||||
handleParseHeaders: handleParseHeaders,
|
handleParseHeaders: handleParseHeaders,
|
||||||
enforceMasterKeyAccess: enforceMasterKeyAccess,
|
enforceMasterKeyAccess: enforceMasterKeyAccess,
|
||||||
promiseEnforceMasterKeyAccess
|
promiseEnforceMasterKeyAccess,
|
||||||
|
clientSDKFromVersion
|
||||||
};
|
};
|
||||||
|
|||||||
18
src/rest.js
18
src/rest.js
@@ -15,21 +15,21 @@ var RestWrite = require('./RestWrite');
|
|||||||
var triggers = require('./triggers');
|
var triggers = require('./triggers');
|
||||||
|
|
||||||
// Returns a promise for an object with optional keys 'results' and 'count'.
|
// 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);
|
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();
|
return query.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get is just like find but only queries an objectId.
|
// 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);
|
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();
|
return query.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a promise that doesn't resolve to any useful value.
|
// 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') {
|
if (typeof objectId !== 'string') {
|
||||||
throw new Parse.Error(Parse.Error.INVALID_JSON,
|
throw new Parse.Error(Parse.Error.INVALID_JSON,
|
||||||
'bad objectId');
|
'bad objectId');
|
||||||
@@ -92,16 +92,16 @@ function del(config, auth, className, objectId) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns a promise for a {response, status, location} object.
|
// 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);
|
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();
|
return write.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a promise that contains the fields of the update that the
|
// Returns a promise that contains the fields of the update that the
|
||||||
// REST API is supposed to return.
|
// REST API is supposed to return.
|
||||||
// Usually, this is just updatedAt.
|
// Usually, this is just updatedAt.
|
||||||
function update(config, auth, className, objectId, restObject) {
|
function update(config, auth, className, objectId, restObject, clientSDK) {
|
||||||
enforceRoleSecurity('update', className, auth);
|
enforceRoleSecurity('update', className, auth);
|
||||||
|
|
||||||
return Promise.resolve().then(() => {
|
return Promise.resolve().then(() => {
|
||||||
@@ -117,7 +117,7 @@ function update(config, auth, className, objectId, restObject) {
|
|||||||
originalRestObject = response.results[0];
|
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();
|
return write.execute();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user