@@ -130,7 +130,7 @@ func (s *Service) RefreshTokenGrant(ctx context.Context, db *storage.Connection,
130130 for retry && time .Since (retryStart ).Seconds () < retryLoopDuration {
131131 retry = false
132132
133- user , token , session , err := models .FindUserWithRefreshToken (db , params .RefreshToken , false )
133+ user , anyToken , session , err := models .FindUserWithRefreshToken (db , params .RefreshToken , false )
134134 if err != nil {
135135 if models .IsNotFoundError (err ) {
136136 return nil , apierrors .NewBadRequestError (apierrors .ErrorCodeRefreshTokenNotFound , "Invalid Refresh Token: Refresh Token Not Found" )
@@ -143,9 +143,11 @@ func (s *Service) RefreshTokenGrant(ctx context.Context, db *storage.Connection,
143143 }
144144
145145 if session == nil {
146- // a refresh token won't have a session if it's created prior to the sessions table introduced
147- if err := db .Destroy (token ); err != nil {
148- return nil , apierrors .NewInternalServerError ("Error deleting refresh token with missing session" ).WithInternalError (err )
146+ if token , ok := anyToken .(* models.RefreshToken ); ok {
147+ // a refresh token won't have a session if it's created prior to the sessions table introduced
148+ if err := db .Destroy (token ); err != nil {
149+ return nil , apierrors .NewInternalServerError ("Error deleting refresh token with missing session" ).WithInternalError (err )
150+ }
149151 }
150152 return nil , apierrors .NewBadRequestError (apierrors .ErrorCodeSessionNotFound , "Invalid Refresh Token: No Valid Session Found" )
151153 }
@@ -281,53 +283,55 @@ func (s *Service) RefreshTokenGrant(ctx context.Context, db *storage.Connection,
281283
282284 var issuedToken * models.RefreshToken
283285
284- if token .Revoked {
285- activeRefreshToken , terr := session .FindCurrentlyActiveRefreshToken (tx )
286- if terr != nil && ! models .IsNotFoundError (terr ) {
287- return apierrors .NewInternalServerError (terr .Error ())
288- }
286+ if token , ok := anyToken .(* models.RefreshToken ); ok {
287+ if token .Revoked {
288+ activeRefreshToken , terr := session .FindCurrentlyActiveRefreshToken (tx )
289+ if terr != nil && ! models .IsNotFoundError (terr ) {
290+ return apierrors .NewInternalServerError (terr .Error ())
291+ }
289292
290- if activeRefreshToken != nil && activeRefreshToken .Parent .String () == token .Token {
291- // Token was revoked, but it's the
292- // parent of the currently active one.
293- // This indicates that the client was
294- // not able to store the result when it
295- // refreshed token. This case is
296- // allowed, provided we return back the
297- // active refresh token instead of
298- // creating a new one.
299- issuedToken = activeRefreshToken
300- } else {
301- // For a revoked refresh token to be reused, it
302- // has to fall within the reuse interval.
303- reuseUntil := token .UpdatedAt .Add (
304- time .Second * time .Duration (config .Security .RefreshTokenReuseInterval ))
305-
306- if s .now ().After (reuseUntil ) {
307- // not OK to reuse this token
308- if config .Security .RefreshTokenRotationEnabled {
309- // Revoke all tokens in token family
310- if err := models .RevokeTokenFamily (tx , token ); err != nil {
311- return apierrors .NewInternalServerError (err .Error ())
293+ if activeRefreshToken != nil && activeRefreshToken .Parent .String () == token .Token {
294+ // Token was revoked, but it's the
295+ // parent of the currently active one.
296+ // This indicates that the client was
297+ // not able to store the result when it
298+ // refreshed token. This case is
299+ // allowed, provided we return back the
300+ // active refresh token instead of
301+ // creating a new one.
302+ issuedToken = activeRefreshToken
303+ } else {
304+ // For a revoked refresh token to be reused, it
305+ // has to fall within the reuse interval.
306+ reuseUntil := token .UpdatedAt .Add (
307+ time .Second * time .Duration (config .Security .RefreshTokenReuseInterval ))
308+
309+ if s .now ().After (reuseUntil ) {
310+ // not OK to reuse this token
311+ if config .Security .RefreshTokenRotationEnabled {
312+ // Revoke all tokens in token family
313+ if err := models .RevokeTokenFamily (tx , token ); err != nil {
314+ return apierrors .NewInternalServerError (err .Error ())
315+ }
312316 }
313- }
314317
315- return storage .NewCommitWithError (apierrors .NewBadRequestError (apierrors .ErrorCodeRefreshTokenAlreadyUsed , "Invalid Refresh Token: Already Used" ).WithInternalMessage ("Possible abuse attempt: %v" , token .ID ))
318+ return storage .NewCommitWithError (apierrors .NewBadRequestError (apierrors .ErrorCodeRefreshTokenAlreadyUsed , "Invalid Refresh Token: Already Used" ).WithInternalMessage ("Possible abuse attempt: %v" , token .ID ))
319+ }
316320 }
317321 }
318- }
319-
320- if terr := models .NewAuditLogEntry (config .AuditLog , r , tx , user , models .TokenRefreshedAction , "" , nil ); terr != nil {
321- return terr
322- }
323322
324- if issuedToken == nil {
325- newToken , terr := models .GrantRefreshTokenSwap (config .AuditLog , r , tx , user , token )
326- if terr != nil {
323+ if terr := models .NewAuditLogEntry (config .AuditLog , r , tx , user , models .TokenRefreshedAction , "" , nil ); terr != nil {
327324 return terr
328325 }
329326
330- issuedToken = newToken
327+ if issuedToken == nil {
328+ newToken , terr := models .GrantRefreshTokenSwap (config .AuditLog , r , tx , user , token )
329+ if terr != nil {
330+ return terr
331+ }
332+
333+ issuedToken = newToken
334+ }
331335 }
332336
333337 tokenString , expiresAt , terr = s .GenerateAccessToken (r , tx , GenerateAccessTokenParams {
0 commit comments