Skip to content

Commit 985577c

Browse files
[10.x] Add purging of invalid refresh tokens to command (#1396)
* Delete invalid refresh tokens Delete refresh tokens referring to non-existing access tokens. * Use whereDoesntHave() instead * Add test for purge command * Update description and output of command * Update PurgeCommand.php Co-authored-by: Taylor Otwell <taylor@laravel.com>
1 parent c2b93a7 commit 985577c

File tree

2 files changed

+52
-4
lines changed

2 files changed

+52
-4
lines changed

src/Console/PurgeCommand.php

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class PurgeCommand extends Command
2222
*
2323
* @var string
2424
*/
25-
protected $description = 'Purge revoked and / or expired tokens and authentication codes';
25+
protected $description = 'Purge revoked and / or expired tokens, authentication codes, and refresh tokens.';
2626

2727
/**
2828
* Execute the console command.
@@ -36,20 +36,23 @@ public function handle()
3636
Passport::token()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
3737
Passport::authCode()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
3838
Passport::refreshToken()->where('revoked', 1)->orWhereDate('expires_at', '<', $expired)->delete();
39+
Passport::refreshToken()->whereDoesntHave('accessToken')->delete();
3940

40-
$this->info('Purged revoked items and items expired for more than seven days.');
41+
$this->info('Purged invalid refresh tokens, revoked tokens, and tokens expired for more than seven days.');
4142
} elseif ($this->option('revoked')) {
4243
Passport::token()->where('revoked', 1)->delete();
4344
Passport::authCode()->where('revoked', 1)->delete();
4445
Passport::refreshToken()->where('revoked', 1)->delete();
46+
Passport::refreshToken()->whereDoesntHave('accessToken')->delete();
4547

46-
$this->info('Purged revoked items.');
48+
$this->info('Purged invalid refresh tokens and revoked tokens.');
4749
} elseif ($this->option('expired')) {
4850
Passport::token()->whereDate('expires_at', '<', $expired)->delete();
4951
Passport::authCode()->whereDate('expires_at', '<', $expired)->delete();
5052
Passport::refreshToken()->whereDate('expires_at', '<', $expired)->delete();
53+
Passport::refreshToken()->whereDoesntHave('accessToken')->delete();
5154

52-
$this->info('Purged items expired for more than seven days.');
55+
$this->info('Purged invalid refresh tokens and tokens expired for more than seven days.');
5356
}
5457
}
5558
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Laravel\Passport\Tests\Feature\Console;
4+
5+
use Laravel\Passport\AuthCode;
6+
use Laravel\Passport\RefreshToken;
7+
use Laravel\Passport\Tests\Feature\PassportTestCase;
8+
use Laravel\Passport\Token;
9+
10+
class PurgeCommand extends PassportTestCase
11+
{
12+
public function test_purge()
13+
{
14+
$expired = now()->subDays(8);
15+
$notExpired = now();
16+
17+
$accessTokenExpired = Token::create(['id' => 'a', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $expired]);
18+
$accessTokenRevoked = Token::create(['id' => 'b', 'user_id' => 1, 'client_id' => 1, 'revoked' => 1, 'expires_at' => $notExpired]);
19+
$accessTokenOk = Token::create(['id' => 'c', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $notExpired]);
20+
21+
$authCodeExpired = AuthCode::create(['id' => 'a', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $expired]);
22+
$authCodeRevoked = AuthCode::create(['id' => 'b', 'user_id' => 1, 'client_id' => 1, 'revoked' => 1, 'expires_at' => $notExpired]);
23+
$authCodeOk = AuthCode::create(['id' => 'c', 'user_id' => 1, 'client_id' => 1, 'revoked' => 0, 'expires_at' => $notExpired]);
24+
25+
$refreshTokenExpired = RefreshToken::create(['id' => 'a', 'access_token_id' => $accessTokenExpired->id, 'revoked' => 0, 'expires_at' => $expired]);
26+
$refreshTokenRevoked = RefreshToken::create(['id' => 'b', 'access_token_id' => $accessTokenRevoked->id, 'revoked' => 1, 'expires_at' => $notExpired]);
27+
$refreshTokenInvalidAccessToken = RefreshToken::create(['id' => 'c', 'access_token_id' => 'xyz', 'revoked' => 0, 'expires_at' => $notExpired]);
28+
$refreshTokenOk = RefreshToken::create(['id' => 'd', 'access_token_id' => $accessTokenOk->id, 'revoked' => 0, 'expires_at' => $notExpired]);
29+
30+
$this->artisan('passport:purge');
31+
32+
$this->assertFalse(Token::whereKey($accessTokenExpired->id)->exists());
33+
$this->assertFalse(Token::whereKey($accessTokenRevoked->id)->exists());
34+
$this->assertTrue(Token::whereKey($accessTokenOk->id)->exists());
35+
36+
$this->assertFalse(AuthCode::whereKey($authCodeExpired->id)->exists());
37+
$this->assertFalse(AuthCode::whereKey($authCodeRevoked->id)->exists());
38+
$this->assertTrue(AuthCode::whereKey($authCodeOk->id)->exists());
39+
40+
$this->assertFalse(RefreshToken::whereKey($refreshTokenExpired->id)->exists());
41+
$this->assertFalse(RefreshToken::whereKey($refreshTokenRevoked->id)->exists());
42+
$this->assertFalse(RefreshToken::whereKey($refreshTokenInvalidAccessToken->id)->exists());
43+
$this->assertTrue(RefreshToken::whereKey($refreshTokenOk->id)->exists());
44+
}
45+
}

0 commit comments

Comments
 (0)