feat: Oberflaeche fuer die Bankanbindung

Einstellungen -> "Bankkonten direkt verbinden": Zugangsdaten hinterlegen,
Land waehlen, Bank suchen, verbinden. Nach der Autorisierung landet man auf
/bank/rueckkehr, wo der Code gegen die Sitzung getauscht wird – ueber den
Server, denn der Code ist ein Einmal-Geheimnis und die Anfrage muss mit dem
privaten Schluessel signiert werden, der den Server nie verlaesst.

Danach stehen die gefundenen Bankkonten da und werden je einem Konto in
Certain zugeordnet. Die Auswahl zeigt nur Konten passender Waehrung, und
solange nichts zugeordnet ist, steht dabei, dass von diesem Konto nichts
abgerufen wird.

Die Einrichtungsanleitung nennt die Rueckleitungs-Adresse kopierfertig – sie
muss bei Enable Banking hinterlegt werden, und ohne sie scheitert die
Autorisierung mit einer Fehlermeldung der Bank, die nichts erklaert.

Laeuft die Zustimmung bald ab, steht das farbig an der Verbindung statt dass
der Abruf eines Tages stumm aufhoert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Guido
2026-08-26 21:34:41 +02:00
co-authored by Claude Opus 5
parent 7a3bd200b1
commit 735ece6843
8 changed files with 508 additions and 0 deletions
+47
View File
@@ -561,5 +561,52 @@
"deleteSender": "Remove mapping",
"deleteSenderConfirm": "Remove mapping “{{text}}”? Payments already captured stay.",
"anyCurrency": "any currency"
},
"bank": {
"title": "Connect bank accounts directly",
"intro": "Under PSD2, EU banks must offer an interface – but only to licensed services. Enable Banking holds that licence and passes it on, so N26 and Revolut can be read directly, without CSV. Switzerland is not covered by PSD2; Raiffeisen stays on file import.",
"setupTitle": "One-time setup",
"setupHint": "You need your own Enable Banking application. It cannot ship with Certain – the key is bound to your registration.",
"setupStep1": "Sign in at enablebanking.com (the account is created on first sign-in).",
"setupStep2": "Create a Production application and download the key file (.pem). It becomes active once you link your own accounts.",
"setupStep3": "Enter this address there as the redirect URL:",
"setupStart": "Enter credentials",
"appTitle": "Enable Banking credentials",
"appReady": "Application configured",
"appSaved": "Saved.",
"applicationId": "Application ID",
"privateKey": "Private key (contents of the .pem file)",
"privateKeyKeep": "Private key (leave empty to keep)",
"privateKeyHint": "Stored encrypted and never leaves the server. Every request to the bank is signed with it – treat it like a password.",
"baseUrl": "Public address of this installation",
"baseUrlHint": "Must start with https:// and be reachable from outside – banks do not redirect to an unencrypted address. This address plus /bank/rueckkehr is what you register with Enable Banking.",
"country": "Country of the bank",
"findBanks": "Find banks",
"noBanks": "Nothing found for this country.",
"pickBank": "{{n}} banks found – pick yours:",
"connect": "Connect",
"notMapped": "not mapped to an account yet",
"mapHint": "Without a mapping nothing is fetched from this account.",
"noAccountsFound": "No accounts were returned.",
"sync": "Fetch transactions",
"synced": "{{geholt}} transactions checked · {{neu}} new in the inbox.",
"noMapping": "No account mapped – map one above first, then it will fetch.",
"lastSync": "last fetched on {{datum}}",
"neverSynced": "never fetched",
"lastError": "Error",
"validUntil": "Consent valid until {{datum}}",
"expiresSoon": "Consent expires on {{datum}} – you will need to authorise again.",
"disconnect": "Disconnect",
"disconnectConfirm": "Disconnect from “{{name}}”? Transactions already fetched stay."
},
"bankReturn": {
"title": "Back from your bank",
"working": "Completing the authorisation …",
"ok": "Connected. {{n}} accounts found.",
"next": "Map them to your Certain accounts in the settings – then you can fetch transactions.",
"failed": "That did not work",
"failedHint": "The code from the bank is single-use and short-lived. Start the connection again in the settings.",
"missing": "The bank did not return a code.",
"toSettings": "Go to settings"
}
}