Skip to content

Add config for objectId size #3950

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 27, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions spec/cryptoUtils.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,10 @@ describe('newObjectId', () => {
expect(cryptoUtils.newObjectId().length).toBeGreaterThan(9);
});

it('returns result with required number of characters', () => {
expect(cryptoUtils.newObjectId(42).length).toBe(42);
});

it('returns unique results', () => {
expect(givesUniqueResults(() => cryptoUtils.newObjectId(), 100)).toBe(true);
});
Expand Down
44 changes: 44 additions & 0 deletions spec/rest.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,55 @@ describe('rest create', () => {
expect(results.length).toEqual(1);
var obj = results[0];
expect(typeof obj.objectId).toEqual('string');
expect(obj.objectId.length).toEqual(10);
expect(obj._id).toBeUndefined();
done();
});
});

it('can use custom _id size', done => {
config.objectIdSize = 20;
rest.create(config, auth.nobody(config), 'Foo', {})
.then(() => database.adapter.find('Foo', { fields: {} }, {}, {}))
.then((results) => {
expect(results.length).toEqual(1);
var obj = results[0];
expect(typeof obj.objectId).toEqual('string');
expect(obj.objectId.length).toEqual(20);
done();
});
});

it('is backwards compatible when _id size changes', done => {
rest.create(config, auth.nobody(config), 'Foo', {size: 10})
.then(() => {
config.objectIdSize = 20;
return rest.find(config, auth.nobody(config), 'Foo', {size: 10});
})
.then((response) => {
expect(response.results.length).toEqual(1);
expect(response.results[0].objectId.length).toEqual(10);
return rest.update(config, auth.nobody(config), 'Foo', {objectId: response.results[0].objectId}, {update: 20});
})
.then(() => {
return rest.find(config, auth.nobody(config), 'Foo', {size: 10});
}).then((response) => {
expect(response.results.length).toEqual(1);
expect(response.results[0].objectId.length).toEqual(10);
expect(response.results[0].update).toEqual(20);
return rest.create(config, auth.nobody(config), 'Foo', {size: 20});
})
.then(() => {
config.objectIdSize = 10;
return rest.find(config, auth.nobody(config), 'Foo', {size: 20});
})
.then((response) => {
expect(response.results.length).toEqual(1);
expect(response.results[0].objectId.length).toEqual(20);
done();
});
});

it('handles array, object, date', (done) => {
const now = new Date();
var obj = {
Expand Down
1 change: 1 addition & 0 deletions src/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ export class Config {
this.generateSessionExpiresAt = this.generateSessionExpiresAt.bind(this);
this.generateEmailVerifyTokenExpiresAt = this.generateEmailVerifyTokenExpiresAt.bind(this);
this.revokeSessionOnPasswordReset = cacheInfo.revokeSessionOnPasswordReset;
this.objectIdSize = cacheInfo.objectIdSize;
}

static validate({
Expand Down
4 changes: 3 additions & 1 deletion src/ParseServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ class ParseServer {
revokeSessionOnPasswordReset = defaults.revokeSessionOnPasswordReset,
schemaCacheTTL = defaults.schemaCacheTTL, // cache for 5s
enableSingleSchemaCache = false,
objectIdSize = defaults.objectIdSize,
__indexBuildCompletionCallbackForTests = () => {},
}) {
// Initialize the node client SDK automatically
Expand Down Expand Up @@ -262,7 +263,8 @@ class ParseServer {
pushWorker,
pushControllerQueue,
hasPushSupport,
hasPushScheduledSupport
hasPushScheduledSupport,
objectIdSize
});

Config.validate(AppCache.get(appId));
Expand Down
2 changes: 1 addition & 1 deletion src/RestWrite.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ RestWrite.prototype.setRequiredFieldsIfNeeded = function() {

// Only assign new objectId if we are creating new object
if (!this.data.objectId) {
this.data.objectId = cryptoUtils.newObjectId();
this.data.objectId = cryptoUtils.newObjectId(this.config.objectIdSize);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/StatusHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ function statusHandler(className, database) {

export function jobStatusHandler(config) {
let jobStatus;
const objectId = newObjectId();
const objectId = newObjectId(config.objectIdSize);
const database = config.database;
const handler = statusHandler(JOB_STATUS_COLLECTION, database);
const setRunning = function(jobName, params) {
Expand Down Expand Up @@ -103,7 +103,7 @@ export function jobStatusHandler(config) {
});
}

export function pushStatusHandler(config, objectId = newObjectId()) {
export function pushStatusHandler(config, objectId = newObjectId(config.objectIdSize)) {

let pushStatus;
const database = config.database;
Expand Down
5 changes: 5 additions & 0 deletions src/cli/definitions/parse-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,5 +256,10 @@ export default {
},
"middleware": {
help: "middleware for express server, can be string or function"
},
"objectIdSize": {
env: "PARSE_SERVER_OBJECT_ID_SIZE",
help: "Sets the number of characters in generated object id's, default 10",
action: numberParser("objectIdSize")
}
};
5 changes: 2 additions & 3 deletions src/cryptoUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ export function randomString(size: number): string {
}

// Returns a new random alphanumeric string suitable for object ID.
export function newObjectId(): string {
//TODO: increase length to better protect against collisions.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally someone took care of this //TODO 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's funny, I must have seen that comment over a year ago and it never registered that there might be a problem :)

return randomString(10);
export function newObjectId(size: number = 10): string {
return randomString(size);
}

// Returns a new random hex string suitable for secure tokens.
Expand Down
3 changes: 2 additions & 1 deletion src/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ export default {
expireInactiveSessions: true,
revokeSessionOnPasswordReset: true,
schemaCacheTTL: 5000, // in ms
userSensitiveFields: ['email']
userSensitiveFields: ['email'],
objectIdSize: 10
}