/* Prueft die Ablage der PayPal-Zugangsdaten. Der wichtigste Punkt ist NICHT, dass Speichern funktioniert, sondern dass ein gespeichertes Geheimnis auf keinem Weg wieder herauskommt. */ import { mkdtempSync, rmSync, appendFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { randomBytes } from "node:crypto"; const tmp = mkdtempSync(join(tmpdir(), "wd-geh-")); process.env.DB_PATH = join(tmp, "test.db"); process.env.ENCRYPTION_KEY = randomBytes(32).toString("base64"); delete process.env.PAYPAL_CLIENT_ID; delete process.env.PAYPAL_CLIENT_SECRET; delete process.env.PAYPAL_ENV; const LOG = "/tmp/wd-geh.log"; const L = (...a) => { try { appendFileSync(LOG, a.join(" ") + "\n"); } catch (e) {} console.log(...a); }; const { db, initDb } = await import("./db.js"); initDb(); const geheim = await import("./lib/webdesign-geheimnisse.js"); const paypal = await import("./lib/webdesign-paypal.js"); let ok = 0, fehler = 0; const pruefe = (n, b, z) => { if (b) { ok++; L(" ok " + n); } else { fehler++; L(" FEHL " + n + (z ? " -> " + z : "")); } }; const SECRET = 'EMeineHeikleZeichen&/\$"~UndLang1234567890'; L("\n1. SPEICHERN UND LESEN"); await geheim.geheimnisseLaden(); pruefe("vor dem Eintragen gilt PayPal als nicht eingerichtet", paypal.istEingerichtet("einmal") === false); await geheim.einstellungSetzen("PAYPAL_CLIENT_ID", "AbC-123"); await geheim.einstellungSetzen("PAYPAL_CLIENT_SECRET", SECRET); pruefe("danach gilt es als eingerichtet", paypal.istEingerichtet("einmal") === true); pruefe("der Wert kommt zeichengenau zurueck", geheim.einstellung("PAYPAL_CLIENT_SECRET") === SECRET); pruefe("Sonderzeichen ueberstehen die Verschluesselung", geheim.einstellung("PAYPAL_CLIENT_SECRET").includes('&/\$"~')); L("\n2. IN DER DATENBANK STEHT NICHTS LESBARES"); const roh = db.prepare("SELECT value FROM app_settings WHERE key = ?").get("wd_geheim_PAYPAL_CLIENT_SECRET"); pruefe("der Eintrag existiert", !!roh); pruefe("er enthaelt NICHT den Klartext", roh && !roh.value.includes(SECRET), roh ? roh.value.slice(0, 30) : "-"); pruefe("er enthaelt auch keinen Teil davon", roh && !roh.value.includes("MeineHeikle")); L("\n3. DER STAND VERRAET DEN WERT NICHT"); const st = geheim.stand(); const alsText = JSON.stringify(st); pruefe("kein Geheimnis in der Antwort", !alsText.includes(SECRET) && !alsText.includes("MeineHeikle")); pruefe("aber es ist erkennbar, DASS etwas da ist", st.PAYPAL_CLIENT_SECRET.gesetzt === true); pruefe("die Laenge wird gemeldet", st.PAYPAL_CLIENT_SECRET.laenge === SECRET.length, String(st.PAYPAL_CLIENT_SECRET.laenge)); pruefe("das Secret ist als geheim markiert", st.PAYPAL_CLIENT_SECRET.wert === null); pruefe("die Betriebsart wird dagegen ausgeschrieben", st.PAYPAL_ENV.wert !== undefined); pruefe("die Herkunft wird benannt", st.PAYPAL_CLIENT_SECRET.quelle === "verwaltung"); L("\n4. DIE .env HAT VORRANG"); process.env.PAYPAL_CLIENT_ID = "AUS-DER-ENV"; pruefe("ein Wert auf dem Server sticht die Verwaltung", geheim.einstellung("PAYPAL_CLIENT_ID") === "AUS-DER-ENV"); pruefe("und das wird auch so angezeigt", geheim.stand().PAYPAL_CLIENT_ID.quelle === "server"); delete process.env.PAYPAL_CLIENT_ID; pruefe("faellt der Server-Wert weg, greift wieder die Verwaltung", geheim.einstellung("PAYPAL_CLIENT_ID") === "AbC-123"); L("\n5. NUR ERLAUBTE SCHLUESSEL"); let abgelehnt = false; try { await geheim.einstellungSetzen("ADMIN_PASSWORT", "x"); } catch (e) { abgelehnt = true; } pruefe("ein fremder Schluessel wird abgewiesen", abgelehnt); let falscheArt = false; try { await geheim.einstellungSetzen("PAYPAL_ENV", "vielleicht"); } catch (e) { falscheArt = true; } pruefe("die Betriebsart erlaubt nur live oder sandbox", falscheArt); L("\n6. LEEREN"); await geheim.einstellungSetzen("PAYPAL_CLIENT_SECRET", ""); pruefe("ein leerer Wert entfernt den Eintrag", geheim.einstellung("PAYPAL_CLIENT_SECRET") === ""); pruefe("und die Zeile ist wirklich weg", !db.prepare("SELECT 1 FROM app_settings WHERE key = ?").get("wd_geheim_PAYPAL_CLIENT_SECRET")); pruefe("danach gilt PayPal wieder als nicht eingerichtet", paypal.istEingerichtet("einmal") === false); L("\n7. FALSCHER SCHLUESSEL BRINGT DEN DIENST NICHT ZUM STEHEN"); await geheim.einstellungSetzen("PAYPAL_CLIENT_SECRET", SECRET); process.env.ENCRYPTION_KEY = randomBytes(32).toString("base64"); let gestuerzt = false; try { await geheim.geheimnisseLaden(); } catch (e) { gestuerzt = true; } pruefe("das Laden mit falschem Schluessel wirft nicht", !gestuerzt); pruefe("der Wert gilt dann als nicht vorhanden", geheim.einstellung("PAYPAL_CLIENT_SECRET") === ""); L(`\n===== ${ok} bestanden, ${fehler} fehlgeschlagen =====`); process.on("exit", () => rmSync(tmp, { recursive: true, force: true })); process.exitCode = fehler ? 1 : 0;