WIP: PayPal-Einstellungen ueber die Verwaltung (Test folgt auf dem Server)
This commit is contained in:
@@ -51,6 +51,7 @@ import { ausweisPruefen } from "../lib/webdesign-ausweis.js";
|
||||
import { brauchtKunde } from "./webdesign-portal.js";
|
||||
import { zustimmungSpeichern } from "./webdesign-widerruf.js";
|
||||
import * as paypal from "../lib/webdesign-paypal.js";
|
||||
import * as geheim from "../lib/webdesign-geheimnisse.js";
|
||||
import {
|
||||
jetzt, neueId, naechsteNummer, text, verlauf, centZuText,
|
||||
besucherIp, spracheOderDe,
|
||||
@@ -454,3 +455,125 @@ export async function zahlungenListe(req, res) {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/* =====================================================================
|
||||
EINSTELLUNGEN — PayPal-Zugangsdaten über die Verwaltung eintragen
|
||||
|
||||
Damit Filipe dafür nicht in die Konsole muss. Die Werte werden
|
||||
verschlüsselt gespeichert (siehe lib/webdesign-geheimnisse.js) und
|
||||
wirken sofort — ohne Dienstneustart.
|
||||
===================================================================== */
|
||||
|
||||
/* GET /webdesign/admin/einstellungen
|
||||
|
||||
Gibt NIE einen hinterlegten Wert zurück, auch nicht teilweise. Nur:
|
||||
ist etwas da, woher stammt es, wie lang ist es, wann zuletzt geändert.
|
||||
Ein Geheimnis, das man wieder auslesen kann, ist über kurz oder lang
|
||||
auch dort, wo es nicht hingehört. */
|
||||
export async function einstellungenLesen(req, res) {
|
||||
const p = await darf(req, "WD_ZAHLUNGEN_VIEW");
|
||||
if (!p.erlaubt) return json(res, { ok: false, error: "Kein Zugriff." }, p.grund);
|
||||
|
||||
return json(res, {
|
||||
ok: true,
|
||||
stand: geheim.stand(),
|
||||
einrichtung: {
|
||||
einmal: paypal.istEingerichtet("einmal"),
|
||||
abo: paypal.istEingerichtet("abo"),
|
||||
fehlt: paypal.fehlendeEinstellungen("abo"),
|
||||
live: paypal.istLive(),
|
||||
},
|
||||
webhookUrl: `${(process.env.API_BASIS_URL || "https://postfach.dogfather-universe.com")}/webdesign/paypal-webhook`,
|
||||
});
|
||||
}
|
||||
|
||||
/* POST /webdesign/admin/einstellungen
|
||||
|
||||
Nimmt beliebig viele der erlaubten Schlüssel entgegen. Ein FEHLENDER
|
||||
Schlüssel bleibt unverändert — nur ein ausdrücklich leerer Wert
|
||||
löscht. Sonst würde ein Formular, das nur ein Feld ausfüllt, beim
|
||||
Speichern alle anderen leeren. */
|
||||
export async function einstellungenSchreiben(req, res) {
|
||||
const p = await darf(req, "WD_ZAHLUNGEN_VIEW");
|
||||
if (!p.erlaubt) return json(res, { ok: false, error: "Kein Zugriff." }, p.grund);
|
||||
|
||||
const eingang = req.body?.werte;
|
||||
if (!eingang || typeof eingang !== "object") {
|
||||
return json(res, { ok: false, error: "Keine Werte übermittelt." }, 400);
|
||||
}
|
||||
|
||||
const geaendert = [];
|
||||
const abgelehnt = [];
|
||||
|
||||
for (const [schluessel, wert] of Object.entries(eingang)) {
|
||||
if (!(schluessel in geheim.ERLAUBTE_SCHLUESSEL)) { abgelehnt.push(schluessel); continue; }
|
||||
/* undefined = "nicht angefasst". Leerer String = "löschen". Das ist
|
||||
ein echter Unterschied und darf nicht verwischt werden. */
|
||||
if (wert === undefined || wert === null) continue;
|
||||
try {
|
||||
const r = await geheim.einstellungSetzen(schluessel, wert);
|
||||
geaendert.push(schluessel + (r.entfernt ? " (entfernt)" : ""));
|
||||
} catch (fehler) {
|
||||
return json(res, { ok: false, error: fehler.message }, 400);
|
||||
}
|
||||
}
|
||||
|
||||
/* PayPal merkt sich ein Zugangstoken. Nach einem Wechsel der
|
||||
Zugangsdaten wäre es das alte — und die nächste Zahlung liefe noch
|
||||
über das vorherige Konto oder scheiterte mit "invalid client".
|
||||
Deshalb hier ausdrücklich vergessen. */
|
||||
paypal.tokenVergessen();
|
||||
|
||||
/* Im Protokoll steht, WAS geändert wurde, nie WOMIT. */
|
||||
verlauf("einstellungen", "paypal", "geaendert",
|
||||
"team:" + (p.sitzung?.actor || "?"), { felder: geaendert });
|
||||
|
||||
return json(res, {
|
||||
ok: true,
|
||||
geaendert,
|
||||
abgelehnt,
|
||||
stand: geheim.stand(),
|
||||
einrichtung: {
|
||||
einmal: paypal.istEingerichtet("einmal"),
|
||||
abo: paypal.istEingerichtet("abo"),
|
||||
fehlt: paypal.fehlendeEinstellungen("abo"),
|
||||
live: paypal.istLive(),
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
/* POST /webdesign/admin/einstellungen/pruefen
|
||||
|
||||
Meldet sich testweise bei PayPal an. Erst das beweist, dass die Werte
|
||||
stimmen — "gesetzt" heisst nur, dass etwas dasteht, nicht dass es
|
||||
richtig ist. Es fliesst dabei kein Geld. */
|
||||
export async function einstellungenPruefen(req, res) {
|
||||
const p = await darf(req, "WD_ZAHLUNGEN_VIEW");
|
||||
if (!p.erlaubt) return json(res, { ok: false, error: "Kein Zugriff." }, p.grund);
|
||||
|
||||
if (!paypal.istEingerichtet("einmal")) {
|
||||
return json(res, {
|
||||
ok: false,
|
||||
error: "Es fehlen noch Werte: " + paypal.fehlendeEinstellungen("einmal").join(", "),
|
||||
}, 400);
|
||||
}
|
||||
|
||||
try {
|
||||
paypal.tokenVergessen();
|
||||
await paypal.zugangstokenPruefen();
|
||||
return json(res, {
|
||||
ok: true,
|
||||
live: paypal.istLive(),
|
||||
meldung: paypal.istLive()
|
||||
? "Anmeldung bei PayPal erfolgreich — Echtbetrieb."
|
||||
: "Anmeldung erfolgreich — aber im TESTMODUS. Es fliesst kein echtes Geld.",
|
||||
});
|
||||
} catch (fehler) {
|
||||
return json(res, {
|
||||
ok: false,
|
||||
error: "PayPal hat die Anmeldung abgelehnt. Meist stimmen Client ID und Secret "
|
||||
+ "nicht zusammen, oder sie stammen aus verschiedenen Apps bzw. aus dem Testbereich.",
|
||||
technisch: String(fehler.message || fehler).slice(0, 200),
|
||||
}, 400);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user