diff --git a/spec/transform.spec.js b/spec/transform.spec.js index 4a47f3598f..58252b229f 100644 --- a/spec/transform.spec.js +++ b/spec/transform.spec.js @@ -1,6 +1,8 @@ // These tests are unit tests designed to only test transform.js. +"use strict"; -var transform = require('../src/transform'); +let transform = require('../src/transform'); +let dd = require('deep-diff'); var dummySchema = { data: {}, @@ -150,14 +152,30 @@ describe('untransformObject', () => { done(); }); - it('nested array', (done) => { - var input = {arr: [{_testKey: 'testValue' }]}; - var output = transform.untransformObject(dummySchema, null, input); - expect(Array.isArray(output.arr)).toEqual(true); - expect(output.arr).toEqual([{ _testKey: 'testValue'}]); - done(); - }); + it('nested array', (done) => { + var input = {arr: [{_testKey: 'testValue' }]}; + var output = transform.untransformObject(dummySchema, null, input); + expect(Array.isArray(output.arr)).toEqual(true); + expect(output.arr).toEqual([{ _testKey: 'testValue'}]); + done(); + }); + it('untransforms objects containing nested special keys', done => { + let input = {array: [{ + _id: "Test ID", + _hashed_password: "I Don't know why you would name a key this, but if you do it should work", + _tombstone: { + _updated_at: "I'm sure people will nest keys like this", + _acl: 7, + _id: { someString: "str", someNumber: 7}, + regularKey: { moreContents: [1, 2, 3] }, + }, + regularKey: "some data", + }]} + let output = transform.untransformObject(dummySchema, null, input); + expect(dd(output, input)).toEqual(undefined); + done(); + }); }); describe('transformKey', () => { diff --git a/src/transform.js b/src/transform.js index eba2ea16b5..d3c14a7c8f 100644 --- a/src/transform.js +++ b/src/transform.js @@ -1,4 +1,5 @@ import log from './logger'; +import _ from 'lodash'; var mongodb = require('mongodb'); var Parse = require('parse/node').Parse; @@ -149,8 +150,6 @@ export function transformKeyValue(schema, className, restKey, restValue, options throw 'There was a problem transforming an ACL.'; } - - // Handle arrays if (restValue instanceof Array) { if (options.query) { @@ -613,6 +612,21 @@ function transformUpdateOperator(operator, flatten) { } } +const specialKeysForUntransform = [ + '_id', + '_hashed_password', + '_acl', + '_email_verify_token', + '_perishable_token', + '_tombstone', + '_session_token', + 'updatedAt', + '_updated_at', + 'createdAt', + '_created_at', + 'expiresAt', + '_expiresAt', +]; // Converts from a mongo-format object to a REST-format object. // Does not strip out anything based on a lack of authentication. @@ -630,10 +644,9 @@ function untransformObject(schema, className, mongoObject, isNestedObject = fals if (mongoObject === null) { return null; } - if (mongoObject instanceof Array) { - return mongoObject.map((o) => { - return untransformObject(schema, className, o, true); + return mongoObject.map(arrayEntry => { + return untransformObject(schema, className, arrayEntry, true); }); } @@ -647,6 +660,10 @@ function untransformObject(schema, className, mongoObject, isNestedObject = fals var restObject = untransformACL(mongoObject); for (var key in mongoObject) { + if (isNestedObject && _.includes(specialKeysForUntransform, key)) { + restObject[key] = untransformObject(schema, className, mongoObject[key], true); + continue; + } switch(key) { case '_id': restObject['objectId'] = '' + mongoObject[key]; @@ -728,8 +745,7 @@ function untransformObject(schema, className, mongoObject, isNestedObject = fals break; } } - restObject[key] = untransformObject(schema, className, - mongoObject[key], true); + restObject[key] = untransformObject(schema, className, mongoObject[key], true); } }