PayPal ohne Konsole einrichten -- Formular in der Verwaltung

Auf die Frage "soll ich das Secret hier reinschicken?" ist die Antwort
nein: Es stuende dauerhaft im Gespraechsverlauf, und schreiben koennte
ich es trotzdem nicht (kein Zugriff auf /home/dogiintern, sudo nur fuer
apt/systemctl/docker). Risiko ohne Nutzen.

Der Fehler lag aber bei mir: Ich hatte SSH-Befehle als Loesung angeboten.
Filipe soll gar nicht in die Konsole. Jetzt traegt er die Werte in seiner
Verwaltung ein.

AUFBAU

lib/webdesign-geheimnisse.js legt die Werte verschluesselt in
app_settings ab -- derselbe AES-GCM-Weg wie fuer die Zugangscodes des
Universe. Wer die Datenbankdatei in die Haende bekommt, etwa ueber eine
alte Sicherung, hat damit nichts.

Die .env behaelt VORRANG. Sonst koennte ein Fehlgriff im Formular
stillschweigend eine funktionierende Servereinstellung aushebeln und
laufenden Zahlungsverkehr umleiten. Die Datenbank ergaenzt, was dort
fehlt -- sie konkurriert nicht.

Kein Neustart noetig: Nach jedem Speichern werden die Werte neu geladen.

DER KNIFF MIT DEM SYNCHRONEN ZUGRIFF

Entschluesseln ist asynchron, die Pruefungen des PayPal-Moduls
(istLive, istEingerichtet, fehlendeEinstellungen) sind synchron und
werden an einem Dutzend Stellen aufgerufen, teils mitten im Aufbau einer
Antwort. Sie alle auf async umzustellen waere ein Eingriff quer durch den
Bezahlvorgang gewesen -- viel Flaeche fuer Fehler genau dort, wo Fehler
Geld kosten.

Stattdessen werden die Werte einmal beim Start entschluesselt und danach
synchron gelesen. Alle 12 Zugriffe auf process.env.PAYPAL* im Modul
laufen jetzt ueber einen einzigen Zugriffspunkt.

WERTE KOMMEN NIE ZURUECK

Es gibt keinen Weg, ein gespeichertes Geheimnis wieder auszulesen. Die
Anzeige zeigt nur: ob etwas da ist, woher es stammt, wie lang es ist,
wann es zuletzt geaendert wurde. Das Formular leert sich nach dem
Speichern selbst -- ein Secret soll nicht stehen bleiben, wenn jemand
anders auf den Bildschirm schaut.

Ein leeres Feld bedeutet "nicht anfassen", nicht "loeschen". Sonst wuerde
das Nachtragen eines einzelnen Werts alle anderen leeren.

Nach jeder Aenderung wird das gemerkte PayPal-Zugangstoken vergessen --
sonst liefe die naechste Zahlung noch ueber die alten Zugangsdaten oder
scheiterte mit "invalid client".

"Verbindung testen" meldet sich probeweise bei PayPal an. Erst das
beweist, dass die Werte stimmen: "gesetzt" heisst nur, dass etwas
dasteht. Es fliesst dabei kein Geld.

GEPRUEFT: 23 Pruefungen auf dem Server, alle bestanden. Darunter die
wichtigsten Verneinungen: In der Datenbank steht kein Klartext, auch
kein Teil davon. Der Stand enthaelt das Geheimnis nicht. Ein fremder
Schluessel wird abgewiesen. Und: Ein gewechselter ENCRYPTION_KEY bringt
den Dienst NICHT zum Stehen -- der Wert gilt dann als nicht vorhanden,
die Seite laeuft weiter.

Verwaltung 69, Gestaltung 0 Befunde, Designsystem 5 -- unveraendert gruen.

Versionsstempel und Cache-Name auf v10.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-23 16:51:56 +02:00
co-authored by Claude Opus 5
parent 5043642951
commit 6a2aa13dd8
17 changed files with 54 additions and 54 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 KiB

After

Width:  |  Height:  |  Size: 155 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 463 KiB

After

Width:  |  Height:  |  Size: 464 KiB

