diff --git a/app/Livewire/Modals/AddSshKey.php b/app/Livewire/Modals/AddSshKey.php index 8c25c11..4bcbc7d 100644 --- a/app/Livewire/Modals/AddSshKey.php +++ b/app/Livewire/Modals/AddSshKey.php @@ -18,6 +18,8 @@ class AddSshKey extends ModalComponent { public int $serverId; + public string $keyName = ''; + public string $publicKey = ''; public ?string $generatedPrivate = null; @@ -40,10 +42,34 @@ class AddSshKey extends ModalComponent { $this->error = null; $key = EC::createKey('ed25519'); - $this->publicKey = $key->getPublicKey()->toString('OpenSSH', ['comment' => 'clusev-key']); + // The comment is what identifies the key in the server's list — use the operator's name. + $this->publicKey = $key->getPublicKey()->toString('OpenSSH', ['comment' => $this->keyComment() ?: 'clusev-key']); $this->generatedPrivate = (string) $key->toString('OpenSSH'); } + /** Sanitised key label, safe as an authorized_keys comment (single line, ≤64 chars), or '' if none. */ + private function keyComment(): string + { + $name = preg_replace('/[\x00-\x1F\x7F]+/', ' ', $this->keyName) ?? ''; + $name = trim(preg_replace('/\s+/', ' ', $name) ?? ''); + + return mb_substr($name, 0, 64); + } + + /** Set the OpenSSH comment of a public-key line to $comment (only when a name was given). */ + private function withComment(string $pub, string $comment): string + { + if ($comment === '') { + return $pub; + } + $parts = preg_split('/\s+/', trim($pub), 3); + if (count($parts) < 2) { + return $pub; // not a recognisable key line — let the SSH layer reject it + } + + return $parts[0].' '.$parts[1].' '.$comment; + } + public function save(FleetService $fleet): void { $this->error = null; @@ -55,8 +81,11 @@ class AddSshKey extends ModalComponent return; } + $name = $this->keyComment(); + try { - $fleet->addAuthorizedKey($server, $this->publicKey); + // Force the key's comment to the operator's name so it is identifiable in the list. + $fleet->addAuthorizedKey($server, $this->withComment($this->publicKey, $name)); } catch (Throwable $e) { $this->error = $e->getMessage(); @@ -68,7 +97,7 @@ class AddSshKey extends ModalComponent 'server_id' => $server->id, 'actor' => Auth::user()?->name ?? 'system', 'action' => 'ssh_key.add', - 'target' => $server->name, + 'target' => $name !== '' ? $server->name.' · '.$name : $server->name, 'ip' => request()->ip(), ]); diff --git a/lang/de/modals.php b/lang/de/modals.php index a4b533a..3272aa7 100644 --- a/lang/de/modals.php +++ b/lang/de/modals.php @@ -7,6 +7,8 @@ return [ // ── Add SSH key ─────────────────────────────────────────────────────── 'add_ssh_key' => [ 'title' => 'SSH-Schlüssel hinzufügen', + 'name_label' => 'Name (optional)', + 'name_placeholder' => 'z.B. Backup-Laptop · Admin-Notebook', 'subtitle_before' => 'Öffentlichen Schlüssel einfügen — er wird in', 'subtitle_after' => 'ergänzt.', 'public_key_label' => 'Öffentlicher Schlüssel', diff --git a/lang/en/modals.php b/lang/en/modals.php index 8317c42..312579d 100644 --- a/lang/en/modals.php +++ b/lang/en/modals.php @@ -6,6 +6,8 @@ return [ // ── Add SSH key ─────────────────────────────────────────────────────── 'add_ssh_key' => [ 'title' => 'Add SSH key', + 'name_label' => 'Name (optional)', + 'name_placeholder' => 'e.g. Backup laptop · Admin notebook', 'subtitle_before' => 'Paste a public key — it is appended to', 'subtitle_after' => '.', 'public_key_label' => 'Public key', diff --git a/resources/views/livewire/modals/add-ssh-key.blade.php b/resources/views/livewire/modals/add-ssh-key.blade.php index d9a9de6..0ceab7d 100644 --- a/resources/views/livewire/modals/add-ssh-key.blade.php +++ b/resources/views/livewire/modals/add-ssh-key.blade.php @@ -9,6 +9,12 @@ +