Page MenuHomePhorge

D1459.1775175972.diff
No OneTemporary

Authored By
Unknown
Size
21 KB
Referenced Files
None
Subscribers
None

D1459.1775175972.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
@@ -20,6 +20,11 @@
$user = Auth::guard()->user();
$response = V4\UsersController::userResponse($user);
+ if (!empty(request()->input('refresh_token'))) {
+ // @phpstan-ignore-next-line
+ return $this->respondWithToken(Auth::guard()->refresh(), $response);
+ }
+
return response()->json($response);
}
@@ -34,13 +39,7 @@
// @phpstan-ignore-next-line
$token = Auth::guard()->login($user);
- return response()->json([
- 'status' => 'success',
- 'access_token' => $token,
- 'token_type' => 'bearer',
- // @phpstan-ignore-next-line
- 'expires_in' => Auth::guard()->factory()->getTTL() * 60,
- ]);
+ return self::respondWithToken($token, ['status' => 'success']);
}
/**
@@ -109,19 +108,18 @@
/**
* Get the token array structure.
*
- * @param string $token Respond with this token.
+ * @param string $token Respond with this token.
+ * @param array $response Additional response data
*
* @return \Illuminate\Http\JsonResponse
*/
- protected function respondWithToken($token)
+ protected static function respondWithToken($token, array $response = [])
{
- return response()->json(
- [
- 'access_token' => $token,
- 'token_type' => 'bearer',
- // @phpstan-ignore-next-line
- 'expires_in' => Auth::guard()->factory()->getTTL() * 60
- ]
- );
+ $response['access_token'] = $token;
+ $response['token_type'] = 'bearer';
+ // @phpstan-ignore-next-line
+ $response['expires_in'] = Auth::guard()->factory()->getTTL() * 60;
+
+ return response()->json($response);
}
}
diff --git a/src/app/Providers/Payment/Mollie.php b/src/app/Providers/Payment/Mollie.php
--- a/src/app/Providers/Payment/Mollie.php
+++ b/src/app/Providers/Payment/Mollie.php
@@ -18,7 +18,11 @@
*/
public function customerLink(Wallet $wallet): ?string
{
- $customer_id = self::mollieCustomerId($wallet);
+ $customer_id = self::mollieCustomerId($wallet, false);
+
+ if (!$customer_id) {
+ return null;
+ }
return sprintf(
'<a href="https://www.mollie.com/dashboard/customers/%s" target="_blank">%s</a>',
@@ -43,7 +47,7 @@
public function createMandate(Wallet $wallet, array $payment): ?array
{
// Register the user in Mollie, if not yet done
- $customer_id = self::mollieCustomerId($wallet);
+ $customer_id = self::mollieCustomerId($wallet, true);
$request = [
'amount' => [
@@ -155,7 +159,7 @@
}
// Register the user in Mollie, if not yet done
- $customer_id = self::mollieCustomerId($wallet);
+ $customer_id = self::mollieCustomerId($wallet, true);
// Note: Required fields: description, amount/currency, amount/value
@@ -211,7 +215,7 @@
return null;
}
- $customer_id = self::mollieCustomerId($wallet);
+ $customer_id = self::mollieCustomerId($wallet, true);
// Note: Required fields: description, amount/currency, amount/value
@@ -353,15 +357,16 @@
* Create one if does not exist yet.
*
* @param \App\Wallet $wallet The wallet
+ * @param bool $create Create the customer if does not exist yet
*
- * @return string Mollie customer identifier
+ * @return ?string Mollie customer identifier
*/
- protected static function mollieCustomerId(Wallet $wallet): string
+ protected static function mollieCustomerId(Wallet $wallet, bool $create = false): ?string
{
$customer_id = $wallet->getSetting('mollie_id');
// Register the user in Mollie
- if (empty($customer_id)) {
+ if (empty($customer_id) && $create) {
$customer = mollie()->customers()->create([
'name' => $wallet->owner->name(),
'email' => $wallet->id . '@private.' . \config('app.domain'),
diff --git a/src/app/Providers/Payment/Stripe.php b/src/app/Providers/Payment/Stripe.php
--- a/src/app/Providers/Payment/Stripe.php
+++ b/src/app/Providers/Payment/Stripe.php
@@ -29,7 +29,11 @@
*/
public function customerLink(Wallet $wallet): ?string
{
- $customer_id = self::stripeCustomerId($wallet);
+ $customer_id = self::stripeCustomerId($wallet, false);
+
+ if (!$customer_id) {
+ return null;
+ }
$location = 'https://dashboard.stripe.com';
@@ -62,7 +66,7 @@
public function createMandate(Wallet $wallet, array $payment): ?array
{
// Register the user in Stripe, if not yet done
- $customer_id = self::stripeCustomerId($wallet);
+ $customer_id = self::stripeCustomerId($wallet, true);
$request = [
'customer' => $customer_id,
@@ -173,7 +177,7 @@
}
// Register the user in Stripe, if not yet done
- $customer_id = self::stripeCustomerId($wallet);
+ $customer_id = self::stripeCustomerId($wallet, true);
$request = [
'customer' => $customer_id,
@@ -371,15 +375,16 @@
* Create one if does not exist yet.
*
* @param \App\Wallet $wallet The wallet
+ * @param bool $create Create the customer if does not exist yet
*
- * @return string Stripe customer identifier
+ * @return string|null Stripe customer identifier
*/
- protected static function stripeCustomerId(Wallet $wallet): string
+ protected static function stripeCustomerId(Wallet $wallet, bool $create = false): ?string
{
$customer_id = $wallet->getSetting('stripe_id');
// Register the user in Stripe
- if (empty($customer_id)) {
+ if (empty($customer_id) && $create) {
$customer = StripeAPI\Customer::create([
'name' => $wallet->owner->name(),
// Stripe will display the email on Checkout page, editable,
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
@@ -69,7 +69,6 @@
let timeout = response.expires_in || 0
// We'll refresh 60 seconds before the token expires
- // or immediately when we have no expiration time (on token re-use)
if (timeout > 60) {
timeout -= 60
}
@@ -82,7 +81,6 @@
axios.post('/api/auth/refresh').then(response => {
this.loginUser(response.data, false, true)
})
-
}, timeout * 1000)
},
// Set user state to "not logged in"
@@ -104,7 +102,7 @@
startLoading() {
this.isLoading = true
// Lock the UI with the 'loading...' element
- let loading = $('#app > .app-loader').show()
+ let loading = $('#app > .app-loader').removeClass('fadeOut')
if (!loading.length) {
$('#app').append($(loader))
}
@@ -170,7 +168,7 @@
})
},
price(price, currency) {
- return (price/100).toLocaleString('de-DE', { style: 'currency', currency: currency || 'CHF' })
+ return ((price || 0) / 100).toLocaleString('de-DE', { style: 'currency', currency: currency || 'CHF' })
},
priceLabel(cost, units = 1, discount) {
let index = ''
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
@@ -17,11 +17,11 @@
this.$root.startLoading()
axios.defaults.headers.common.Authorization = 'Bearer ' + token
- axios.get('/api/auth/info')
+ axios.get('/api/auth/info?refresh_token=1')
.then(response => {
this.isLoading = false
this.$root.stopLoading()
- this.$root.loginUser({ access_token: token }, false)
+ this.$root.loginUser(response.data, false)
this.$store.state.authInfo = response.data
})
.catch(error => {
diff --git a/src/resources/vue/User/Info.vue b/src/resources/vue/User/Info.vue
--- a/src/resources/vue/User/Info.vue
+++ b/src/resources/vue/User/Info.vue
@@ -193,10 +193,14 @@
this.discount_description = wallet.discount_description
}
+ this.$root.startLoading()
+
if (this.user_id === 'new') {
// do nothing (for now)
axios.get('/api/v4/packages')
.then(response => {
+ this.$root.stopLoading()
+
this.packages = response.data.filter(pkg => !pkg.isDomain)
this.package_id = this.packages[0].id
})
@@ -205,6 +209,8 @@
else {
axios.get('/api/v4/users/' + this.user_id)
.then(response => {
+ this.$root.stopLoading()
+
this.user = response.data
this.user.first_name = response.data.settings.first_name
this.user.last_name = response.data.settings.last_name
diff --git a/src/tests/Browser/Admin/DashboardTest.php b/src/tests/Browser/Admin/DashboardTest.php
--- a/src/tests/Browser/Admin/DashboardTest.php
+++ b/src/tests/Browser/Admin/DashboardTest.php
@@ -70,8 +70,10 @@
->click('@search form button')
->assertMissing('@search table')
->waitForLocation('/user/' . $john->id)
- ->waitFor('#user-info')
- ->assertSeeIn('#user-info .card-title', $john->email);
+ ->waitUntilMissing('.app-loader')
+ ->whenAvailable('#user-info', function (Browser $browser) use ($john) {
+ $browser->assertSeeIn('.card-title', $john->email);
+ });
});
}
}
diff --git a/src/tests/Browser/Admin/UserFinancesTest.php b/src/tests/Browser/Admin/UserFinancesTest.php
--- a/src/tests/Browser/Admin/UserFinancesTest.php
+++ b/src/tests/Browser/Admin/UserFinancesTest.php
@@ -30,6 +30,7 @@
$wallet->discount()->dissociate();
$wallet->balance = 0;
$wallet->save();
+ $wallet->setSettings(['mollie_id' => null, 'stripe_id' => null]);
}
/**
@@ -40,7 +41,9 @@
// Assert Jack's Finances tab
$this->browse(function (Browser $browser) {
$jack = $this->getTestUser('jack@kolab.org');
- $jack->wallets()->first()->transactions()->delete();
+ $wallet = $jack->wallets()->first();
+ $wallet->transactions()->delete();
+ $wallet->setSetting('stripe_id', 'abc');
$page = new UserPage($jack->id);
$browser->visit(new Home())
@@ -54,12 +57,11 @@
->assertSeeIn('.card-title:first-child', 'Account balance')
->assertSeeIn('.card-title:first-child .text-success', '0,00 CHF')
->with('form', function (Browser $browser) {
- $payment_provider = ucfirst(\config('services.payment_provider'));
$browser->assertElementsCount('.row', 2)
->assertSeeIn('.row:nth-child(1) label', 'Discount')
->assertSeeIn('.row:nth-child(1) #discount span', 'none')
- ->assertSeeIn('.row:nth-child(2) label', $payment_provider . ' ID')
- ->assertVisible('.row:nth-child(2) a');
+ ->assertSeeIn('.row:nth-child(2) label', 'Stripe ID')
+ ->assertSeeIn('.row:nth-child(2) a', 'abc');
})
->assertSeeIn('h2:nth-of-type(2)', 'Transactions')
->with('table', function (Browser $browser) {
@@ -101,7 +103,7 @@
->assertSeeIn('.card-title:first-child', 'Account balance')
->assertSeeIn('.card-title:first-child .text-danger', '-20,10 CHF')
->with('form', function (Browser $browser) {
- $browser->assertElementsCount('.row', 2)
+ $browser->assertElementsCount('.row', 1)
->assertSeeIn('.row:nth-child(1) label', 'Discount')
->assertSeeIn('.row:nth-child(1) #discount span', '10% - Test voucher');
})
@@ -127,7 +129,7 @@
->assertSeeIn('.card-title:first-child', 'Account balance')
->assertSeeIn('.card-title:first-child .text-success', '0,00 CHF')
->with('form', function (Browser $browser) {
- $browser->assertElementsCount('.row', 2)
+ $browser->assertElementsCount('.row', 1)
->assertSeeIn('.row:nth-child(1) label', 'Discount')
->assertSeeIn('.row:nth-child(1) #discount span', 'none');
})
diff --git a/src/tests/Browser/Admin/UserTest.php b/src/tests/Browser/Admin/UserTest.php
--- a/src/tests/Browser/Admin/UserTest.php
+++ b/src/tests/Browser/Admin/UserTest.php
@@ -33,6 +33,7 @@
}
$wallet = $john->wallets()->first();
$wallet->discount()->dissociate();
+ $wallet->save();
}
/**
@@ -50,6 +51,7 @@
}
$wallet = $john->wallets()->first();
$wallet->discount()->dissociate();
+ $wallet->save();
parent::tearDown();
}
diff --git a/src/tests/Browser/DomainTest.php b/src/tests/Browser/DomainTest.php
--- a/src/tests/Browser/DomainTest.php
+++ b/src/tests/Browser/DomainTest.php
@@ -118,6 +118,7 @@
->click('@links a.link-domains')
// On Domains List page click the domain entry
->on(new DomainList())
+ ->waitFor('@table tbody tr')
->assertVisible('@table tbody tr:first-child td:first-child svg.fa-globe.text-success')
->assertText('@table tbody tr:first-child td:first-child svg title', 'Active')
->assertSeeIn('@table tbody tr:first-child td:first-child', 'kolab.org')
diff --git a/src/tests/Browser/Pages/PaymentStripe.php b/src/tests/Browser/Pages/PaymentStripe.php
--- a/src/tests/Browser/Pages/PaymentStripe.php
+++ b/src/tests/Browser/Pages/PaymentStripe.php
@@ -37,8 +37,8 @@
{
return [
'@form' => '.App-Payment > form',
- '@title' => '.App-Overview .ProductSummary-Info .Text',
- '@amount' => '#ProductSummary-TotalAmount',
+ '@title' => '.App-Overview .ProductSummary',
+ '@amount' => '#ProductSummary-totalAmount',
'@description' => '#ProductSummary-Description',
'@email-input' => '.App-Payment #email',
'@cardnumber-input' => '.App-Payment #cardNumber',
diff --git a/src/tests/Browser/Pages/UserInfo.php b/src/tests/Browser/Pages/UserInfo.php
--- a/src/tests/Browser/Pages/UserInfo.php
+++ b/src/tests/Browser/Pages/UserInfo.php
@@ -25,7 +25,8 @@
*/
public function assert($browser)
{
- $browser->waitFor('@form');
+ $browser->waitFor('@form')
+ ->waitUntilMissing('.app-loader');
}
/**
diff --git a/src/tests/Browser/PasswordResetTest.php b/src/tests/Browser/PasswordResetTest.php
--- a/src/tests/Browser/PasswordResetTest.php
+++ b/src/tests/Browser/PasswordResetTest.php
@@ -146,9 +146,10 @@
$browser->waitFor('.toast-error');
- $step->assertVisible('#reset_short_code.is-invalid');
- $step->assertVisible('#reset_short_code + .invalid-feedback');
- $step->assertFocused('#reset_short_code');
+ $step->waitFor('#reset_short_code.is-invalid')
+ ->assertVisible('#reset_short_code.is-invalid')
+ ->assertVisible('#reset_short_code + .invalid-feedback')
+ ->assertFocused('#reset_short_code');
$browser->click('.toast-error'); // remove the toast
});
@@ -249,9 +250,10 @@
$browser->waitFor('.toast-error');
- $step->assertVisible('#reset_password.is-invalid');
- $step->assertVisible('#reset_password + .invalid-feedback');
- $step->assertFocused('#reset_password');
+ $step->waitFor('#reset_password.is-invalid')
+ ->assertVisible('#reset_password.is-invalid')
+ ->assertVisible('#reset_password + .invalid-feedback')
+ ->assertFocused('#reset_password');
$browser->click('.toast-error'); // remove the toast
});
diff --git a/src/tests/Browser/SignupTest.php b/src/tests/Browser/SignupTest.php
--- a/src/tests/Browser/SignupTest.php
+++ b/src/tests/Browser/SignupTest.php
@@ -482,6 +482,7 @@
$this->browse(function (Browser $browser) {
$browser->visit('/signup/voucher/TEST')
->onWithoutAssert(new Signup())
+ ->waitUntilMissing('.app-loader')
->waitFor('@step0')
->click('.plan-individual button')
->whenAvailable('@step1', function (Browser $browser) {
diff --git a/src/tests/Browser/StatusTest.php b/src/tests/Browser/StatusTest.php
--- a/src/tests/Browser/StatusTest.php
+++ b/src/tests/Browser/StatusTest.php
@@ -158,6 +158,7 @@
$browser->on(new Dashboard())
->click('@links a.link-domains')
->on(new DomainList())
+ ->waitFor('@table tbody tr')
// Assert domain status icon
->assertVisible('@table tbody tr:first-child td:first-child svg.fa-globe.text-danger')
->assertText('@table tbody tr:first-child td:first-child svg title', 'Not Ready')
@@ -222,6 +223,7 @@
$browser->visit(new Dashboard())
->click('@links a.link-users')
->on(new UserList())
+ ->waitFor('@table tbody tr')
// Assert user status icons
->assertVisible('@table tbody tr:first-child td:first-child svg.fa-user.text-success')
->assertText('@table tbody tr:first-child td:first-child svg title', 'Active')
diff --git a/src/tests/Browser/UsersTest.php b/src/tests/Browser/UsersTest.php
--- a/src/tests/Browser/UsersTest.php
+++ b/src/tests/Browser/UsersTest.php
@@ -107,7 +107,8 @@
->click('@links .link-users')
->on(new UserList())
->whenAvailable('@table', function (Browser $browser) {
- $browser->assertElementsCount('tbody tr', 4)
+ $browser->waitFor('tbody tr')
+ ->assertElementsCount('tbody tr', 4)
->assertSeeIn('tbody tr:nth-child(1) a', 'jack@kolab.org')
->assertSeeIn('tbody tr:nth-child(2) a', 'joe@kolab.org')
->assertSeeIn('tbody tr:nth-child(3) a', 'john@kolab.org')
@@ -516,6 +517,7 @@
->on(new Home())
->submitLogon('john@kolab.org', 'simple123', true)
->visit(new UserList())
+ ->waitFor('@table tr:nth-child(2)')
->click('@table tr:nth-child(2) a')
->on(new UserInfo())
->with('@form', function (Browser $browser) {
diff --git a/src/tests/Feature/Controller/Admin/WalletsTest.php b/src/tests/Feature/Controller/Admin/WalletsTest.php
--- a/src/tests/Feature/Controller/Admin/WalletsTest.php
+++ b/src/tests/Feature/Controller/Admin/WalletsTest.php
@@ -63,7 +63,7 @@
$this->assertTrue(empty($json['description']));
$this->assertTrue(empty($json['discount_description']));
$this->assertTrue(!empty($json['provider']));
- $this->assertTrue(!empty($json['providerLink']));
+ $this->assertTrue(empty($json['providerLink']));
$this->assertTrue(!empty($json['mandate']));
}
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
@@ -52,8 +52,27 @@
$this->assertTrue(is_array($json['statusInfo']));
$this->assertTrue(is_array($json['settings']));
$this->assertTrue(is_array($json['aliases']));
+ $this->assertTrue(!isset($json['access_token']));
// Note: Details of the content are tested in testUserResponse()
+
+ // Test token refresh via the info request
+ // First we log in as we need the token (actingAs() will not work)
+ $post = ['email' => 'john@kolab.org', 'password' => 'simple123'];
+ $response = $this->post("api/auth/login", $post);
+ $json = $response->json();
+ $response = $this->withHeaders(['Authorization' => 'Bearer ' . $json['access_token']])
+ ->get("api/auth/info?refresh_token=1");
+ $response->assertStatus(200);
+
+ $json = $response->json();
+
+ $this->assertEquals('john@kolab.org', $json['email']);
+ $this->assertTrue(is_array($json['statusInfo']));
+ $this->assertTrue(is_array($json['settings']));
+ $this->assertTrue(is_array($json['aliases']));
+ $this->assertTrue(!empty($json['access_token']));
+ $this->assertTrue(!empty($json['expires_in']));
}
/**

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 12:26 AM (14 h, 31 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18821683
Default Alt Text
D1459.1775175972.diff (21 KB)

Event Timeline