Skip to content

Commit 308fe14

Browse files
committed
Centralizes list of system classes into Schema
1 parent 49531e7 commit 308fe14

File tree

3 files changed

+39
-26
lines changed

3 files changed

+39
-26
lines changed

src/RestQuery.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// An object that encapsulates everything we need to run a 'find'
22
// operation, encoded in the REST API format.
33

4+
var Schema = require('./Schema');
45
var Parse = require('parse/node').Parse;
56

67
import { default as FilesController } from './Controllers/FilesController';
@@ -171,7 +172,7 @@ RestQuery.prototype.redirectClassNameForKey = function() {
171172

172173
// Validates this operation against the allowClientClassCreation config.
173174
RestQuery.prototype.validateClientClassCreation = function() {
174-
let sysClass = ['_User', '_Installation', '_Role', '_Session', '_Product'];
175+
let sysClass = Schema.systemClasses;
175176
if (this.config.allowClientClassCreation === false && !this.auth.isMaster
176177
&& sysClass.indexOf(this.className) === -1) {
177178
return this.config.database.collectionExists(this.className).then((hasClass) => {
@@ -423,7 +424,7 @@ RestQuery.prototype.handleInclude = function() {
423424
this.include = this.include.slice(1);
424425
return this.handleInclude();
425426
}
426-
427+
427428
return pathResponse;
428429
};
429430

src/RestWrite.js

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// This could be either a "create" or an "update".
44

55
import cache from './cache';
6+
var Schema = require('./Schema');
67
var deepcopy = require('deepcopy');
78

89
var Auth = require('./Auth');
@@ -32,7 +33,7 @@ function RestWrite(config, auth, className, query, data, originalData) {
3233
throw new Parse.Error(Parse.Error.INVALID_KEY_NAME, 'objectId ' +
3334
'is an invalid field name.');
3435
}
35-
36+
3637
// When the operation is complete, this.response may have several
3738
// fields.
3839
// response: the actual data to be returned
@@ -108,7 +109,7 @@ RestWrite.prototype.getUserAndRoleACL = function() {
108109

109110
// Validates this operation against the allowClientClassCreation config.
110111
RestWrite.prototype.validateClientClassCreation = function() {
111-
let sysClass = ['_User', '_Installation', '_Role', '_Session', '_Product'];
112+
let sysClass = Schema.systemClasses;
112113
if (this.config.allowClientClassCreation === false && !this.auth.isMaster
113114
&& sysClass.indexOf(this.className) === -1) {
114115
return this.config.database.collectionExists(this.className).then((hasClass) => {
@@ -136,7 +137,7 @@ RestWrite.prototype.runBeforeTrigger = function() {
136137
if (this.response) {
137138
return;
138139
}
139-
140+
140141
// Avoid doing any setup for triggers if there is no 'beforeSave' trigger for this class.
141142
if (!triggers.triggerExists(this.className, triggers.Types.beforeSave, this.config.applicationId)) {
142143
return Promise.resolve();
@@ -254,14 +255,14 @@ RestWrite.prototype.findUsersWithAuthData = function(authData) {
254255
}, []).filter((q) => {
255256
return typeof q !== undefined;
256257
});
257-
258+
258259
let findPromise = Promise.resolve([]);
259260
if (query.length > 0) {
260261
findPromise = this.config.database.find(
261262
this.className,
262263
{'$or': query}, {})
263264
}
264-
265+
265266
return findPromise;
266267
}
267268

@@ -276,9 +277,9 @@ RestWrite.prototype.handleAuthData = function(authData) {
276277
throw new Parse.Error(Parse.Error.ACCOUNT_ALREADY_LINKED,
277278
'this auth is already used');
278279
}
279-
280+
280281
this.storage['authProvider'] = Object.keys(authData).join(',');
281-
282+
282283
if (results.length == 0) {
283284
this.data.username = cryptoUtils.newToken();
284285
} else if (!this.query) {
@@ -404,7 +405,7 @@ RestWrite.prototype.transformUser = function() {
404405

405406
// Handles any followup logic
406407
RestWrite.prototype.handleFollowup = function() {
407-
408+
408409
if (this.storage && this.storage['clearSessions']) {
409410
var sessionQuery = {
410411
user: {
@@ -417,7 +418,7 @@ RestWrite.prototype.handleFollowup = function() {
417418
this.config.database.destroy('_Session', sessionQuery)
418419
.then(this.handleFollowup.bind(this));
419420
}
420-
421+
421422
if (this.storage && this.storage['sendVerificationEmail']) {
422423
delete this.storage['sendVerificationEmail'];
423424
// Fire and forget!
@@ -695,7 +696,7 @@ RestWrite.prototype.runDatabaseOperation = function() {
695696
throw new Parse.Error(Parse.Error.SESSION_MISSING,
696697
'cannot modify user ' + this.query.objectId);
697698
}
698-
699+
699700
if (this.className === '_Product' && this.data.download) {
700701
this.data.downloadName = this.data.download.name;
701702
}
@@ -722,7 +723,7 @@ RestWrite.prototype.runDatabaseOperation = function() {
722723
ACL[this.data.objectId] = { read: true, write: true };
723724
ACL['*'] = { read: true, write: false };
724725
this.data.ACL = ACL;
725-
}
726+
}
726727
// Run a create
727728
return this.config.database.create(this.className, this.data, this.runOptions)
728729
.then(() => {

src/Schema.js

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,20 @@ var defaultColumns = {
6767
"icon": {type:'File'},
6868
"order": {type:'Number'},
6969
"title": {type:'String'},
70-
"subtitle": {type:'String'},
70+
"subtitle": {type:'String'},
71+
},
72+
_PushStatus: {
73+
"pushTime": {type:'String'},
74+
"source": {type:'String'}, // rest or web
75+
"query": {type:'String'}, // the stringified JSON query
76+
"payload": {type:'Object'}, // the JSON payload,
77+
"title": {type:'String'},
78+
"expiry": {type:'Number'},
79+
"status": {type:'String'},
80+
"numSent": {type:'Number'},
81+
"pushHash": {type:'String'},
82+
"errorMessage": {type:'Object'},
83+
"sentPerType": {type:'Object'}
7184
}
7285
};
7386

@@ -76,6 +89,8 @@ var requiredColumns = {
7689
_Role: ["name", "ACL"]
7790
}
7891

92+
const systemClasses = ['_User', '_Installation', '_Role', '_Session', '_Product', '_PushStatus'];
93+
7994
// 10 alpha numberic chars + uppercase
8095
const userIdRegex = /^[a-zA-Z0-9]{10}$/;
8196
// Anything that start with role
@@ -127,13 +142,8 @@ function validateCLP(perms) {
127142
var joinClassRegex = /^_Join:[A-Za-z0-9_]+:[A-Za-z0-9_]+/;
128143
var classAndFieldRegex = /^[A-Za-z][A-Za-z0-9_]*$/;
129144
function classNameIsValid(className) {
130-
return (
131-
className === '_User' ||
132-
className === '_Installation' ||
133-
className === '_Session' ||
145+
return (systemClasses.indexOf(className) > -1 ||
134146
className === '_SCHEMA' || //TODO: remove this, as _SCHEMA is not a valid class name for storing Parse Objects.
135-
className === '_Role' ||
136-
className === '_Product' ||
137147
joinClassRegex.test(className) ||
138148
//Class names have the same constraints as field names, but also allow the previous additional names.
139149
fieldNameIsValid(className)
@@ -284,7 +294,7 @@ class Schema {
284294
return Promise.reject(error);
285295
});
286296
}
287-
297+
288298
updateClass(className, submittedFields, classLevelPermissions, database) {
289299
if (!this.data[className]) {
290300
throw new Parse.Error(Parse.Error.INVALID_CLASS_NAME, `Class ${className} does not exist.`);
@@ -299,7 +309,7 @@ class Schema {
299309
throw new Parse.Error(255, `Field ${name} does not exist, cannot delete.`);
300310
}
301311
});
302-
312+
303313
let newSchema = buildMergedSchemaObject(existingFields, submittedFields);
304314
let mongoObject = mongoSchemaFromFieldsAndClassNameAndCLP(newSchema, className, classLevelPermissions);
305315
if (!mongoObject.result) {
@@ -327,7 +337,7 @@ class Schema {
327337
});
328338
return Promise.all(promises);
329339
})
330-
.then(() => {
340+
.then(() => {
331341
return this.setPermissions(className, classLevelPermissions)
332342
})
333343
.then(() => { return mongoSchemaToSchemaAPIResponse(mongoObject.result) });
@@ -697,7 +707,7 @@ function mongoSchemaFromFieldsAndClassNameAndCLP(fields, className, classLevelPe
697707
error: 'currently, only one GeoPoint field may exist in an object. Adding ' + geoPoints[1] + ' when ' + geoPoints[0] + ' already exists.',
698708
};
699709
}
700-
710+
701711
validateCLP(classLevelPermissions);
702712
if (typeof classLevelPermissions !== 'undefined') {
703713
mongoObject._metadata = mongoObject._metadata || {};
@@ -886,11 +896,11 @@ function mongoSchemaToSchemaAPIResponse(schema) {
886896
className: schema._id,
887897
fields: mongoSchemaAPIResponseFields(schema),
888898
};
889-
899+
890900
let classLevelPermissions = DefaultClassLevelPermissions;
891901
if (schema._metadata && schema._metadata.class_permissions) {
892902
classLevelPermissions = Object.assign(classLevelPermissions, schema._metadata.class_permissions);
893-
}
903+
}
894904
result.classLevelPermissions = classLevelPermissions;
895905
return result;
896906
}
@@ -903,4 +913,5 @@ module.exports = {
903913
buildMergedSchemaObject: buildMergedSchemaObject,
904914
mongoFieldTypeToSchemaAPIType: mongoFieldTypeToSchemaAPIType,
905915
mongoSchemaToSchemaAPIResponse,
916+
systemClasses,
906917
};

0 commit comments

Comments
 (0)