@@ -905,6 +905,50 @@ describe('Parse.User testing', () => {
905905 }
906906 } ;
907907 } ;
908+
909+ var getMockMyOauthProvider = function ( ) {
910+ return {
911+ authData : {
912+ id : "12345" ,
913+ access_token : "12345" ,
914+ expiration_date : new Date ( ) . toJSON ( ) ,
915+ } ,
916+ shouldError : false ,
917+ loggedOut : false ,
918+ synchronizedUserId : null ,
919+ synchronizedAuthToken : null ,
920+ synchronizedExpiration : null ,
921+
922+ authenticate : function ( options ) {
923+ if ( this . shouldError ) {
924+ options . error ( this , "An error occurred" ) ;
925+ } else if ( this . shouldCancel ) {
926+ options . error ( this , null ) ;
927+ } else {
928+ options . success ( this , this . authData ) ;
929+ }
930+ } ,
931+ restoreAuthentication : function ( authData ) {
932+ if ( ! authData ) {
933+ this . synchronizedUserId = null ;
934+ this . synchronizedAuthToken = null ;
935+ this . synchronizedExpiration = null ;
936+ return true ;
937+ }
938+ this . synchronizedUserId = authData . id ;
939+ this . synchronizedAuthToken = authData . access_token ;
940+ this . synchronizedExpiration = authData . expiration_date ;
941+ return true ;
942+ } ,
943+ getAuthType : function ( ) {
944+ return "myoauth" ;
945+ } ,
946+ deauthenticate : function ( ) {
947+ this . loggedOut = true ;
948+ this . restoreAuthentication ( null ) ;
949+ }
950+ } ;
951+ } ;
908952
909953 var ExtendedUser = Parse . User . extend ( {
910954 extended : function ( ) {
@@ -1285,6 +1329,151 @@ describe('Parse.User testing', () => {
12851329 }
12861330 } ) ;
12871331 } ) ;
1332+
1333+ it ( "link multiple providers" , ( done ) => {
1334+ var provider = getMockFacebookProvider ( ) ;
1335+ var mockProvider = getMockMyOauthProvider ( ) ;
1336+ Parse . User . _registerAuthenticationProvider ( provider ) ;
1337+ Parse . User . _logInWith ( "facebook" , {
1338+ success : function ( model ) {
1339+ ok ( model instanceof Parse . User , "Model should be a Parse.User" ) ;
1340+ strictEqual ( Parse . User . current ( ) , model ) ;
1341+ ok ( model . extended ( ) , "Should have used the subclass." ) ;
1342+ strictEqual ( provider . authData . id , provider . synchronizedUserId ) ;
1343+ strictEqual ( provider . authData . access_token , provider . synchronizedAuthToken ) ;
1344+ strictEqual ( provider . authData . expiration_date , provider . synchronizedExpiration ) ;
1345+ ok ( model . _isLinked ( "facebook" ) , "User should be linked to facebook" ) ;
1346+ Parse . User . _registerAuthenticationProvider ( mockProvider ) ;
1347+ let objectId = model . id ;
1348+ model . _linkWith ( "myoauth" , {
1349+ success : function ( model ) {
1350+ expect ( model . id ) . toEqual ( objectId ) ;
1351+ ok ( model . _isLinked ( "facebook" ) , "User should be linked to facebook" ) ;
1352+ ok ( model . _isLinked ( "myoauth" ) , "User should be linked to myoauth" ) ;
1353+ done ( ) ;
1354+ } ,
1355+ error : function ( error ) {
1356+ console . error ( error ) ;
1357+ fail ( 'SHould not fail' ) ;
1358+ done ( ) ;
1359+ }
1360+ } )
1361+ } ,
1362+ error : function ( model , error ) {
1363+ ok ( false , "linking should have worked" ) ;
1364+ done ( ) ;
1365+ }
1366+ } ) ;
1367+ } ) ;
1368+
1369+ it ( "link multiple providers and update token" , ( done ) => {
1370+ var provider = getMockFacebookProvider ( ) ;
1371+ var mockProvider = getMockMyOauthProvider ( ) ;
1372+ Parse . User . _registerAuthenticationProvider ( provider ) ;
1373+ Parse . User . _logInWith ( "facebook" , {
1374+ success : function ( model ) {
1375+ ok ( model instanceof Parse . User , "Model should be a Parse.User" ) ;
1376+ strictEqual ( Parse . User . current ( ) , model ) ;
1377+ ok ( model . extended ( ) , "Should have used the subclass." ) ;
1378+ strictEqual ( provider . authData . id , provider . synchronizedUserId ) ;
1379+ strictEqual ( provider . authData . access_token , provider . synchronizedAuthToken ) ;
1380+ strictEqual ( provider . authData . expiration_date , provider . synchronizedExpiration ) ;
1381+ ok ( model . _isLinked ( "facebook" ) , "User should be linked to facebook" ) ;
1382+ Parse . User . _registerAuthenticationProvider ( mockProvider ) ;
1383+ let objectId = model . id ;
1384+ model . _linkWith ( "myoauth" , {
1385+ success : function ( model ) {
1386+ expect ( model . id ) . toEqual ( objectId ) ;
1387+ ok ( model . _isLinked ( "facebook" ) , "User should be linked to facebook" ) ;
1388+ ok ( model . _isLinked ( "myoauth" ) , "User should be linked to myoauth" ) ;
1389+ model . _linkWith ( "facebook" , {
1390+ success : ( ) => {
1391+ ok ( model . _isLinked ( "facebook" ) , "User should be linked to facebook" ) ;
1392+ ok ( model . _isLinked ( "myoauth" ) , "User should be linked to myoauth" ) ;
1393+ done ( ) ;
1394+ } ,
1395+ error : ( ) => {
1396+ fail ( 'should link again' ) ;
1397+ done ( ) ;
1398+ }
1399+ } )
1400+ } ,
1401+ error : function ( error ) {
1402+ console . error ( error ) ;
1403+ fail ( 'SHould not fail' ) ;
1404+ done ( ) ;
1405+ }
1406+ } )
1407+ } ,
1408+ error : function ( model , error ) {
1409+ ok ( false , "linking should have worked" ) ;
1410+ done ( ) ;
1411+ }
1412+ } ) ;
1413+ } ) ;
1414+
1415+ it ( 'should fail linking with existing' , ( done ) => {
1416+ var provider = getMockFacebookProvider ( ) ;
1417+ Parse . User . _registerAuthenticationProvider ( provider ) ;
1418+ Parse . User . _logInWith ( "facebook" , {
1419+ success : function ( model ) {
1420+ Parse . User . logOut ( ) . then ( ( ) => {
1421+ let user = new Parse . User ( ) ;
1422+ user . setUsername ( 'user' ) ;
1423+ user . setPassword ( 'password' ) ;
1424+ return user . signUp ( ) . then ( ( ) => {
1425+ // try to link here
1426+ user . _linkWith ( 'facebook' , {
1427+ success : ( ) => {
1428+ fail ( 'should not succeed' ) ;
1429+ done ( ) ;
1430+ } ,
1431+ error : ( err ) => {
1432+ done ( ) ;
1433+ }
1434+ } ) ;
1435+ } ) ;
1436+ } ) ;
1437+ }
1438+ } ) ;
1439+ } ) ;
1440+
1441+ it ( 'should have authData in beforeSave and afterSave' , ( done ) => {
1442+
1443+ Parse . Cloud . beforeSave ( '_User' , ( request , response ) => {
1444+ let authData = request . object . get ( 'authData' ) ;
1445+ expect ( authData ) . not . toBeUndefined ( ) ;
1446+ if ( authData ) {
1447+ expect ( authData . facebook . id ) . toEqual ( '8675309' ) ;
1448+ expect ( authData . facebook . access_token ) . toEqual ( 'jenny' ) ;
1449+ } else {
1450+ fail ( 'authData should be set' ) ;
1451+ }
1452+ response . success ( ) ;
1453+ } ) ;
1454+
1455+ Parse . Cloud . afterSave ( '_User' , ( request , response ) => {
1456+ let authData = request . object . get ( 'authData' ) ;
1457+ expect ( authData ) . not . toBeUndefined ( ) ;
1458+ if ( authData ) {
1459+ expect ( authData . facebook . id ) . toEqual ( '8675309' ) ;
1460+ expect ( authData . facebook . access_token ) . toEqual ( 'jenny' ) ;
1461+ } else {
1462+ fail ( 'authData should be set' ) ;
1463+ }
1464+ response . success ( ) ;
1465+ } ) ;
1466+
1467+ var provider = getMockFacebookProvider ( ) ;
1468+ Parse . User . _registerAuthenticationProvider ( provider ) ;
1469+ Parse . User . _logInWith ( "facebook" , {
1470+ success : function ( model ) {
1471+ Parse . Cloud . _removeHook ( 'Triggers' , 'beforeSave' , Parse . User . className ) ;
1472+ Parse . Cloud . _removeHook ( 'Triggers' , 'afterSave' , Parse . User . className ) ;
1473+ done ( ) ;
1474+ }
1475+ } ) ;
1476+ } ) ;
12881477
12891478 it ( 'set password then change password' , ( done ) => {
12901479 Parse . User . signUp ( 'bob' , 'barker' ) . then ( ( bob ) => {
0 commit comments