Case insensitive signup (#5634)
* Always delete data after each, even for mongo. * Add failing simple case test * run all tests * 1. when validating username be case insensitive 2. add _auth_data_anonymous to specialQueryKeys...whatever that is! * More case sensitivity 1. also make email validation case insensitive 2. update comments to reflect what this change does * wordsmithery and grammar * first pass at a preformant case insensitive query. mongo only so far. * change name of parameter from insensitive to caseInsensitive * Postgres support * properly handle auth data null * wip * use 'caseInsensitive' instead of 'insensitive' in all places. * update commenet to reclect current plan * skip the mystery test for now * create case insensitive indecies for mongo to support case insensitive checks for email and username * remove unneeded specialKey * pull collation out to a function. * not sure what i planned to do with this test. removing. * remove typo * remove another unused flag * maintain order * maintain order of params * boil the ocean on param sequence i like having explain last cause it seems like something you would change/remove after getting what you want from the explain? * add test to verify creation and use of caseInsensitive index * add no op func to prostgress * get collation object from mongocollection make flow lint happy by declaring things Object. * fix typo * add changelog * kick travis * properly reference static method * add a test to confirm that anonymous users with unique username that do collide when compared insensitively can still be created. * minot doc nits * add a few tests to make sure our spy is working as expected wordsmith the changelog Co-authored-by: Diamond Lewis <findlewis@gmail.com>
This commit is contained in:
@@ -12,6 +12,7 @@ const MongoStorageAdapter = require('../lib/Adapters/Storage/Mongo/MongoStorageA
|
||||
const request = require('../lib/request');
|
||||
const passwordCrypto = require('../lib/password');
|
||||
const Config = require('../lib/Config');
|
||||
const cryptoUtils = require('../lib/cryptoUtils');
|
||||
|
||||
function verifyACL(user) {
|
||||
const ACL = user.getACL();
|
||||
@@ -2244,6 +2245,128 @@ describe('Parse.User testing', () => {
|
||||
);
|
||||
});
|
||||
|
||||
describe('case insensitive signup not allowed', () => {
|
||||
it('signup should fail with duplicate case insensitive username with basic setter', async () => {
|
||||
const user = new Parse.User();
|
||||
user.set('username', 'test1');
|
||||
user.set('password', 'test');
|
||||
await user.signUp();
|
||||
|
||||
const user2 = new Parse.User();
|
||||
user2.set('username', 'Test1');
|
||||
user2.set('password', 'test');
|
||||
await expectAsync(user2.signUp()).toBeRejectedWith(
|
||||
new Parse.Error(
|
||||
Parse.Error.USERNAME_TAKEN,
|
||||
'Account already exists for this username.'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('signup should fail with duplicate case insensitive username with field specific setter', async () => {
|
||||
const user = new Parse.User();
|
||||
user.setUsername('test1');
|
||||
user.setPassword('test');
|
||||
await user.signUp();
|
||||
|
||||
const user2 = new Parse.User();
|
||||
user2.setUsername('Test1');
|
||||
user2.setPassword('test');
|
||||
await expectAsync(user2.signUp()).toBeRejectedWith(
|
||||
new Parse.Error(
|
||||
Parse.Error.USERNAME_TAKEN,
|
||||
'Account already exists for this username.'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('signup should fail with duplicate case insensitive email', async () => {
|
||||
const user = new Parse.User();
|
||||
user.setUsername('test1');
|
||||
user.setPassword('test');
|
||||
user.setEmail('test@example.com');
|
||||
await user.signUp();
|
||||
|
||||
const user2 = new Parse.User();
|
||||
user2.setUsername('test2');
|
||||
user2.setPassword('test');
|
||||
user2.setEmail('Test@Example.Com');
|
||||
await expectAsync(user2.signUp()).toBeRejectedWith(
|
||||
new Parse.Error(
|
||||
Parse.Error.EMAIL_TAKEN,
|
||||
'Account already exists for this email address.'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it('edit should fail with duplicate case insensitive email', async () => {
|
||||
const user = new Parse.User();
|
||||
user.setUsername('test1');
|
||||
user.setPassword('test');
|
||||
user.setEmail('test@example.com');
|
||||
await user.signUp();
|
||||
|
||||
const user2 = new Parse.User();
|
||||
user2.setUsername('test2');
|
||||
user2.setPassword('test');
|
||||
user2.setEmail('Foo@Example.Com');
|
||||
await user2.signUp();
|
||||
|
||||
user2.setEmail('Test@Example.Com');
|
||||
await expectAsync(user2.save()).toBeRejectedWith(
|
||||
new Parse.Error(
|
||||
Parse.Error.EMAIL_TAKEN,
|
||||
'Account already exists for this email address.'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
describe('anonymous users', () => {
|
||||
beforeEach(() => {
|
||||
const insensitiveCollisions = [
|
||||
'abcdefghijklmnop',
|
||||
'Abcdefghijklmnop',
|
||||
'ABcdefghijklmnop',
|
||||
'ABCdefghijklmnop',
|
||||
'ABCDefghijklmnop',
|
||||
'ABCDEfghijklmnop',
|
||||
'ABCDEFghijklmnop',
|
||||
'ABCDEFGhijklmnop',
|
||||
'ABCDEFGHijklmnop',
|
||||
'ABCDEFGHIjklmnop',
|
||||
'ABCDEFGHIJklmnop',
|
||||
'ABCDEFGHIJKlmnop',
|
||||
'ABCDEFGHIJKLmnop',
|
||||
'ABCDEFGHIJKLMnop',
|
||||
'ABCDEFGHIJKLMnop',
|
||||
'ABCDEFGHIJKLMNop',
|
||||
'ABCDEFGHIJKLMNOp',
|
||||
'ABCDEFGHIJKLMNOP',
|
||||
];
|
||||
|
||||
// need a bunch of spare random strings per api request
|
||||
spyOn(cryptoUtils, 'randomString').and.returnValues(
|
||||
...insensitiveCollisions
|
||||
);
|
||||
});
|
||||
|
||||
it('should not fail on case insensitive matches', async () => {
|
||||
const user1 = await Parse.AnonymousUtils.logIn();
|
||||
const username1 = user1.get('username');
|
||||
|
||||
const user2 = await Parse.AnonymousUtils.logIn();
|
||||
const username2 = user2.get('username');
|
||||
|
||||
expect(username1).not.toBeUndefined();
|
||||
expect(username2).not.toBeUndefined();
|
||||
expect(username1.toLowerCase()).toBe('abcdefghijklmnop');
|
||||
expect(username2.toLowerCase()).toBe('abcdefghijklmnop');
|
||||
expect(username2).not.toBe(username1);
|
||||
expect(username2.toLowerCase()).toBe(username1.toLowerCase()); // this is redundant :).
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('user cannot update email to existing user', done => {
|
||||
const user = new Parse.User();
|
||||
user.set('username', 'test1');
|
||||
|
||||
Reference in New Issue
Block a user