@@ -420,11 +420,21 @@ class ParseLiveQueryServer {
420420 . then ( auth => {
421421 return { auth, userId : auth && auth . user && auth . user . id } ;
422422 } )
423- . catch ( ( ) => {
424- // If you can't continue, let's just wrap it up and delete it.
425- // Next time, one will try again
426- this . authCache . del ( sessionToken ) ;
427- return { } ;
423+ . catch ( error => {
424+ // There was an error with the session token
425+ const result = { } ;
426+ if ( error && error . code === Parse . Error . INVALID_SESSION_TOKEN ) {
427+ // Store a resolved promise with the error for 10 minutes
428+ result . error = error ;
429+ this . authCache . set (
430+ sessionToken ,
431+ Promise . resolve ( result ) ,
432+ 60 * 10 * 1000
433+ ) ;
434+ } else {
435+ this . authCache . del ( sessionToken ) ;
436+ }
437+ return result ;
428438 } ) ;
429439 this . authCache . set ( sessionToken , authPromise ) ;
430440 return authPromise ;
@@ -482,25 +492,19 @@ class ParseLiveQueryServer {
482492 : 'find' ;
483493 }
484494
485- async _matchesACL (
486- acl: any ,
487- client : any ,
488- requestId : number
489- ) : Promise < boolean > {
490- // Return true directly if ACL isn't present, ACL is public read, or client has master key
491- if ( ! acl || acl . getPublicReadAccess ( ) || client . hasMasterKey ) {
492- return true ;
493- }
494- // Check subscription sessionToken matches ACL first
495- const subscriptionInfo = client . getSubscriptionInfo ( requestId ) ;
496- if ( typeof subscriptionInfo === 'undefined' ) {
495+ async _verifyACL ( acl : any , token : string ) {
496+ if ( ! token ) {
497497 return false ;
498498 }
499499
500- // TODO: get auth there and de-duplicate code below to work with the same Auth obj.
501- const { auth , userId } = await this . getAuthForSessionToken (
502- subscriptionInfo . sessionToken
503- ) ;
500+ const { auth, userId } = await this . getAuthForSessionToken ( token ) ;
501+
502+ // Getting the session token failed
503+ // This means that no additional auth is available
504+ // At this point, just bail out as no additional visibility can be inferred.
505+ if ( ! auth || ! userId ) {
506+ return false ;
507+ }
504508 const isSubscriptionSessionTokenMatched = acl . getReadAccess ( userId ) ;
505509 if ( isSubscriptionSessionTokenMatched ) {
506510 return true ;
@@ -527,27 +531,40 @@ class ParseLiveQueryServer {
527531 }
528532 return false ;
529533 } )
530- . then ( async isRoleMatched => {
531- if ( isRoleMatched ) {
532- return Promise . resolve ( true ) ;
533- }
534-
535- // Check client sessionToken matches ACL
536- const clientSessionToken = client . sessionToken ;
537- if ( clientSessionToken ) {
538- const { userId } = await this . getAuthForSessionToken (
539- clientSessionToken
540- ) ;
541- return acl . getReadAccess ( userId ) ;
542- } else {
543- return isRoleMatched ;
544- }
545- } )
546534 . catch ( ( ) => {
547535 return false ;
548536 } ) ;
549537 }
550538
539+ async _matchesACL (
540+ acl: any ,
541+ client : any ,
542+ requestId : number
543+ ) : Promise < boolean > {
544+ // Return true directly if ACL isn't present, ACL is public read, or client has master key
545+ if ( ! acl || acl . getPublicReadAccess ( ) || client . hasMasterKey ) {
546+ return true ;
547+ }
548+ // Check subscription sessionToken matches ACL first
549+ const subscriptionInfo = client . getSubscriptionInfo ( requestId ) ;
550+ if ( typeof subscriptionInfo === 'undefined' ) {
551+ return false ;
552+ }
553+
554+ const subscriptionToken = subscriptionInfo . sessionToken ;
555+ const clientSessionToken = client . sessionToken ;
556+
557+ if ( await this . _verifyACL ( acl , subscriptionToken ) ) {
558+ return true ;
559+ }
560+
561+ if ( await this . _verifyACL ( acl , clientSessionToken ) ) {
562+ return true ;
563+ }
564+
565+ return false ;
566+ }
567+
551568 _handleConnect ( parseWebsocket : any , request : any ) : any {
552569 if ( ! this . _validateKeys ( request , this . keyPairs ) ) {
553570 Client . pushError ( parseWebsocket , 4 , 'Key in request is not valid' ) ;
0 commit comments