Skip to content

Commit 51d2dd9

Browse files
steven-supersolidnatanrolnik
authored andcommitted
Add config for objectId size (#3950)
* Add objectId config property, default to 10 * Update Config constructor * Add test for backwards compatibility when changing objectId size
1 parent bd6816c commit 51d2dd9

File tree

9 files changed

+64
-8
lines changed

9 files changed

+64
-8
lines changed

spec/cryptoUtils.spec.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,10 @@ describe('newObjectId', () => {
6363
expect(cryptoUtils.newObjectId().length).toBeGreaterThan(9);
6464
});
6565

66+
it('returns result with required number of characters', () => {
67+
expect(cryptoUtils.newObjectId(42).length).toBe(42);
68+
});
69+
6670
it('returns unique results', () => {
6771
expect(givesUniqueResults(() => cryptoUtils.newObjectId(), 100)).toBe(true);
6872
});

spec/rest.spec.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,55 @@ describe('rest create', () => {
2323
expect(results.length).toEqual(1);
2424
var obj = results[0];
2525
expect(typeof obj.objectId).toEqual('string');
26+
expect(obj.objectId.length).toEqual(10);
2627
expect(obj._id).toBeUndefined();
2728
done();
2829
});
2930
});
3031

32+
it('can use custom _id size', done => {
33+
config.objectIdSize = 20;
34+
rest.create(config, auth.nobody(config), 'Foo', {})
35+
.then(() => database.adapter.find('Foo', { fields: {} }, {}, {}))
36+
.then((results) => {
37+
expect(results.length).toEqual(1);
38+
var obj = results[0];
39+
expect(typeof obj.objectId).toEqual('string');
40+
expect(obj.objectId.length).toEqual(20);
41+
done();
42+
});
43+
});
44+
45+
it('is backwards compatible when _id size changes', done => {
46+
rest.create(config, auth.nobody(config), 'Foo', {size: 10})
47+
.then(() => {
48+
config.objectIdSize = 20;
49+
return rest.find(config, auth.nobody(config), 'Foo', {size: 10});
50+
})
51+
.then((response) => {
52+
expect(response.results.length).toEqual(1);
53+
expect(response.results[0].objectId.length).toEqual(10);
54+
return rest.update(config, auth.nobody(config), 'Foo', {objectId: response.results[0].objectId}, {update: 20});
55+
})
56+
.then(() => {
57+
return rest.find(config, auth.nobody(config), 'Foo', {size: 10});
58+
}).then((response) => {
59+
expect(response.results.length).toEqual(1);
60+
expect(response.results[0].objectId.length).toEqual(10);
61+
expect(response.results[0].update).toEqual(20);
62+
return rest.create(config, auth.nobody(config), 'Foo', {size: 20});
63+
})
64+
.then(() => {
65+
config.objectIdSize = 10;
66+
return rest.find(config, auth.nobody(config), 'Foo', {size: 20});
67+
})
68+
.then((response) => {
69+
expect(response.results.length).toEqual(1);
70+
expect(response.results[0].objectId.length).toEqual(20);
71+
done();
72+
});
73+
});
74+
3175
it('handles array, object, date', (done) => {
3276
const now = new Date();
3377
var obj = {

src/Config.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export class Config {
7373
this.generateSessionExpiresAt = this.generateSessionExpiresAt.bind(this);
7474
this.generateEmailVerifyTokenExpiresAt = this.generateEmailVerifyTokenExpiresAt.bind(this);
7575
this.revokeSessionOnPasswordReset = cacheInfo.revokeSessionOnPasswordReset;
76+
this.objectIdSize = cacheInfo.objectIdSize;
7677
}
7778

7879
static validate({

src/ParseServer.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class ParseServer {
141141
revokeSessionOnPasswordReset = defaults.revokeSessionOnPasswordReset,
142142
schemaCacheTTL = defaults.schemaCacheTTL, // cache for 5s
143143
enableSingleSchemaCache = false,
144+
objectIdSize = defaults.objectIdSize,
144145
__indexBuildCompletionCallbackForTests = () => {},
145146
}) {
146147
// Initialize the node client SDK automatically
@@ -262,7 +263,8 @@ class ParseServer {
262263
pushWorker,
263264
pushControllerQueue,
264265
hasPushSupport,
265-
hasPushScheduledSupport
266+
hasPushScheduledSupport,
267+
objectIdSize
266268
});
267269

268270
Config.validate(AppCache.get(appId));

src/RestWrite.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ RestWrite.prototype.setRequiredFieldsIfNeeded = function() {
187187

188188
// Only assign new objectId if we are creating new object
189189
if (!this.data.objectId) {
190-
this.data.objectId = cryptoUtils.newObjectId();
190+
this.data.objectId = cryptoUtils.newObjectId(this.config.objectIdSize);
191191
}
192192
}
193193
}

src/StatusHandler.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ function statusHandler(className, database) {
5252

5353
export function jobStatusHandler(config) {
5454
let jobStatus;
55-
const objectId = newObjectId();
55+
const objectId = newObjectId(config.objectIdSize);
5656
const database = config.database;
5757
const handler = statusHandler(JOB_STATUS_COLLECTION, database);
5858
const setRunning = function(jobName, params) {
@@ -103,7 +103,7 @@ export function jobStatusHandler(config) {
103103
});
104104
}
105105

106-
export function pushStatusHandler(config, objectId = newObjectId()) {
106+
export function pushStatusHandler(config, objectId = newObjectId(config.objectIdSize)) {
107107

108108
let pushStatus;
109109
const database = config.database;

src/cli/definitions/parse-server.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,5 +256,10 @@ export default {
256256
},
257257
"middleware": {
258258
help: "middleware for express server, can be string or function"
259+
},
260+
"objectIdSize": {
261+
env: "PARSE_SERVER_OBJECT_ID_SIZE",
262+
help: "Sets the number of characters in generated object id's, default 10",
263+
action: numberParser("objectIdSize")
259264
}
260265
};

src/cryptoUtils.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,8 @@ export function randomString(size: number): string {
3535
}
3636

3737
// Returns a new random alphanumeric string suitable for object ID.
38-
export function newObjectId(): string {
39-
//TODO: increase length to better protect against collisions.
40-
return randomString(10);
38+
export function newObjectId(size: number = 10): string {
39+
return randomString(size);
4140
}
4241

4342
// Returns a new random hex string suitable for secure tokens.

src/defaults.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,5 +32,6 @@ export default {
3232
expireInactiveSessions: true,
3333
revokeSessionOnPasswordReset: true,
3434
schemaCacheTTL: 5000, // in ms
35-
userSensitiveFields: ['email']
35+
userSensitiveFields: ['email'],
36+
objectIdSize: 10
3637
}

0 commit comments

Comments
 (0)