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 @@ -621,6 +621,10 @@ list($login, $domain) = explode('@', $email); + if (strlen($login) === 0 || strlen($domain) === 0) { + return \trans('validation.entryinvalid', ['attribute' => $attribute]); + } + // Check if domain exists $domain = Domain::where('namespace', Str::lower($domain))->first(); diff --git a/src/resources/vue/Widgets/ListInput.vue b/src/resources/vue/Widgets/ListInput.vue --- a/src/resources/vue/Widgets/ListInput.vue +++ b/src/resources/vue/Widgets/ListInput.vue @@ -10,7 +10,7 @@
- +
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 @@ -414,6 +414,29 @@ $this->assertSame('Julia', $julia->getSetting('first_name')); $this->assertSame('Roberts', $julia->getSetting('last_name')); $this->assertSame('Test Org', $julia->getSetting('organization')); + + // Some additional tests for the list input widget + $browser->click('tbody tr:nth-child(4) a') + ->on(new UserInfo()) + ->with(new ListInput('#aliases'), function (Browser $browser) { + $browser->assertListInputValue(['julia.roberts2@kolab.org']) + ->addListEntry('invalid address') + ->type('.input-group:nth-child(2) input', '@kolab.org'); + }) + ->click('button[type=submit]') + ->assertToast(Toast::TYPE_ERROR, 'Form validation error') + ->with(new ListInput('#aliases'), function (Browser $browser) { + $browser->assertVisible('.input-group:nth-child(2) input.is-invalid') + ->assertVisible('.input-group:nth-child(3) input.is-invalid') + ->type('.input-group:nth-child(2) input', 'julia.roberts3@kolab.org') + ->type('.input-group:nth-child(3) input', 'julia.roberts4@kolab.org'); + }) + ->click('button[type=submit]') + ->assertToast(Toast::TYPE_SUCCESS, 'User data updated successfully.'); + + $julia = User::where('email', 'julia.roberts@kolab.org')->first(); + $aliases = $julia->aliases()->orderBy('alias')->get()->pluck('alias')->all(); + $this->assertSame(['julia.roberts3@kolab.org', 'julia.roberts4@kolab.org'], $aliases); }); } 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 @@ -649,11 +649,14 @@ $this->assertCount(1, $aliases); $this->assertSame('useralias2@' . \config('app.domain'), $aliases[0]->alias); - // Test error on setting an alias to other user's domain - // and missing password confirmation + // Test error on some invalid aliases missing password confirmation $post = [ 'password' => 'simple123', - 'aliases' => ['useralias2@' . \config('app.domain'), 'useralias1@kolab.org'] + 'aliases' => [ + 'useralias2@' . \config('app.domain'), + 'useralias1@kolab.org', + '@kolab.org', + ] ]; $response = $this->actingAs($userA)->put("/api/v4/users/{$userA->id}", $post); @@ -663,8 +666,9 @@ $this->assertSame('error', $json['status']); $this->assertCount(2, $json['errors']); - $this->assertCount(1, $json['errors']['aliases']); + $this->assertCount(2, $json['errors']['aliases']); $this->assertSame("The specified domain is not available.", $json['errors']['aliases'][1]); + $this->assertSame("The specified alias is invalid.", $json['errors']['aliases'][2]); $this->assertSame("The password confirmation does not match.", $json['errors']['password'][0]); // Test authorized update of other user