From 8326a6f1d7cda0ca8c6f1a3a7ea82448881e118e Mon Sep 17 00:00:00 2001 From: dblythy Date: Mon, 30 May 2022 04:26:59 +1000 Subject: [PATCH] fix: invalid name for `Parse.Role` throws incorrect error (#1481) --- integration/test/ParseACLTest.js | 9 +++++++++ src/ParseRole.js | 25 +++++++++++++++++-------- src/__tests__/ParseRole-test.js | 9 +++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/integration/test/ParseACLTest.js b/integration/test/ParseACLTest.js index 75b7d312d..4251f059c 100644 --- a/integration/test/ParseACLTest.js +++ b/integration/test/ParseACLTest.js @@ -533,4 +533,13 @@ describe('Parse.ACL', () => { const obj1withInclude = await query.first(); assert(obj1withInclude.get('other').get('ACL')); }); + + it('prevents save with invalid role name', async () => { + expect(() => new Parse.Role(':%#', new Parse.ACL())).toThrow( + new Parse.Error( + Parse.Error.OTHER_CAUSE, + `A role's name can be only contain alphanumeric characters, _, -, and spaces.` + ) + ); + }); }); diff --git a/src/ParseRole.js b/src/ParseRole.js index 07d4c8fa2..c50560496 100644 --- a/src/ParseRole.js +++ b/src/ParseRole.js @@ -75,6 +75,7 @@ class ParseRole extends ParseObject { * @returns {(ParseObject|boolean)} true if the set succeeded. */ setName(name: string, options?: mixed): ParseObject | boolean { + this._validateName(name); return this.set('name', name, options); } @@ -108,6 +109,18 @@ class ParseRole extends ParseObject { return this.relation('roles'); } + _validateName(newName) { + if (typeof newName !== 'string') { + throw new ParseError(ParseError.OTHER_CAUSE, "A role's name must be a String."); + } + if (!/^[0-9a-zA-Z\-_ ]+$/.test(newName)) { + throw new ParseError( + ParseError.OTHER_CAUSE, + "A role's name can be only contain alphanumeric characters, _, " + '-, and spaces.' + ); + } + } + validate(attrs: AttributeMap, options?: mixed): ParseError | boolean { const isInvalid = super.validate(attrs, options); if (isInvalid) { @@ -125,14 +138,10 @@ class ParseRole extends ParseObject { "A role's name can only be set before it has been saved." ); } - if (typeof newName !== 'string') { - return new ParseError(ParseError.OTHER_CAUSE, "A role's name must be a String."); - } - if (!/^[0-9a-zA-Z\-_ ]+$/.test(newName)) { - return new ParseError( - ParseError.OTHER_CAUSE, - "A role's name can be only contain alphanumeric characters, _, " + '-, and spaces.' - ); + try { + this._validateName(newName); + } catch (e) { + return e; } } return false; diff --git a/src/__tests__/ParseRole-test.js b/src/__tests__/ParseRole-test.js index e2e7fa0ff..825ec60a3 100644 --- a/src/__tests__/ParseRole-test.js +++ b/src/__tests__/ParseRole-test.js @@ -45,6 +45,15 @@ describe('ParseRole', () => { expect(role.getName()).toBe(''); }); + it('should throw error string with invalid name', () => { + expect(() => new ParseRole('invalid:name', new ParseACL())).toThrow( + new ParseError( + ParseError.OTHER_CAUSE, + "A role's name can be only contain alphanumeric characters, _, " + '-, and spaces.' + ) + ); + }); + it('can validate attributes', () => { const acl = new ParseACL({ aUserId: { read: true, write: true } }); const role = new ParseRole('admin', acl);