Throw error when setting authData to null (#6154)
* added ignore authData field * add fix for Postgres * add test for mongoDB * add test login with provider despite invalid authData * removed fit * fixed ignoring authData in postgres * Fix postgres test * Throw error instead of ignore * improve tests * Add mongo test * allow authData when not user class * fix tests * more tests * add condition to synthesize authData field only in _User class it is forbidden to add a custom field name beginning with `_`, so if the object is not `_User` , the transform should throw * add warning log when ignoring invalid `authData` in `_User` * add test to throw when custom field begins with underscore
This commit is contained in:
committed by
Diamond Lewis
parent
1c8d4a6519
commit
9d781c481f
@@ -479,6 +479,46 @@ describe('parseObjectToMongoObjectForCreate', () => {
|
|||||||
}).toThrow();
|
}).toThrow();
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('ignores User authData field in DB so it can be synthesized in code', done => {
|
||||||
|
const input = {
|
||||||
|
_id: '123',
|
||||||
|
_auth_data_acme: { id: 'abc' },
|
||||||
|
authData: null,
|
||||||
|
};
|
||||||
|
const output = transform.mongoObjectToParseObject('_User', input, {
|
||||||
|
fields: {},
|
||||||
|
});
|
||||||
|
expect(output.authData.acme.id).toBe('abc');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can set authData when not User class', done => {
|
||||||
|
const input = {
|
||||||
|
_id: '123',
|
||||||
|
authData: 'random',
|
||||||
|
};
|
||||||
|
const output = transform.mongoObjectToParseObject('TestObject', input, {
|
||||||
|
fields: {},
|
||||||
|
});
|
||||||
|
expect(output.authData).toBe('random');
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('cannot have a custom field name beginning with underscore', done => {
|
||||||
|
const input = {
|
||||||
|
_id: '123',
|
||||||
|
_thisFieldNameIs: 'invalid',
|
||||||
|
};
|
||||||
|
try {
|
||||||
|
transform.mongoObjectToParseObject('TestObject', input, {
|
||||||
|
fields: {},
|
||||||
|
});
|
||||||
|
} catch (e) {
|
||||||
|
expect(e).toBeDefined();
|
||||||
|
}
|
||||||
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('transformUpdate', () => {
|
describe('transformUpdate', () => {
|
||||||
|
|||||||
@@ -276,6 +276,16 @@ describe('Parse.Object testing', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can set authData when not user class', async () => {
|
||||||
|
const obj = new Parse.Object('TestObject');
|
||||||
|
obj.set('authData', 'random');
|
||||||
|
await obj.save();
|
||||||
|
expect(obj.get('authData')).toBe('random');
|
||||||
|
const query = new Parse.Query('TestObject');
|
||||||
|
const object = await query.get(obj.id, { useMasterKey: true });
|
||||||
|
expect(object.get('authData')).toBe('random');
|
||||||
|
});
|
||||||
|
|
||||||
it('invalid class name', function(done) {
|
it('invalid class name', function(done) {
|
||||||
const item = new Parse.Object('Foo^bar');
|
const item = new Parse.Object('Foo^bar');
|
||||||
item.save().then(
|
item.save().then(
|
||||||
|
|||||||
@@ -1246,6 +1246,32 @@ describe('Parse.User testing', () => {
|
|||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can not set authdata to null', async () => {
|
||||||
|
try {
|
||||||
|
const provider = getMockFacebookProvider();
|
||||||
|
Parse.User._registerAuthenticationProvider(provider);
|
||||||
|
const user = await Parse.User._logInWith('facebook');
|
||||||
|
user.set('authData', null);
|
||||||
|
await user.save();
|
||||||
|
fail();
|
||||||
|
} catch (e) {
|
||||||
|
expect(e.message).toBe('This authentication method is unsupported.');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('ignore setting authdata to undefined', async () => {
|
||||||
|
const provider = getMockFacebookProvider();
|
||||||
|
Parse.User._registerAuthenticationProvider(provider);
|
||||||
|
const user = await Parse.User._logInWith('facebook');
|
||||||
|
user.set('authData', undefined);
|
||||||
|
await user.save();
|
||||||
|
let authData = user.get('authData');
|
||||||
|
expect(authData).toBe(undefined);
|
||||||
|
await user.fetch();
|
||||||
|
authData = user.get('authData');
|
||||||
|
expect(authData.facebook.id).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
it('user authData should be available in cloudcode (#2342)', async done => {
|
it('user authData should be available in cloudcode (#2342)', async done => {
|
||||||
Parse.Cloud.define('checkLogin', req => {
|
Parse.Cloud.define('checkLogin', req => {
|
||||||
expect(req.user).not.toBeUndefined();
|
expect(req.user).not.toBeUndefined();
|
||||||
@@ -3924,4 +3950,29 @@ describe('Security Advisory GHSA-8w3j-g983-8jh5', function() {
|
|||||||
done();
|
done();
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
it_only_db('mongo')('should ignore authData field', async () => {
|
||||||
|
// Add User to Database with authData
|
||||||
|
const database = Config.get(Parse.applicationId).database;
|
||||||
|
const collection = await database.adapter._adaptiveCollection('_User');
|
||||||
|
await collection.insertOne({
|
||||||
|
_id: '1234ABCDEF',
|
||||||
|
name: '<some_name>',
|
||||||
|
email: '<some_email>',
|
||||||
|
username: '<some_username>',
|
||||||
|
_hashed_password: '<some_password>',
|
||||||
|
_auth_data_custom: {
|
||||||
|
id: 'linkedID',
|
||||||
|
},
|
||||||
|
sessionToken: '<some_session_token>',
|
||||||
|
authData: null, // should ignore
|
||||||
|
});
|
||||||
|
const provider = {
|
||||||
|
getAuthType: () => 'custom',
|
||||||
|
restoreAuthentication: () => true,
|
||||||
|
};
|
||||||
|
Parse.User._registerAuthenticationProvider(provider);
|
||||||
|
const query = new Parse.Query(Parse.User);
|
||||||
|
const user = await query.get('1234ABCDEF', { useMasterKey: true });
|
||||||
|
expect(user.get('authData')).toEqual({ custom: { id: 'linkedID' } });
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1403,10 +1403,19 @@ const mongoObjectToParseObject = (className, mongoObject, schema) => {
|
|||||||
case 'times_used':
|
case 'times_used':
|
||||||
restObject['timesUsed'] = mongoObject[key];
|
restObject['timesUsed'] = mongoObject[key];
|
||||||
break;
|
break;
|
||||||
|
case 'authData':
|
||||||
|
if (className === '_User') {
|
||||||
|
log.warn(
|
||||||
|
'ignoring authData in _User as this key is reserved to be synthesized of `_auth_data_*` keys'
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
restObject['authData'] = mongoObject[key];
|
||||||
|
}
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
// Check other auth data keys
|
// Check other auth data keys
|
||||||
var authDataMatch = key.match(/^_auth_data_([a-zA-Z0-9_]+)$/);
|
var authDataMatch = key.match(/^_auth_data_([a-zA-Z0-9_]+)$/);
|
||||||
if (authDataMatch) {
|
if (authDataMatch && className === '_User') {
|
||||||
var provider = authDataMatch[1];
|
var provider = authDataMatch[1];
|
||||||
restObject['authData'] = restObject['authData'] || {};
|
restObject['authData'] = restObject['authData'] || {};
|
||||||
restObject['authData'][provider] = mongoObject[key];
|
restObject['authData'][provider] = mongoObject[key];
|
||||||
|
|||||||
@@ -417,8 +417,21 @@ RestWrite.prototype.validateAuthData = function() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.data.authData || !Object.keys(this.data.authData).length) {
|
if (
|
||||||
|
(this.data.authData && !Object.keys(this.data.authData).length) ||
|
||||||
|
!Object.prototype.hasOwnProperty.call(this.data, 'authData')
|
||||||
|
) {
|
||||||
|
// Handle saving authData to {} or if authData doesn't exist
|
||||||
return;
|
return;
|
||||||
|
} else if (
|
||||||
|
Object.prototype.hasOwnProperty.call(this.data, 'authData') &&
|
||||||
|
!this.data.authData
|
||||||
|
) {
|
||||||
|
// Handle saving authData to null
|
||||||
|
throw new Parse.Error(
|
||||||
|
Parse.Error.UNSUPPORTED_SERVICE,
|
||||||
|
'This authentication method is unsupported.'
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
var authData = this.data.authData;
|
var authData = this.data.authData;
|
||||||
|
|||||||
Reference in New Issue
Block a user