Enable prefer-const lint rule (#3202)
This commit is contained in:
committed by
Florent Vilmart
parent
a6c988176e
commit
ca286b7108
@@ -11,7 +11,7 @@ export class AccountLockout {
|
||||
* set _failed_login_count to value
|
||||
*/
|
||||
_setFailedLoginCount(value) {
|
||||
let query = {
|
||||
const query = {
|
||||
username: this._user.username
|
||||
};
|
||||
|
||||
|
||||
@@ -57,11 +57,11 @@ function authDataValidator(adapter, appIds, options) {
|
||||
|
||||
module.exports = function(authOptions = {}, enableAnonymousUsers = true) {
|
||||
let _enableAnonymousUsers = enableAnonymousUsers;
|
||||
let setEnableAnonymousUsers = function(enable) {
|
||||
const setEnableAnonymousUsers = function(enable) {
|
||||
_enableAnonymousUsers = enable;
|
||||
}
|
||||
// To handle the test cases on configuration
|
||||
let getValidatorForProvider = function(provider) {
|
||||
const getValidatorForProvider = function(provider) {
|
||||
|
||||
if (provider === 'anonymous' && !_enableAnonymousUsers) {
|
||||
return;
|
||||
|
||||
@@ -28,7 +28,7 @@ function validateAppId() {
|
||||
|
||||
function handleMultipleConfigurations(authData, options) {
|
||||
if (Array.isArray(options)) {
|
||||
let consumer_key = authData.consumer_key;
|
||||
const consumer_key = authData.consumer_key;
|
||||
if (!consumer_key) {
|
||||
logger.error('Twitter Auth', 'Multiple twitter configurations are available, by no consumer_key was sent by the client.');
|
||||
throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'Twitter auth is invalid for this user.');
|
||||
|
||||
@@ -10,7 +10,7 @@ export class InMemoryCache {
|
||||
}
|
||||
|
||||
get(key) {
|
||||
let record = this.cache[key];
|
||||
const record = this.cache[key];
|
||||
if (record == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ export class InMemoryCacheAdapter {
|
||||
|
||||
get(key) {
|
||||
return new Promise((resolve) => {
|
||||
let record = this.cache.get(key);
|
||||
const record = this.cache.get(key);
|
||||
if (record == null) {
|
||||
return resolve(null);
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ export class GridStoreAdapter extends FilesAdapter {
|
||||
// Returns a promise
|
||||
createFile(filename: string, data) {
|
||||
return this._connect().then(database => {
|
||||
let gridStore = new GridStore(database, filename, 'w');
|
||||
const gridStore = new GridStore(database, filename, 'w');
|
||||
return gridStore.open();
|
||||
}).then(gridStore => {
|
||||
return gridStore.write(data);
|
||||
@@ -41,7 +41,7 @@ export class GridStoreAdapter extends FilesAdapter {
|
||||
|
||||
deleteFile(filename: string) {
|
||||
return this._connect().then(database => {
|
||||
let gridStore = new GridStore(database, filename, 'r');
|
||||
const gridStore = new GridStore(database, filename, 'r');
|
||||
return gridStore.open();
|
||||
}).then((gridStore) => {
|
||||
return gridStore.unlink();
|
||||
@@ -54,7 +54,7 @@ export class GridStoreAdapter extends FilesAdapter {
|
||||
return this._connect().then(database => {
|
||||
return GridStore.exist(database, filename)
|
||||
.then(() => {
|
||||
let gridStore = new GridStore(database, filename, 'r');
|
||||
const gridStore = new GridStore(database, filename, 'r');
|
||||
return gridStore.open();
|
||||
});
|
||||
}).then(gridStore => {
|
||||
@@ -69,7 +69,7 @@ export class GridStoreAdapter extends FilesAdapter {
|
||||
getFileStream(filename: string) {
|
||||
return this._connect().then(database => {
|
||||
return GridStore.exist(database, filename).then(() => {
|
||||
let gridStore = new GridStore(database, filename, 'r');
|
||||
const gridStore = new GridStore(database, filename, 'r');
|
||||
return gridStore.open();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -9,9 +9,9 @@ const logger = new winston.Logger();
|
||||
const additionalTransports = [];
|
||||
|
||||
function updateTransports(options) {
|
||||
let transports = Object.assign({}, logger.transports);
|
||||
const transports = Object.assign({}, logger.transports);
|
||||
if (options) {
|
||||
let silent = options.silent;
|
||||
const silent = options.silent;
|
||||
delete options.silent;
|
||||
if (_.isNull(options.dirname)) {
|
||||
delete transports['parse-server'];
|
||||
@@ -84,8 +84,8 @@ export function addTransport(transport) {
|
||||
}
|
||||
|
||||
export function removeTransport(transport) {
|
||||
let transportName = typeof transport == 'string' ? transport : transport.name;
|
||||
let transports = Object.assign({}, logger.transports);
|
||||
const transportName = typeof transport == 'string' ? transport : transport.name;
|
||||
const transports = Object.assign({}, logger.transports);
|
||||
delete transports[transportName];
|
||||
logger.configure({
|
||||
transports: _.values(transports)
|
||||
|
||||
@@ -28,11 +28,11 @@ export class WinstonLoggerAdapter extends LoggerAdapter {
|
||||
options = {};
|
||||
}
|
||||
// defaults to 7 days prior
|
||||
let from = options.from || new Date(Date.now() - (7 * MILLISECONDS_IN_A_DAY));
|
||||
let until = options.until || new Date();
|
||||
let limit = options.size || 10;
|
||||
let order = options.order || 'desc';
|
||||
let level = options.level || 'info';
|
||||
const from = options.from || new Date(Date.now() - (7 * MILLISECONDS_IN_A_DAY));
|
||||
const until = options.until || new Date();
|
||||
const limit = options.size || 10;
|
||||
const order = options.order || 'desc';
|
||||
const level = options.level || 'info';
|
||||
|
||||
const queryOptions = {
|
||||
from,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import events from 'events';
|
||||
|
||||
let emitter = new events.EventEmitter();
|
||||
const emitter = new events.EventEmitter();
|
||||
|
||||
class Publisher {
|
||||
emitter: any;
|
||||
@@ -25,7 +25,7 @@ class Subscriber extends events.EventEmitter {
|
||||
}
|
||||
|
||||
subscribe(channel: string): void {
|
||||
let handler = (message) => {
|
||||
const handler = (message) => {
|
||||
this.emit('message', channel, message);
|
||||
}
|
||||
this.subscriptions.set(channel, handler);
|
||||
@@ -49,7 +49,7 @@ function createSubscriber(): any {
|
||||
return new Subscriber(emitter);
|
||||
}
|
||||
|
||||
let EventEmitterPubSub = {
|
||||
const EventEmitterPubSub = {
|
||||
createPublisher,
|
||||
createSubscriber
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
let mongodb = require('mongodb');
|
||||
let Collection = mongodb.Collection;
|
||||
const mongodb = require('mongodb');
|
||||
const Collection = mongodb.Collection;
|
||||
|
||||
export default class MongoCollection {
|
||||
_mongoCollection:Collection;
|
||||
@@ -21,7 +21,7 @@ export default class MongoCollection {
|
||||
throw error;
|
||||
}
|
||||
// Figure out what key needs an index
|
||||
let key = error.message.match(/field=([A-Za-z_0-9]+) /)[1];
|
||||
const key = error.message.match(/field=([A-Za-z_0-9]+) /)[1];
|
||||
if (!key) {
|
||||
throw error;
|
||||
}
|
||||
@@ -50,7 +50,7 @@ export default class MongoCollection {
|
||||
}
|
||||
|
||||
count(query, { skip, limit, sort, maxTimeMS } = {}) {
|
||||
let countOperation = this._mongoCollection.count(query, { skip, limit, sort, maxTimeMS });
|
||||
const countOperation = this._mongoCollection.count(query, { skip, limit, sort, maxTimeMS });
|
||||
|
||||
return countOperation;
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ function mongoSchemaToParseSchema(mongoSchema) {
|
||||
}
|
||||
|
||||
function _mongoSchemaQueryFromNameQuery(name: string, query) {
|
||||
let object = { _id: name };
|
||||
const object = { _id: name };
|
||||
if (query) {
|
||||
Object.keys(query).forEach(key => {
|
||||
object[key] = query[key];
|
||||
|
||||
@@ -15,8 +15,8 @@ import Parse from 'parse/node';
|
||||
import _ from 'lodash';
|
||||
import defaults from '../../../defaults';
|
||||
|
||||
let mongodb = require('mongodb');
|
||||
let MongoClient = mongodb.MongoClient;
|
||||
const mongodb = require('mongodb');
|
||||
const MongoClient = mongodb.MongoClient;
|
||||
|
||||
const MongoSchemaCollectionName = '_SCHEMA';
|
||||
|
||||
@@ -53,14 +53,14 @@ const convertParseSchemaToMongoSchema = ({...schema}) => {
|
||||
// Returns { code, error } if invalid, or { result }, an object
|
||||
// suitable for inserting into _SCHEMA collection, otherwise.
|
||||
const mongoSchemaFromFieldsAndClassNameAndCLP = (fields, className, classLevelPermissions) => {
|
||||
let mongoObject = {
|
||||
const mongoObject = {
|
||||
_id: className,
|
||||
objectId: 'string',
|
||||
updatedAt: 'string',
|
||||
createdAt: 'string'
|
||||
};
|
||||
|
||||
for (let fieldName in fields) {
|
||||
for (const fieldName in fields) {
|
||||
mongoObject[fieldName] = MongoSchemaCollection.parseFieldTypeToMongoFieldType(fields[fieldName]);
|
||||
}
|
||||
|
||||
@@ -157,7 +157,7 @@ export class MongoStorageAdapter {
|
||||
|
||||
createClass(className, schema) {
|
||||
schema = convertParseSchemaToMongoSchema(schema);
|
||||
let mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(schema.fields, className, schema.classLevelPermissions);
|
||||
const mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(schema.fields, className, schema.classLevelPermissions);
|
||||
mongoObject._id = className;
|
||||
return this._schemaCollection()
|
||||
.then(schemaCollection => schemaCollection._collection.insertOne(mongoObject))
|
||||
@@ -282,7 +282,7 @@ export class MongoStorageAdapter {
|
||||
schema = convertParseSchemaToMongoSchema(schema);
|
||||
return this._adaptiveCollection(className)
|
||||
.then(collection => {
|
||||
let mongoWhere = transformWhere(className, query, schema);
|
||||
const mongoWhere = transformWhere(className, query, schema);
|
||||
return collection.deleteMany(mongoWhere)
|
||||
})
|
||||
.then(({ result }) => {
|
||||
@@ -327,9 +327,9 @@ export class MongoStorageAdapter {
|
||||
// Executes a find. Accepts: className, query in Parse format, and { skip, limit, sort }.
|
||||
find(className, schema, query, { skip, limit, sort, keys }) {
|
||||
schema = convertParseSchemaToMongoSchema(schema);
|
||||
let mongoWhere = transformWhere(className, query, schema);
|
||||
let mongoSort = _.mapKeys(sort, (value, fieldName) => transformKey(className, fieldName, schema));
|
||||
let mongoKeys = _.reduce(keys, (memo, key) => {
|
||||
const mongoWhere = transformWhere(className, query, schema);
|
||||
const mongoSort = _.mapKeys(sort, (value, fieldName) => transformKey(className, fieldName, schema));
|
||||
const mongoKeys = _.reduce(keys, (memo, key) => {
|
||||
memo[transformKey(className, key, schema)] = 1;
|
||||
return memo;
|
||||
}, {});
|
||||
@@ -351,8 +351,8 @@ export class MongoStorageAdapter {
|
||||
// which is why we use sparse indexes.
|
||||
ensureUniqueness(className, schema, fieldNames) {
|
||||
schema = convertParseSchemaToMongoSchema(schema);
|
||||
let indexCreationRequest = {};
|
||||
let mongoFieldNames = fieldNames.map(fieldName => transformKey(className, fieldName, schema));
|
||||
const indexCreationRequest = {};
|
||||
const mongoFieldNames = fieldNames.map(fieldName => transformKey(className, fieldName, schema));
|
||||
mongoFieldNames.forEach(fieldName => {
|
||||
indexCreationRequest[fieldName] = 1;
|
||||
});
|
||||
|
||||
@@ -243,9 +243,9 @@ function transformQueryKeyValue(className, key, value, schema) {
|
||||
// restWhere is the "where" clause in REST API form.
|
||||
// Returns the mongo form of the query.
|
||||
function transformWhere(className, restWhere, schema) {
|
||||
let mongoWhere = {};
|
||||
for (let restKey in restWhere) {
|
||||
let out = transformQueryKeyValue(className, restKey, restWhere[restKey], schema);
|
||||
const mongoWhere = {};
|
||||
for (const restKey in restWhere) {
|
||||
const out = transformQueryKeyValue(className, restKey, restWhere[restKey], schema);
|
||||
mongoWhere[out.key] = out.value;
|
||||
}
|
||||
return mongoWhere;
|
||||
@@ -331,12 +331,12 @@ const parseObjectKeyValueToMongoObjectKeyValue = (restKey, restValue, schema) =>
|
||||
|
||||
const parseObjectToMongoObjectForCreate = (className, restCreate, schema) => {
|
||||
restCreate = addLegacyACL(restCreate);
|
||||
let mongoCreate = {}
|
||||
for (let restKey in restCreate) {
|
||||
const mongoCreate = {}
|
||||
for (const restKey in restCreate) {
|
||||
if (restCreate[restKey] && restCreate[restKey].__type === 'Relation') {
|
||||
continue;
|
||||
}
|
||||
let { key, value } = parseObjectKeyValueToMongoObjectKeyValue(
|
||||
const { key, value } = parseObjectKeyValueToMongoObjectKeyValue(
|
||||
restKey,
|
||||
restCreate[restKey],
|
||||
schema
|
||||
@@ -361,8 +361,8 @@ const parseObjectToMongoObjectForCreate = (className, restCreate, schema) => {
|
||||
|
||||
// Main exposed method to help update old objects.
|
||||
const transformUpdate = (className, restUpdate, parseFormatSchema) => {
|
||||
let mongoUpdate = {};
|
||||
let acl = addLegacyACL(restUpdate);
|
||||
const mongoUpdate = {};
|
||||
const acl = addLegacyACL(restUpdate);
|
||||
if (acl._rperm || acl._wperm || acl._acl) {
|
||||
mongoUpdate.$set = {};
|
||||
if (acl._rperm) {
|
||||
@@ -398,8 +398,8 @@ const transformUpdate = (className, restUpdate, parseFormatSchema) => {
|
||||
|
||||
// Add the legacy _acl format.
|
||||
const addLegacyACL = restObject => {
|
||||
let restObjectCopy = {...restObject};
|
||||
let _acl = {};
|
||||
const restObjectCopy = {...restObject};
|
||||
const _acl = {};
|
||||
|
||||
if (restObject._wperm) {
|
||||
restObject._wperm.forEach(entry => {
|
||||
@@ -532,12 +532,12 @@ function transformConstraint(constraint, inArray) {
|
||||
|
||||
case '$in':
|
||||
case '$nin': {
|
||||
let arr = constraint[key];
|
||||
const arr = constraint[key];
|
||||
if (!(arr instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, 'bad ' + key + ' value');
|
||||
}
|
||||
answer[key] = arr.map(value => {
|
||||
let result = inArray ? transformInteriorAtom(value) : transformTopLevelAtom(value);
|
||||
const result = inArray ? transformInteriorAtom(value) : transformTopLevelAtom(value);
|
||||
if (result === CannotTransform) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `bad atom: ${value}`);
|
||||
}
|
||||
@@ -546,7 +546,7 @@ function transformConstraint(constraint, inArray) {
|
||||
break;
|
||||
}
|
||||
case '$all': {
|
||||
let arr = constraint[key];
|
||||
const arr = constraint[key];
|
||||
if (!(arr instanceof Array)) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON,
|
||||
'bad ' + key + ' value');
|
||||
@@ -761,7 +761,7 @@ const mongoObjectToParseObject = (className, mongoObject, schema) => {
|
||||
return BytesCoder.databaseToJSON(mongoObject);
|
||||
}
|
||||
|
||||
let restObject = {};
|
||||
const restObject = {};
|
||||
if (mongoObject._rperm || mongoObject._wperm) {
|
||||
restObject._rperm = mongoObject._rperm || [];
|
||||
restObject._wperm = mongoObject._wperm || [];
|
||||
@@ -861,7 +861,7 @@ const mongoObjectToParseObject = (className, mongoObject, schema) => {
|
||||
}
|
||||
|
||||
const relationFieldNames = Object.keys(schema.fields).filter(fieldName => schema.fields[fieldName].type === 'Relation');
|
||||
let relationFields = {};
|
||||
const relationFields = {};
|
||||
relationFieldNames.forEach(relationFieldName => {
|
||||
relationFields[relationFieldName] = {
|
||||
__type: 'Relation',
|
||||
|
||||
@@ -2,7 +2,6 @@ const pgp = require('pg-promise')();
|
||||
const parser = require('./PostgresConfigParser');
|
||||
|
||||
export function createClient(uri, databaseOptions) {
|
||||
let client;
|
||||
let dbOptions = {};
|
||||
databaseOptions = databaseOptions || {};
|
||||
|
||||
@@ -14,7 +13,7 @@ export function createClient(uri, databaseOptions) {
|
||||
dbOptions[key] = databaseOptions[key];
|
||||
}
|
||||
|
||||
client = pgp(dbOptions);
|
||||
const client = pgp(dbOptions);
|
||||
|
||||
if (dbOptions.pgOptions) {
|
||||
for (const key in dbOptions.pgOptions) {
|
||||
|
||||
@@ -11,7 +11,7 @@ const logger = require('../../../logger');
|
||||
const debug = function(){
|
||||
let args = [...arguments];
|
||||
args = ['PG: '+arguments[0]].concat(args.slice(1, args.length));
|
||||
let log = logger.getLogger();
|
||||
const log = logger.getLogger();
|
||||
log.debug.apply(log, args);
|
||||
}
|
||||
|
||||
@@ -116,8 +116,8 @@ const toPostgresSchema = (schema) => {
|
||||
const handleDotFields = (object) => {
|
||||
Object.keys(object).forEach(fieldName => {
|
||||
if (fieldName.indexOf('.') > -1) {
|
||||
let components = fieldName.split('.');
|
||||
let first = components.shift();
|
||||
const components = fieldName.split('.');
|
||||
const first = components.shift();
|
||||
object[first] = object[first] || {};
|
||||
let currentObj = object[first];
|
||||
let next;
|
||||
@@ -156,7 +156,7 @@ const validateKeys = (object) => {
|
||||
|
||||
// Returns the list of join tables on a schema
|
||||
const joinTablesForSchema = (schema) => {
|
||||
let list = [];
|
||||
const list = [];
|
||||
if (schema) {
|
||||
Object.keys(schema.fields).forEach((field) => {
|
||||
if (schema.fields[field].type === 'Relation') {
|
||||
@@ -168,17 +168,17 @@ const joinTablesForSchema = (schema) => {
|
||||
}
|
||||
|
||||
const buildWhereClause = ({ schema, query, index }) => {
|
||||
let patterns = [];
|
||||
const patterns = [];
|
||||
let values = [];
|
||||
let sorts = [];
|
||||
const sorts = [];
|
||||
|
||||
schema = toPostgresSchema(schema);
|
||||
for (let fieldName in query) {
|
||||
let isArrayField = schema.fields
|
||||
for (const fieldName in query) {
|
||||
const isArrayField = schema.fields
|
||||
&& schema.fields[fieldName]
|
||||
&& schema.fields[fieldName].type === 'Array';
|
||||
let initialPatternsLength = patterns.length;
|
||||
let fieldValue = query[fieldName];
|
||||
const initialPatternsLength = patterns.length;
|
||||
const fieldValue = query[fieldName];
|
||||
|
||||
// nothingin the schema, it's gonna blow up
|
||||
if (!schema.fields[fieldName]) {
|
||||
@@ -189,7 +189,7 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
}
|
||||
|
||||
if (fieldName.indexOf('.') >= 0) {
|
||||
let components = fieldName.split('.').map((cmpt, index) => {
|
||||
const components = fieldName.split('.').map((cmpt, index) => {
|
||||
if (index === 0) {
|
||||
return `"${cmpt}"`;
|
||||
}
|
||||
@@ -211,17 +211,17 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
values.push(fieldName, fieldValue);
|
||||
index += 2;
|
||||
} else if (fieldName === '$or' || fieldName === '$and') {
|
||||
let clauses = [];
|
||||
let clauseValues = [];
|
||||
const clauses = [];
|
||||
const clauseValues = [];
|
||||
fieldValue.forEach((subQuery) => {
|
||||
let clause = buildWhereClause({ schema, query: subQuery, index });
|
||||
const clause = buildWhereClause({ schema, query: subQuery, index });
|
||||
if (clause.pattern.length > 0) {
|
||||
clauses.push(clause.pattern);
|
||||
clauseValues.push(...clause.values);
|
||||
index += clause.values.length;
|
||||
}
|
||||
});
|
||||
let orOrAnd = fieldName === '$or' ? ' OR ' : ' AND ';
|
||||
const orOrAnd = fieldName === '$or' ? ' OR ' : ' AND ';
|
||||
patterns.push(`(${clauses.join(orOrAnd)})`);
|
||||
values.push(...clauseValues);
|
||||
}
|
||||
@@ -254,7 +254,7 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
isArrayField &&
|
||||
schema.fields[fieldName].contents &&
|
||||
schema.fields[fieldName].contents.type === 'String') {
|
||||
let inPatterns = [];
|
||||
const inPatterns = [];
|
||||
let allowNull = false;
|
||||
values.push(fieldName);
|
||||
fieldValue.$in.forEach((listElem, listIndex) => {
|
||||
@@ -274,13 +274,13 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
} else if (isInOrNin) {
|
||||
var createConstraint = (baseArray, notIn) => {
|
||||
if (baseArray.length > 0) {
|
||||
let not = notIn ? ' NOT ' : '';
|
||||
const not = notIn ? ' NOT ' : '';
|
||||
if (isArrayField) {
|
||||
patterns.push(`${not} array_contains($${index}:name, $${index+1})`);
|
||||
values.push(fieldName, JSON.stringify(baseArray));
|
||||
index += 2;
|
||||
} else {
|
||||
let inPatterns = [];
|
||||
const inPatterns = [];
|
||||
values.push(fieldName);
|
||||
baseArray.forEach((listElem, listIndex) => {
|
||||
values.push(listElem);
|
||||
@@ -320,9 +320,9 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
}
|
||||
|
||||
if (fieldValue.$nearSphere) {
|
||||
let point = fieldValue.$nearSphere;
|
||||
let distance = fieldValue.$maxDistance;
|
||||
let distanceInKM = distance*6371*1000;
|
||||
const point = fieldValue.$nearSphere;
|
||||
const distance = fieldValue.$maxDistance;
|
||||
const distanceInKM = distance*6371*1000;
|
||||
patterns.push(`ST_distance_sphere($${index}:name::geometry, POINT($${index+1}, $${index+2})::geometry) <= $${index+3}`);
|
||||
sorts.push(`ST_distance_sphere($${index}:name::geometry, POINT($${index+1}, $${index+2})::geometry) ASC`)
|
||||
values.push(fieldName, point.longitude, point.latitude, distanceInKM);
|
||||
@@ -330,11 +330,11 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
}
|
||||
|
||||
if (fieldValue.$within && fieldValue.$within.$box) {
|
||||
let box = fieldValue.$within.$box;
|
||||
let left = box[0].longitude;
|
||||
let bottom = box[0].latitude;
|
||||
let right = box[1].longitude;
|
||||
let top = box[1].latitude;
|
||||
const box = fieldValue.$within.$box;
|
||||
const left = box[0].longitude;
|
||||
const bottom = box[0].latitude;
|
||||
const right = box[1].longitude;
|
||||
const top = box[1].latitude;
|
||||
|
||||
patterns.push(`$${index}:name::point <@ $${index+1}::box`);
|
||||
values.push(fieldName, `((${left}, ${bottom}), (${right}, ${top}))`);
|
||||
@@ -344,7 +344,7 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
if (fieldValue.$regex) {
|
||||
let regex = fieldValue.$regex;
|
||||
let operator = '~';
|
||||
let opts = fieldValue.$options;
|
||||
const opts = fieldValue.$options;
|
||||
if (opts) {
|
||||
if (opts.indexOf('i') >= 0) {
|
||||
operator = '~*';
|
||||
@@ -381,7 +381,7 @@ const buildWhereClause = ({ schema, query, index }) => {
|
||||
|
||||
Object.keys(ParseToPosgresComparator).forEach(cmp => {
|
||||
if (fieldValue[cmp]) {
|
||||
let pgComparator = ParseToPosgresComparator[cmp];
|
||||
const pgComparator = ParseToPosgresComparator[cmp];
|
||||
patterns.push(`$${index}:name ${pgComparator} $${index + 1}`);
|
||||
values.push(fieldName, toPostgresValue(fieldValue[cmp]));
|
||||
index += 2;
|
||||
@@ -461,9 +461,9 @@ export class PostgresStorageAdapter {
|
||||
createTable(className, schema, conn) {
|
||||
conn = conn || this._client;
|
||||
debug('createTable', className, schema);
|
||||
let valuesArray = [];
|
||||
let patternsArray = [];
|
||||
let fields = Object.assign({}, schema.fields);
|
||||
const valuesArray = [];
|
||||
const patternsArray = [];
|
||||
const fields = Object.assign({}, schema.fields);
|
||||
if (className === '_User') {
|
||||
fields._email_verify_token_expires_at = {type: 'Date'};
|
||||
fields._email_verify_token = {type: 'String'};
|
||||
@@ -475,9 +475,9 @@ export class PostgresStorageAdapter {
|
||||
fields._password_history = { type: 'Array'};
|
||||
}
|
||||
let index = 2;
|
||||
let relations = [];
|
||||
const relations = [];
|
||||
Object.keys(fields).forEach((fieldName) => {
|
||||
let parseType = fields[fieldName];
|
||||
const parseType = fields[fieldName];
|
||||
// Skip when it's a relation
|
||||
// We'll create the tables later
|
||||
if (parseType.type === 'Relation') {
|
||||
@@ -557,7 +557,7 @@ export class PostgresStorageAdapter {
|
||||
// and resolves with false if it wasn't (eg. a join table). Rejects if deletion was impossible.
|
||||
deleteClass(className) {
|
||||
return Promise.resolve().then(() => {
|
||||
let operations = [[`DROP TABLE IF EXISTS $1:name`, [className]],
|
||||
const operations = [[`DROP TABLE IF EXISTS $1:name`, [className]],
|
||||
[`DELETE FROM "_SCHEMA" WHERE "className"=$1`, [className]]];
|
||||
return this._client.tx(t=>t.batch(operations.map(statement=>t.none(statement[0], statement[1]))));
|
||||
}).then(() => {
|
||||
@@ -568,11 +568,11 @@ export class PostgresStorageAdapter {
|
||||
|
||||
// Delete all data known to this adapter. Used for testing.
|
||||
deleteAllClasses() {
|
||||
let now = new Date().getTime();
|
||||
const now = new Date().getTime();
|
||||
debug('deleteAllClasses');
|
||||
return this._client.any('SELECT * FROM "_SCHEMA"')
|
||||
.then(results => {
|
||||
let joins = results.reduce((list, schema) => {
|
||||
const joins = results.reduce((list, schema) => {
|
||||
return list.concat(joinTablesForSchema(schema.schema));
|
||||
}, []);
|
||||
const classes = ['_SCHEMA','_PushStatus','_JobStatus','_Hooks','_GlobalConfig', ...results.map(result => result.className), ...joins];
|
||||
@@ -607,7 +607,7 @@ export class PostgresStorageAdapter {
|
||||
return Promise.resolve()
|
||||
.then(() => {
|
||||
fieldNames = fieldNames.reduce((list, fieldName) => {
|
||||
let field = schema.fields[fieldName]
|
||||
const field = schema.fields[fieldName]
|
||||
if (field.type !== 'Relation') {
|
||||
list.push(fieldName);
|
||||
}
|
||||
@@ -615,13 +615,13 @@ export class PostgresStorageAdapter {
|
||||
return list;
|
||||
}, []);
|
||||
|
||||
let values = [className, ...fieldNames];
|
||||
let columns = fieldNames.map((name, idx) => {
|
||||
const values = [className, ...fieldNames];
|
||||
const columns = fieldNames.map((name, idx) => {
|
||||
return `$${idx+2}:name`;
|
||||
}).join(',');
|
||||
|
||||
let doBatch = (t) => {
|
||||
let batch = [
|
||||
const doBatch = (t) => {
|
||||
const batch = [
|
||||
t.none('UPDATE "_SCHEMA" SET "schema"=$<schema> WHERE "className"=$<className>', {schema, className})
|
||||
];
|
||||
if (values.length > 1) {
|
||||
@@ -663,9 +663,9 @@ export class PostgresStorageAdapter {
|
||||
createObject(className, schema, object) {
|
||||
debug('createObject', className, object);
|
||||
let columnsArray = [];
|
||||
let valuesArray = [];
|
||||
const valuesArray = [];
|
||||
schema = toPostgresSchema(schema);
|
||||
let geoPoints = {};
|
||||
const geoPoints = {};
|
||||
|
||||
object = handleDotFields(object);
|
||||
|
||||
@@ -747,9 +747,9 @@ export class PostgresStorageAdapter {
|
||||
});
|
||||
|
||||
columnsArray = columnsArray.concat(Object.keys(geoPoints));
|
||||
let initialValues = valuesArray.map((val, index) => {
|
||||
const initialValues = valuesArray.map((val, index) => {
|
||||
let termination = '';
|
||||
let fieldName = columnsArray[index];
|
||||
const fieldName = columnsArray[index];
|
||||
if (['_rperm','_wperm'].indexOf(fieldName) >= 0) {
|
||||
termination = '::text[]';
|
||||
} else if (schema.fields[fieldName] && schema.fields[fieldName].type === 'Array') {
|
||||
@@ -757,18 +757,18 @@ export class PostgresStorageAdapter {
|
||||
}
|
||||
return `$${index + 2 + columnsArray.length}${termination}`;
|
||||
});
|
||||
let geoPointsInjects = Object.keys(geoPoints).map((key) => {
|
||||
let value = geoPoints[key];
|
||||
const geoPointsInjects = Object.keys(geoPoints).map((key) => {
|
||||
const value = geoPoints[key];
|
||||
valuesArray.push(value.longitude, value.latitude);
|
||||
let l = valuesArray.length + columnsArray.length;
|
||||
const l = valuesArray.length + columnsArray.length;
|
||||
return `POINT($${l}, $${l+1})`;
|
||||
});
|
||||
|
||||
let columnsPattern = columnsArray.map((col, index) => `$${index + 2}:name`).join(',');
|
||||
let valuesPattern = initialValues.concat(geoPointsInjects).join(',')
|
||||
const columnsPattern = columnsArray.map((col, index) => `$${index + 2}:name`).join(',');
|
||||
const valuesPattern = initialValues.concat(geoPointsInjects).join(',')
|
||||
|
||||
let qs = `INSERT INTO $1:name (${columnsPattern}) VALUES (${valuesPattern})`
|
||||
let values = [className, ...columnsArray, ...valuesArray]
|
||||
const qs = `INSERT INTO $1:name (${columnsPattern}) VALUES (${valuesPattern})`
|
||||
const values = [className, ...columnsArray, ...valuesArray]
|
||||
debug(qs, values);
|
||||
return this._client.any(qs, values)
|
||||
.then(() => ({ ops: [object] }))
|
||||
@@ -786,14 +786,14 @@ export class PostgresStorageAdapter {
|
||||
// If there is some other error, reject with INTERNAL_SERVER_ERROR.
|
||||
deleteObjectsByQuery(className, schema, query) {
|
||||
debug('deleteObjectsByQuery', className, query);
|
||||
let values = [className];
|
||||
let index = 2;
|
||||
let where = buildWhereClause({ schema, index, query })
|
||||
const values = [className];
|
||||
const index = 2;
|
||||
const where = buildWhereClause({ schema, index, query })
|
||||
values.push(...where.values);
|
||||
if (Object.keys(query).length === 0) {
|
||||
where.pattern = 'TRUE';
|
||||
}
|
||||
let qs = `WITH deleted AS (DELETE FROM $1:name WHERE ${where.pattern} RETURNING *) SELECT count(*) FROM deleted`;
|
||||
const qs = `WITH deleted AS (DELETE FROM $1:name WHERE ${where.pattern} RETURNING *) SELECT count(*) FROM deleted`;
|
||||
debug(qs, values);
|
||||
return this._client.one(qs, values , a => +a.count)
|
||||
.then(count => {
|
||||
@@ -813,8 +813,8 @@ export class PostgresStorageAdapter {
|
||||
// Apply the update to all objects that match the given Parse Query.
|
||||
updateObjectsByQuery(className, schema, query, update) {
|
||||
debug('updateObjectsByQuery', className, query, update);
|
||||
let updatePatterns = [];
|
||||
let values = [className]
|
||||
const updatePatterns = [];
|
||||
const values = [className]
|
||||
let index = 2;
|
||||
schema = toPostgresSchema(schema);
|
||||
|
||||
@@ -822,19 +822,19 @@ export class PostgresStorageAdapter {
|
||||
update = handleDotFields(update);
|
||||
// Resolve authData first,
|
||||
// So we don't end up with multiple key updates
|
||||
for (let fieldName in update) {
|
||||
let authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/);
|
||||
for (const fieldName in update) {
|
||||
const authDataMatch = fieldName.match(/^_auth_data_([a-zA-Z0-9_]+)$/);
|
||||
if (authDataMatch) {
|
||||
var provider = authDataMatch[1];
|
||||
let value = update[fieldName];
|
||||
const value = update[fieldName];
|
||||
delete update[fieldName];
|
||||
update['authData'] = update['authData'] || {};
|
||||
update['authData'][provider] = value;
|
||||
}
|
||||
}
|
||||
|
||||
for (let fieldName in update) {
|
||||
let fieldValue = update[fieldName];
|
||||
for (const fieldName in update) {
|
||||
const fieldValue = update[fieldName];
|
||||
if (fieldValue === null) {
|
||||
updatePatterns.push(`$${index}:name = NULL`);
|
||||
values.push(fieldName);
|
||||
@@ -842,15 +842,15 @@ export class PostgresStorageAdapter {
|
||||
} else if (fieldName == 'authData') {
|
||||
// This recursively sets the json_object
|
||||
// Only 1 level deep
|
||||
let generate = (jsonb, key, value) => {
|
||||
const generate = (jsonb, key, value) => {
|
||||
return `json_object_set_key(COALESCE(${jsonb}, '{}'::jsonb), ${key}, ${value})::jsonb`;
|
||||
}
|
||||
let lastKey = `$${index}:name`;
|
||||
let fieldNameIndex = index;
|
||||
const lastKey = `$${index}:name`;
|
||||
const fieldNameIndex = index;
|
||||
index+=1;
|
||||
values.push(fieldName);
|
||||
let update = Object.keys(fieldValue).reduce((lastKey, key) => {
|
||||
let str = generate(lastKey, `$${index}::text`, `$${index+1}::jsonb`)
|
||||
const update = Object.keys(fieldValue).reduce((lastKey, key) => {
|
||||
const str = generate(lastKey, `$${index}::text`, `$${index+1}::jsonb`)
|
||||
index+=2;
|
||||
let value = fieldValue[key];
|
||||
if (value) {
|
||||
@@ -941,12 +941,12 @@ export class PostgresStorageAdapter {
|
||||
} else if (Array.isArray(fieldValue)
|
||||
&& schema.fields[fieldName]
|
||||
&& schema.fields[fieldName].type === 'Array') {
|
||||
let expectedType = parseTypeToPostgresType(schema.fields[fieldName]);
|
||||
const expectedType = parseTypeToPostgresType(schema.fields[fieldName]);
|
||||
if (expectedType === 'text[]') {
|
||||
updatePatterns.push(`$${index}:name = $${index + 1}::text[]`);
|
||||
} else {
|
||||
let type = 'text';
|
||||
for (let elt of fieldValue) {
|
||||
for (const elt of fieldValue) {
|
||||
if (typeof elt == 'object') {
|
||||
type = 'json';
|
||||
break;
|
||||
@@ -962,10 +962,10 @@ export class PostgresStorageAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
let where = buildWhereClause({ schema, index, query })
|
||||
const where = buildWhereClause({ schema, index, query })
|
||||
values.push(...where.values);
|
||||
|
||||
let qs = `UPDATE $1:name SET ${updatePatterns.join(',')} WHERE ${where.pattern} RETURNING *`;
|
||||
const qs = `UPDATE $1:name SET ${updatePatterns.join(',')} WHERE ${where.pattern} RETURNING *`;
|
||||
debug('update: ', qs, values);
|
||||
return this._client.any(qs, values); // TODO: This is unsafe, verification is needed, or a different query method;
|
||||
}
|
||||
@@ -973,7 +973,7 @@ export class PostgresStorageAdapter {
|
||||
// Hopefully, we can get rid of this. It's only used for config and hooks.
|
||||
upsertOneObject(className, schema, query, update) {
|
||||
debug('upsertOneObject', {className, query, update});
|
||||
let createValue = Object.assign({}, query, update);
|
||||
const createValue = Object.assign({}, query, update);
|
||||
return this.createObject(className, schema, createValue).catch((err) => {
|
||||
// ignore duplicate value errors as it's upsert
|
||||
if (err.code === Parse.Error.DUPLICATE_VALUE) {
|
||||
@@ -988,7 +988,7 @@ export class PostgresStorageAdapter {
|
||||
const hasLimit = limit !== undefined;
|
||||
const hasSkip = skip !== undefined;
|
||||
let values = [className];
|
||||
let where = buildWhereClause({ schema, query, index: 2 })
|
||||
const where = buildWhereClause({ schema, query, index: 2 })
|
||||
values.push(...where.values);
|
||||
|
||||
const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : '';
|
||||
@@ -1003,7 +1003,7 @@ export class PostgresStorageAdapter {
|
||||
|
||||
let sortPattern = '';
|
||||
if (sort) {
|
||||
let sorting = Object.keys(sort).map((key) => {
|
||||
const sorting = Object.keys(sort).map((key) => {
|
||||
// Using $idx pattern gives: non-integer constant in ORDER BY
|
||||
if (sort[key] === 1) {
|
||||
return `"${key}" ASC`;
|
||||
@@ -1085,7 +1085,7 @@ export class PostgresStorageAdapter {
|
||||
object._password_changed_at = { __type: 'Date', iso: object._password_changed_at.toISOString() };
|
||||
}
|
||||
|
||||
for (let fieldName in object) {
|
||||
for (const fieldName in object) {
|
||||
if (object[fieldName] === null) {
|
||||
delete object[fieldName];
|
||||
}
|
||||
@@ -1125,8 +1125,8 @@ export class PostgresStorageAdapter {
|
||||
// Executes a count.
|
||||
count(className, schema, query) {
|
||||
debug('count', className, query);
|
||||
let values = [className];
|
||||
let where = buildWhereClause({ schema, query, index: 2 });
|
||||
const values = [className];
|
||||
const where = buildWhereClause({ schema, query, index: 2 });
|
||||
values.push(...where.values);
|
||||
|
||||
const wherePattern = where.pattern.length > 0 ? `WHERE ${where.pattern}` : '';
|
||||
@@ -1140,7 +1140,7 @@ export class PostgresStorageAdapter {
|
||||
}
|
||||
|
||||
performInitialization({ VolatileClassesSchemas }) {
|
||||
let now = new Date().getTime();
|
||||
const now = new Date().getTime();
|
||||
debug('performInitialization');
|
||||
let promises = VolatileClassesSchemas.map((schema) => {
|
||||
return this.createTable(schema.className, schema).catch((err) =>{
|
||||
|
||||
14
src/Auth.js
14
src/Auth.js
@@ -44,7 +44,7 @@ function nobody(config) {
|
||||
var getAuthForSessionToken = function({ config, sessionToken, installationId } = {}) {
|
||||
return config.cacheController.user.get(sessionToken).then((userJSON) => {
|
||||
if (userJSON) {
|
||||
let cachedUser = Parse.Object.fromJSON(userJSON);
|
||||
const cachedUser = Parse.Object.fromJSON(userJSON);
|
||||
return Promise.resolve(new Auth({config, isMaster: false, installationId, user: cachedUser}));
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ var getAuthForSessionToken = function({ config, sessionToken, installationId } =
|
||||
obj['className'] = '_User';
|
||||
obj['sessionToken'] = sessionToken;
|
||||
config.cacheController.user.put(sessionToken, obj);
|
||||
let userObject = Parse.Object.fromJSON(obj);
|
||||
const userObject = Parse.Object.fromJSON(obj);
|
||||
return new Auth({config, isMaster: false, installationId, user: userObject});
|
||||
});
|
||||
});
|
||||
@@ -87,9 +87,9 @@ var getAuthForLegacySessionToken = function({config, sessionToken, installationI
|
||||
if (results.length !== 1) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid legacy session token');
|
||||
}
|
||||
let obj = results[0];
|
||||
const obj = results[0];
|
||||
obj.className = '_User';
|
||||
let userObject = Parse.Object.fromJSON(obj);
|
||||
const userObject = Parse.Object.fromJSON(obj);
|
||||
return new Auth({config, isMaster: false, installationId, user: userObject});
|
||||
});
|
||||
}
|
||||
@@ -162,7 +162,7 @@ Auth.prototype._loadRoles = function() {
|
||||
|
||||
// Given a list of roleIds, find all the parent roles, returns a promise with all names
|
||||
Auth.prototype._getAllRolesNamesForRoleIds = function(roleIDs, names = [], queriedRoles = {}) {
|
||||
let ins = roleIDs.filter((roleID) => {
|
||||
const ins = roleIDs.filter((roleID) => {
|
||||
return queriedRoles[roleID] !== true;
|
||||
}).map((roleID) => {
|
||||
// mark as queried
|
||||
@@ -185,7 +185,7 @@ Auth.prototype._getAllRolesNamesForRoleIds = function(roleIDs, names = [], queri
|
||||
} else {
|
||||
restWhere = { 'roles': { '$in': ins }}
|
||||
}
|
||||
let query = new RestQuery(this.config, master(this.config), '_Role', restWhere, {});
|
||||
const query = new RestQuery(this.config, master(this.config), '_Role', restWhere, {});
|
||||
return query.execute().then((response) => {
|
||||
var results = response.results;
|
||||
// Nothing found
|
||||
@@ -193,7 +193,7 @@ Auth.prototype._getAllRolesNamesForRoleIds = function(roleIDs, names = [], queri
|
||||
return Promise.resolve(names);
|
||||
}
|
||||
// Map the results with all Ids and names
|
||||
let resultMap = results.reduce((memo, role) => {
|
||||
const resultMap = results.reduce((memo, role) => {
|
||||
memo.names.push(role.name);
|
||||
memo.ids.push(role.objectId);
|
||||
return memo;
|
||||
|
||||
@@ -9,8 +9,8 @@ function compatible(compatibleSDK) {
|
||||
if (!clientSDK) {
|
||||
return true;
|
||||
}
|
||||
let clientVersion = clientSDK.version;
|
||||
let compatiblityVersion = compatibleSDK[clientSDK.sdk];
|
||||
const clientVersion = clientSDK.version;
|
||||
const compatiblityVersion = compatibleSDK[clientSDK.sdk];
|
||||
return semver.satisfies(clientVersion, compatiblityVersion);
|
||||
}
|
||||
}
|
||||
@@ -22,8 +22,8 @@ function supportsForwardDelete(clientSDK) {
|
||||
}
|
||||
|
||||
function fromString(version) {
|
||||
let versionRE = /([-a-zA-Z]+)([0-9\.]+)/;
|
||||
let match = version.toLowerCase().match(versionRE);
|
||||
const versionRE = /([-a-zA-Z]+)([0-9\.]+)/;
|
||||
const match = version.toLowerCase().match(versionRE);
|
||||
if (match && match.length === 3) {
|
||||
return {
|
||||
sdk: match[1],
|
||||
|
||||
@@ -18,7 +18,7 @@ function removeTrailingSlash(str) {
|
||||
|
||||
export class Config {
|
||||
constructor(applicationId: string, mount: string) {
|
||||
let cacheInfo = AppCache.get(applicationId);
|
||||
const cacheInfo = AppCache.get(applicationId);
|
||||
if (!cacheInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -42,14 +42,14 @@ export class AdaptableController {
|
||||
throw new Error(this.constructor.name+" requires an adapter");
|
||||
}
|
||||
|
||||
let Type = this.expectedAdapterType();
|
||||
const Type = this.expectedAdapterType();
|
||||
// Allow skipping for testing
|
||||
if (!Type) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Makes sure the prototype matches
|
||||
let mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => {
|
||||
const mismatches = Object.getOwnPropertyNames(Type.prototype).reduce((obj, key) => {
|
||||
const adapterType = typeof adapter[key];
|
||||
const expectedType = typeof Type.prototype[key];
|
||||
if (adapterType !== expectedType) {
|
||||
|
||||
@@ -20,17 +20,17 @@ export class SubCache {
|
||||
}
|
||||
|
||||
get(key) {
|
||||
let cacheKey = joinKeys(this.prefix, key);
|
||||
const cacheKey = joinKeys(this.prefix, key);
|
||||
return this.cache.get(cacheKey);
|
||||
}
|
||||
|
||||
put(key, value, ttl) {
|
||||
let cacheKey = joinKeys(this.prefix, key);
|
||||
const cacheKey = joinKeys(this.prefix, key);
|
||||
return this.cache.put(cacheKey, value, ttl);
|
||||
}
|
||||
|
||||
del(key) {
|
||||
let cacheKey = joinKeys(this.prefix, key);
|
||||
const cacheKey = joinKeys(this.prefix, key);
|
||||
return this.cache.del(cacheKey);
|
||||
}
|
||||
|
||||
@@ -50,17 +50,17 @@ export class CacheController extends AdaptableController {
|
||||
}
|
||||
|
||||
get(key) {
|
||||
let cacheKey = joinKeys(this.appId, key);
|
||||
const cacheKey = joinKeys(this.appId, key);
|
||||
return this.adapter.get(cacheKey).then(null, () => Promise.resolve(null));
|
||||
}
|
||||
|
||||
put(key, value, ttl) {
|
||||
let cacheKey = joinKeys(this.appId, key);
|
||||
const cacheKey = joinKeys(this.appId, key);
|
||||
return this.adapter.put(cacheKey, value, ttl);
|
||||
}
|
||||
|
||||
del(key) {
|
||||
let cacheKey = joinKeys(this.appId, key);
|
||||
const cacheKey = joinKeys(this.appId, key);
|
||||
return this.adapter.del(cacheKey);
|
||||
}
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ import logger from '../logger';
|
||||
import * as SchemaController from './SchemaController';
|
||||
|
||||
function addWriteACL(query, acl) {
|
||||
let newQuery = _.cloneDeep(query);
|
||||
const newQuery = _.cloneDeep(query);
|
||||
//Can't be any existing '_wperm' query, we don't allow client queries on that, no need to $and
|
||||
newQuery._wperm = { "$in" : [null, ...acl]};
|
||||
return newQuery;
|
||||
}
|
||||
|
||||
function addReadACL(query, acl) {
|
||||
let newQuery = _.cloneDeep(query);
|
||||
const newQuery = _.cloneDeep(query);
|
||||
//Can't be any existing '_rperm' query, we don't allow client queries on that, no need to $and
|
||||
newQuery._rperm = { "$in" : [null, "*", ...acl]};
|
||||
return newQuery;
|
||||
@@ -31,7 +31,7 @@ const transformObjectACL = ({ ACL, ...result }) => {
|
||||
result._wperm = [];
|
||||
result._rperm = [];
|
||||
|
||||
for (let entry in ACL) {
|
||||
for (const entry in ACL) {
|
||||
if (ACL[entry].read) {
|
||||
result._rperm.push(entry);
|
||||
}
|
||||
@@ -139,7 +139,7 @@ DatabaseController.prototype.redirectClassNameForKey = function(className, key)
|
||||
// batch request, that could confuse other users of the schema.
|
||||
DatabaseController.prototype.validateObject = function(className, object, query, { acl }) {
|
||||
let schema;
|
||||
let isMaster = acl === undefined;
|
||||
const isMaster = acl === undefined;
|
||||
var aclGroup = acl || [];
|
||||
return this.loadSchema().then(s => {
|
||||
schema = s;
|
||||
@@ -241,7 +241,7 @@ DatabaseController.prototype.update = function(className, query, update, {
|
||||
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, `Invalid field name for update: ${fieldName}`);
|
||||
}
|
||||
});
|
||||
for (let updateOperation in update) {
|
||||
for (const updateOperation in update) {
|
||||
if (Object.keys(updateOperation).some(innerKey => innerKey.includes('$') || innerKey.includes('.'))) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_NESTED_KEY, "Nested keys should not contain the '$' or '.' characters");
|
||||
}
|
||||
@@ -270,12 +270,12 @@ DatabaseController.prototype.update = function(className, query, update, {
|
||||
};
|
||||
|
||||
function sanitizeDatabaseResult(originalObject, result) {
|
||||
let response = {};
|
||||
const response = {};
|
||||
if (!result) {
|
||||
return Promise.resolve(response);
|
||||
}
|
||||
Object.keys(originalObject).forEach(key => {
|
||||
let keyUpdate = originalObject[key];
|
||||
const keyUpdate = originalObject[key];
|
||||
// determine if that was an op
|
||||
if (keyUpdate && typeof keyUpdate === 'object' && keyUpdate.__op
|
||||
&& ['Add', 'AddUnique', 'Remove', 'Increment'].indexOf(keyUpdate.__op) > -1) {
|
||||
@@ -300,7 +300,7 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
|
||||
return;
|
||||
}
|
||||
if (op.__op == 'AddRelation') {
|
||||
for (let object of op.objects) {
|
||||
for (const object of op.objects) {
|
||||
pending.push(this.addRelation(key, className,
|
||||
objectId,
|
||||
object.objectId));
|
||||
@@ -309,7 +309,7 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
|
||||
}
|
||||
|
||||
if (op.__op == 'RemoveRelation') {
|
||||
for (let object of op.objects) {
|
||||
for (const object of op.objects) {
|
||||
pending.push(this.removeRelation(key, className,
|
||||
objectId,
|
||||
object.objectId));
|
||||
@@ -324,10 +324,10 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
|
||||
}
|
||||
};
|
||||
|
||||
for (let key in update) {
|
||||
for (const key in update) {
|
||||
process(update[key], key);
|
||||
}
|
||||
for (let key of deleteMe) {
|
||||
for (const key of deleteMe) {
|
||||
delete update[key];
|
||||
}
|
||||
return Promise.all(pending);
|
||||
@@ -337,7 +337,7 @@ DatabaseController.prototype.handleRelationUpdates = function(className, objectI
|
||||
// Returns a promise that resolves successfully iff the add was successful.
|
||||
const relationSchema = { fields: { relatedId: { type: 'String' }, owningId: { type: 'String' } } };
|
||||
DatabaseController.prototype.addRelation = function(key, fromClassName, fromId, toId) {
|
||||
let doc = {
|
||||
const doc = {
|
||||
relatedId: toId,
|
||||
owningId : fromId
|
||||
};
|
||||
@@ -410,7 +410,7 @@ DatabaseController.prototype.destroy = function(className, query, { acl } = {})
|
||||
};
|
||||
|
||||
const flattenUpdateOperatorsForCreate = object => {
|
||||
for (let key in object) {
|
||||
for (const key in object) {
|
||||
if (object[key] && object[key].__op) {
|
||||
switch (object[key].__op) {
|
||||
case 'Increment':
|
||||
@@ -469,7 +469,7 @@ const transformAuthData = (className, object, schema) => {
|
||||
// Returns a promise that resolves successfully iff the object saved.
|
||||
DatabaseController.prototype.create = function(className, object, { acl } = {}) {
|
||||
// Make a copy of the object, so we don't mutate the incoming data.
|
||||
let originalObject = object;
|
||||
const originalObject = object;
|
||||
object = transformObjectACL(object);
|
||||
|
||||
object.createdAt = { iso: object.createdAt, __type: 'Date' };
|
||||
@@ -496,13 +496,13 @@ DatabaseController.prototype.create = function(className, object, { acl } = {})
|
||||
};
|
||||
|
||||
DatabaseController.prototype.canAddField = function(schema, className, object, aclGroup) {
|
||||
let classSchema = schema.data[className];
|
||||
const classSchema = schema.data[className];
|
||||
if (!classSchema) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let fields = Object.keys(object);
|
||||
let schemaFields = Object.keys(classSchema);
|
||||
let newKeys = fields.filter((field) => {
|
||||
const fields = Object.keys(object);
|
||||
const schemaFields = Object.keys(classSchema);
|
||||
const newKeys = fields.filter((field) => {
|
||||
return schemaFields.indexOf(field) < 0;
|
||||
})
|
||||
if (newKeys.length > 0) {
|
||||
@@ -543,7 +543,7 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
|
||||
// Search for an in-relation or equal-to-relation
|
||||
// Make it sequential for now, not sure of paralleization side effects
|
||||
if (query['$or']) {
|
||||
let ors = query['$or'];
|
||||
const ors = query['$or'];
|
||||
return Promise.all(ors.map((aQuery, index) => {
|
||||
return this.reduceInRelation(className, aQuery, schema).then((aQuery) => {
|
||||
query['$or'][index] = aQuery;
|
||||
@@ -553,14 +553,14 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
|
||||
});
|
||||
}
|
||||
|
||||
let promises = Object.keys(query).map((key) => {
|
||||
const promises = Object.keys(query).map((key) => {
|
||||
if (query[key] && (query[key]['$in'] || query[key]['$ne'] || query[key]['$nin'] || query[key].__type == 'Pointer')) {
|
||||
let t = schema.getExpectedType(className, key);
|
||||
const t = schema.getExpectedType(className, key);
|
||||
if (!t || t.type !== 'Relation') {
|
||||
return Promise.resolve(query);
|
||||
}
|
||||
// Build the list of queries
|
||||
let queries = Object.keys(query[key]).map((constraintKey) => {
|
||||
const queries = Object.keys(query[key]).map((constraintKey) => {
|
||||
let relatedIds;
|
||||
let isNegation = false;
|
||||
if (constraintKey === 'objectId') {
|
||||
@@ -586,7 +586,7 @@ DatabaseController.prototype.reduceInRelation = function(className, query, schem
|
||||
delete query[key];
|
||||
// execute each query independnently to build the list of
|
||||
// $in / $nin
|
||||
let promises = queries.map((q) => {
|
||||
const promises = queries.map((q) => {
|
||||
if (!q) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -637,12 +637,12 @@ DatabaseController.prototype.reduceRelationKeys = function(className, query) {
|
||||
};
|
||||
|
||||
DatabaseController.prototype.addInObjectIdsIds = function(ids = null, query) {
|
||||
let idsFromString = typeof query.objectId === 'string' ? [query.objectId] : null;
|
||||
let idsFromEq = query.objectId && query.objectId['$eq'] ? [query.objectId['$eq']] : null;
|
||||
let idsFromIn = query.objectId && query.objectId['$in'] ? query.objectId['$in'] : null;
|
||||
const idsFromString = typeof query.objectId === 'string' ? [query.objectId] : null;
|
||||
const idsFromEq = query.objectId && query.objectId['$eq'] ? [query.objectId['$eq']] : null;
|
||||
const idsFromIn = query.objectId && query.objectId['$in'] ? query.objectId['$in'] : null;
|
||||
|
||||
let allIds = [idsFromString, idsFromEq, idsFromIn, ids].filter(list => list !== null);
|
||||
let totalLength = allIds.reduce((memo, list) => memo + list.length, 0);
|
||||
const allIds = [idsFromString, idsFromEq, idsFromIn, ids].filter(list => list !== null);
|
||||
const totalLength = allIds.reduce((memo, list) => memo + list.length, 0);
|
||||
|
||||
let idsIntersection = [];
|
||||
if (totalLength > 125) {
|
||||
@@ -665,7 +665,7 @@ DatabaseController.prototype.addInObjectIdsIds = function(ids = null, query) {
|
||||
}
|
||||
|
||||
DatabaseController.prototype.addNotInObjectIdsIds = function(ids = [], query) {
|
||||
let idsFromNin = query.objectId && query.objectId['$nin'] ? query.objectId['$nin'] : [];
|
||||
const idsFromNin = query.objectId && query.objectId['$nin'] ? query.objectId['$nin'] : [];
|
||||
let allIds = [...idsFromNin,...ids].filter(list => list !== null);
|
||||
|
||||
// make a set and spread to remove duplicates
|
||||
@@ -707,8 +707,8 @@ DatabaseController.prototype.find = function(className, query, {
|
||||
keys,
|
||||
op
|
||||
} = {}) {
|
||||
let isMaster = acl === undefined;
|
||||
let aclGroup = acl || [];
|
||||
const isMaster = acl === undefined;
|
||||
const aclGroup = acl || [];
|
||||
op = op || (typeof query.objectId == 'string' && Object.keys(query).length === 1 ? 'get' : 'find');
|
||||
let classExists = true;
|
||||
return this.loadSchema()
|
||||
@@ -846,9 +846,9 @@ DatabaseController.prototype.addPointerPermissions = function(schema, className,
|
||||
if (schema.testBaseCLP(className, aclGroup, operation)) {
|
||||
return query;
|
||||
}
|
||||
let perms = schema.perms[className];
|
||||
let field = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
let userACL = aclGroup.filter((acl) => {
|
||||
const perms = schema.perms[className];
|
||||
const field = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
const userACL = aclGroup.filter((acl) => {
|
||||
return acl.indexOf('role:') != 0 && acl != '*';
|
||||
});
|
||||
// the ACL should have exactly 1 user
|
||||
@@ -858,16 +858,16 @@ DatabaseController.prototype.addPointerPermissions = function(schema, className,
|
||||
if (userACL.length != 1) {
|
||||
return;
|
||||
}
|
||||
let userId = userACL[0];
|
||||
let userPointer = {
|
||||
const userId = userACL[0];
|
||||
const userPointer = {
|
||||
"__type": "Pointer",
|
||||
"className": "_User",
|
||||
"objectId": userId
|
||||
};
|
||||
|
||||
let permFields = perms[field];
|
||||
let ors = permFields.map((key) => {
|
||||
let q = {
|
||||
const permFields = perms[field];
|
||||
const ors = permFields.map((key) => {
|
||||
const q = {
|
||||
[key]: userPointer
|
||||
};
|
||||
return {'$and': [q, query]};
|
||||
@@ -886,17 +886,17 @@ DatabaseController.prototype.addPointerPermissions = function(schema, className,
|
||||
DatabaseController.prototype.performInitialization = function() {
|
||||
const requiredUserFields = { fields: { ...SchemaController.defaultColumns._Default, ...SchemaController.defaultColumns._User } };
|
||||
|
||||
let userClassPromise = this.loadSchema()
|
||||
const userClassPromise = this.loadSchema()
|
||||
.then(schema => schema.enforceClassExists('_User'))
|
||||
|
||||
let usernameUniqueness = userClassPromise
|
||||
const usernameUniqueness = userClassPromise
|
||||
.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['username']))
|
||||
.catch(error => {
|
||||
logger.warn('Unable to ensure uniqueness for usernames: ', error);
|
||||
return Promise.reject(error);
|
||||
});
|
||||
|
||||
let emailUniqueness = userClassPromise
|
||||
const emailUniqueness = userClassPromise
|
||||
.then(() => this.adapter.ensureUniqueness('_User', requiredUserFields, ['email']))
|
||||
.catch(error => {
|
||||
logger.warn('Unable to ensure uniqueness for user email addresses: ', error);
|
||||
@@ -904,7 +904,7 @@ DatabaseController.prototype.performInitialization = function() {
|
||||
});
|
||||
|
||||
// Create tables for volatile classes
|
||||
let adapterInit = this.adapter.performInitialization({ VolatileClassesSchemas: SchemaController.VolatileClassesSchemas });
|
||||
const adapterInit = this.adapter.performInitialization({ VolatileClassesSchemas: SchemaController.VolatileClassesSchemas });
|
||||
return Promise.all([usernameUniqueness, emailUniqueness, adapterInit]);
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export class FilesController extends AdaptableController {
|
||||
|
||||
createFile(config, filename, data, contentType) {
|
||||
|
||||
let extname = path.extname(filename);
|
||||
const extname = path.extname(filename);
|
||||
|
||||
const hasExtension = extname.length > 0;
|
||||
|
||||
@@ -53,13 +53,13 @@ export class FilesController extends AdaptableController {
|
||||
if (typeof object !== 'object') {
|
||||
return;
|
||||
}
|
||||
for (let key in object) {
|
||||
let fileObject = object[key];
|
||||
for (const key in object) {
|
||||
const fileObject = object[key];
|
||||
if (fileObject && fileObject['__type'] === 'File') {
|
||||
if (fileObject['url']) {
|
||||
continue;
|
||||
}
|
||||
let filename = fileObject['name'];
|
||||
const filename = fileObject['name'];
|
||||
// all filenames starting with "tfss-" should be from files.parsetfss.com
|
||||
// all filenames starting with a "-" seperated UUID should be from files.parse.com
|
||||
// all other filenames have been migrated or created from Parse Server
|
||||
|
||||
@@ -157,7 +157,7 @@ export class HooksController {
|
||||
|
||||
function wrapToHTTPRequest(hook, key) {
|
||||
return (req, res) => {
|
||||
let jsonBody = {};
|
||||
const jsonBody = {};
|
||||
for (var i in req) {
|
||||
jsonBody[i] = req[i];
|
||||
}
|
||||
@@ -169,7 +169,7 @@ function wrapToHTTPRequest(hook, key) {
|
||||
jsonBody.original = req.original.toJSON();
|
||||
jsonBody.original.className = req.original.className;
|
||||
}
|
||||
let jsonRequest: any = {
|
||||
const jsonRequest: any = {
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
|
||||
@@ -20,7 +20,7 @@ export class LiveQueryController {
|
||||
if (!this.hasLiveQuery(className)) {
|
||||
return;
|
||||
}
|
||||
let req = this._makePublisherRequest(currentObject, originalObject);
|
||||
const req = this._makePublisherRequest(currentObject, originalObject);
|
||||
this.liveQueryPublisher.onCloudCodeAfterSave(req);
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export class LiveQueryController {
|
||||
if (!this.hasLiveQuery(className)) {
|
||||
return;
|
||||
}
|
||||
let req = this._makePublisherRequest(currentObject, originalObject);
|
||||
const req = this._makePublisherRequest(currentObject, originalObject);
|
||||
this.liveQueryPublisher.onCloudCodeAfterDelete(req);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ export class LiveQueryController {
|
||||
}
|
||||
|
||||
_makePublisherRequest(currentObject: any, originalObject: any): any {
|
||||
let req = {
|
||||
const req = {
|
||||
object: currentObject
|
||||
};
|
||||
if (currentObject) {
|
||||
|
||||
@@ -45,7 +45,7 @@ export class LoggerController extends AdaptableController {
|
||||
}
|
||||
|
||||
if (e.body) {
|
||||
for (let key of Object.keys(e.body)) {
|
||||
for (const key of Object.keys(e.body)) {
|
||||
if (key === 'password') {
|
||||
e.body[key] = '********';
|
||||
break;
|
||||
@@ -111,12 +111,12 @@ export class LoggerController extends AdaptableController {
|
||||
}
|
||||
|
||||
static parseOptions(options = {}) {
|
||||
let from = LoggerController.validDateTime(options.from) ||
|
||||
const from = LoggerController.validDateTime(options.from) ||
|
||||
new Date(Date.now() - 7 * MILLISECONDS_IN_A_DAY);
|
||||
let until = LoggerController.validDateTime(options.until) || new Date();
|
||||
let size = Number(options.size) || 10;
|
||||
let order = options.order || LogOrder.DESCENDING;
|
||||
let level = options.level || LogLevel.INFO;
|
||||
const until = LoggerController.validDateTime(options.until) || new Date();
|
||||
const size = Number(options.size) || 10;
|
||||
const order = options.order || LogOrder.DESCENDING;
|
||||
const level = options.level || LogLevel.INFO;
|
||||
|
||||
return {
|
||||
from,
|
||||
|
||||
@@ -57,7 +57,7 @@ export class PushController extends AdaptableController {
|
||||
return Promise.resolve();
|
||||
}
|
||||
if (body.data && body.data.badge) {
|
||||
let badge = body.data.badge;
|
||||
const badge = body.data.badge;
|
||||
let restUpdate = {};
|
||||
if (typeof badge == 'string' && badge.toLowerCase() === 'increment') {
|
||||
restUpdate = { badge: { __op: 'Increment', amount: 1 } }
|
||||
@@ -66,20 +66,20 @@ export class PushController extends AdaptableController {
|
||||
} else {
|
||||
throw "Invalid value for badge, expected number or 'Increment'";
|
||||
}
|
||||
let updateWhere = deepcopy(where);
|
||||
const updateWhere = deepcopy(where);
|
||||
|
||||
badgeUpdate = () => {
|
||||
updateWhere.deviceType = 'ios';
|
||||
// Build a real RestQuery so we can use it in RestWrite
|
||||
let restQuery = new RestQuery(config, master(config), '_Installation', updateWhere);
|
||||
const restQuery = new RestQuery(config, master(config), '_Installation', updateWhere);
|
||||
return restQuery.buildRestWhere().then(() => {
|
||||
let write = new RestWrite(config, master(config), '_Installation', restQuery.restWhere, restUpdate);
|
||||
const write = new RestWrite(config, master(config), '_Installation', restQuery.restWhere, restUpdate);
|
||||
write.runOptions.many = true;
|
||||
return write.execute();
|
||||
});
|
||||
}
|
||||
}
|
||||
let pushStatus = pushStatusHandler(config);
|
||||
const pushStatus = pushStatusHandler(config);
|
||||
return Promise.resolve().then(() => {
|
||||
return pushStatus.setInitial(body, where);
|
||||
}).then(() => {
|
||||
@@ -105,7 +105,7 @@ export class PushController extends AdaptableController {
|
||||
sendToAdapter(body, installations, pushStatus) {
|
||||
if (body.data && body.data.badge && typeof body.data.badge == 'string' && body.data.badge.toLowerCase() == "increment") {
|
||||
// Collect the badges to reduce the # of calls
|
||||
let badgeInstallationsMap = installations.reduce((map, installation) => {
|
||||
const badgeInstallationsMap = installations.reduce((map, installation) => {
|
||||
let badge = installation.badge;
|
||||
if (installation.deviceType != "ios") {
|
||||
badge = UNSUPPORTED_BADGE_KEY;
|
||||
@@ -116,8 +116,8 @@ export class PushController extends AdaptableController {
|
||||
}, {});
|
||||
|
||||
// Map the on the badges count and return the send result
|
||||
let promises = Object.keys(badgeInstallationsMap).map((badge) => {
|
||||
let payload = deepcopy(body);
|
||||
const promises = Object.keys(badgeInstallationsMap).map((badge) => {
|
||||
const payload = deepcopy(body);
|
||||
if (badge == UNSUPPORTED_BADGE_KEY) {
|
||||
delete payload.data.badge;
|
||||
} else {
|
||||
|
||||
@@ -76,7 +76,7 @@ export default class SchemaCache {
|
||||
if (!allKeys) {
|
||||
return;
|
||||
}
|
||||
let promises = Object.keys(allKeys).map((key) => {
|
||||
const promises = Object.keys(allKeys).map((key) => {
|
||||
return this.cache.del(key);
|
||||
});
|
||||
return Promise.all(promises);
|
||||
|
||||
@@ -128,7 +128,7 @@ const requireAuthenticationRegex = /^requiresAuthentication$/
|
||||
const permissionKeyRegex = Object.freeze([userIdRegex, roleRegex, publicRegex, requireAuthenticationRegex]);
|
||||
|
||||
function verifyPermissionKey(key) {
|
||||
let result = permissionKeyRegex.reduce((isGood, regEx) => {
|
||||
const result = permissionKeyRegex.reduce((isGood, regEx) => {
|
||||
isGood = isGood || key.match(regEx) != null;
|
||||
return isGood;
|
||||
}, false);
|
||||
@@ -162,7 +162,7 @@ function validateCLP(perms, fields) {
|
||||
|
||||
Object.keys(perms[operation]).forEach((key) => {
|
||||
verifyPermissionKey(key);
|
||||
let perm = perms[operation][key];
|
||||
const perm = perms[operation][key];
|
||||
if (perm !== true) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_JSON, `'${perm}' is not a valid value for class level permissions ${operation}:${key}:${perm}`);
|
||||
}
|
||||
@@ -346,7 +346,7 @@ export default class SchemaController {
|
||||
|
||||
// Inject the in-memory classes
|
||||
volatileClasses.forEach(className => {
|
||||
let schema = injectDefaultSchema({ className });
|
||||
const schema = injectDefaultSchema({ className });
|
||||
this.data[className] = schema.fields;
|
||||
this.perms[className] = schema.classLevelPermissions;
|
||||
});
|
||||
@@ -439,9 +439,9 @@ export default class SchemaController {
|
||||
updateClass(className, submittedFields, classLevelPermissions, database) {
|
||||
return this.getOneSchema(className)
|
||||
.then(schema => {
|
||||
let existingFields = schema.fields;
|
||||
const existingFields = schema.fields;
|
||||
Object.keys(submittedFields).forEach(name => {
|
||||
let field = submittedFields[name];
|
||||
const field = submittedFields[name];
|
||||
if (existingFields[name] && field.__op !== 'Delete') {
|
||||
throw new Parse.Error(255, `Field ${name} exists, cannot update.`);
|
||||
}
|
||||
@@ -452,16 +452,16 @@ export default class SchemaController {
|
||||
|
||||
delete existingFields._rperm;
|
||||
delete existingFields._wperm;
|
||||
let newSchema = buildMergedSchemaObject(existingFields, submittedFields);
|
||||
let validationError = this.validateSchemaData(className, newSchema, classLevelPermissions, Object.keys(existingFields));
|
||||
const newSchema = buildMergedSchemaObject(existingFields, submittedFields);
|
||||
const validationError = this.validateSchemaData(className, newSchema, classLevelPermissions, Object.keys(existingFields));
|
||||
if (validationError) {
|
||||
throw new Parse.Error(validationError.code, validationError.error);
|
||||
}
|
||||
|
||||
// Finally we have checked to make sure the request is valid and we can start deleting fields.
|
||||
// Do all deletions first, then a single save to _SCHEMA collection to handle all additions.
|
||||
let deletePromises = [];
|
||||
let insertedFields = [];
|
||||
const deletePromises = [];
|
||||
const insertedFields = [];
|
||||
Object.keys(submittedFields).forEach(fieldName => {
|
||||
if (submittedFields[fieldName].__op === 'Delete') {
|
||||
const promise = this.deleteField(fieldName, className, database);
|
||||
@@ -474,7 +474,7 @@ export default class SchemaController {
|
||||
return Promise.all(deletePromises) // Delete Everything
|
||||
.then(() => this.reloadData({ clearCache: true })) // Reload our Schema, so we have all the new values
|
||||
.then(() => {
|
||||
let promises = insertedFields.map(fieldName => {
|
||||
const promises = insertedFields.map(fieldName => {
|
||||
const type = submittedFields[fieldName];
|
||||
return this.enforceFieldExists(className, fieldName, type);
|
||||
});
|
||||
@@ -542,7 +542,7 @@ export default class SchemaController {
|
||||
}
|
||||
|
||||
validateSchemaData(className, fields, classLevelPermissions, existingFieldNames) {
|
||||
for (let fieldName in fields) {
|
||||
for (const fieldName in fields) {
|
||||
if (existingFieldNames.indexOf(fieldName) < 0) {
|
||||
if (!fieldNameIsValid(fieldName)) {
|
||||
return {
|
||||
@@ -561,11 +561,11 @@ export default class SchemaController {
|
||||
}
|
||||
}
|
||||
|
||||
for (let fieldName in defaultColumns[className]) {
|
||||
for (const fieldName in defaultColumns[className]) {
|
||||
fields[fieldName] = defaultColumns[className][fieldName];
|
||||
}
|
||||
|
||||
let geoPoints = Object.keys(fields).filter(key => fields[key] && fields[key].type === 'GeoPoint');
|
||||
const geoPoints = Object.keys(fields).filter(key => fields[key] && fields[key].type === 'GeoPoint');
|
||||
if (geoPoints.length > 1) {
|
||||
return {
|
||||
code: Parse.Error.INCORRECT_TYPE,
|
||||
@@ -605,7 +605,7 @@ export default class SchemaController {
|
||||
}
|
||||
|
||||
return this.reloadData().then(() => {
|
||||
let expectedType = this.getExpectedType(className, fieldName);
|
||||
const expectedType = this.getExpectedType(className, fieldName);
|
||||
if (typeof type === 'string') {
|
||||
type = { type };
|
||||
}
|
||||
@@ -690,11 +690,11 @@ export default class SchemaController {
|
||||
validateObject(className, object, query) {
|
||||
let geocount = 0;
|
||||
let promise = this.enforceClassExists(className);
|
||||
for (let fieldName in object) {
|
||||
for (const fieldName in object) {
|
||||
if (object[fieldName] === undefined) {
|
||||
continue;
|
||||
}
|
||||
let expected = getType(object[fieldName]);
|
||||
const expected = getType(object[fieldName]);
|
||||
if (expected === 'GeoPoint') {
|
||||
geocount++;
|
||||
}
|
||||
@@ -722,12 +722,12 @@ export default class SchemaController {
|
||||
|
||||
// Validates that all the properties are set for the object
|
||||
validateRequiredColumns(className, object, query) {
|
||||
let columns = requiredColumns[className];
|
||||
const columns = requiredColumns[className];
|
||||
if (!columns || columns.length == 0) {
|
||||
return Promise.resolve(this);
|
||||
}
|
||||
|
||||
let missingColumns = columns.filter(function(column){
|
||||
const missingColumns = columns.filter(function(column){
|
||||
if (query && query.objectId) {
|
||||
if (object[column] && typeof object[column] === "object") {
|
||||
// Trying to delete a required column
|
||||
@@ -752,8 +752,8 @@ export default class SchemaController {
|
||||
if (!this.perms[className] || !this.perms[className][operation]) {
|
||||
return true;
|
||||
}
|
||||
let classPerms = this.perms[className];
|
||||
let perms = classPerms[operation];
|
||||
const classPerms = this.perms[className];
|
||||
const perms = classPerms[operation];
|
||||
// Handle the public scenario quickly
|
||||
if (perms['*']) {
|
||||
return true;
|
||||
@@ -774,8 +774,8 @@ export default class SchemaController {
|
||||
if (!this.perms[className] || !this.perms[className][operation]) {
|
||||
return true;
|
||||
}
|
||||
let classPerms = this.perms[className];
|
||||
let perms = classPerms[operation];
|
||||
const classPerms = this.perms[className];
|
||||
const perms = classPerms[operation];
|
||||
|
||||
// If only for authenticated users
|
||||
// make sure we have an aclGroup
|
||||
@@ -797,7 +797,7 @@ export default class SchemaController {
|
||||
|
||||
// No matching CLP, let's check the Pointer permissions
|
||||
// And handle those later
|
||||
let permissionField = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
const permissionField = ['get', 'find'].indexOf(operation) > -1 ? 'readUserFields' : 'writeUserFields';
|
||||
|
||||
// Reject create when write lockdown
|
||||
if (permissionField == 'writeUserFields' && operation == 'create') {
|
||||
@@ -831,7 +831,7 @@ export default class SchemaController {
|
||||
|
||||
// Returns a promise for a new Schema.
|
||||
const load = (dbAdapter, schemaCache, options) => {
|
||||
let schema = new SchemaController(dbAdapter, schemaCache);
|
||||
const schema = new SchemaController(dbAdapter, schemaCache);
|
||||
return schema.reloadData(options).then(() => schema);
|
||||
}
|
||||
|
||||
@@ -841,20 +841,20 @@ const load = (dbAdapter, schemaCache, options) => {
|
||||
// to mongoSchemaFromFieldsAndClassName. No validation is done here, it
|
||||
// is done in mongoSchemaFromFieldsAndClassName.
|
||||
function buildMergedSchemaObject(existingFields, putRequest) {
|
||||
let newSchema = {};
|
||||
let sysSchemaField = Object.keys(defaultColumns).indexOf(existingFields._id) === -1 ? [] : Object.keys(defaultColumns[existingFields._id]);
|
||||
for (let oldField in existingFields) {
|
||||
const newSchema = {};
|
||||
const sysSchemaField = Object.keys(defaultColumns).indexOf(existingFields._id) === -1 ? [] : Object.keys(defaultColumns[existingFields._id]);
|
||||
for (const oldField in existingFields) {
|
||||
if (oldField !== '_id' && oldField !== 'ACL' && oldField !== 'updatedAt' && oldField !== 'createdAt' && oldField !== 'objectId') {
|
||||
if (sysSchemaField.length > 0 && sysSchemaField.indexOf(oldField) !== -1) {
|
||||
continue;
|
||||
}
|
||||
let fieldIsDeleted = putRequest[oldField] && putRequest[oldField].__op === 'Delete'
|
||||
const fieldIsDeleted = putRequest[oldField] && putRequest[oldField].__op === 'Delete'
|
||||
if (!fieldIsDeleted) {
|
||||
newSchema[oldField] = existingFields[oldField];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let newField in putRequest) {
|
||||
for (const newField in putRequest) {
|
||||
if (newField !== 'objectId' && putRequest[newField].__op !== 'Delete') {
|
||||
if (sysSchemaField.length > 0 && sysSchemaField.indexOf(newField) !== -1) {
|
||||
continue;
|
||||
@@ -879,7 +879,7 @@ function thenValidateRequiredColumns(schemaPromise, className, object, query) {
|
||||
// The output should be a valid schema value.
|
||||
// TODO: ensure that this is compatible with the format used in Open DB
|
||||
function getType(obj) {
|
||||
let type = typeof obj;
|
||||
const type = typeof obj;
|
||||
switch(type) {
|
||||
case 'boolean':
|
||||
return 'Boolean';
|
||||
|
||||
@@ -48,8 +48,8 @@ export class UserController extends AdaptableController {
|
||||
throw undefined;
|
||||
}
|
||||
|
||||
let query = {username: username, _email_verify_token: token};
|
||||
let updateFields = { emailVerified: true, _email_verify_token: {__op: 'Delete'}};
|
||||
const query = {username: username, _email_verify_token: token};
|
||||
const updateFields = { emailVerified: true, _email_verify_token: {__op: 'Delete'}};
|
||||
|
||||
// if the email verify token needs to be validated then
|
||||
// add additional query params and additional fields that need to be updated
|
||||
@@ -119,8 +119,8 @@ export class UserController extends AdaptableController {
|
||||
// We may need to fetch the user in case of update email
|
||||
this.getUserIfNeeded(user).then((user) => {
|
||||
const username = encodeURIComponent(user.username);
|
||||
let link = `${this.config.verifyEmailURL}?token=${token}&username=${username}`;
|
||||
let options = {
|
||||
const link = `${this.config.verifyEmailURL}?token=${token}&username=${username}`;
|
||||
const options = {
|
||||
appName: this.config.appName,
|
||||
link: link,
|
||||
user: inflate('_User', user),
|
||||
@@ -153,9 +153,9 @@ export class UserController extends AdaptableController {
|
||||
.then(user => {
|
||||
const token = encodeURIComponent(user._perishable_token);
|
||||
const username = encodeURIComponent(user.username);
|
||||
let link = `${this.config.requestResetPasswordURL}?token=${token}&username=${username}`
|
||||
const link = `${this.config.requestResetPasswordURL}?token=${token}&username=${username}`
|
||||
|
||||
let options = {
|
||||
const options = {
|
||||
appName: this.config.appName,
|
||||
link: link,
|
||||
user: inflate('_User', user),
|
||||
@@ -188,22 +188,22 @@ export class UserController extends AdaptableController {
|
||||
}
|
||||
|
||||
defaultVerificationEmail({link, user, appName, }) {
|
||||
let text = "Hi,\n\n" +
|
||||
const text = "Hi,\n\n" +
|
||||
"You are being asked to confirm the e-mail address " + user.get("email") + " with " + appName + "\n\n" +
|
||||
"" +
|
||||
"Click here to confirm it:\n" + link;
|
||||
let to = user.get("email");
|
||||
let subject = 'Please verify your e-mail for ' + appName;
|
||||
const to = user.get("email");
|
||||
const subject = 'Please verify your e-mail for ' + appName;
|
||||
return { text, to, subject };
|
||||
}
|
||||
|
||||
defaultResetPasswordEmail({link, user, appName, }) {
|
||||
let text = "Hi,\n\n" +
|
||||
const text = "Hi,\n\n" +
|
||||
"You requested to reset your password for " + appName + ".\n\n" +
|
||||
"" +
|
||||
"Click here to reset it:\n" + link;
|
||||
let to = user.get("email") || user.get('username');
|
||||
let subject = 'Password Reset for ' + appName;
|
||||
const to = user.get("email") || user.get('username');
|
||||
const subject = 'Password Reset for ' + appName;
|
||||
return { text, to, subject };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import logger from '../logger';
|
||||
import type { FlattenedObjectData } from './Subscription';
|
||||
export type Message = { [attr: string]: any };
|
||||
|
||||
let dafaultFields = ['className', 'objectId', 'updatedAt', 'createdAt', 'ACL'];
|
||||
const dafaultFields = ['className', 'objectId', 'updatedAt', 'createdAt', 'ACL'];
|
||||
|
||||
class Client {
|
||||
id: number;
|
||||
@@ -63,7 +63,7 @@ class Client {
|
||||
|
||||
_pushEvent(type: string): Function {
|
||||
return function(subscriptionId: number, parseObjectJSON: any): void {
|
||||
let response: Message = {
|
||||
const response: Message = {
|
||||
'op' : type,
|
||||
'clientId' : this.id
|
||||
};
|
||||
@@ -85,11 +85,11 @@ class Client {
|
||||
if (!fields) {
|
||||
return parseObjectJSON;
|
||||
}
|
||||
let limitedParseObject = {};
|
||||
for (let field of dafaultFields) {
|
||||
const limitedParseObject = {};
|
||||
for (const field of dafaultFields) {
|
||||
limitedParseObject[field] = parseObjectJSON[field];
|
||||
}
|
||||
for (let field of fields) {
|
||||
for (const field of fields) {
|
||||
if (field in parseObjectJSON) {
|
||||
limitedParseObject[field] = parseObjectJSON[field];
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ class ParseCloudCodePublisher {
|
||||
_onCloudCodeMessage(type: string, request: any): void {
|
||||
logger.verbose('Raw request from cloud code current : %j | original : %j', request.object, request.original);
|
||||
// We need the full JSON which includes className
|
||||
let message = {
|
||||
const message = {
|
||||
currentParseObject: request.object._toFullJSON()
|
||||
}
|
||||
if (request.original) {
|
||||
|
||||
@@ -28,9 +28,9 @@ class ParseLiveQueryServer {
|
||||
config = config || {};
|
||||
|
||||
// Store keys, convert obj to map
|
||||
let keyPairs = config.keyPairs || {};
|
||||
const keyPairs = config.keyPairs || {};
|
||||
this.keyPairs = new Map();
|
||||
for (let key of Object.keys(keyPairs)) {
|
||||
for (const key of Object.keys(keyPairs)) {
|
||||
this.keyPairs.set(key, keyPairs[key]);
|
||||
}
|
||||
logger.verbose('Support key pairs', this.keyPairs);
|
||||
@@ -39,11 +39,11 @@ class ParseLiveQueryServer {
|
||||
Parse.Object.disableSingleInstance();
|
||||
Parse.User.enableUnsafeCurrentUser();
|
||||
|
||||
let serverURL = config.serverURL || Parse.serverURL;
|
||||
const serverURL = config.serverURL || Parse.serverURL;
|
||||
Parse.serverURL = serverURL;
|
||||
let appId = config.appId || Parse.applicationId;
|
||||
let javascriptKey = Parse.javaScriptKey;
|
||||
let masterKey = config.masterKey || Parse.masterKey;
|
||||
const appId = config.appId || Parse.applicationId;
|
||||
const javascriptKey = Parse.javaScriptKey;
|
||||
const masterKey = config.masterKey || Parse.masterKey;
|
||||
Parse.initialize(appId, javascriptKey, masterKey);
|
||||
|
||||
// Initialize websocket server
|
||||
@@ -86,13 +86,13 @@ class ParseLiveQueryServer {
|
||||
// Message.originalParseObject is the original ParseObject JSON.
|
||||
_inflateParseObject(message: any): void {
|
||||
// Inflate merged object
|
||||
let currentParseObject = message.currentParseObject;
|
||||
const currentParseObject = message.currentParseObject;
|
||||
let className = currentParseObject.className;
|
||||
let parseObject = new Parse.Object(className);
|
||||
parseObject._finishFetch(currentParseObject);
|
||||
message.currentParseObject = parseObject;
|
||||
// Inflate original object
|
||||
let originalParseObject = message.originalParseObject;
|
||||
const originalParseObject = message.originalParseObject;
|
||||
if (originalParseObject) {
|
||||
className = originalParseObject.className;
|
||||
parseObject = new Parse.Object(className);
|
||||
@@ -106,28 +106,28 @@ class ParseLiveQueryServer {
|
||||
_onAfterDelete(message: any): void {
|
||||
logger.verbose(Parse.applicationId + 'afterDelete is triggered');
|
||||
|
||||
let deletedParseObject = message.currentParseObject.toJSON();
|
||||
let className = deletedParseObject.className;
|
||||
const deletedParseObject = message.currentParseObject.toJSON();
|
||||
const className = deletedParseObject.className;
|
||||
logger.verbose('ClassName: %j | ObjectId: %s', className, deletedParseObject.id);
|
||||
logger.verbose('Current client number : %d', this.clients.size);
|
||||
|
||||
let classSubscriptions = this.subscriptions.get(className);
|
||||
const classSubscriptions = this.subscriptions.get(className);
|
||||
if (typeof classSubscriptions === 'undefined') {
|
||||
logger.debug('Can not find subscriptions under this class ' + className);
|
||||
return;
|
||||
}
|
||||
for (let subscription of classSubscriptions.values()) {
|
||||
let isSubscriptionMatched = this._matchesSubscription(deletedParseObject, subscription);
|
||||
for (const subscription of classSubscriptions.values()) {
|
||||
const isSubscriptionMatched = this._matchesSubscription(deletedParseObject, subscription);
|
||||
if (!isSubscriptionMatched) {
|
||||
continue;
|
||||
}
|
||||
for (let [clientId, requestIds] of _.entries(subscription.clientRequestIds)) {
|
||||
let client = this.clients.get(clientId);
|
||||
for (const [clientId, requestIds] of _.entries(subscription.clientRequestIds)) {
|
||||
const client = this.clients.get(clientId);
|
||||
if (typeof client === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
for (let requestId of requestIds) {
|
||||
let acl = message.currentParseObject.getACL();
|
||||
for (const requestId of requestIds) {
|
||||
const acl = message.currentParseObject.getACL();
|
||||
// Check ACL
|
||||
this._matchesACL(acl, client, requestId).then((isMatched) => {
|
||||
if (!isMatched) {
|
||||
@@ -151,25 +151,25 @@ class ParseLiveQueryServer {
|
||||
if (message.originalParseObject) {
|
||||
originalParseObject = message.originalParseObject.toJSON();
|
||||
}
|
||||
let currentParseObject = message.currentParseObject.toJSON();
|
||||
let className = currentParseObject.className;
|
||||
const currentParseObject = message.currentParseObject.toJSON();
|
||||
const className = currentParseObject.className;
|
||||
logger.verbose('ClassName: %s | ObjectId: %s', className, currentParseObject.id);
|
||||
logger.verbose('Current client number : %d', this.clients.size);
|
||||
|
||||
let classSubscriptions = this.subscriptions.get(className);
|
||||
const classSubscriptions = this.subscriptions.get(className);
|
||||
if (typeof classSubscriptions === 'undefined') {
|
||||
logger.debug('Can not find subscriptions under this class ' + className);
|
||||
return;
|
||||
}
|
||||
for (let subscription of classSubscriptions.values()) {
|
||||
let isOriginalSubscriptionMatched = this._matchesSubscription(originalParseObject, subscription);
|
||||
let isCurrentSubscriptionMatched = this._matchesSubscription(currentParseObject, subscription);
|
||||
for (let [clientId, requestIds] of _.entries(subscription.clientRequestIds)) {
|
||||
let client = this.clients.get(clientId);
|
||||
for (const subscription of classSubscriptions.values()) {
|
||||
const isOriginalSubscriptionMatched = this._matchesSubscription(originalParseObject, subscription);
|
||||
const isCurrentSubscriptionMatched = this._matchesSubscription(currentParseObject, subscription);
|
||||
for (const [clientId, requestIds] of _.entries(subscription.clientRequestIds)) {
|
||||
const client = this.clients.get(clientId);
|
||||
if (typeof client === 'undefined') {
|
||||
continue;
|
||||
}
|
||||
for (let requestId of requestIds) {
|
||||
for (const requestId of requestIds) {
|
||||
// Set orignal ParseObject ACL checking promise, if the object does not match
|
||||
// subscription, we do not need to check ACL
|
||||
let originalACLCheckingPromise;
|
||||
@@ -188,7 +188,7 @@ class ParseLiveQueryServer {
|
||||
if (!isCurrentSubscriptionMatched) {
|
||||
currentACLCheckingPromise = Parse.Promise.as(false);
|
||||
} else {
|
||||
let currentACL = message.currentParseObject.getACL();
|
||||
const currentACL = message.currentParseObject.getACL();
|
||||
currentACLCheckingPromise = this._matchesACL(currentACL, client, requestId);
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ class ParseLiveQueryServer {
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
let functionName = 'push' + type;
|
||||
const functionName = 'push' + type;
|
||||
client[functionName](requestId, currentParseObject);
|
||||
}, (error) => {
|
||||
logger.error('Matching ACL error : ', error);
|
||||
@@ -271,23 +271,23 @@ class ParseLiveQueryServer {
|
||||
|
||||
parseWebsocket.on('disconnect', () => {
|
||||
logger.info('Client disconnect: %d', parseWebsocket.clientId);
|
||||
let clientId = parseWebsocket.clientId;
|
||||
const clientId = parseWebsocket.clientId;
|
||||
if (!this.clients.has(clientId)) {
|
||||
logger.error('Can not find client %d on disconnect', clientId);
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete client
|
||||
let client = this.clients.get(clientId);
|
||||
const client = this.clients.get(clientId);
|
||||
this.clients.delete(clientId);
|
||||
|
||||
// Delete client from subscriptions
|
||||
for (let [requestId, subscriptionInfo] of _.entries(client.subscriptionInfos)) {
|
||||
let subscription = subscriptionInfo.subscription;
|
||||
for (const [requestId, subscriptionInfo] of _.entries(client.subscriptionInfos)) {
|
||||
const subscription = subscriptionInfo.subscription;
|
||||
subscription.deleteClientSubscription(clientId, requestId);
|
||||
|
||||
// If there is no client which is subscribing this subscription, remove it from subscriptions
|
||||
let classSubscriptions = this.subscriptions.get(subscription.className);
|
||||
const classSubscriptions = this.subscriptions.get(subscription.className);
|
||||
if (!subscription.hasSubscribingClient()) {
|
||||
classSubscriptions.delete(subscription.hash);
|
||||
}
|
||||
@@ -316,12 +316,12 @@ class ParseLiveQueryServer {
|
||||
return Parse.Promise.as(true);
|
||||
}
|
||||
// Check subscription sessionToken matches ACL first
|
||||
let subscriptionInfo = client.getSubscriptionInfo(requestId);
|
||||
const subscriptionInfo = client.getSubscriptionInfo(requestId);
|
||||
if (typeof subscriptionInfo === 'undefined') {
|
||||
return Parse.Promise.as(false);
|
||||
}
|
||||
|
||||
let subscriptionSessionToken = subscriptionInfo.sessionToken;
|
||||
const subscriptionSessionToken = subscriptionInfo.sessionToken;
|
||||
return this.sessionTokenCache.getUserId(subscriptionSessionToken).then((userId) => {
|
||||
return acl.getReadAccess(userId);
|
||||
}).then((isSubscriptionSessionTokenMatched) => {
|
||||
@@ -368,7 +368,7 @@ class ParseLiveQueryServer {
|
||||
then((roles) => {
|
||||
|
||||
// Finally, see if any of the user's roles allow them read access
|
||||
for (let role of roles) {
|
||||
for (const role of roles) {
|
||||
if (acl.getRoleReadAccess(role)) {
|
||||
return resolve(true);
|
||||
}
|
||||
@@ -387,7 +387,7 @@ class ParseLiveQueryServer {
|
||||
}
|
||||
|
||||
// Check client sessionToken matches ACL
|
||||
let clientSessionToken = client.sessionToken;
|
||||
const clientSessionToken = client.sessionToken;
|
||||
return this.sessionTokenCache.getUserId(clientSessionToken).then((userId) => {
|
||||
return acl.getReadAccess(userId);
|
||||
});
|
||||
@@ -404,7 +404,7 @@ class ParseLiveQueryServer {
|
||||
logger.error('Key in request is not valid');
|
||||
return;
|
||||
}
|
||||
let client = new Client(this.clientId, parseWebsocket);
|
||||
const client = new Client(this.clientId, parseWebsocket);
|
||||
parseWebsocket.clientId = this.clientId;
|
||||
this.clientId += 1;
|
||||
this.clients.set(parseWebsocket.clientId, client);
|
||||
@@ -417,7 +417,7 @@ class ParseLiveQueryServer {
|
||||
return true;
|
||||
}
|
||||
let isValid = false;
|
||||
for (let [key, secret] of validKeyPairs) {
|
||||
for (const [key, secret] of validKeyPairs) {
|
||||
if (!request[key] || request[key] !== secret) {
|
||||
continue;
|
||||
}
|
||||
@@ -434,16 +434,16 @@ class ParseLiveQueryServer {
|
||||
logger.error('Can not find this client, make sure you connect to server before subscribing');
|
||||
return;
|
||||
}
|
||||
let client = this.clients.get(parseWebsocket.clientId);
|
||||
const client = this.clients.get(parseWebsocket.clientId);
|
||||
|
||||
// Get subscription from subscriptions, create one if necessary
|
||||
let subscriptionHash = queryHash(request.query);
|
||||
const subscriptionHash = queryHash(request.query);
|
||||
// Add className to subscriptions if necessary
|
||||
let className = request.query.className;
|
||||
const className = request.query.className;
|
||||
if (!this.subscriptions.has(className)) {
|
||||
this.subscriptions.set(className, new Map());
|
||||
}
|
||||
let classSubscriptions = this.subscriptions.get(className);
|
||||
const classSubscriptions = this.subscriptions.get(className);
|
||||
let subscription;
|
||||
if (classSubscriptions.has(subscriptionHash)) {
|
||||
subscription = classSubscriptions.get(subscriptionHash);
|
||||
@@ -453,7 +453,7 @@ class ParseLiveQueryServer {
|
||||
}
|
||||
|
||||
// Add subscriptionInfo to client
|
||||
let subscriptionInfo = {
|
||||
const subscriptionInfo = {
|
||||
subscription: subscription
|
||||
};
|
||||
// Add selected fields and sessionToken for this subscription if necessary
|
||||
@@ -486,8 +486,8 @@ class ParseLiveQueryServer {
|
||||
logger.error('Can not find this client, make sure you connect to server before unsubscribing');
|
||||
return;
|
||||
}
|
||||
let requestId = request.requestId;
|
||||
let client = this.clients.get(parseWebsocket.clientId);
|
||||
const requestId = request.requestId;
|
||||
const client = this.clients.get(parseWebsocket.clientId);
|
||||
if (typeof client === 'undefined') {
|
||||
Client.pushError(parseWebsocket, 2, 'Cannot find client with clientId ' + parseWebsocket.clientId +
|
||||
'. Make sure you connect to live query server before unsubscribing.');
|
||||
@@ -495,7 +495,7 @@ class ParseLiveQueryServer {
|
||||
return;
|
||||
}
|
||||
|
||||
let subscriptionInfo = client.getSubscriptionInfo(requestId);
|
||||
const subscriptionInfo = client.getSubscriptionInfo(requestId);
|
||||
if (typeof subscriptionInfo === 'undefined') {
|
||||
Client.pushError(parseWebsocket, 2, 'Cannot find subscription with clientId ' + parseWebsocket.clientId +
|
||||
' subscriptionId ' + requestId + '. Make sure you subscribe to live query server before unsubscribing.');
|
||||
@@ -506,11 +506,11 @@ class ParseLiveQueryServer {
|
||||
// Remove subscription from client
|
||||
client.deleteSubscriptionInfo(requestId);
|
||||
// Remove client from subscription
|
||||
let subscription = subscriptionInfo.subscription;
|
||||
let className = subscription.className;
|
||||
const subscription = subscriptionInfo.subscription;
|
||||
const className = subscription.className;
|
||||
subscription.deleteClientSubscription(parseWebsocket.clientId, requestId);
|
||||
// If there is no client which is subscribing this subscription, remove it from subscriptions
|
||||
let classSubscriptions = this.subscriptions.get(className);
|
||||
const classSubscriptions = this.subscriptions.get(className);
|
||||
if (!subscription.hasSubscribingClient()) {
|
||||
classSubscriptions.delete(subscription.hash);
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import {
|
||||
RedisPubSub
|
||||
} from '../Adapters/PubSub/RedisPubSub';
|
||||
|
||||
let ParsePubSub = {};
|
||||
const ParsePubSub = {};
|
||||
|
||||
function useRedis(config: any): boolean {
|
||||
let redisURL = config.redisURL;
|
||||
const redisURL = config.redisURL;
|
||||
return typeof redisURL !== 'undefined' && redisURL !== '';
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ ParsePubSub.createPublisher = function(config: any): any {
|
||||
if (useRedis(config)) {
|
||||
return RedisPubSub.createPublisher(config);
|
||||
} else {
|
||||
let adapter = loadAdapter(config.pubSubAdapter, EventEmitterPubSub, config)
|
||||
const adapter = loadAdapter(config.pubSubAdapter, EventEmitterPubSub, config)
|
||||
if (typeof adapter.createPublisher !== 'function') {
|
||||
throw 'pubSubAdapter should have createPublisher()';
|
||||
}
|
||||
@@ -30,7 +30,7 @@ ParsePubSub.createSubscriber = function(config: any): void {
|
||||
if (useRedis(config)) {
|
||||
return RedisPubSub.createSubscriber(config);
|
||||
} else {
|
||||
let adapter = loadAdapter(config.pubSubAdapter, EventEmitterPubSub, config)
|
||||
const adapter = loadAdapter(config.pubSubAdapter, EventEmitterPubSub, config)
|
||||
if (typeof adapter.createSubscriber !== 'function') {
|
||||
throw 'pubSubAdapter should have createSubscriber()';
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import logger from '../logger';
|
||||
|
||||
let typeMap = new Map([['disconnect', 'close']]);
|
||||
const typeMap = new Map([['disconnect', 'close']]);
|
||||
|
||||
export class ParseWebSocketServer {
|
||||
server: Object;
|
||||
|
||||
constructor(server: any, onConnect: Function, websocketTimeout: number = 10 * 1000) {
|
||||
let WebSocketServer = require('ws').Server;
|
||||
let wss = new WebSocketServer({ server: server });
|
||||
const WebSocketServer = require('ws').Server;
|
||||
const wss = new WebSocketServer({ server: server });
|
||||
wss.on('listening', () => {
|
||||
logger.info('Parse LiveQuery Server starts running');
|
||||
});
|
||||
wss.on('connection', (ws) => {
|
||||
onConnect(new ParseWebSocket(ws));
|
||||
// Send ping to client periodically
|
||||
let pingIntervalId = setInterval(() => {
|
||||
const pingIntervalId = setInterval(() => {
|
||||
if (ws.readyState == ws.OPEN) {
|
||||
ws.ping();
|
||||
} else {
|
||||
@@ -34,7 +34,7 @@ export class ParseWebSocket {
|
||||
}
|
||||
|
||||
on(type: string, callback): void {
|
||||
let wsType = typeMap.has(type) ? typeMap.get(type) : type;
|
||||
const wsType = typeMap.has(type) ? typeMap.get(type) : type;
|
||||
this.ws.on(wsType, callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -217,8 +217,8 @@ function matchesKeyConstraints(object, key, constraints) {
|
||||
}
|
||||
break;
|
||||
case '$exists': {
|
||||
let propertyExists = typeof object[key] !== 'undefined';
|
||||
let existenceIsRequired = constraints['$exists'];
|
||||
const propertyExists = typeof object[key] !== 'undefined';
|
||||
const existenceIsRequired = constraints['$exists'];
|
||||
if (typeof constraints['$exists'] !== 'boolean') {
|
||||
// The SDK will never submit a non-boolean for $exists, but if someone
|
||||
// tries to submit a non-boolean for $exits outside the SDKs, just ignore it.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
let general = {
|
||||
const general = {
|
||||
'title': 'General request schema',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -9,7 +9,7 @@ let general = {
|
||||
},
|
||||
};
|
||||
|
||||
let connect = {
|
||||
const connect = {
|
||||
'title': 'Connect operation schema',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -40,7 +40,7 @@ let connect = {
|
||||
"additionalProperties": false
|
||||
};
|
||||
|
||||
let subscribe = {
|
||||
const subscribe = {
|
||||
'title': 'Subscribe operation schema',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -78,7 +78,7 @@ let subscribe = {
|
||||
'additionalProperties': false
|
||||
};
|
||||
|
||||
let update = {
|
||||
const update = {
|
||||
'title': 'Update operation schema',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -116,7 +116,7 @@ let update = {
|
||||
'additionalProperties': false
|
||||
};
|
||||
|
||||
let unsubscribe = {
|
||||
const unsubscribe = {
|
||||
'title': 'Unsubscribe operation schema',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
@@ -129,7 +129,7 @@ let unsubscribe = {
|
||||
"additionalProperties": false
|
||||
}
|
||||
|
||||
let RequestSchema = {
|
||||
const RequestSchema = {
|
||||
'general': general,
|
||||
'connect': connect,
|
||||
'subscribe': subscribe,
|
||||
|
||||
@@ -16,14 +16,14 @@ class SessionTokenCache {
|
||||
if (!sessionToken) {
|
||||
return Parse.Promise.error('Empty sessionToken');
|
||||
}
|
||||
let userId = this.cache.get(sessionToken);
|
||||
const userId = this.cache.get(sessionToken);
|
||||
if (userId) {
|
||||
logger.verbose('Fetch userId %s of sessionToken %s from Cache', userId, sessionToken);
|
||||
return Parse.Promise.as(userId);
|
||||
}
|
||||
return Parse.User.become(sessionToken).then((user) => {
|
||||
logger.verbose('Fetch userId %s of sessionToken %s from Parse', user.id, sessionToken);
|
||||
let userId = user.id;
|
||||
const userId = user.id;
|
||||
this.cache.set(sessionToken, userId);
|
||||
return Parse.Promise.as(userId);
|
||||
}, (error) => {
|
||||
|
||||
@@ -21,18 +21,18 @@ class Subscription {
|
||||
if (!this.clientRequestIds.has(clientId)) {
|
||||
this.clientRequestIds.set(clientId, []);
|
||||
}
|
||||
let requestIds = this.clientRequestIds.get(clientId);
|
||||
const requestIds = this.clientRequestIds.get(clientId);
|
||||
requestIds.push(requestId);
|
||||
}
|
||||
|
||||
deleteClientSubscription(clientId: number, requestId: number): void {
|
||||
let requestIds = this.clientRequestIds.get(clientId);
|
||||
const requestIds = this.clientRequestIds.get(clientId);
|
||||
if (typeof requestIds === 'undefined') {
|
||||
logger.error('Can not find client %d to delete', clientId);
|
||||
return;
|
||||
}
|
||||
|
||||
let index = requestIds.indexOf(requestId);
|
||||
const index = requestIds.indexOf(requestId);
|
||||
if (index < 0) {
|
||||
logger.error('Can not find client %d subscription %d to delete', clientId, requestId);
|
||||
return;
|
||||
|
||||
@@ -307,7 +307,7 @@ class ParseServer {
|
||||
api.use(middlewares.allowMethodOverride);
|
||||
api.use(middlewares.handleParseHeaders);
|
||||
|
||||
let appRouter = ParseServer.promiseRouter({ appId });
|
||||
const appRouter = ParseServer.promiseRouter({ appId });
|
||||
api.use(appRouter.expressRouter());
|
||||
|
||||
api.use(middlewares.handleParseErrors);
|
||||
@@ -332,7 +332,7 @@ class ParseServer {
|
||||
}
|
||||
|
||||
static promiseRouter({appId}) {
|
||||
let routers = [
|
||||
const routers = [
|
||||
new ClassesRouter(),
|
||||
new UsersRouter(),
|
||||
new SessionsRouter(),
|
||||
@@ -351,11 +351,11 @@ class ParseServer {
|
||||
new CloudCodeRouter()
|
||||
];
|
||||
|
||||
let routes = routers.reduce((memo, router) => {
|
||||
const routes = routers.reduce((memo, router) => {
|
||||
return memo.concat(router.routes);
|
||||
}, []);
|
||||
|
||||
let appRouter = new PromiseRouter(routes, appId);
|
||||
const appRouter = new PromiseRouter(routes, appId);
|
||||
|
||||
batch.mountOnto(appRouter);
|
||||
return appRouter;
|
||||
|
||||
@@ -33,10 +33,10 @@ function getAuth(options = {}, config) {
|
||||
function ParseServerRESTController(applicationId, router) {
|
||||
function handleRequest(method, path, data = {}, options = {}) {
|
||||
// Store the arguments, for later use if internal fails
|
||||
let args = arguments;
|
||||
const args = arguments;
|
||||
|
||||
let config = new Config(applicationId);
|
||||
let serverURL = URL.parse(config.serverURL);
|
||||
const config = new Config(applicationId);
|
||||
const serverURL = URL.parse(config.serverURL);
|
||||
if (path.indexOf(serverURL.path) === 0) {
|
||||
path = path.slice(serverURL.path.length, path.length);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ function ParseServerRESTController(applicationId, router) {
|
||||
}
|
||||
|
||||
if (path === '/batch') {
|
||||
let promises = data.requests.map((request) => {
|
||||
const promises = data.requests.map((request) => {
|
||||
return handleRequest(request.method, request.path, request.body, options).then((response) => {
|
||||
return Parse.Promise.as({success: response});
|
||||
}, (error) => {
|
||||
@@ -63,7 +63,7 @@ function ParseServerRESTController(applicationId, router) {
|
||||
|
||||
return new Parse.Promise((resolve, reject) => {
|
||||
getAuth(options, config).then((auth) => {
|
||||
let request = {
|
||||
const request = {
|
||||
body: data,
|
||||
config,
|
||||
auth,
|
||||
|
||||
@@ -93,10 +93,10 @@ export default class PromiseRouter {
|
||||
if (route.method != method) {
|
||||
continue;
|
||||
}
|
||||
let layer = route.layer || new Layer(route.path, null, route.handler);
|
||||
let match = layer.match(path);
|
||||
const layer = route.layer || new Layer(route.path, null, route.handler);
|
||||
const match = layer.match(path);
|
||||
if (match) {
|
||||
let params = layer.params;
|
||||
const params = layer.params;
|
||||
Object.keys(params).forEach((key) => {
|
||||
params[key] = validateParameter(key, params[key]);
|
||||
});
|
||||
@@ -108,8 +108,8 @@ export default class PromiseRouter {
|
||||
// Mount the routes on this router onto an express app (or express router)
|
||||
mountOnto(expressApp) {
|
||||
this.routes.forEach((route) => {
|
||||
let method = route.method.toLowerCase();
|
||||
let handler = makeExpressHandler(this.appId, route.handler);
|
||||
const method = route.method.toLowerCase();
|
||||
const handler = makeExpressHandler(this.appId, route.handler);
|
||||
expressApp[method].call(expressApp, route.path, handler);
|
||||
});
|
||||
return expressApp;
|
||||
@@ -140,9 +140,9 @@ export default class PromiseRouter {
|
||||
function makeExpressHandler(appId, promiseHandler) {
|
||||
return function(req, res, next) {
|
||||
try {
|
||||
let url = maskSensitiveUrl(req);
|
||||
let body = Object.assign({}, req.body);
|
||||
let stringifiedBody = JSON.stringify(body, null, 2);
|
||||
const url = maskSensitiveUrl(req);
|
||||
const body = Object.assign({}, req.body);
|
||||
const stringifiedBody = JSON.stringify(body, null, 2);
|
||||
log.verbose(`REQUEST for [${req.method}] ${url}: ${stringifiedBody}`, {
|
||||
method: req.method,
|
||||
url: url,
|
||||
@@ -155,7 +155,7 @@ function makeExpressHandler(appId, promiseHandler) {
|
||||
throw 'control should not get here';
|
||||
}
|
||||
|
||||
let stringifiedResponse = JSON.stringify(result, null, 2);
|
||||
const stringifiedResponse = JSON.stringify(result, null, 2);
|
||||
log.verbose(
|
||||
`RESPONSE from [${req.method}] ${url}: ${stringifiedResponse}`,
|
||||
{result: result}
|
||||
@@ -198,7 +198,7 @@ function makeExpressHandler(appId, promiseHandler) {
|
||||
|
||||
function maskSensitiveUrl(req) {
|
||||
let maskUrl = req.originalUrl.toString();
|
||||
let shouldMaskUrl = req.method === 'GET' && req.originalUrl.includes('/login')
|
||||
const shouldMaskUrl = req.method === 'GET' && req.originalUrl.includes('/login')
|
||||
&& !req.originalUrl.includes('classes');
|
||||
if (shouldMaskUrl) {
|
||||
maskUrl = log.maskSensitiveUrl(maskUrl);
|
||||
|
||||
@@ -252,7 +252,7 @@ RestQuery.prototype.replaceInQuery = function() {
|
||||
'improper usage of $inQuery');
|
||||
}
|
||||
|
||||
let additionalOptions = {
|
||||
const additionalOptions = {
|
||||
redirectClassNameForKey: inQueryValue.redirectClassNameForKey
|
||||
};
|
||||
|
||||
@@ -300,7 +300,7 @@ RestQuery.prototype.replaceNotInQuery = function() {
|
||||
'improper usage of $notInQuery');
|
||||
}
|
||||
|
||||
let additionalOptions = {
|
||||
const additionalOptions = {
|
||||
redirectClassNameForKey: notInQueryValue.redirectClassNameForKey
|
||||
};
|
||||
|
||||
@@ -350,7 +350,7 @@ RestQuery.prototype.replaceSelect = function() {
|
||||
'improper usage of $select');
|
||||
}
|
||||
|
||||
let additionalOptions = {
|
||||
const additionalOptions = {
|
||||
redirectClassNameForKey: selectValue.query.redirectClassNameForKey
|
||||
};
|
||||
|
||||
@@ -398,7 +398,7 @@ RestQuery.prototype.replaceDontSelect = function() {
|
||||
throw new Parse.Error(Parse.Error.INVALID_QUERY,
|
||||
'improper usage of $dontSelect');
|
||||
}
|
||||
let additionalOptions = {
|
||||
const additionalOptions = {
|
||||
redirectClassNameForKey: dontSelectValue.query.redirectClassNameForKey
|
||||
};
|
||||
|
||||
@@ -445,7 +445,7 @@ RestQuery.prototype.runFind = function(options = {}) {
|
||||
this.response = {results: []};
|
||||
return Promise.resolve();
|
||||
}
|
||||
let findOptions = Object.assign({}, this.findOptions);
|
||||
const findOptions = Object.assign({}, this.findOptions);
|
||||
if (this.keys) {
|
||||
findOptions.keys = this.keys.map((key) => {
|
||||
return key.split('.')[0];
|
||||
@@ -535,23 +535,23 @@ function includePath(config, auth, response, path, restOptions = {}) {
|
||||
if (pointers.length == 0) {
|
||||
return response;
|
||||
}
|
||||
let pointersHash = {};
|
||||
const pointersHash = {};
|
||||
for (var pointer of pointers) {
|
||||
if (!pointer) {
|
||||
continue;
|
||||
}
|
||||
let className = pointer.className;
|
||||
const className = pointer.className;
|
||||
// only include the good pointers
|
||||
if (className) {
|
||||
pointersHash[className] = pointersHash[className] || new Set();
|
||||
pointersHash[className].add(pointer.objectId);
|
||||
}
|
||||
}
|
||||
let includeRestOptions = {};
|
||||
const includeRestOptions = {};
|
||||
if (restOptions.keys) {
|
||||
let keys = new Set(restOptions.keys.split(','));
|
||||
let keySet = Array.from(keys).reduce((set, key) => {
|
||||
let keyPath = key.split('.');
|
||||
const keys = new Set(restOptions.keys.split(','));
|
||||
const keySet = Array.from(keys).reduce((set, key) => {
|
||||
const keyPath = key.split('.');
|
||||
let i=0;
|
||||
for (i; i<path.length; i++) {
|
||||
if (path[i] != keyPath[i]) {
|
||||
@@ -568,8 +568,8 @@ function includePath(config, auth, response, path, restOptions = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
let queryPromises = Object.keys(pointersHash).map((className) => {
|
||||
let where = {'objectId': {'$in': Array.from(pointersHash[className])}};
|
||||
const queryPromises = Object.keys(pointersHash).map((className) => {
|
||||
const where = {'objectId': {'$in': Array.from(pointersHash[className])}};
|
||||
var query = new RestQuery(config, auth, className, where, includeRestOptions);
|
||||
return query.execute({op: 'get'}).then((results) => {
|
||||
results.className = className;
|
||||
@@ -682,7 +682,7 @@ function findObjectWithKey(root, key) {
|
||||
}
|
||||
if (root instanceof Array) {
|
||||
for (var item of root) {
|
||||
let answer = findObjectWithKey(item, key);
|
||||
const answer = findObjectWithKey(item, key);
|
||||
if (answer) {
|
||||
return answer;
|
||||
}
|
||||
@@ -692,7 +692,7 @@ function findObjectWithKey(root, key) {
|
||||
return root;
|
||||
}
|
||||
for (var subkey in root) {
|
||||
let answer = findObjectWithKey(root[subkey], key);
|
||||
const answer = findObjectWithKey(root[subkey], key);
|
||||
if (answer) {
|
||||
return answer;
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ RestWrite.prototype.runBeforeTrigger = function() {
|
||||
}
|
||||
|
||||
let originalObject = null;
|
||||
let updatedObject = triggers.inflate(extraData, this.originalData);
|
||||
const updatedObject = triggers.inflate(extraData, this.originalData);
|
||||
if (this.query && this.query.objectId) {
|
||||
// This is an update for existing object.
|
||||
originalObject = triggers.inflate(extraData, this.originalData);
|
||||
@@ -221,7 +221,7 @@ RestWrite.prototype.validateAuthData = function() {
|
||||
var authData = this.data.authData;
|
||||
var providers = Object.keys(authData);
|
||||
if (providers.length > 0) {
|
||||
let canHandleAuthData = providers.reduce((canHandle, provider) => {
|
||||
const canHandleAuthData = providers.reduce((canHandle, provider) => {
|
||||
var providerAuthData = authData[provider];
|
||||
var hasToken = (providerAuthData && providerAuthData.id);
|
||||
return canHandle && (hasToken || providerAuthData == null);
|
||||
@@ -235,11 +235,11 @@ RestWrite.prototype.validateAuthData = function() {
|
||||
};
|
||||
|
||||
RestWrite.prototype.handleAuthDataValidation = function(authData) {
|
||||
let validations = Object.keys(authData).map((provider) => {
|
||||
const validations = Object.keys(authData).map((provider) => {
|
||||
if (authData[provider] === null) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
let validateAuthData = this.config.authDataManager.getValidatorForProvider(provider);
|
||||
const validateAuthData = this.config.authDataManager.getValidatorForProvider(provider);
|
||||
if (!validateAuthData) {
|
||||
throw new Parse.Error(Parse.Error.UNSUPPORTED_SERVICE,
|
||||
'This authentication method is unsupported.');
|
||||
@@ -250,13 +250,13 @@ RestWrite.prototype.handleAuthDataValidation = function(authData) {
|
||||
}
|
||||
|
||||
RestWrite.prototype.findUsersWithAuthData = function(authData) {
|
||||
let providers = Object.keys(authData);
|
||||
let query = providers.reduce((memo, provider) => {
|
||||
const providers = Object.keys(authData);
|
||||
const query = providers.reduce((memo, provider) => {
|
||||
if (!authData[provider]) {
|
||||
return memo;
|
||||
}
|
||||
let queryKey = `authData.${provider}.id`;
|
||||
let query = {};
|
||||
const queryKey = `authData.${provider}.id`;
|
||||
const query = {};
|
||||
query[queryKey] = authData[provider].id;
|
||||
memo.push(query);
|
||||
return memo;
|
||||
@@ -293,16 +293,16 @@ RestWrite.prototype.handleAuthData = function(authData) {
|
||||
if (!this.query) {
|
||||
// Login with auth data
|
||||
delete results[0].password;
|
||||
let userResult = results[0];
|
||||
const userResult = results[0];
|
||||
|
||||
// need to set the objectId first otherwise location has trailing undefined
|
||||
this.data.objectId = userResult.objectId;
|
||||
|
||||
// Determine if authData was updated
|
||||
let mutatedAuthData = {};
|
||||
const mutatedAuthData = {};
|
||||
Object.keys(authData).forEach((provider) => {
|
||||
let providerData = authData[provider];
|
||||
let userAuthData = userResult.authData[provider];
|
||||
const providerData = authData[provider];
|
||||
const userAuthData = userResult.authData[provider];
|
||||
if (!_.isEqual(providerData, userAuthData)) {
|
||||
mutatedAuthData[provider] = providerData;
|
||||
}
|
||||
@@ -489,7 +489,7 @@ RestWrite.prototype._validatePasswordHistory = function() {
|
||||
oldPasswords.push(user.password);
|
||||
const newPassword = this.data.password;
|
||||
// compare the new password hash with all old password hashes
|
||||
let promises = oldPasswords.map(function (hash) {
|
||||
const promises = oldPasswords.map(function (hash) {
|
||||
return passwordCrypto.compare(newPassword, hash).then((result) => {
|
||||
if (result) // reject if there is a match
|
||||
return Promise.reject("REPEAT_PASSWORD");
|
||||
@@ -687,7 +687,7 @@ RestWrite.prototype.handleInstallation = function() {
|
||||
var deviceTokenMatches = [];
|
||||
|
||||
// Instead of issuing 3 reads, let's do it with one OR.
|
||||
let orQueries = [];
|
||||
const orQueries = [];
|
||||
if (this.query && this.query.objectId) {
|
||||
orQueries.push({
|
||||
objectId: this.query.objectId
|
||||
@@ -802,7 +802,7 @@ RestWrite.prototype.handleInstallation = function() {
|
||||
// Exactly one device token match and it doesn't have an installation
|
||||
// ID. This is the one case where we want to merge with the existing
|
||||
// object.
|
||||
let delQuery = {objectId: idMatch.objectId};
|
||||
const delQuery = {objectId: idMatch.objectId};
|
||||
return this.config.database.destroy('_Installation', delQuery)
|
||||
.then(() => {
|
||||
return deviceTokenMatches[0]['objectId'];
|
||||
@@ -813,7 +813,7 @@ RestWrite.prototype.handleInstallation = function() {
|
||||
// We're setting the device token on an existing installation, so
|
||||
// we should try cleaning out old installations that match this
|
||||
// device token.
|
||||
let delQuery = {
|
||||
const delQuery = {
|
||||
'deviceToken': this.data.deviceToken,
|
||||
};
|
||||
// We have a unique install Id, use that to preserve
|
||||
@@ -1004,8 +1004,8 @@ RestWrite.prototype.runAfterTrigger = function() {
|
||||
}
|
||||
|
||||
// Avoid doing any setup for triggers if there is no 'afterSave' trigger for this class.
|
||||
let hasAfterSaveHook = triggers.triggerExists(this.className, triggers.Types.afterSave, this.config.applicationId);
|
||||
let hasLiveQuery = this.config.liveQueryController.hasLiveQuery(this.className);
|
||||
const hasAfterSaveHook = triggers.triggerExists(this.className, triggers.Types.afterSave, this.config.applicationId);
|
||||
const hasLiveQuery = this.config.liveQueryController.hasLiveQuery(this.className);
|
||||
if (!hasAfterSaveHook && !hasLiveQuery) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -1023,7 +1023,7 @@ RestWrite.prototype.runAfterTrigger = function() {
|
||||
|
||||
// Build the inflated object, different from beforeSave, originalData is not empty
|
||||
// since developers can change data in the beforeSave.
|
||||
let updatedObject = triggers.inflate(extraData, this.originalData);
|
||||
const updatedObject = triggers.inflate(extraData, this.originalData);
|
||||
updatedObject.set(this.sanitizedData());
|
||||
updatedObject._handleSaveResponse(this.response.response, this.response.status || 200);
|
||||
|
||||
@@ -1049,7 +1049,7 @@ RestWrite.prototype.objectId = function() {
|
||||
|
||||
// Returns a copy of the data and delete bad keys (_auth_data, _hashed_password...)
|
||||
RestWrite.prototype.sanitizedData = function() {
|
||||
let data = Object.keys(this.data).reduce((data, key) => {
|
||||
const data = Object.keys(this.data).reduce((data, key) => {
|
||||
// Regexp comes from Parse.Object.prototype.validate
|
||||
if (!(/^[A-Za-z][0-9A-Za-z_]*$/).test(key)) {
|
||||
delete data[key];
|
||||
@@ -1061,7 +1061,7 @@ RestWrite.prototype.sanitizedData = function() {
|
||||
|
||||
RestWrite.prototype.cleanUserAuthData = function() {
|
||||
if (this.response && this.response.response && this.className === '_User') {
|
||||
let user = this.response.response;
|
||||
const user = this.response.response;
|
||||
if (user.authData) {
|
||||
Object.keys(user.authData).forEach((provider) => {
|
||||
if (user.authData[provider] === null) {
|
||||
@@ -1079,10 +1079,10 @@ RestWrite.prototype._updateResponseWithData = function(response, data) {
|
||||
if (_.isEmpty(this.storage.fieldsChangedByTrigger)) {
|
||||
return response;
|
||||
}
|
||||
let clientSupportsDelete = ClientSDK.supportsForwardDelete(this.clientSDK);
|
||||
const clientSupportsDelete = ClientSDK.supportsForwardDelete(this.clientSDK);
|
||||
this.storage.fieldsChangedByTrigger.forEach(fieldName => {
|
||||
let dataValue = data[fieldName];
|
||||
let responseValue = response[fieldName];
|
||||
const dataValue = data[fieldName];
|
||||
const responseValue = response[fieldName];
|
||||
|
||||
response[fieldName] = responseValue || dataValue;
|
||||
|
||||
|
||||
@@ -9,12 +9,12 @@ const ALLOWED_GET_QUERY_KEYS = ['keys', 'include'];
|
||||
export class ClassesRouter extends PromiseRouter {
|
||||
|
||||
handleFind(req) {
|
||||
let body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
|
||||
let options = {};
|
||||
let allowConstraints = ['skip', 'limit', 'order', 'count', 'keys',
|
||||
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
|
||||
const options = {};
|
||||
const allowConstraints = ['skip', 'limit', 'order', 'count', 'keys',
|
||||
'include', 'redirectClassNameForKey', 'where'];
|
||||
|
||||
for (let key of Object.keys(body)) {
|
||||
for (const key of Object.keys(body)) {
|
||||
if (allowConstraints.indexOf(key) === -1) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_QUERY, `Invalid parameter for query: ${key}`);
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export class ClassesRouter extends PromiseRouter {
|
||||
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) {
|
||||
for (const result of response.results) {
|
||||
if (result.sessionToken) {
|
||||
result.sessionToken = req.info.sessionToken || result.sessionToken;
|
||||
}
|
||||
@@ -61,10 +61,10 @@ export class ClassesRouter extends PromiseRouter {
|
||||
|
||||
// Returns a promise for a {response} object.
|
||||
handleGet(req) {
|
||||
let body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
|
||||
let options = {};
|
||||
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
|
||||
const options = {};
|
||||
|
||||
for (let key of Object.keys(body)) {
|
||||
for (const key of Object.keys(body)) {
|
||||
if (ALLOWED_GET_QUERY_KEYS.indexOf(key) === -1) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_QUERY, 'Improper encode of parameter');
|
||||
}
|
||||
@@ -114,8 +114,8 @@ export class ClassesRouter extends PromiseRouter {
|
||||
}
|
||||
|
||||
static JSONFromQuery(query) {
|
||||
let json = {};
|
||||
for (let [key, value] of _.entries(query)) {
|
||||
const json = {};
|
||||
for (const [key, value] of _.entries(query)) {
|
||||
try {
|
||||
json[key] = JSON.parse(value);
|
||||
} catch (e) {
|
||||
|
||||
@@ -7,8 +7,8 @@ export class CloudCodeRouter extends PromiseRouter {
|
||||
}
|
||||
|
||||
static getJobs(req) {
|
||||
let config = req.config;
|
||||
let jobs = triggers.getJobs(config.applicationId) || {};
|
||||
const config = req.config;
|
||||
const jobs = triggers.getJobs(config.applicationId) || {};
|
||||
return Promise.resolve({
|
||||
response: Object.keys(jobs).map((jobName) => {
|
||||
return {
|
||||
|
||||
@@ -10,13 +10,13 @@ export class GlobalConfigRouter extends PromiseRouter {
|
||||
// If there is no config in the database - return empty config.
|
||||
return { response: { params: {} } };
|
||||
}
|
||||
let globalConfig = results[0];
|
||||
const globalConfig = results[0];
|
||||
return { response: { params: globalConfig.params } };
|
||||
});
|
||||
}
|
||||
|
||||
updateGlobalConfig(req) {
|
||||
let params = req.body.params;
|
||||
const params = req.body.params;
|
||||
// Transform in dot notation to make sure it works
|
||||
const update = Object.keys(params).reduce((acc, key) => {
|
||||
acc[`params.${key}`] = params[key];
|
||||
|
||||
@@ -5,7 +5,7 @@ import rest from '../rest';
|
||||
|
||||
export class InstallationsRouter extends ClassesRouter {
|
||||
handleFind(req) {
|
||||
let body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
|
||||
const body = Object.assign(req.body, ClassesRouter.JSONFromQuery(req.query));
|
||||
var options = {};
|
||||
|
||||
if (body.skip) {
|
||||
|
||||
@@ -5,15 +5,15 @@ import path from 'path';
|
||||
import fs from 'fs';
|
||||
import qs from 'querystring';
|
||||
|
||||
let public_html = path.resolve(__dirname, "../../public_html");
|
||||
let views = path.resolve(__dirname, '../../views');
|
||||
const public_html = path.resolve(__dirname, "../../public_html");
|
||||
const views = path.resolve(__dirname, '../../views');
|
||||
|
||||
export class PublicAPIRouter extends PromiseRouter {
|
||||
|
||||
verifyEmail(req) {
|
||||
let { token, username }= req.query;
|
||||
let appId = req.params.appId;
|
||||
let config = new Config(appId);
|
||||
const { token, username } = req.query;
|
||||
const appId = req.params.appId;
|
||||
const config = new Config(appId);
|
||||
|
||||
if (!config.publicServerURL) {
|
||||
return this.missingPublicServerURL();
|
||||
@@ -23,9 +23,9 @@ export class PublicAPIRouter extends PromiseRouter {
|
||||
return this.invalidLink(req);
|
||||
}
|
||||
|
||||
let userController = config.userController;
|
||||
const userController = config.userController;
|
||||
return userController.verifyEmail(username, token).then(() => {
|
||||
let params = qs.stringify({username});
|
||||
const params = qs.stringify({username});
|
||||
return Promise.resolve({
|
||||
status: 302,
|
||||
location: `${config.verifyEmailSuccessURL}?${params}`
|
||||
@@ -37,7 +37,7 @@ export class PublicAPIRouter extends PromiseRouter {
|
||||
|
||||
changePassword(req) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let config = new Config(req.query.id);
|
||||
const config = new Config(req.query.id);
|
||||
if (!config.publicServerURL) {
|
||||
return resolve({
|
||||
status: 404,
|
||||
@@ -59,20 +59,20 @@ export class PublicAPIRouter extends PromiseRouter {
|
||||
|
||||
requestResetPassword(req) {
|
||||
|
||||
let config = req.config;
|
||||
const config = req.config;
|
||||
|
||||
if (!config.publicServerURL) {
|
||||
return this.missingPublicServerURL();
|
||||
}
|
||||
|
||||
let { username, token } = req.query;
|
||||
const { username, token } = req.query;
|
||||
|
||||
if (!username || !token) {
|
||||
return this.invalidLink(req);
|
||||
}
|
||||
|
||||
return config.userController.checkResetTokenValidity(username, token).then(() => {
|
||||
let params = qs.stringify({token, id: config.applicationId, username, app: config.appName, });
|
||||
const params = qs.stringify({token, id: config.applicationId, username, app: config.appName, });
|
||||
return Promise.resolve({
|
||||
status: 302,
|
||||
location: `${config.choosePasswordURL}?${params}`
|
||||
@@ -84,13 +84,13 @@ export class PublicAPIRouter extends PromiseRouter {
|
||||
|
||||
resetPassword(req) {
|
||||
|
||||
let config = req.config;
|
||||
const config = req.config;
|
||||
|
||||
if (!config.publicServerURL) {
|
||||
return this.missingPublicServerURL();
|
||||
}
|
||||
|
||||
let {
|
||||
const {
|
||||
username,
|
||||
token,
|
||||
new_password
|
||||
@@ -101,13 +101,13 @@ export class PublicAPIRouter extends PromiseRouter {
|
||||
}
|
||||
|
||||
return config.userController.updatePassword(username, token, new_password).then(() => {
|
||||
let params = qs.stringify({username: username});
|
||||
const params = qs.stringify({username: username});
|
||||
return Promise.resolve({
|
||||
status: 302,
|
||||
location: `${config.passwordResetSuccessURL}?${params}`
|
||||
});
|
||||
}, (err) => {
|
||||
let params = qs.stringify({username: username, token: token, id: config.applicationId, error:err, app:config.appName})
|
||||
const params = qs.stringify({username: username, token: token, id: config.applicationId, error:err, app:config.appName})
|
||||
return Promise.resolve({
|
||||
status: 302,
|
||||
location: `${config.choosePasswordURL}?${params}`
|
||||
@@ -153,7 +153,7 @@ export class PublicAPIRouter extends PromiseRouter {
|
||||
}
|
||||
|
||||
expressRouter() {
|
||||
let router = express.Router();
|
||||
const router = express.Router();
|
||||
router.use("/apps", express.static(public_html));
|
||||
router.use("/", super.expressRouter());
|
||||
return router;
|
||||
|
||||
@@ -14,9 +14,9 @@ export class PushRouter extends PromiseRouter {
|
||||
throw new Parse.Error(Parse.Error.PUSH_MISCONFIGURED, 'Push controller is not set');
|
||||
}
|
||||
|
||||
let where = PushRouter.getQueryCondition(req);
|
||||
const where = PushRouter.getQueryCondition(req);
|
||||
let resolve;
|
||||
let promise = new Promise((_resolve) => {
|
||||
const promise = new Promise((_resolve) => {
|
||||
resolve = _resolve;
|
||||
});
|
||||
pushController.sendPush(req.body, where, req.config, req.auth, (pushStatusId) => {
|
||||
@@ -38,9 +38,9 @@ export class PushRouter extends PromiseRouter {
|
||||
* @returns {Object} The query condition, the where field in a query api call
|
||||
*/
|
||||
static getQueryCondition(req) {
|
||||
let body = req.body || {};
|
||||
let hasWhere = typeof body.where !== 'undefined';
|
||||
let hasChannels = typeof body.channels !== 'undefined';
|
||||
const body = req.body || {};
|
||||
const hasWhere = typeof body.where !== 'undefined';
|
||||
const hasChannels = typeof body.channels !== 'undefined';
|
||||
|
||||
let where;
|
||||
if (hasWhere && hasChannels) {
|
||||
|
||||
@@ -55,8 +55,8 @@ function modifySchema(req) {
|
||||
return classNameMismatchResponse(req.body.className, req.params.className);
|
||||
}
|
||||
|
||||
let submittedFields = req.body.fields || {};
|
||||
let className = req.params.className;
|
||||
const submittedFields = req.body.fields || {};
|
||||
const className = req.params.className;
|
||||
|
||||
return req.config.database.loadSchema({ clearCache: true})
|
||||
.then(schema => schema.updateClass(className, submittedFields, req.body.classLevelPermissions, req.config.database))
|
||||
|
||||
@@ -9,7 +9,7 @@ import rest from '../rest';
|
||||
import Auth from '../Auth';
|
||||
import passwordCrypto from '../password';
|
||||
import RestWrite from '../RestWrite';
|
||||
let cryptoUtils = require('../cryptoUtils');
|
||||
const cryptoUtils = require('../cryptoUtils');
|
||||
|
||||
export class UsersRouter extends ClassesRouter {
|
||||
handleFind(req) {
|
||||
@@ -23,7 +23,7 @@ export class UsersRouter extends ClassesRouter {
|
||||
}
|
||||
|
||||
handleCreate(req) {
|
||||
let data = deepcopy(req.body);
|
||||
const data = deepcopy(req.body);
|
||||
req.body = data;
|
||||
req.params.className = '_User';
|
||||
|
||||
@@ -44,7 +44,7 @@ export class UsersRouter extends ClassesRouter {
|
||||
if (!req.info || !req.info.sessionToken) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid session token');
|
||||
}
|
||||
let sessionToken = req.info.sessionToken;
|
||||
const sessionToken = req.info.sessionToken;
|
||||
return rest.find(req.config, Auth.master(req.config), '_Session',
|
||||
{ sessionToken },
|
||||
{ include: 'user' }, req.info.clientSDK)
|
||||
@@ -54,7 +54,7 @@ export class UsersRouter extends ClassesRouter {
|
||||
!response.results[0].user) {
|
||||
throw new Parse.Error(Parse.Error.INVALID_SESSION_TOKEN, 'invalid session token');
|
||||
} else {
|
||||
let user = response.results[0].user;
|
||||
const user = response.results[0].user;
|
||||
// Send token back on the login, because SDKs expect that.
|
||||
user.sessionToken = sessionToken;
|
||||
return { response: user };
|
||||
@@ -96,7 +96,7 @@ export class UsersRouter extends ClassesRouter {
|
||||
})
|
||||
.then((correct) => {
|
||||
isValidPassword = correct;
|
||||
let accountLockoutPolicy = new AccountLockout(user, req.config);
|
||||
const accountLockoutPolicy = new AccountLockout(user, req.config);
|
||||
return accountLockoutPolicy.handleLoginAttempt(isValidPassword);
|
||||
})
|
||||
.then(() => {
|
||||
@@ -126,7 +126,7 @@ export class UsersRouter extends ClassesRouter {
|
||||
}
|
||||
}
|
||||
|
||||
let token = 'r:' + cryptoUtils.newToken();
|
||||
const token = 'r:' + cryptoUtils.newToken();
|
||||
user.sessionToken = token;
|
||||
delete user.password;
|
||||
|
||||
@@ -145,8 +145,8 @@ export class UsersRouter extends ClassesRouter {
|
||||
|
||||
req.config.filesController.expandFilesInObject(req.config, user);
|
||||
|
||||
let expiresAt = req.config.generateSessionExpiresAt();
|
||||
let sessionData = {
|
||||
const expiresAt = req.config.generateSessionExpiresAt();
|
||||
const sessionData = {
|
||||
sessionToken: token,
|
||||
user: {
|
||||
__type: 'Pointer',
|
||||
@@ -165,7 +165,7 @@ export class UsersRouter extends ClassesRouter {
|
||||
sessionData.installationId = req.info.installationId
|
||||
}
|
||||
|
||||
let create = new RestWrite(req.config, Auth.master(req.config), '_Session', null, sessionData);
|
||||
const create = new RestWrite(req.config, Auth.master(req.config), '_Session', null, sessionData);
|
||||
return create.execute();
|
||||
}).then(() => {
|
||||
return { response: user };
|
||||
@@ -173,7 +173,7 @@ export class UsersRouter extends ClassesRouter {
|
||||
}
|
||||
|
||||
handleLogOut(req) {
|
||||
let success = {response: {}};
|
||||
const success = {response: {}};
|
||||
if (req.info && req.info.sessionToken) {
|
||||
return rest.find(req.config, Auth.master(req.config), '_Session',
|
||||
{ sessionToken: req.info.sessionToken }, undefined, req.info.clientSDK
|
||||
@@ -207,14 +207,14 @@ export class UsersRouter extends ClassesRouter {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
let { email } = req.body;
|
||||
const { email } = req.body;
|
||||
if (!email) {
|
||||
throw new Parse.Error(Parse.Error.EMAIL_MISSING, "you must provide an email");
|
||||
}
|
||||
if (typeof email !== 'string') {
|
||||
throw new Parse.Error(Parse.Error.INVALID_EMAIL_ADDRESS, 'you must provide a valid email string');
|
||||
}
|
||||
let userController = req.config.userController;
|
||||
const userController = req.config.userController;
|
||||
return userController.sendPasswordResetEmail(email).then(() => {
|
||||
return Promise.resolve({
|
||||
response: {}
|
||||
|
||||
@@ -42,11 +42,11 @@ function statusHandler(className, database) {
|
||||
|
||||
export function jobStatusHandler(config) {
|
||||
let jobStatus;
|
||||
let objectId = newObjectId();
|
||||
let database = config.database;
|
||||
let handler = statusHandler(JOB_STATUS_COLLECTION, database);
|
||||
let setRunning = function(jobName, params) {
|
||||
let now = new Date();
|
||||
const objectId = newObjectId();
|
||||
const database = config.database;
|
||||
const handler = statusHandler(JOB_STATUS_COLLECTION, database);
|
||||
const setRunning = function(jobName, params) {
|
||||
const now = new Date();
|
||||
jobStatus = {
|
||||
objectId,
|
||||
jobName,
|
||||
@@ -61,24 +61,24 @@ export function jobStatusHandler(config) {
|
||||
return handler.create(jobStatus);
|
||||
}
|
||||
|
||||
let setMessage = function(message) {
|
||||
const setMessage = function(message) {
|
||||
if (!message || typeof message !== 'string') {
|
||||
return Promise.resolve();
|
||||
}
|
||||
return handler.update({ objectId }, { message });
|
||||
}
|
||||
|
||||
let setSucceeded = function(message) {
|
||||
const setSucceeded = function(message) {
|
||||
return setFinalStatus('succeeded', message);
|
||||
}
|
||||
|
||||
let setFailed = function(message) {
|
||||
const setFailed = function(message) {
|
||||
return setFinalStatus('failed', message);
|
||||
}
|
||||
|
||||
let setFinalStatus = function(status, message = undefined) {
|
||||
let finishedAt = new Date();
|
||||
let update = { status, finishedAt };
|
||||
const setFinalStatus = function(status, message = undefined) {
|
||||
const finishedAt = new Date();
|
||||
const update = { status, finishedAt };
|
||||
if (message && typeof message === 'string') {
|
||||
update.message = message;
|
||||
}
|
||||
@@ -96,13 +96,13 @@ export function jobStatusHandler(config) {
|
||||
export function pushStatusHandler(config) {
|
||||
|
||||
let pushStatus;
|
||||
let objectId = newObjectId();
|
||||
let database = config.database;
|
||||
let handler = statusHandler(PUSH_STATUS_COLLECTION, database);
|
||||
let setInitial = function(body = {}, where, options = {source: 'rest'}) {
|
||||
let now = new Date();
|
||||
let data = body.data || {};
|
||||
let payloadString = JSON.stringify(data);
|
||||
const objectId = newObjectId();
|
||||
const database = config.database;
|
||||
const handler = statusHandler(PUSH_STATUS_COLLECTION, database);
|
||||
const setInitial = function(body = {}, where, options = {source: 'rest'}) {
|
||||
const now = new Date();
|
||||
const data = body.data || {};
|
||||
const payloadString = JSON.stringify(data);
|
||||
let pushHash;
|
||||
if (typeof data.alert === 'string') {
|
||||
pushHash = md5Hash(data.alert);
|
||||
@@ -111,7 +111,7 @@ export function pushStatusHandler(config) {
|
||||
} else {
|
||||
pushHash = 'd41d8cd98f00b204e9800998ecf8427e';
|
||||
}
|
||||
let object = {
|
||||
const object = {
|
||||
objectId,
|
||||
createdAt: now,
|
||||
pushTime: now.toISOString(),
|
||||
@@ -135,14 +135,14 @@ export function pushStatusHandler(config) {
|
||||
});
|
||||
}
|
||||
|
||||
let setRunning = function(installations) {
|
||||
const setRunning = function(installations) {
|
||||
logger.verbose('sending push to %d installations', installations.length);
|
||||
return handler.update({status:"pending", objectId: objectId},
|
||||
{status: "running", updatedAt: new Date() });
|
||||
}
|
||||
|
||||
let complete = function(results) {
|
||||
let update = {
|
||||
const complete = function(results) {
|
||||
const update = {
|
||||
status: 'succeeded',
|
||||
updatedAt: new Date(),
|
||||
numSent: 0,
|
||||
@@ -155,7 +155,7 @@ export function pushStatusHandler(config) {
|
||||
if (!result || !result.device || !result.device.deviceType) {
|
||||
return memo;
|
||||
}
|
||||
let deviceType = result.device.deviceType;
|
||||
const deviceType = result.device.deviceType;
|
||||
if (result.transmitted)
|
||||
{
|
||||
memo.numSent++;
|
||||
@@ -175,8 +175,8 @@ export function pushStatusHandler(config) {
|
||||
return handler.update({status:"running", objectId }, update);
|
||||
}
|
||||
|
||||
let fail = function(err) {
|
||||
let update = {
|
||||
const fail = function(err) {
|
||||
const update = {
|
||||
errorMessage: JSON.stringify(err),
|
||||
status: 'failed',
|
||||
updatedAt: new Date()
|
||||
|
||||
10
src/batch.js
10
src/batch.js
@@ -22,10 +22,10 @@ function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) {
|
||||
serverURL = serverURL ? parseURL(serverURL) : undefined;
|
||||
publicServerURL = publicServerURL ? parseURL(publicServerURL): undefined;
|
||||
|
||||
let apiPrefixLength = originalUrl.length - batchPath.length;
|
||||
const apiPrefixLength = originalUrl.length - batchPath.length;
|
||||
let apiPrefix = originalUrl.slice(0, apiPrefixLength);
|
||||
|
||||
let makeRoutablePath = function(requestPath) {
|
||||
const makeRoutablePath = function(requestPath) {
|
||||
// The routablePath is the path minus the api prefix
|
||||
if (requestPath.slice(0, apiPrefix.length) != apiPrefix) {
|
||||
throw new Parse.Error(
|
||||
@@ -37,14 +37,14 @@ function makeBatchRoutingPathFunction(originalUrl, serverURL, publicServerURL) {
|
||||
|
||||
if (serverURL && publicServerURL
|
||||
&& (serverURL.path != publicServerURL.path)) {
|
||||
let localPath = serverURL.path;
|
||||
let publicPath = publicServerURL.path;
|
||||
const localPath = serverURL.path;
|
||||
const publicPath = publicServerURL.path;
|
||||
// Override the api prefix
|
||||
apiPrefix = localPath;
|
||||
return function(requestPath) {
|
||||
// Build the new path by removing the public path
|
||||
// and joining with the local path
|
||||
let newPath = path.posix.join('/', localPath, '/' , requestPath.slice(publicPath.length));
|
||||
const newPath = path.posix.join('/', localPath, '/' , requestPath.slice(publicPath.length));
|
||||
// Use the method for local routing
|
||||
return makeRoutablePath(newPath);
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ function startServer(options, callback) {
|
||||
|
||||
app.use(options.mountPath, api);
|
||||
|
||||
let server = app.listen(options.port, options.host, callback);
|
||||
const server = app.listen(options.port, options.host, callback);
|
||||
server.on('connection', initializeConnections);
|
||||
|
||||
if (options.startLiveQueryServer || options.liveQueryServerOptions) {
|
||||
@@ -69,7 +69,7 @@ function startServer(options, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
let handleShutdown = function() {
|
||||
const handleShutdown = function() {
|
||||
console.log('Termination signal received. Shutting down.');
|
||||
destroyAliveConnections();
|
||||
server.close(function () {
|
||||
|
||||
@@ -68,7 +68,7 @@ function parseConfigFile(program) {
|
||||
if (program.args.length > 0) {
|
||||
let jsonPath = program.args[0];
|
||||
jsonPath = path.resolve(jsonPath);
|
||||
let jsonConfig = require(jsonPath);
|
||||
const jsonConfig = require(jsonPath);
|
||||
if (jsonConfig.apps) {
|
||||
if (jsonConfig.apps.length > 1) {
|
||||
throw 'Multiple apps are not supported';
|
||||
@@ -78,11 +78,11 @@ function parseConfigFile(program) {
|
||||
options = jsonConfig;
|
||||
}
|
||||
Object.keys(options).forEach((key) => {
|
||||
let value = options[key];
|
||||
const value = options[key];
|
||||
if (!_definitions[key]) {
|
||||
throw `error: unknown option ${key}`;
|
||||
}
|
||||
let action = _definitions[key].action;
|
||||
const action = _definitions[key].action;
|
||||
if (action) {
|
||||
options[key] = action(value);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import program from './commander';
|
||||
|
||||
function logStartupOptions(options) {
|
||||
for (let key in options) {
|
||||
for (const key in options) {
|
||||
let value = options[key];
|
||||
if (key == "masterKey") {
|
||||
value = "***REDACTED***";
|
||||
@@ -31,7 +31,7 @@ export default function({
|
||||
}
|
||||
program.parse(process.argv, process.env);
|
||||
|
||||
let options = program.getOptions();
|
||||
const options = program.getOptions();
|
||||
start(program, options, function() {
|
||||
logStartupOptions(options);
|
||||
});
|
||||
|
||||
@@ -14,7 +14,7 @@ export default class HTTPResponse {
|
||||
_data = body;
|
||||
}
|
||||
|
||||
let getText = () => {
|
||||
const getText = () => {
|
||||
if (!_text && this.buffer) {
|
||||
_text = this.buffer.toString('utf-8');
|
||||
} else if (!_text && _data) {
|
||||
@@ -23,7 +23,7 @@ export default class HTTPResponse {
|
||||
return _text;
|
||||
}
|
||||
|
||||
let getData = () => {
|
||||
const getData = () => {
|
||||
if (!_data) {
|
||||
try {
|
||||
_data = JSON.parse(getText());
|
||||
|
||||
@@ -62,7 +62,7 @@ module.exports = function(options) {
|
||||
}
|
||||
return promise.reject(error);
|
||||
}
|
||||
let httpResponse = new HTTPResponse(response, body);
|
||||
const httpResponse = new HTTPResponse(response, body);
|
||||
|
||||
// Consider <200 && >= 400 as errors
|
||||
if (httpResponse.status < 200 || httpResponse.status >= 400) {
|
||||
|
||||
@@ -23,11 +23,11 @@ export function randomString(size: number): string {
|
||||
if (size === 0) {
|
||||
throw new Error('Zero-length randomString is useless.');
|
||||
}
|
||||
let chars = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
|
||||
const chars = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
|
||||
'abcdefghijklmnopqrstuvwxyz' +
|
||||
'0123456789');
|
||||
let objectId = '';
|
||||
let bytes = randomBytes(size);
|
||||
const bytes = randomBytes(size);
|
||||
for (let i = 0; i < bytes.length; ++i) {
|
||||
objectId += chars[bytes.readUInt8(i) % chars.length];
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {nullParser} from './cli/utils/parsers';
|
||||
|
||||
let logsFolder = (() => {
|
||||
const logsFolder = (() => {
|
||||
let folder = './logs/';
|
||||
if (typeof process !== 'undefined' && process.env.NODE_ENV === 'test') {
|
||||
folder = './test_logs/'
|
||||
@@ -11,8 +11,8 @@ let logsFolder = (() => {
|
||||
return folder;
|
||||
})();
|
||||
|
||||
let { verbose, level } = (() => {
|
||||
let verbose = process.env.VERBOSE ? true : false;
|
||||
const { verbose, level } = (() => {
|
||||
const verbose = process.env.VERBOSE ? true : false;
|
||||
return { verbose, level: verbose ? 'verbose' : undefined }
|
||||
})();
|
||||
|
||||
|
||||
@@ -9,14 +9,14 @@ import { useExternal } from './deprecated';
|
||||
import { getLogger } from './logger';
|
||||
|
||||
// Factory function
|
||||
let _ParseServer = function(options) {
|
||||
let server = new ParseServer(options);
|
||||
const _ParseServer = function(options) {
|
||||
const server = new ParseServer(options);
|
||||
return server.app;
|
||||
}
|
||||
// Mount the create liveQueryServer
|
||||
_ParseServer.createLiveQueryServer = ParseServer.createLiveQueryServer;
|
||||
|
||||
let GCSAdapter = useExternal('GCSAdapter', 'parse-server-gcs-adapter');
|
||||
const GCSAdapter = useExternal('GCSAdapter', 'parse-server-gcs-adapter');
|
||||
|
||||
Object.defineProperty(module.exports, 'logger', {
|
||||
get: getLogger
|
||||
|
||||
@@ -4,7 +4,7 @@ import { WinstonLoggerAdapter } from './Adapters/Logger/WinstonLoggerAdapter';
|
||||
import { LoggerController } from './Controllers/LoggerController';
|
||||
|
||||
function defaultLogger() {
|
||||
let adapter = new WinstonLoggerAdapter({
|
||||
const adapter = new WinstonLoggerAdapter({
|
||||
logsFolder: defaults.logsFolder,
|
||||
jsonLogs: defaults.jsonLogs,
|
||||
verbose: defaults.verbose,
|
||||
|
||||
@@ -274,7 +274,7 @@ export function enforceMasterKeyAccess(req, res, next) {
|
||||
|
||||
export function promiseEnforceMasterKeyAccess(request) {
|
||||
if (!request.auth.isMaster) {
|
||||
let error = new Error();
|
||||
const error = new Error();
|
||||
error.status = 403;
|
||||
error.message = "unauthorized: master key is required";
|
||||
throw error;
|
||||
|
||||
@@ -20,7 +20,7 @@ function find(config, auth, className, restWhere, restOptions, clientSDK) {
|
||||
return triggers.maybeRunQueryTrigger(triggers.Types.beforeFind, className, restWhere, restOptions, config, auth).then((result) => {
|
||||
restWhere = result.restWhere || restWhere;
|
||||
restOptions = result.restOptions || restOptions;
|
||||
let query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK);
|
||||
const query = new RestQuery(config, auth, className, restWhere, restOptions, clientSDK);
|
||||
return query.execute();
|
||||
});
|
||||
}
|
||||
@@ -28,7 +28,7 @@ function find(config, auth, className, restWhere, restOptions, clientSDK) {
|
||||
// get is just like find but only queries an objectId.
|
||||
const get = (config, auth, className, objectId, restOptions, clientSDK) => {
|
||||
enforceRoleSecurity('get', className, auth);
|
||||
let query = new RestQuery(config, auth, className, { objectId }, restOptions, clientSDK);
|
||||
const query = new RestQuery(config, auth, className, { objectId }, restOptions, clientSDK);
|
||||
return query.execute();
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ function update(config, auth, className, objectId, restObject, clientSDK) {
|
||||
function enforceRoleSecurity(method, className, auth) {
|
||||
if (className === '_Installation' && !auth.isMaster) {
|
||||
if (method === 'delete' || method === 'find') {
|
||||
let error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`
|
||||
const error = `Clients aren't allowed to perform the ${method} operation on the installation collection.`
|
||||
throw new Parse.Error(Parse.Error.OPERATION_FORBIDDEN, error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ export const Types = {
|
||||
};
|
||||
|
||||
const baseStore = function() {
|
||||
let Validators = {};
|
||||
let Functions = {};
|
||||
let Jobs = {};
|
||||
let Triggers = Object.keys(Types).reduce(function(base, key){
|
||||
const Validators = {};
|
||||
const Functions = {};
|
||||
const Jobs = {};
|
||||
const Triggers = Object.keys(Types).reduce(function(base, key){
|
||||
base[key] = {};
|
||||
return base;
|
||||
}, {});
|
||||
@@ -286,7 +286,7 @@ export function maybeRunAfterFindTrigger(triggerType, auth, className, objects,
|
||||
}
|
||||
|
||||
export function maybeRunQueryTrigger(triggerType, className, restWhere, restOptions, config, auth) {
|
||||
let trigger = getTrigger(className, triggerType, config.applicationId);
|
||||
const trigger = getTrigger(className, triggerType, config.applicationId);
|
||||
if (!trigger) {
|
||||
return Promise.resolve({
|
||||
restWhere,
|
||||
@@ -294,7 +294,7 @@ export function maybeRunQueryTrigger(triggerType, className, restWhere, restOpti
|
||||
});
|
||||
}
|
||||
|
||||
let parseQuery = new Parse.Query(className);
|
||||
const parseQuery = new Parse.Query(className);
|
||||
if (restWhere) {
|
||||
parseQuery._where = restWhere;
|
||||
}
|
||||
@@ -309,7 +309,7 @@ export function maybeRunQueryTrigger(triggerType, className, restWhere, restOpti
|
||||
parseQuery._limit = restOptions.limit;
|
||||
}
|
||||
}
|
||||
let requestObject = getRequestQueryObject(triggerType, auth, parseQuery, config);
|
||||
const requestObject = getRequestQueryObject(triggerType, auth, parseQuery, config);
|
||||
return Promise.resolve().then(() => {
|
||||
return trigger(requestObject);
|
||||
}).then((result) => {
|
||||
@@ -317,7 +317,7 @@ export function maybeRunQueryTrigger(triggerType, className, restWhere, restOpti
|
||||
if (result && result instanceof Parse.Query) {
|
||||
queryResult = result;
|
||||
}
|
||||
let jsonQuery = queryResult.toJSON();
|
||||
const jsonQuery = queryResult.toJSON();
|
||||
if (jsonQuery.where) {
|
||||
restWhere = jsonQuery.where;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user