diff --git a/lib/helpers/validate-account.js b/lib/helpers/validate-account.js index 6d2e924d..ecac3ff8 100644 --- a/lib/helpers/validate-account.js +++ b/lib/helpers/validate-account.js @@ -22,12 +22,34 @@ var getRequiredRegistrationFields = require('./get-required-registration-fields' */ module.exports = function (formData, stormpathConfig, callback) { var accountFieldNames = Object.keys(formData); + var customFieldNames = formData.customData + ? Object.keys(formData.customData) + : []; var errors = []; + // Considers `0` and `false` valid values + function isSet(value) { + return value !== '' && value !== null && typeof value !== 'undefined'; + } + + function isFieldIncluded(field) { + // Is it included directly in the core object? + if (accountFieldNames.indexOf(field.name) >= 0 && isSet(formData[field.name])) { + return true; + } + + // Is it included in the custom data? + if (customFieldNames.indexOf(field.name) >= 0 && isSet(formData.customData[field.name])) { + return true; + } + + return false; + } + getRequiredRegistrationFields(stormpathConfig, function (requiredFields) { async.each(requiredFields, function (field, cb) { - if (accountFieldNames.indexOf(field.name) <= -1 || (accountFieldNames.indexOf(field.name) > -1 && !formData[field.name])) { - errors.push(new Error((field.label || field.label) + ' required.')); + if (!isFieldIncluded(field)) { + errors.push(new Error((field.label || field.name) + ' required.')); } cb(); diff --git a/test/helpers/test-validate-account.js b/test/helpers/test-validate-account.js index a3d9c02b..e17b37f4 100644 --- a/test/helpers/test-validate-account.js +++ b/test/helpers/test-validate-account.js @@ -29,6 +29,11 @@ describe('validateAccount', function () { confirmPassword: { enabled: true, required: true + }, + color: { + enabled: true, + required: true, + label: 'Color' } } } @@ -42,7 +47,26 @@ describe('validateAccount', function () { surname: 'Degges', email: 'randall@stormpath.com', password: 'FASRbaBjkrqJSNVlUrV2ZyUy5iUX8UEZ3TW3nejX', - confirmPassword: 'FASRbaBjkrqJSNVlUrV2ZyUy5iUX8UEZ3TW3nejX' + confirmPassword: 'FASRbaBjkrqJSNVlUrV2ZyUy5iUX8UEZ3TW3nejX', + customData: { + color: 'purple' + } + }; + + helpers.validateAccount(accountData, config, function (errors) { + assert.equal(errors, null); + done(); + }); + }); + + it('should support custom data properties on the root object', function (done) { + var accountData = { + givenName: 'Randall', + surname: 'Degges', + email: 'randall@stormpath.com', + password: 'FASRbaBjkrqJSNVlUrV2ZyUy5iUX8UEZ3TW3nejX', + confirmPassword: 'FASRbaBjkrqJSNVlUrV2ZyUy5iUX8UEZ3TW3nejX', + color: 'purple' }; helpers.validateAccount(accountData, config, function (errors) { @@ -57,7 +81,10 @@ describe('validateAccount', function () { surname: 'Degges', email: 'randall@stormpath.com', password: 'woot', - confirmPassword: 'woothi' + confirmPassword: 'woothi', + customData: { + color: 'purple' + } }; helpers.validateAccount(accountData, config, function (errors) { @@ -70,7 +97,10 @@ describe('validateAccount', function () { it('should return the right number of errors if errors are present', function (done) { var accountData = { givenName: 'Randall', - surname: 'Degges' + surname: 'Degges', + customData: { + color: 'purple' + } }; helpers.validateAccount(accountData, config, function (errors) { @@ -78,4 +108,20 @@ describe('validateAccount', function () { done(); }); }); + + it('should correctly validate required fields by also looking into custom data', function (done) { + var accountData = { + givenName: 'Randall', + surname: 'Degges', + email: 'randall@stormpath.com', + password: 'FASRbaBjkrqJSNVlUrV2ZyUy5iUX8UEZ3TW3nejX', + confirmPassword: 'FASRbaBjkrqJSNVlUrV2ZyUy5iUX8UEZ3TW3nejX' + }; + + helpers.validateAccount(accountData, config, function (errors) { + assert.equal(errors.length, 1); + assert.equal(errors[0].message, 'Color required.'); + done(); + }); + }); });