* #6101 Let users define objectId * Add `allowCustomObjectId` to PS Option * Add checking in objectId creation * Add test * Update docs * Update definition * Change default to false * throw on empty, null, undefined * better tests * unused async * removed comment * retain comment * Linting fix according to contributing spec.
This commit is contained in:
@@ -44,6 +44,66 @@ describe('rest create', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should use objectId from client when allowCustomObjectId true', async () => {
|
||||||
|
config.allowCustomObjectId = true;
|
||||||
|
|
||||||
|
// use time as unique custom id for test reusability
|
||||||
|
const customId = `${Date.now()}`;
|
||||||
|
const obj = {
|
||||||
|
objectId: customId,
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
status,
|
||||||
|
response: { objectId },
|
||||||
|
} = await rest.create(config, auth.nobody(config), 'MyClass', obj);
|
||||||
|
|
||||||
|
expect(status).toEqual(201);
|
||||||
|
expect(objectId).toEqual(customId);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw on invalid objectId when allowCustomObjectId true', () => {
|
||||||
|
config.allowCustomObjectId = true;
|
||||||
|
|
||||||
|
const objIdNull = {
|
||||||
|
objectId: null,
|
||||||
|
};
|
||||||
|
|
||||||
|
const objIdUndef = {
|
||||||
|
objectId: undefined,
|
||||||
|
};
|
||||||
|
|
||||||
|
const objIdEmpty = {
|
||||||
|
objectId: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
const err = 'objectId must not be empty, null or undefined';
|
||||||
|
|
||||||
|
expect(() =>
|
||||||
|
rest.create(config, auth.nobody(config), 'MyClass', objIdEmpty)
|
||||||
|
).toThrowError(err);
|
||||||
|
|
||||||
|
expect(() =>
|
||||||
|
rest.create(config, auth.nobody(config), 'MyClass', objIdNull)
|
||||||
|
).toThrowError(err);
|
||||||
|
|
||||||
|
expect(() =>
|
||||||
|
rest.create(config, auth.nobody(config), 'MyClass', objIdUndef)
|
||||||
|
).toThrowError(err);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should generate objectId when not set by client with allowCustomObjectId true', async () => {
|
||||||
|
config.allowCustomObjectId = true;
|
||||||
|
|
||||||
|
const {
|
||||||
|
status,
|
||||||
|
response: { objectId },
|
||||||
|
} = await rest.create(config, auth.nobody(config), 'MyClass', {});
|
||||||
|
|
||||||
|
expect(status).toEqual(201);
|
||||||
|
expect(objectId).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('is backwards compatible when _id size changes', done => {
|
it('is backwards compatible when _id size changes', done => {
|
||||||
rest
|
rest
|
||||||
.create(config, auth.nobody(config), 'Foo', { size: 10 })
|
.create(config, auth.nobody(config), 'Foo', { size: 10 })
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ module.exports.ParseServerOptions = {
|
|||||||
action: parsers.booleanParser,
|
action: parsers.booleanParser,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
allowCustomObjectId: {
|
||||||
|
env: 'PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID',
|
||||||
|
help: 'Enable (or disable) custom objectId, defaults to false',
|
||||||
|
action: parsers.booleanParser,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
allowHeaders: {
|
allowHeaders: {
|
||||||
env: 'PARSE_SERVER_ALLOW_HEADERS',
|
env: 'PARSE_SERVER_ALLOW_HEADERS',
|
||||||
help: 'Add headers to Access-Control-Allow-Headers',
|
help: 'Add headers to Access-Control-Allow-Headers',
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
* @interface ParseServerOptions
|
* @interface ParseServerOptions
|
||||||
* @property {Any} accountLockout account lockout policy for failed login attempts
|
* @property {Any} accountLockout account lockout policy for failed login attempts
|
||||||
* @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true
|
* @property {Boolean} allowClientClassCreation Enable (or disable) client class creation, defaults to true
|
||||||
|
* @property {Boolean} allowCustomObjectId Enable (or disable) custom objectId, defaults to false
|
||||||
* @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers
|
* @property {String[]} allowHeaders Add headers to Access-Control-Allow-Headers
|
||||||
* @property {Adapter<AnalyticsAdapter>} analyticsAdapter Adapter module for the analytics
|
* @property {Adapter<AnalyticsAdapter>} analyticsAdapter Adapter module for the analytics
|
||||||
* @property {String} appId Your Parse Application ID
|
* @property {String} appId Your Parse Application ID
|
||||||
|
|||||||
@@ -102,6 +102,10 @@ export interface ParseServerOptions {
|
|||||||
:ENV: PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION
|
:ENV: PARSE_SERVER_ALLOW_CLIENT_CLASS_CREATION
|
||||||
:DEFAULT: true */
|
:DEFAULT: true */
|
||||||
allowClientClassCreation: ?boolean;
|
allowClientClassCreation: ?boolean;
|
||||||
|
/* Enable (or disable) custom objectId
|
||||||
|
:ENV: PARSE_SERVER_ALLOW_CUSTOM_OBJECT_ID
|
||||||
|
:DEFAULT: false */
|
||||||
|
allowCustomObjectId: ?boolean;
|
||||||
/* Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication
|
/* Configuration for your authentication providers, as stringified JSON. See http://docs.parseplatform.org/parse-server/guide/#oauth-and-3rd-party-authentication
|
||||||
:ENV: PARSE_SERVER_AUTH_PROVIDERS */
|
:ENV: PARSE_SERVER_AUTH_PROVIDERS */
|
||||||
auth: ?any;
|
auth: ?any;
|
||||||
|
|||||||
@@ -46,17 +46,32 @@ function RestWrite(
|
|||||||
this.storage = {};
|
this.storage = {};
|
||||||
this.runOptions = {};
|
this.runOptions = {};
|
||||||
this.context = {};
|
this.context = {};
|
||||||
if (!query && data.objectId) {
|
|
||||||
throw new Parse.Error(
|
if (!query) {
|
||||||
Parse.Error.INVALID_KEY_NAME,
|
if (this.config.allowCustomObjectId) {
|
||||||
'objectId is an invalid field name.'
|
if (
|
||||||
);
|
Object.prototype.hasOwnProperty.call(data, 'objectId') &&
|
||||||
}
|
!data.objectId
|
||||||
if (!query && data.id) {
|
) {
|
||||||
throw new Parse.Error(
|
throw new Parse.Error(
|
||||||
Parse.Error.INVALID_KEY_NAME,
|
Parse.Error.MISSING_OBJECT_ID,
|
||||||
'id is an invalid field name.'
|
'objectId must not be empty, null or undefined'
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (data.objectId) {
|
||||||
|
throw new Parse.Error(
|
||||||
|
Parse.Error.INVALID_KEY_NAME,
|
||||||
|
'objectId is an invalid field name.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (data.id) {
|
||||||
|
throw new Parse.Error(
|
||||||
|
Parse.Error.INVALID_KEY_NAME,
|
||||||
|
'id is an invalid field name.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the operation is complete, this.response may have several
|
// When the operation is complete, this.response may have several
|
||||||
|
|||||||
Reference in New Issue
Block a user