@@ -212,10 +212,21 @@ describe('verifyAndRotateRefreshToken', () => {
212212 } ) ;
213213 } ) ;
214214
215- test ( 'returns invalid_grant and revokes all tokens when refresh token is not found (theft detection)' , async ( ) => {
215+ test ( 'returns invalid_grant immediately if token does not have the correct prefix' , async ( ) => {
216+ const result = await verifyAndRotateRefreshToken ( {
217+ rawRefreshToken : 'invalid_prefix_token' ,
218+ clientId : 'test-client-id' ,
219+ resource : null ,
220+ } ) ;
221+
222+ expect ( result ) . toMatchObject ( { error : 'invalid_grant' } ) ;
223+ expect ( prisma . oAuthRefreshToken . findUnique ) . not . toHaveBeenCalled ( ) ;
224+ expect ( prisma . oAuthToken . deleteMany ) . not . toHaveBeenCalled ( ) ;
225+ expect ( prisma . oAuthRefreshToken . deleteMany ) . not . toHaveBeenCalled ( ) ;
226+ } ) ;
227+
228+ test ( 'returns invalid_grant when refresh token is not found without revoking other tokens' , async ( ) => {
216229 prisma . oAuthRefreshToken . findUnique . mockResolvedValue ( null ) ;
217- prisma . oAuthToken . deleteMany . mockResolvedValue ( { count : 1 } ) ;
218- prisma . oAuthRefreshToken . deleteMany . mockResolvedValue ( { count : 1 } ) ;
219230
220231 const result = await verifyAndRotateRefreshToken ( {
221232 rawRefreshToken : 'sbor_used' ,
@@ -224,8 +235,8 @@ describe('verifyAndRotateRefreshToken', () => {
224235 } ) ;
225236
226237 expect ( result ) . toMatchObject ( { error : 'invalid_grant' } ) ;
227- expect ( prisma . oAuthToken . deleteMany ) . toHaveBeenCalledWith ( { where : { clientId : 'test-client-id' } } ) ;
228- expect ( prisma . oAuthRefreshToken . deleteMany ) . toHaveBeenCalledWith ( { where : { clientId : 'test-client-id' } } ) ;
238+ expect ( prisma . oAuthToken . deleteMany ) . not . toHaveBeenCalled ( ) ;
239+ expect ( prisma . oAuthRefreshToken . deleteMany ) . not . toHaveBeenCalled ( ) ;
229240 } ) ;
230241
231242 test ( 'returns invalid_grant if client_id does not match' , async ( ) => {
0 commit comments