fix(admin): promote only role-less legacy admins; allow editing datacenters with legacy free-form location

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat/portal-design
nexxo 2026-07-25 18:26:09 +02:00
parent fd7cba7403
commit 3a794b05dd
3 changed files with 18 additions and 3 deletions

View File

@ -19,7 +19,9 @@ class EnsureAdmin
{
$user = $request->user();
if ($user instanceof User && $user->is_admin && ! $user->isOperator()) {
// Only a genuinely un-migrated legacy admin (is_admin, but NO roles at
// all) is promoted — never override an intentional demotion/other role.
if ($user instanceof User && $user->is_admin && $user->roles->isEmpty()) {
$user->assignRole('Owner');
}

View File

@ -22,6 +22,9 @@ class EditDatacenter extends ModalComponent
public string $location = '';
/** The location present when the modal opened — a pre-curation free-form value. */
public string $originalLocation = '';
public function mount(string $uuid): void
{
$this->authorize('datacenters.manage'); // modals are reachable without the route middleware
@ -30,15 +33,22 @@ class EditDatacenter extends ModalComponent
$this->code = $dc->code;
$this->name = $dc->name;
$this->location = (string) $dc->location;
$this->originalLocation = (string) $dc->location;
}
public function save()
{
$this->authorize('datacenters.manage');
// Validate the country against the configured list so add + edit stay in sync.
// Accept the configured countries plus the record's own legacy value, so a
// datacenter created before the curated list can still be edited (e.g. a
// name-only change) without being forced to replace a free-form location.
$allowed = array_keys((array) config('countries'));
if ($this->originalLocation !== '') {
$allowed[] = $this->originalLocation;
}
$data = $this->validate([
'name' => 'required|string|max:255',
'location' => 'nullable|in:'.implode(',', array_keys((array) config('countries'))),
'location' => 'nullable|in:'.implode(',', $allowed),
]);
Datacenter::query()->where('uuid', $this->uuid)->update([

View File

@ -14,6 +14,9 @@
<label class="text-sm font-medium text-body" for="dc-location">{{ __('datacenters.location') }}</label>
<select id="dc-location" wire:model="location" class="mt-1.5 w-full rounded-md border border-line-strong bg-surface px-3 py-2 text-sm text-body">
<option value="">{{ __('datacenters.no_country') }}</option>
@if ($originalLocation !== '' && ! array_key_exists($originalLocation, $countries))
<option value="{{ $originalLocation }}">{{ $originalLocation }}</option>
@endif
@foreach ($countries as $code => $name)
<option value="{{ $code }}">{{ $name }} ({{ $code }})</option>
@endforeach