Files
proxdeploy/tests/e2e/einstellungen.spec.ts
T
florian.wildeandClaude Opus 5.5 426d3ec95a feat(schluessel): SSH-Schlüssel hinterlegen statt in jedes Formular
Benutzer hinterlegen ihre öffentlichen Schlüssel einmal, Admins
zusätzlich Team-Schlüssel. Sie kommen in jeden Gast: im Assistenten
vorausgewählt und abwählbar, per API und CLI automatisch, wenn die
Anfrage keine nennt. Die Schlüssel kommen über die Schnittstelle
SchluesselQuelle – dort lässt sich später eine externe Verwaltung
anbinden.

Vorgezogen aus #015 auf die Frage, ob Schlüssel ins Template gehören:
nein, in die Verwaltung.

Refs #015

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 14:28:45 +02:00

50 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { execFileSync } from "node:child_process";
import { mkdtempSync, readFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { expect, test } from "@playwright/test";
import { anmelden, E2E_PRAEFIX, keinQuerscrollen } from "./helfer";
/** Je Lauf ein eigener Schlüssel – derselbe zweimal wäre für denselben Benutzer ein Duplikat. */
function neuerSchluessel(): string {
const ordner = mkdtempSync(join(tmpdir(), "pd-e2e-"));
execFileSync("ssh-keygen", ["-q", "-t", "ed25519", "-N", "", "-C", "e2e@test", "-f", join(ordner, "k")]);
return readFileSync(join(ordner, "k.pub"), "utf8").trim();
}
test("SSH-Schlüssel hinterlegen, im Assistenten vorausgewählt, wieder entfernen", async ({ page }) => {
const name = `${E2E_PRAEFIX}-${test.info().project.name}`;
await anmelden(page, "/einstellungen");
// Reste eines abgebrochenen Laufs wegräumen.
for (const alt of (await (await page.request.get("/api/v1/schluessel")).json()) as Array<{
id: string;
name: string;
}>) {
if (alt.name.startsWith(E2E_PRAEFIX)) await page.request.delete(`/api/v1/schluessel/${alt.id}`);
}
await page.reload();
await page.getByLabel("Name").fill(name);
await page.getByLabel("Öffentlicher Schlüssel").fill("-----BEGIN OPENSSH PRIVATE KEY-----");
await page.getByRole("button", { name: "Hinzufügen" }).click();
await expect(page.getByText(/nie den privaten Schlüssel/)).toBeVisible();
await page.getByLabel("Öffentlicher Schlüssel").fill(neuerSchluessel());
await page.getByRole("button", { name: "Hinzufügen" }).click();
await expect(page.getByText(name)).toBeVisible();
await keinQuerscrollen(page);
await page.goto("/ausrollen");
if (await page.getByText("Erst einen Server anlegen").isVisible())
test.skip(true, "Kein getesteter Server vorhanden");
for (let i = 0; i < 3; i++) await page.getByRole("button", { name: "Weiter" }).click();
await page.getByLabel("Name (Hostname)").fill("pd-e2e");
for (let i = 0; i < 3; i++) await page.getByRole("button", { name: "Weiter" }).click();
await expect(page.getByLabel(name)).toBeChecked();
// Mit hinterlegtem Schlüssel geht es ohne Eingabe weiter.
await expect(page.getByRole("button", { name: "Weiter" })).toBeEnabled();
await page.goto("/einstellungen");
page.once("dialog", (d) => void d.accept());
await page.getByRole("button", { name: `Schlüssel ${name} entfernen` }).click();
await expect(page.getByText(name)).toHaveCount(0);
});