@@ -5,8 +5,9 @@ const Parse = require('parse/node');
55// An Auth object tells you who is requesting something and whether
66// the master key was used.
77// userObject is a Parse.User and can be null if there's no user.
8- function Auth ( { config, isMaster = false , isReadOnly = false , user, installationId } = { } ) {
8+ function Auth ( { config, cacheController = undefined , isMaster = false , isReadOnly = false , user, installationId } ) {
99 this . config = config ;
10+ this . cacheController = cacheController || ( config && config . cacheController ) ;
1011 this . installationId = installationId ;
1112 this . isMaster = isMaster ;
1213 this . user = user ;
@@ -48,47 +49,58 @@ function nobody(config) {
4849
4950
5051// Returns a promise that resolves to an Auth object
51- var getAuthForSessionToken = function ( { config, sessionToken, installationId } = { } ) {
52- return config . cacheController . user . get ( sessionToken ) . then ( ( userJSON ) => {
52+ const getAuthForSessionToken = async function ( { config, cacheController, sessionToken, installationId } ) {
53+ cacheController = cacheController || ( config && config . cacheController ) ;
54+ if ( cacheController ) {
55+ const userJSON = await cacheController . user . get ( sessionToken ) ;
5356 if ( userJSON ) {
5457 const cachedUser = Parse . Object . fromJSON ( userJSON ) ;
55- return Promise . resolve ( new Auth ( { config, isMaster : false , installationId, user : cachedUser } ) ) ;
58+ return Promise . resolve ( new Auth ( { config, cacheController , isMaster : false , installationId, user : cachedUser } ) ) ;
5659 }
60+ }
5761
58- var restOptions = {
62+ let results ;
63+ if ( config ) {
64+ const restOptions = {
5965 limit : 1 ,
6066 include : 'user'
6167 } ;
6268
63- var query = new RestQuery ( config , master ( config ) , '_Session' , { sessionToken} , restOptions ) ;
64- return query . execute ( ) . then ( ( response ) => {
65- var results = response . results ;
66- if ( results . length !== 1 || ! results [ 0 ] [ 'user' ] ) {
67- throw new Parse . Error ( Parse . Error . INVALID_SESSION_TOKEN , 'Invalid session token' ) ;
68- }
69+ const query = new RestQuery ( config , master ( config ) , '_Session' , { sessionToken } , restOptions ) ;
70+ results = ( await query . execute ( ) ) . results ;
71+ } else {
72+ results = ( await new Parse . Query ( Parse . Session )
73+ . limit ( 1 )
74+ . include ( 'user' )
75+ . equalTo ( 'sessionToken' , sessionToken )
76+ . find ( { useMasterKey : true } ) ) . map ( ( obj ) => obj . toJSON ( ) )
77+ }
6978
70- var now = new Date ( ) ,
71- expiresAt = results [ 0 ] . expiresAt ? new Date ( results [ 0 ] . expiresAt . iso ) : undefined ;
72- if ( expiresAt < now ) {
73- throw new Parse . Error ( Parse . Error . INVALID_SESSION_TOKEN ,
74- 'Session token is expired.' ) ;
75- }
76- var obj = results [ 0 ] [ 'user' ] ;
77- delete obj . password ;
78- obj [ 'className' ] = '_User' ;
79- obj [ 'sessionToken' ] = sessionToken ;
80- config . cacheController . user . put ( sessionToken , obj ) ;
81- const userObject = Parse . Object . fromJSON ( obj ) ;
82- return new Auth ( { config, isMaster : false , installationId, user : userObject } ) ;
83- } ) ;
84- } ) ;
79+ if ( results . length !== 1 || ! results [ 0 ] [ 'user' ] ) {
80+ throw new Parse . Error ( Parse . Error . INVALID_SESSION_TOKEN , 'Invalid session token' ) ;
81+ }
82+ const now = new Date ( ) ,
83+ expiresAt = results [ 0 ] . expiresAt ? new Date ( results [ 0 ] . expiresAt . iso ) : undefined ;
84+ if ( expiresAt < now ) {
85+ throw new Parse . Error ( Parse . Error . INVALID_SESSION_TOKEN ,
86+ 'Session token is expired.' ) ;
87+ }
88+ const obj = results [ 0 ] [ 'user' ] ;
89+ delete obj . password ;
90+ obj [ 'className' ] = '_User' ;
91+ obj [ 'sessionToken' ] = sessionToken ;
92+ if ( cacheController ) {
93+ cacheController . user . put ( sessionToken , obj ) ;
94+ }
95+ const userObject = Parse . Object . fromJSON ( obj ) ;
96+ return new Auth ( { config, cacheController, isMaster : false , installationId, user : userObject } ) ;
8597} ;
8698
87- var getAuthForLegacySessionToken = function ( { config, sessionToken, installationId } = { } ) {
99+ var getAuthForLegacySessionToken = function ( { config, sessionToken, installationId } ) {
88100 var restOptions = {
89101 limit : 1
90102 } ;
91- var query = new RestQuery ( config , master ( config ) , '_User' , { sessionToken : sessionToken } , restOptions ) ;
103+ var query = new RestQuery ( config , master ( config ) , '_User' , { sessionToken } , restOptions ) ;
92104 return query . execute ( ) . then ( ( response ) => {
93105 var results = response . results ;
94106 if ( results . length !== 1 ) {
@@ -97,7 +109,7 @@ var getAuthForLegacySessionToken = function({config, sessionToken, installationI
97109 const obj = results [ 0 ] ;
98110 obj . className = '_User' ;
99111 const userObject = Parse . Object . fromJSON ( obj ) ;
100- return new Auth ( { config, isMaster : false , installationId, user : userObject } ) ;
112+ return new Auth ( { config, isMaster : false , installationId, user : userObject } ) ;
101113 } ) ;
102114}
103115
@@ -116,84 +128,113 @@ Auth.prototype.getUserRoles = function() {
116128 return this . rolePromise ;
117129} ;
118130
119- // Iterates through the role tree and compiles a users roles
120- Auth . prototype . _loadRoles = function ( ) {
121- var cacheAdapter = this . config . cacheController ;
122- return cacheAdapter . role . get ( this . user . id ) . then ( ( cachedRoles ) => {
123- if ( cachedRoles != null ) {
124- this . fetchedRoles = true ;
125- this . userRoles = cachedRoles ;
126- return Promise . resolve ( cachedRoles ) ;
127- }
128-
129- var restWhere = {
131+ Auth . prototype . getRolesForUser = function ( ) {
132+ if ( this . config ) {
133+ const restWhere = {
130134 'users' : {
131135 __type : 'Pointer' ,
132136 className : '_User' ,
133137 objectId : this . user . id
134138 }
135139 } ;
136- // First get the role ids this user is directly a member of
137- var query = new RestQuery ( this . config , master ( this . config ) , '_Role' , restWhere , { } ) ;
138- return query . execute ( ) . then ( ( response ) => {
139- var results = response . results ;
140- if ( ! results . length ) {
141- this . userRoles = [ ] ;
142- this . fetchedRoles = true ;
143- this . rolePromise = null ;
144-
145- cacheAdapter . role . put ( this . user . id , Array ( ...this . userRoles ) ) ;
146- return Promise . resolve ( this . userRoles ) ;
147- }
148- var rolesMap = results . reduce ( ( m , r ) => {
149- m . names . push ( r . name ) ;
150- m . ids . push ( r . objectId ) ;
151- return m ;
152- } , { ids : [ ] , names : [ ] } ) ;
153-
154- // run the recursive finding
155- return this . _getAllRolesNamesForRoleIds ( rolesMap . ids , rolesMap . names )
156- . then ( ( roleNames ) => {
157- this . userRoles = roleNames . map ( ( r ) => {
158- return 'role:' + r ;
159- } ) ;
160- this . fetchedRoles = true ;
161- this . rolePromise = null ;
162- cacheAdapter . role . put ( this . user . id , Array ( ...this . userRoles ) ) ;
163- return Promise . resolve ( this . userRoles ) ;
164- } ) ;
165- } ) ;
140+ const query = new RestQuery ( this . config , master ( this . config ) , '_Role' , restWhere , { } ) ;
141+ return query . execute ( ) . then ( ( { results } ) => results ) ;
142+ }
143+
144+ return new Parse . Query ( Parse . Role )
145+ . equalTo ( 'users' , this . user )
146+ . find ( { useMasterKey : true } )
147+ . then ( ( results ) => results . map ( ( obj ) => obj . toJSON ( ) ) ) ;
148+ }
149+
150+ // Iterates through the role tree and compiles a user's roles
151+ Auth . prototype . _loadRoles = async function ( ) {
152+ if ( this . cacheController ) {
153+ const cachedRoles = await this . cacheController . role . get ( this . user . id ) ;
154+ if ( cachedRoles != null ) {
155+ this . fetchedRoles = true ;
156+ this . userRoles = cachedRoles ;
157+ return cachedRoles ;
158+ }
159+ }
160+
161+ // First get the role ids this user is directly a member of
162+ const results = await this . getRolesForUser ( ) ;
163+ if ( ! results . length ) {
164+ this . userRoles = [ ] ;
165+ this . fetchedRoles = true ;
166+ this . rolePromise = null ;
167+
168+ this . cacheRoles ( ) ;
169+ return this . userRoles ;
170+ }
171+
172+ const rolesMap = results . reduce ( ( m , r ) => {
173+ m . names . push ( r . name ) ;
174+ m . ids . push ( r . objectId ) ;
175+ return m ;
176+ } , { ids : [ ] , names : [ ] } ) ;
177+
178+ // run the recursive finding
179+ const roleNames = await this . _getAllRolesNamesForRoleIds ( rolesMap . ids , rolesMap . names ) ;
180+ this . userRoles = roleNames . map ( ( r ) => {
181+ return 'role:' + r ;
166182 } ) ;
183+ this . fetchedRoles = true ;
184+ this . rolePromise = null ;
185+ this . cacheRoles ( ) ;
186+ return this . userRoles ;
167187} ;
168188
169- // Given a list of roleIds, find all the parent roles, returns a promise with all names
170- Auth . prototype . _getAllRolesNamesForRoleIds = function ( roleIDs , names = [ ] , queriedRoles = { } ) {
171- const ins = roleIDs . filter ( ( roleID ) => {
172- return queriedRoles [ roleID ] !== true ;
173- } ) . map ( ( roleID ) => {
174- // mark as queried
175- queriedRoles [ roleID ] = true ;
189+ Auth . prototype . cacheRoles = function ( ) {
190+ if ( ! this . cacheController ) {
191+ return false ;
192+ }
193+ this . cacheController . role . put ( this . user . id , Array ( ...this . userRoles ) ) ;
194+ return true ;
195+ }
196+
197+ Auth . prototype . getRolesByIds = function ( ins ) {
198+ const roles = ins . map ( ( id ) => {
176199 return {
177200 __type : 'Pointer' ,
178201 className : '_Role' ,
179- objectId : roleID
202+ objectId : id
180203 }
181204 } ) ;
205+ const restWhere = { 'roles' : { '$in' : roles } } ;
206+
207+ // Build an OR query across all parentRoles
208+ if ( ! this . config ) {
209+ return new Parse . Query ( Parse . Role )
210+ . containedIn ( 'roles' , ins . map ( ( id ) => {
211+ const role = new Parse . Object ( Parse . Role ) ;
212+ role . id = id ;
213+ return role ;
214+ } ) )
215+ . find ( { useMasterKey : true } )
216+ . then ( ( results ) => results . map ( ( obj ) => obj . toJSON ( ) ) ) ;
217+ }
218+
219+ return new RestQuery ( this . config , master ( this . config ) , '_Role' , restWhere , { } )
220+ . execute ( )
221+ . then ( ( { results } ) => results ) ;
222+ }
223+
224+ // Given a list of roleIds, find all the parent roles, returns a promise with all names
225+ Auth . prototype . _getAllRolesNamesForRoleIds = function ( roleIDs , names = [ ] , queriedRoles = { } ) {
226+ const ins = roleIDs . filter ( ( roleID ) => {
227+ const wasQueried = queriedRoles [ roleID ] !== true ;
228+ queriedRoles [ roleID ] = true ;
229+ return wasQueried ;
230+ } ) ;
182231
183232 // all roles are accounted for, return the names
184233 if ( ins . length == 0 ) {
185234 return Promise . resolve ( [ ...new Set ( names ) ] ) ;
186235 }
187- // Build an OR query across all parentRoles
188- let restWhere ;
189- if ( ins . length == 1 ) {
190- restWhere = { 'roles' : ins [ 0 ] } ;
191- } else {
192- restWhere = { 'roles' : { '$in' : ins } }
193- }
194- const query = new RestQuery ( this . config , master ( this . config ) , '_Role' , restWhere , { } ) ;
195- return query . execute ( ) . then ( ( response ) => {
196- var results = response . results ;
236+
237+ return this . getRolesByIds ( ins ) . then ( ( results ) => {
197238 // Nothing found
198239 if ( ! results . length ) {
199240 return Promise . resolve ( names ) ;
0 commit comments