+4 -4
View File
@@ -13,8 +13,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
/* Zeitstrahl: die Linie verbindet die Nummernkreise. Sie liegt hinter
den Kreisen (z-index) und endet beim letzten Schritt, damit sie nicht
@@ -183,7 +183,7 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-ablauf.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-ablauf.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
</body>
</html>
+5 -5
View File
@@ -13,8 +13,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
/* ---------- Schrittanzeige ----------
Zeigt alle vier Schritte gleichzeitig statt nur "3 von 4". Man sieht
@@ -418,8 +418,8 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-anfrage.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/wd-anfrage.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-anfrage.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
<script src="/assets/js/wd-anfrage.js?v=20260823wd10"></script>
</body>
</html>
+4 -4
View File
@@ -13,8 +13,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
.fq-thema { scroll-margin-top: 90px; }
.fq-thema + .fq-thema { margin-top: clamp(2rem, 4vw, 3rem); }
@@ -195,7 +195,7 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-faq.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-faq.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
</body>
</html>
+4 -4
View File
@@ -16,8 +16,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
/* ---------- Nur auf der Startseite gebraucht ---------- */
@@ -407,8 +407,8 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-index.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-index.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
<script>
/* ---------------------------------------------------------------------
Marken-Intro (Masterplan S.3, Schritt 02: "Nach erfolgreichem Code
+4 -4
View File
@@ -13,8 +13,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
/* Sprungmarken.
Frueher eine waagerecht wischbare Leiste. Rueckmeldung 22.08.2026:
@@ -331,7 +331,7 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-leistungen.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-leistungen.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
</body>
</html>
+5 -5
View File
@@ -12,8 +12,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
.po-login { max-width: 440px; margin: clamp(1.5rem,6vh,4rem) auto; }
@@ -134,8 +134,8 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-portal.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/wd-portal.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-portal.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
<script src="/assets/js/wd-portal.js?v=20260823wd10"></script>
</body>
</html>
+4 -4
View File
@@ -13,8 +13,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
.pfo-projekt { overflow: hidden; padding: 0; margin-bottom: clamp(1.4rem, 3vw, 2.2rem); }
.pfo-bild {
@@ -192,7 +192,7 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-portfolio.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-portfolio.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
</body>
</html>
+4 -4
View File
@@ -13,8 +13,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
.pr-preis-gross { font-family: var(--font-head); font-weight: 800; color: var(--wd-blau); white-space: nowrap; }
@@ -196,7 +196,7 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-preise.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-preise.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
</body>
</html>
+3 -3
View File
@@ -8,8 +8,8 @@
<link rel="icon" type="image/png" href="/assets/img/favicon.png" />
<link rel="manifest" href="/webdesign/app.webmanifest" />
<meta name="theme-color" content="#05070b" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
</head>
<body class="wd">
<div id="wd-kopf"></div>
@@ -400,6 +400,6 @@
<div id="wd-fuss"></div>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
</body>
</html>
+1 -1
View File
@@ -34,7 +34,7 @@
Start alle alten Zwischenspeicher weg. Muss bei jeder Änderung an den
Dateien unten hochgezählt werden, sonst hängen Nutzer auf einem alten
Stand fest. */
const CACHE_NAME = "dogfather-webdesign-v9";
const CACHE_NAME = "dogfather-webdesign-v10";
/* Bausteine, die die Oberfläche zum Anzeigen braucht. Bewusst KEINE
HTML-Datei in dieser Liste. */
+4 -4
View File
@@ -13,8 +13,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
.ue-kopf { display: grid; grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
/* Auf dem Handy zuerst der Text, dann das Bild: sonst schiebt ein
@@ -127,7 +127,7 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-ueber.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-ueber.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
</body>
</html>
+3 -3
View File
@@ -11,8 +11,8 @@
<link rel="apple-touch-icon" href="/assets/img/wd-app-180.png" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-title" content="DF Verwaltung" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
/* =====================================================================
Verwaltungsbereich — bewusst NUR AUF DEUTSCH.
@@ -761,7 +761,7 @@
<div class="vw-detail-blatt" id="vw-detail-blatt"></div>
</div>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
<script>
/* =====================================================================
Verwaltung: Anfragen ansehen, Status ändern, Notizen, Archivieren.
+5 -5
View File
@@ -9,8 +9,8 @@
<link rel="icon" type="image/png" href="/assets/img/favicon.png" />
<link rel="manifest" href="/webdesign/app.webmanifest" />
<meta name="theme-color" content="#05070b" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
</head>
<body class="wd">
<div id="wd-kopf"></div>
@@ -137,8 +137,8 @@
<div id="wd-fuss"></div>
<script src="/assets/js/i18n-wd-widerruf.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/wd-widerruf.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-widerruf.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
<script src="/assets/js/wd-widerruf.js?v=20260823wd10"></script>
</body>
</html>
+4 -4
View File
@@ -21,8 +21,8 @@
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="apple-mobile-web-app-title" content="Dogfather Webdesign" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd9" />
<link rel="stylesheet" href="/assets/css/main.css?v=20260823wd10" />
<link rel="stylesheet" href="/assets/css/webdesign.css?v=20260823wd10" />
<style>
/* =====================================================================
Zugangswand — nur hier gebraucht, deshalb bewusst NICHT in
@@ -177,8 +177,8 @@
</div>
</main>
<script src="/assets/js/i18n-wd-zugang.js?v=20260823wd9"></script>
<script src="/assets/js/wd-core.js?v=20260823wd9"></script>
<script src="/assets/js/i18n-wd-zugang.js?v=20260823wd10"></script>
<script src="/assets/js/wd-core.js?v=20260823wd10"></script>
<script>
(function () {
"use strict";