Page MenuHomePhorge

D1876.1775240435.diff
No OneTemporary

Authored By
Unknown
Size
7 KB
Referenced Files
None
Subscribers
None

D1876.1775240435.diff

diff --git a/src/app/Http/Controllers/API/V4/UsersController.php b/src/app/Http/Controllers/API/V4/UsersController.php
--- a/src/app/Http/Controllers/API/V4/UsersController.php
+++ b/src/app/Http/Controllers/API/V4/UsersController.php
@@ -135,13 +135,20 @@
if (!empty(request()->input('refresh'))) {
$updated = false;
+ $async = false;
$last_step = 'none';
foreach ($response['process'] as $idx => $step) {
$last_step = $step['label'];
if (!$step['state']) {
- if (!$this->execProcessStep($user, $step['label'])) {
+ $exec = $this->execProcessStep($user, $step['label']);
+
+ if (!$exec) {
+ if ($exec === null) {
+ $async = true;
+ }
+
break;
}
@@ -158,6 +165,12 @@
$response['status'] = $success ? 'success' : 'error';
$response['message'] = \trans('app.process-' . $suffix);
+
+ if ($async && !$success) {
+ $response['processState'] = 'waiting';
+ $response['status'] = 'success';
+ $response['message'] = \trans('app.process-async');
+ }
}
$response = array_merge($response, self::userStatuses($user));
@@ -594,9 +607,10 @@
* @param \App\User $user User object
* @param string $step Step identifier (as in self::statusInfo())
*
- * @return bool True if the execution succeeded, False otherwise
+ * @return bool|null True if the execution succeeded, False if not, Null when
+ * the job has been sent to the worker (result unknown)
*/
- public static function execProcessStep(User $user, string $step): bool
+ public static function execProcessStep(User $user, string $step): ?bool
{
try {
if (strpos($step, 'domain-') === 0) {
@@ -618,6 +632,14 @@
case 'user-imap-ready':
// User not in IMAP? Verify again
+ // Do it synchronously if the imap admin credentials are available
+ // otherwise let the worker do the job
+ if (!\config('imap.admin_password')) {
+ \App\Jobs\User\VerifyJob::dispatch($user->id);
+
+ return null;
+ }
+
$job = new \App\Jobs\User\VerifyJob($user->id);
$job->handle();
diff --git a/src/resources/lang/en/app.php b/src/resources/lang/en/app.php
--- a/src/resources/lang/en/app.php
+++ b/src/resources/lang/en/app.php
@@ -15,6 +15,7 @@
'planbutton' => 'Choose :plan',
+ 'process-async' => 'Setup process has been pushed. Please wait.',
'process-user-new' => 'Registering a user...',
'process-user-ldap-ready' => 'Creating a user...',
'process-user-imap-ready' => 'Creating a mailbox...',
diff --git a/src/resources/vue/Widgets/Status.vue b/src/resources/vue/Widgets/Status.vue
--- a/src/resources/vue/Widgets/Status.vue
+++ b/src/resources/vue/Widgets/Status.vue
@@ -51,12 +51,17 @@
refresh: false,
delay: 5000,
scope: 'user',
- state: { isReady: true }
+ state: { isReady: true },
+ waiting: 0,
}
},
watch: {
// We use property watcher because parent component
// might set the property with a delay and we need to parse it
+ // FIXME: Problem with this and update-status event is that whenever
+ // we emit the event a watcher function is executed, causing
+ // duplicate parseStatusInfo() calls. Fortunaltely this does not
+ // cause duplicate http requests.
status: function (val, oldVal) {
this.parseStatusInfo(val)
}
@@ -99,18 +104,26 @@
})
// Unhide the Refresh button, the process is in failure state
- this.refresh = info.processState == 'failed'
+ this.refresh = info.processState == 'failed' && this.waiting == 0
if (this.refresh || info.step == 'domain-confirmed') {
this.className = 'failed'
}
+
+ // A async job has been dispatched, switch to a waiting mode where
+ // we hide the Refresh button and pull status for about a minute,
+ // after that we switch to normal mode, i.e. user can Refresh again (if still not ready)
+ if (info.processState == 'waiting') {
+ this.waiting = 10
+ this.delay = 5000
+ } else if (this.waiting > 0) {
+ this.waiting -= 1
+ }
}
- // Update status process info every 10 seconds
- // FIXME: This probably should have some limit, or the interval
- // should grow (well, until it could be done with websocket notifications)
+ // Update status process info every 5,6,7,8,9,... seconds
clearTimeout(window.infoRequest)
- if (!this.refresh && (!info || !info.isReady)) {
+ if ((!this.refresh || this.waiting > 0) && (!info || !info.isReady)) {
window.infoRequest = setTimeout(() => {
delete window.infoRequest
// Stop updates after user logged out
diff --git a/src/tests/Feature/Controller/UsersTest.php b/src/tests/Feature/Controller/UsersTest.php
--- a/src/tests/Feature/Controller/UsersTest.php
+++ b/src/tests/Feature/Controller/UsersTest.php
@@ -293,6 +293,8 @@
*/
public function testStatus(): void
{
+ Queue::fake();
+
$john = $this->getTestUser('john@kolab.org');
$jack = $this->getTestUser('jack@kolab.org');
@@ -337,6 +339,28 @@
$this->assertSame(true, $json['process'][2]['state']);
$this->assertSame('success', $json['status']);
$this->assertSame('Setup process finished successfully.', $json['message']);
+
+ Queue::size(1);
+
+ // Test case for when the verify job is dispatched to the worker
+ $john->refresh();
+ $john->status ^= User::STATUS_IMAP_READY;
+ $john->save();
+
+ \config(['imap.admin_password' => null]);
+
+ $response = $this->actingAs($john)->get("/api/v4/users/{$john->id}/status?refresh=1");
+ $response->assertStatus(200);
+
+ $json = $response->json();
+
+ $this->assertFalse($json['isImapReady']);
+ $this->assertFalse($json['isReady']);
+ $this->assertSame('success', $json['status']);
+ $this->assertSame('waiting', $json['processState']);
+ $this->assertSame('Setup process has been pushed. Please wait.', $json['message']);
+
+ Queue::assertPushed(\App\Jobs\User\VerifyJob::class, 1);
}
/**

File Metadata

Mime Type
text/plain
Expires
Fri, Apr 3, 6:20 PM (6 h, 11 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18819943
Default Alt Text
D1876.1775240435.diff (7 KB)

Event Timeline