diff --git a/app/Http/Controllers/Admin/UserController.php b/app/Http/Controllers/Admin/UserController.php index 1a82b02e86..bcc52d66cf 100644 --- a/app/Http/Controllers/Admin/UserController.php +++ b/app/Http/Controllers/Admin/UserController.php @@ -48,6 +48,32 @@ class UserController extends Controller ); } + /** + * @param User $user + * + * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function delete(User $user) + { + $subTitle = trans('firefly.delete_user', ['email' => $user->email]); + + return view('admin.users.delete', compact('user', 'subTitle')); + } + + /** + * @param User $user + * @param UserRepositoryInterface $repository + * + * @return \Illuminate\Http\RedirectResponse|\Illuminate\Routing\Redirector + */ + public function destroy(User $user, UserRepositoryInterface $repository) + { + $repository->destroy($user); + Session::flash('success', strval(trans('firefly.user_deleted'))); + + return redirect(route('admin.users')); + } + /** * @param User $user * @@ -64,9 +90,10 @@ class UserController extends Controller $subTitle = strval(trans('firefly.edit_user', ['email' => $user->email])); $subTitleIcon = 'fa-user-o'; $codes = [ - '' => strval(trans('firefly.no_block_code')), - 'bounced' => strval(trans('firefly.block_code_bounced')), - 'expired' => strval(trans('firefly.block_code_expired')), + '' => strval(trans('firefly.no_block_code')), + 'bounced' => strval(trans('firefly.block_code_bounced')), + 'expired' => strval(trans('firefly.block_code_expired')), + 'email_changed' => strval(trans('firefly.block_code_email_changed')), ]; return view('admin.users.edit', compact('user', 'subTitle', 'subTitleIcon', 'codes')); @@ -143,6 +170,7 @@ class UserController extends Controller } $repository->changeStatus($user, $data['blocked'], $data['blocked_code']); + $repository->updateEmail($user, $data['email']); Session::flash('success', strval(trans('firefly.updated_user', ['email' => $user->email]))); Preferences::mark(); diff --git a/app/Http/breadcrumbs.php b/app/Http/breadcrumbs.php index cd0ed7939f..ee01c256f2 100644 --- a/app/Http/breadcrumbs.php +++ b/app/Http/breadcrumbs.php @@ -138,6 +138,12 @@ Breadcrumbs::register( $breadcrumbs->push(trans('firefly.edit_user', ['email' => $user->email]), route('admin.users.edit', [$user->id])); } ); +Breadcrumbs::register( + 'admin.users.delete', function (BreadCrumbGenerator $breadcrumbs, User $user) { + $breadcrumbs->parent('admin.users'); + $breadcrumbs->push(trans('firefly.delete_user', ['email' => $user->email]), route('admin.users.delete', [$user->id])); +} +); Breadcrumbs::register( 'admin.users.domains', function (BreadCrumbGenerator $breadcrumbs) { diff --git a/app/Repositories/User/UserRepository.php b/app/Repositories/User/UserRepository.php index c66ab9b494..37ebc03148 100644 --- a/app/Repositories/User/UserRepository.php +++ b/app/Repositories/User/UserRepository.php @@ -53,9 +53,14 @@ class UserRepository implements UserRepositoryInterface } /** + * This updates the users email address and records some things so it can be confirmed or undone later. + * The user is blocked until the change is confirmed. + * * @param User $user * @param string $newEmail * + * @see updateEmail + * * @return bool */ public function changeEmail(User $user, string $newEmail): bool @@ -212,4 +217,29 @@ class UserRepository implements UserRepositoryInterface { return $user->hasRole($role); } + + /** + * This updates the users email address. Same as changeEmail just without most logging. This makes sure that the undo/confirm routine can't catch this one. + * The user is NOT blocked. + * + * @param User $user + * @param string $newEmail + * + * @see changeEmail + * + * @return bool + */ + public function updateEmail(User $user, string $newEmail): bool + { + $oldEmail = $user->email; + + // save old email as pref + Preferences::setForUser($user, 'admin_previous_email_latest', $oldEmail); + Preferences::setForUser($user, 'admin_previous_email_' . date('Y-m-d-H-i-s'), $oldEmail); + + $user->email = $newEmail; + $user->save(); + + return true; + } } diff --git a/app/Repositories/User/UserRepositoryInterface.php b/app/Repositories/User/UserRepositoryInterface.php index 93af01ba07..a3a184fd89 100644 --- a/app/Repositories/User/UserRepositoryInterface.php +++ b/app/Repositories/User/UserRepositoryInterface.php @@ -43,9 +43,14 @@ interface UserRepositoryInterface public function attachRole(User $user, string $role): bool; /** + * This updates the users email address and records some things so it can be confirmed or undone later. + * The user is blocked until the change is confirmed. + * * @param User $user * @param string $newEmail * + * @see updateEmail + * * @return bool */ public function changeEmail(User $user, string $newEmail): bool; @@ -111,4 +116,17 @@ interface UserRepositoryInterface * @return bool */ public function hasRole(User $user, string $role): bool; + + /** + * This updates the users email address. Same as changeEmail just without most logging. This makes sure that the undo/confirm routine can't catch this one. + * The user is NOT blocked. + * + * @param User $user + * @param string $newEmail + * + * @see changeEmail + * + * @return bool + */ + public function updateEmail(User $user, string $newEmail): bool; } diff --git a/resources/lang/en_US/firefly.php b/resources/lang/en_US/firefly.php index 4a0a21e0af..4f663bca3e 100644 --- a/resources/lang/en_US/firefly.php +++ b/resources/lang/en_US/firefly.php @@ -430,6 +430,7 @@ return [ 'login_with_new_email' => 'You can now login with your new email address.', 'login_with_old_email' => 'You can now login with your old email address again.', + // attachments 'nr_of_attachments' => 'One attachment|:count attachments', 'attachments' => 'Attachments', @@ -902,6 +903,13 @@ return [ 'block_code_bounced' => 'Email message(s) bounced', 'block_code_expired' => 'Demo account expired', 'no_block_code' => 'No reason for block or user not blocked', + 'block_code_email_changed' => 'User has not yet confirmed new email address', + 'admin_update_email' => 'Contrary to the profile page, the user will NOT be notified their email address has changed!', + 'update_user' => 'Update user', + 'updated_user' => 'User data has been changed.', + 'delete_user' => 'Delete user :email', + 'user_deleted' => 'The user has been deleted', + // links 'journal_link_configuration' => 'Transaction links configuration', 'create_new_link_type' => 'Create new link type', diff --git a/resources/lang/en_US/form.php b/resources/lang/en_US/form.php index d12f7f7230..890a940ead 100644 --- a/resources/lang/en_US/form.php +++ b/resources/lang/en_US/form.php @@ -132,6 +132,8 @@ return [ 'delete_rule' => 'Delete rule ":title"', 'delete_rule_group' => 'Delete rule group ":title"', 'delete_link_type' => 'Delete link type ":name"', + 'delete_user' => 'Delete user ":email"', + 'user_areYouSure' => 'If you delete user ":email", everything will be gone. There is no undo, undelete or anything. If you delete yourself, you will lose access to this instance of Firefly III.', 'attachment_areYouSure' => 'Are you sure you want to delete the attachment named ":name"?', 'account_areYouSure' => 'Are you sure you want to delete the account named ":name"?', 'bill_areYouSure' => 'Are you sure you want to delete the bill named ":name"?', diff --git a/resources/views/admin/users/delete.twig b/resources/views/admin/users/delete.twig new file mode 100644 index 0000000000..17efd643a8 --- /dev/null +++ b/resources/views/admin/users/delete.twig @@ -0,0 +1,37 @@ +{% extends "./layout/default" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.renderIfExists(Route.getCurrentRoute.getName, user) }} +{% endblock %} + +{% block content %} + +
+{% endblock %} diff --git a/resources/views/admin/users/edit.twig b/resources/views/admin/users/edit.twig index 0e7a531fc3..19a9cb0465 100644 --- a/resources/views/admin/users/edit.twig +++ b/resources/views/admin/users/edit.twig @@ -17,7 +17,7 @@