Page MenuHomePhorge

D5730.1774879958.diff
No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None

D5730.1774879958.diff

diff --git a/src/app/Http/Controllers/API/AuthController.php b/src/app/Http/Controllers/API/AuthController.php
--- a/src/app/Http/Controllers/API/AuthController.php
+++ b/src/app/Http/Controllers/API/AuthController.php
@@ -172,6 +172,8 @@
/**
* Refresh a session token.
+ *
+ * @unauthenticated
*/
public function refresh(Request $request)
{
@@ -186,8 +188,6 @@
return response()->json(['status' => 'error', 'errors' => $v->errors()], 422);
}
- $user = $request->info ? $this->guard()->user() : null;
-
$proxyRequest = Request::create('/oauth/token', 'POST', [
'grant_type' => 'refresh_token',
'refresh_token' => $request->refresh_token,
@@ -197,6 +197,20 @@
$tokenResponse = app()->handle($proxyRequest);
+ $user = null;
+
+ // Get user information (resolve user from the token)
+ // FIXME: This is a very hacky approach, but I couldn't find an easier way
+ if ($request->info && $tokenResponse->getStatusCode() == 200) {
+ $data = json_decode($tokenResponse->getContent());
+ $request->headers->set('Authorization', 'Bearer ' . $data->access_token);
+ $reflectionMethod = new \ReflectionMethod(\Laravel\Passport\Guards\TokenGuard::class, 'getPsrRequestViaBearerToken');
+ $psr = $reflectionMethod->invoke($this->guard(), $request);
+ if ($user_id = $psr->getAttribute('oauth_user_id')) {
+ $user = User::find($user_id);
+ }
+ }
+
return self::respondWithToken($tokenResponse, $user);
}
diff --git a/src/resources/js/app.js b/src/resources/js/app.js
--- a/src/resources/js/app.js
+++ b/src/resources/js/app.js
@@ -156,9 +156,11 @@
// while the token is being refreshed
this.refreshTimeout = setTimeout(() => {
- axios.post('api/auth/refresh', { refresh_token: localStorage.getItem('refreshToken') }).then(response => {
- this.loginUser(response.data, false, true)
- })
+ const refresh_token = localStorage.getItem('refreshToken')
+ axios.post('api/auth/refresh', { refresh_token }, { headers: { Authorization: null } })
+ .then(response => {
+ this.loginUser(response.data, false, true)
+ })
}, timeout * 1000)
},
// Set user state to "not logged in"
diff --git a/src/resources/vue/App.vue b/src/resources/vue/App.vue
--- a/src/resources/vue/App.vue
+++ b/src/resources/vue/App.vue
@@ -31,7 +31,7 @@
if (token) {
const post = { refresh_token: localStorage.getItem("refreshToken"), info: 1 }
- axios.post('/api/auth/refresh', post, { ignoreErrors: true, loader: true })
+ axios.post('/api/auth/refresh', post, { ignoreErrors: true, loader: true, headers: { Authorization: null } })
.then(response => {
this.$root.loginUser(response.data, false)
})
diff --git a/src/routes/api.php b/src/routes/api.php
--- a/src/routes/api.php
+++ b/src/routes/api.php
@@ -16,6 +16,7 @@
],
static function () {
Route::post('login', [API\AuthController::class, 'login']);
+ Route::post('refresh', [API\AuthController::class, 'refresh']);
Route::post('password-policy-check', [API\V4\PolicyController::class, 'checkPassword']);
Route::post('password-reset/init', [API\PasswordResetController::class, 'init']);
@@ -39,7 +40,6 @@
Route::get('info', [API\AuthController::class, 'info']);
Route::get('location', [API\AuthController::class, 'location']);
Route::post('logout', [API\AuthController::class, 'logout']);
- Route::post('refresh', [API\AuthController::class, 'refresh']);
}
);
}
diff --git a/src/tests/Feature/Controller/AuthTest.php b/src/tests/Feature/Controller/AuthTest.php
--- a/src/tests/Feature/Controller/AuthTest.php
+++ b/src/tests/Feature/Controller/AuthTest.php
@@ -157,10 +157,7 @@
$response->assertStatus(200);
$this->assertTrue(!empty($json['access_token']));
- $this->assertTrue(
- ($this->expectedExpiry - 5) < $json['expires_in']
- && $json['expires_in'] < ($this->expectedExpiry + 5)
- );
+ $this->assertEqualsWithDelta($this->expectedExpiry, $json['expires_in'], 5);
$this->assertSame('bearer', $json['token_type']);
$this->assertSame($user->id, $json['id']);
$this->assertSame($user->email, $json['user']['email']);
@@ -181,10 +178,7 @@
$response->assertStatus(200);
$this->assertTrue(!empty($json['access_token']));
- $this->assertTrue(
- ($this->expectedExpiry - 5) < $json['expires_in']
- && $json['expires_in'] < ($this->expectedExpiry + 5)
- );
+ $this->assertEqualsWithDelta($this->expectedExpiry, $json['expires_in'], 5);
$this->assertSame('bearer', $json['token_type']);
// No user info in the response
@@ -298,13 +292,14 @@
*/
public function testRefresh(): void
{
- // Request with no token, testing that it requires auth
- $response = $this->post("api/auth/refresh");
- $response->assertStatus(401);
+ // Test refresh token requirement
+ $response = $this->post("api/auth/refresh", []);
+ $response->assertStatus(422);
- // Test the same using JSON mode
- $response = $this->json('POST', "api/auth/refresh", []);
- $response->assertStatus(401);
+ $json = $response->json();
+
+ $this->assertSame('error', $json['status']);
+ $this->assertSame(['refresh_token' => ['The refresh token field is required.']], $json['errors']);
// Login the user to get a valid token
$post = ['email' => 'john@kolab.org', 'password' => 'simple123'];
@@ -317,25 +312,25 @@
// Request with a valid token (include user info in the response)
$post = ['refresh_token' => $json['refresh_token'], 'info' => 1];
- $response = $this->actingAs($user)->post("api/auth/refresh", $post);
+ $response = $this->post("api/auth/refresh", $post);
$response->assertStatus(200);
$json = $response->json();
- $this->assertSame('john@kolab.org', $json['user']['email']);
+ $this->assertSame($user->email, $json['user']['email']);
$this->assertTrue(is_array($json['user']['statusInfo']));
$this->assertTrue(is_array($json['user']['settings']));
$this->assertTrue($json['access_token'] != $token);
- $this->assertTrue(
- ($this->expectedExpiry - 5) < $json['expires_in']
- && $json['expires_in'] < ($this->expectedExpiry + 5)
- );
+ $this->assertEqualsWithDelta($this->expectedExpiry, $json['expires_in'], 5);
$this->assertSame('bearer', $json['token_type']);
$new_token = $json['access_token'];
+ $new_refresh_token = $json['refresh_token'];
- // TODO: Shall we invalidate the old token?
+ // The old token should not work anymore
+ $response = $this->withHeaders(['Authorization' => 'Bearer ' . $token])->get("api/auth/info");
+ $response->assertStatus(401);
- // And if the new token is working
+ // Check if the new token is working
$response = $this->withHeaders(['Authorization' => 'Bearer ' . $new_token])->get("api/auth/info");
$response->assertStatus(200);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Mar 30, 2:12 PM (2 d, 23 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18813078
Default Alt Text
D5730.1774879958.diff (7 KB)

Event Timeline