diff --git a/modules/Admin/Controllers/UserController.php b/modules/Admin/Controllers/UserController.php
index 85aa24cf..99441dc5 100644
--- a/modules/Admin/Controllers/UserController.php
+++ b/modules/Admin/Controllers/UserController.php
@@ -143,6 +143,17 @@ class UserController extends BaseController
$authorize = Services::authorization();
$roles = $this->request->getPost('roles');
+
+ if ($this->user->isOwner) {
+ return redirect()
+ ->back()
+ ->with('errors', [
+ lang('User.messages.editOwnerError', [
+ 'username' => $this->user->username,
+ ]),
+ ]);
+ }
+
$authorize->setUserGroups($this->user->id, $roles ?? []);
// Success!
diff --git a/modules/Admin/Language/en/User.php b/modules/Admin/Language/en/User.php
index 8b2e478b..585d6799 100644
--- a/modules/Admin/Language/en/User.php
+++ b/modules/Admin/Language/en/User.php
@@ -45,6 +45,8 @@ return [
'{username} will be prompted with a password reset upon next visit.',
'banSuccess' => '{username} has been banned.',
'unbanSuccess' => '{username} has been unbanned.',
+ 'editOwnerError' =>
+ '{username} is the instance owner, you cannot edit its roles.',
'banSuperAdminError' =>
'{username} is a superadmin, one does not simply ban a superadmin…',
'deleteSuperAdminError' =>
diff --git a/modules/Auth/Entities/User.php b/modules/Auth/Entities/User.php
index c94e23f6..5a7d9a6c 100644
--- a/modules/Auth/Entities/User.php
+++ b/modules/Auth/Entities/User.php
@@ -13,6 +13,7 @@ namespace Modules\Auth\Entities;
use App\Entities\Podcast;
use App\Models\NotificationModel;
use App\Models\PodcastModel;
+use App\Models\UserModel;
use Myth\Auth\Entities\User as MythAuthUser;
use RuntimeException;
@@ -31,6 +32,8 @@ use RuntimeException;
*/
class User extends MythAuthUser
{
+ public bool $is_owner;
+
/**
* @var Podcast[]|null
*/
@@ -54,6 +57,17 @@ class User extends MythAuthUser
'podcast_role' => '?string',
];
+ public function getIsOwner(): bool
+ {
+ $firstUser = (new UserModel())->first();
+
+ if (! $firstUser instanceof self) {
+ return false;
+ }
+
+ return $this->username === $firstUser->username;
+ }
+
/**
* Returns the podcasts the user is contributing to
*
diff --git a/themes/cp_admin/user/edit.php b/themes/cp_admin/user/edit.php
index 88c641d8..2981b9f3 100644
--- a/themes/cp_admin/user/edit.php
+++ b/themes/cp_admin/user/edit.php
@@ -23,7 +23,6 @@
id="roles"
name="roles[]"
label="= lang('User.form.roles') ?>"
- required="true"
options="= esc(json_encode($roleOptions)) ?>"
selected="= esc(json_encode($user->roles)) ?>" />
diff --git a/themes/cp_admin/user/list.php b/themes/cp_admin/user/list.php
index 54c7bdb6..ce977792 100644
--- a/themes/cp_admin/user/list.php
+++ b/themes/cp_admin/user/list.php
@@ -30,10 +30,13 @@
[
'header' => lang('User.list.roles'),
'cell' => function ($user) {
- return implode(',', $user->roles) .
- '' . lang('User.edit_roles', [
- 'username' => esc($user->username),
- ]) . '';
+ if ($user->isOwner) {
+ return 'owner, ' . implode(',', $user->roles);
+ }
+
+ return implode(',', $user->roles) . '' . lang('User.edit_roles', [
+ 'username' => esc($user->username),
+ ]) . '';
},
],
[