Skip to content

Commit

Permalink
refactor: Add option to convert Parse.Object to instance in Cloud F…
Browse files Browse the repository at this point in the history
…unction payload (#8646)
  • Loading branch information
dblythy committed Jun 23, 2023
1 parent 1850be4 commit 068fb9e
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 7 deletions.
1 change: 1 addition & 0 deletions DEPRECATIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h
| DEPPS7 | Remove file trigger syntax `Parse.Cloud.beforeSaveFile((request) => {})` | [#7966](https://github.com/parse-community/parse-server/pull/7966) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - |
| DEPPS8 | Login with expired 3rd party authentication token defaults to `false` | [#7079](https://github.com/parse-community/parse-server/pull/7079) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - |
| DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | deprecated | - |
| DEPPS10 | Config option `encodeParseObjectInCloudFunction` defaults to `true` | [#8634](https://github.com/parse-community/parse-server/issues/8634) | 6.2.0 (2023) | 7.0.0 (2024) | deprecated | - |

[i_deprecation]: ## "The version and date of the deprecation."
[i_removal]: ## "The version and date of the planned removal."
Expand Down
20 changes: 20 additions & 0 deletions spec/CloudCode.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 +1353,27 @@ describe('Cloud Code', () => {
});
});

it('should not encode Parse Objects', async () => {
const user = new Parse.User();
user.setUsername('username');
user.setPassword('password');
user.set('deleted', false);
await user.signUp();
Parse.Cloud.define(
'deleteAccount',
async req => {
expect(req.params.object instanceof Parse.Object).not.toBeTrue();
return 'Object deleted';
},
{
requireMaster: true,
}
);
await Parse.Cloud.run('deleteAccount', { object: user.toPointer() }, { useMasterKey: true });
});

it('allow cloud to encode Parse Objects', async () => {
await reconfigureServer({ encodeParseObjectInCloudFunction: true });
const user = new Parse.User();
user.setUsername('username');
user.setPassword('password');
Expand Down
1 change: 1 addition & 0 deletions src/Deprecator/Deprecations.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@
module.exports = [
{ optionKey: 'allowClientClassCreation', changeNewDefault: 'false' },
{ optionKey: 'allowExpiredAuthDataToken', changeNewDefault: 'false' },
{ optionKey: 'encodeParseObjectInCloudFunction', changeNewDefault: 'true' },
];
7 changes: 7 additions & 0 deletions src/Options/Definitions.js
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,13 @@ module.exports.ParseServerOptions = {
action: parsers.booleanParser,
default: false,
},
encodeParseObjectInCloudFunction: {
env: 'PARSE_SERVER_ENCODE_PARSE_OBJECT_IN_CLOUD_FUNCTION',
help:
'If set to `true`, a `Parse.Object` that is in the payload when calling a Cloud Function will be converted to an instance of `Parse.Object`. If `false`, the object will not be converted and instead be a plain JavaScript object, which contains the raw data of a `Parse.Object` but is not an actual instance of `Parse.Object`. Default is `false`. <br><br>\u2139\uFE0F The expected behavior would be that the object is converted to an instance of `Parse.Object`, so you would normally set this option to `true`. The default is `false` because this is a temporary option that has been introduced to avoid a breaking change when fixing a bug where JavaScript objects are not converted to actual instances of `Parse.Object`.',
action: parsers.booleanParser,
default: false,
},
encryptionKey: {
env: 'PARSE_SERVER_ENCRYPTION_KEY',
help: 'Key for encrypting your files',
Expand Down
1 change: 1 addition & 0 deletions src/Options/docs.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/Options/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ export interface ParseServerOptions {
cacheAdapter: ?Adapter<CacheAdapter>;
/* Adapter module for email sending */
emailAdapter: ?Adapter<MailAdapter>;
/* If set to `true`, a `Parse.Object` that is in the payload when calling a Cloud Function will be converted to an instance of `Parse.Object`. If `false`, the object will not be converted and instead be a plain JavaScript object, which contains the raw data of a `Parse.Object` but is not an actual instance of `Parse.Object`. Default is `false`. <br><br>ℹ️ The expected behavior would be that the object is converted to an instance of `Parse.Object`, so you would normally set this option to `true`. The default is `false` because this is a temporary option that has been introduced to avoid a breaking change when fixing a bug where JavaScript objects are not converted to actual instances of `Parse.Object`.
:DEFAULT: false */
encodeParseObjectInCloudFunction: ?boolean;
/* Public URL to your parse server with http:// or https://.
:ENV: PARSE_PUBLIC_SERVER_URL */
publicServerURL: ?string;
Expand Down
14 changes: 7 additions & 7 deletions src/Routers/FunctionsRouter.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { jobStatusHandler } from '../StatusHandler';
import _ from 'lodash';
import { logger } from '../logger';

function parseObject(obj) {
function parseObject(obj, config) {
if (Array.isArray(obj)) {
return obj.map(item => {
return parseObject(item);
Expand All @@ -18,21 +18,21 @@ function parseObject(obj) {
return Object.assign(new Date(obj.iso), obj);
} else if (obj && obj.__type == 'File') {
return Parse.File.fromJSON(obj);
} else if (obj && obj.__type == 'Pointer') {
} else if (obj && obj.__type == 'Pointer' && config.encodeParseObjectInCloudFunction) {
return Parse.Object.fromJSON({
__type: 'Pointer',
className: obj.className,
objectId: obj.objectId,
});
} else if (obj && typeof obj === 'object') {
return parseParams(obj);
return parseParams(obj, config);
} else {
return obj;
}
}

function parseParams(params) {
return _.mapValues(params, parseObject);
function parseParams(params, config) {
return _.mapValues(params, item => parseObject(item, config));
}

export class FunctionsRouter extends PromiseRouter {
Expand Down Expand Up @@ -66,7 +66,7 @@ export class FunctionsRouter extends PromiseRouter {
throw new Parse.Error(Parse.Error.SCRIPT_FAILED, 'Invalid job.');
}
let params = Object.assign({}, req.body, req.query);
params = parseParams(params);
params = parseParams(params, req.config);
const request = {
params: params,
log: req.config.loggerController,
Expand Down Expand Up @@ -126,7 +126,7 @@ export class FunctionsRouter extends PromiseRouter {
throw new Parse.Error(Parse.Error.SCRIPT_FAILED, `Invalid function: "${functionName}"`);
}
let params = Object.assign({}, req.body, req.query);
params = parseParams(params);
params = parseParams(params, req.config);
const request = {
params: params,
master: req.auth && req.auth.isMaster,
Expand Down

0 comments on commit 068fb9e

Please sign in to comment.