Skip to content

Commit cd4d440

Browse files
committed
new: allow options to be async on Cloud Validator
1 parent 25fb576 commit cd4d440

File tree

2 files changed

+83
-5
lines changed

2 files changed

+83
-5
lines changed

spec/CloudCode.Validator.spec.js

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,4 +1266,78 @@ describe('cloud validator', () => {
12661266
done();
12671267
}
12681268
});
1269+
1270+
it('set params options function async', async () => {
1271+
Parse.Cloud.define(
1272+
'hello',
1273+
() => {
1274+
return 'Hello world!';
1275+
},
1276+
{
1277+
fields: {
1278+
data: {
1279+
type: String,
1280+
required: true,
1281+
options: async val => {
1282+
await new Promise(resolve => {
1283+
setTimeout(resolve, 500);
1284+
});
1285+
return val === 'f';
1286+
},
1287+
error: 'Validation failed.',
1288+
},
1289+
},
1290+
}
1291+
);
1292+
try {
1293+
await Parse.Cloud.run('hello', { data: 'd' });
1294+
} catch (error) {
1295+
expect(error.code).toEqual(Parse.Error.VALIDATION_ERROR);
1296+
expect(error.message).toEqual('Validation failed.');
1297+
}
1298+
await Parse.Cloud.run('hello', { data: 'f' });
1299+
});
1300+
1301+
it('basic beforeSave requireUserKey as custom async function', async () => {
1302+
Parse.Cloud.beforeSave(Parse.User, () => {}, {
1303+
fields: {
1304+
accType: {
1305+
default: 'normal',
1306+
constant: true,
1307+
},
1308+
},
1309+
});
1310+
Parse.Cloud.define(
1311+
'secureFunction',
1312+
() => {
1313+
return "Here's all the secure data!";
1314+
},
1315+
{
1316+
requireUserKeys: {
1317+
accType: {
1318+
options: async val => {
1319+
await new Promise(resolve => {
1320+
setTimeout(resolve, 500);
1321+
});
1322+
return ['admin', 'admin2'].includes(val);
1323+
},
1324+
error: 'Unauthorized.',
1325+
},
1326+
},
1327+
}
1328+
);
1329+
const user = new Parse.User();
1330+
user.set('username', 'testuser');
1331+
user.set('password', 'p@ssword');
1332+
user.set('accType', 'admin');
1333+
await user.signUp();
1334+
expect(user.get('accType')).toBe('normal');
1335+
try {
1336+
await Parse.Cloud.run('secureFunction');
1337+
fail('function should only be available to admin users');
1338+
} catch (error) {
1339+
expect(error.code).toEqual(Parse.Error.VALIDATION_ERROR);
1340+
expect(error.message).toEqual('Unauthorized.');
1341+
}
1342+
});
12691343
});

src/triggers.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ export function maybeRunValidator(request, functionName) {
617617
});
618618
});
619619
}
620-
function builtInTriggerValidator(options, request) {
620+
async function builtInTriggerValidator(options, request) {
621621
if (request.master && !options.validateMasterKey) {
622622
return;
623623
}
@@ -647,11 +647,11 @@ function builtInTriggerValidator(options, request) {
647647
}
648648
};
649649

650-
const validateOptions = (opt, key, val) => {
650+
const validateOptions = async (opt, key, val) => {
651651
let opts = opt.options;
652652
if (typeof opts === 'function') {
653653
try {
654-
const result = opts(val);
654+
const result = await opts(val);
655655
if (!result && result != null) {
656656
throw opt.error || `Validation failed. Invalid value for ${key}.`;
657657
}
@@ -684,6 +684,7 @@ function builtInTriggerValidator(options, request) {
684684
requiredParam(key);
685685
}
686686
} else {
687+
const optionPromises = [];
687688
for (const key in options.fields) {
688689
const opt = options.fields[key];
689690
let val = params[key];
@@ -717,10 +718,11 @@ function builtInTriggerValidator(options, request) {
717718
}
718719
}
719720
if (opt.options) {
720-
validateOptions(opt, key, val);
721+
optionPromises.push(validateOptions(opt, key, val));
721722
}
722723
}
723724
}
725+
await Promise.all(optionPromises);
724726
}
725727
const userKeys = options.requireUserKeys || [];
726728
if (Array.isArray(userKeys)) {
@@ -734,12 +736,14 @@ function builtInTriggerValidator(options, request) {
734736
}
735737
}
736738
} else if (typeof userKeys === 'object') {
739+
const optionPromises = [];
737740
for (const key in options.requireUserKeys) {
738741
const opt = options.requireUserKeys[key];
739742
if (opt.options) {
740-
validateOptions(opt, key, reqUser.get(key));
743+
optionPromises.push(validateOptions(opt, key, reqUser.get(key)));
741744
}
742745
}
746+
await Promise.all(optionPromises);
743747
}
744748
}
745749

0 commit comments

Comments
 (0)