Finanzen: Setup-Skript mit --iban und strenger Pruefung von --valid-until, Enable-Banking-Variablen in .env.example
M5: --iban speichert iban und ibanMasked (erste und letzte vier Zeichen); --valid-until nur als Datum oder voller ISO-Zeitpunkt mit Zeitzone, sonst Abbruch. M16: ENABLE_BANKING_APP_ID und ENABLE_BANKING_KEY_PATH auskommentiert dokumentiert. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
039fdcaf27
commit
5ed4fbd188
3 files changed
+205
-8
No files matched your search
@@ -7,13 +7,15 @@
|
||||
* Optional uebernimmt das Skript eine bereits bestehende Enable-Banking-Sitzung (einmalig beim Livegang):
|
||||
* --session <id> Sitzungs-ID (wird nie ausgegeben)
|
||||
* --account <uid> Konto-UID aus der Sitzung
|
||||
* --valid-until <iso> Ende der Freigabe (ISO-Zeitpunkt)
|
||||
* --valid-until <iso> Ende der Freigabe: Datum (JJJJ-MM-TT) oder voller ISO-Zeitpunkt mit Zeitzone
|
||||
* (z. B. 2027-03-29T00:00:00Z); alles andere bricht ab
|
||||
* --iban <iban> (optional) IBAN des Kontos: wird gespeichert, die Seite zeigt sie als DE00...1234
|
||||
* Dann wird bankConnections/finom mit status "aktiv" angelegt bzw. aktualisiert und financeSettings/main
|
||||
* mit den Standardwerten angelegt, falls es fehlt. Ohne diese Argumente werden nur die Collections angelegt.
|
||||
*
|
||||
* Usage (im Container):
|
||||
* docker exec -w /app webklar-kundenbereich-server node scripts/setup-finanzen.mjs \
|
||||
* --session <id> --account <uid> --valid-until <iso>
|
||||
* --session <id> --account <uid> --valid-until <iso> [--iban <iban>]
|
||||
*/
|
||||
import { parseArgs } from 'node:util'
|
||||
|
||||
@@ -26,21 +28,45 @@ try {
|
||||
session: { type: 'string' },
|
||||
account: { type: 'string' },
|
||||
'valid-until': { type: 'string' },
|
||||
iban: { type: 'string' },
|
||||
},
|
||||
strict: true,
|
||||
allowPositionals: false,
|
||||
}).values
|
||||
} catch {
|
||||
console.error('Ungueltige Argumente. Erlaubt: --session <id> --account <uid> --valid-until <iso>')
|
||||
console.error('Ungueltige Argumente. Erlaubt: --session <id> --account <uid> --valid-until <iso> [--iban <iban>]')
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
/**
|
||||
* Strenger ISO-Zeitpunkt: JJJJ-MM-TT (Mitternacht UTC) oder JJJJ-MM-TTThh:mm:ss[.f]Z bzw. mit Versatz +hh:mm. Gibt es den
|
||||
* Tag oder die Uhrzeit nicht (30.02., 25 Uhr), ist es kein Zeitpunkt. Sonst null.
|
||||
*/
|
||||
function parseIsoInstant(value) {
|
||||
const m = /^(\d{4})-(\d{2})-(\d{2})(?:T(\d{2}):(\d{2}):(\d{2})(?:\.\d{1,9})?(Z|[+-]\d{2}:\d{2}))?$/.exec(value)
|
||||
if (!m) return null
|
||||
const [year, month, day] = [Number(m[1]), Number(m[2]), Number(m[3])]
|
||||
const [hour, minute, second] = [Number(m[4] ?? 0), Number(m[5] ?? 0), Number(m[6] ?? 0)]
|
||||
const calendar = new Date(Date.UTC(year, month - 1, day))
|
||||
if (calendar.getUTCFullYear() !== year || calendar.getUTCMonth() !== month - 1 || calendar.getUTCDate() !== day) return null
|
||||
if (hour > 23 || minute > 59 || second > 59) return null
|
||||
if (m[7] && m[7] !== 'Z' && (Number(m[7].slice(1, 3)) > 23 || Number(m[7].slice(4)) > 59)) return null
|
||||
const date = new Date(value)
|
||||
return Number.isNaN(date.getTime()) ? null : date
|
||||
}
|
||||
|
||||
/** IBAN ohne Leerzeichen in Grossbuchstaben, oder null, wenn sie nicht wie eine IBAN aussieht (2 Buchstaben, 2 Ziffern, 11 bis 30 Zeichen). */
|
||||
function normalizeIban(value) {
|
||||
const compact = String(value).replace(/\s+/g, '').toUpperCase()
|
||||
return /^[A-Z]{2}\d{2}[A-Z0-9]{11,30}$/.test(compact) ? compact : null
|
||||
}
|
||||
|
||||
const takeover = Object.values(args).some((v) => v !== undefined)
|
||||
let takeoverData = null
|
||||
if (takeover) {
|
||||
const session = String(args.session ?? '').trim()
|
||||
const account = String(args.account ?? '').trim()
|
||||
const validUntil = new Date(String(args['valid-until'] ?? '').trim())
|
||||
const validUntil = parseIsoInstant(String(args['valid-until'] ?? '').trim())
|
||||
if (!session || !account || !args['valid-until']) {
|
||||
console.error('Zur Uebernahme sind --session, --account und --valid-until zusammen noetig')
|
||||
process.exit(1)
|
||||
@@ -49,11 +75,19 @@ if (takeover) {
|
||||
console.error('--session und --account duerfen hoechstens 64 Zeichen lang sein')
|
||||
process.exit(1)
|
||||
}
|
||||
if (Number.isNaN(validUntil.getTime())) {
|
||||
console.error('--valid-until ist kein gueltiger ISO-Zeitpunkt')
|
||||
if (!validUntil) {
|
||||
console.error('--valid-until ist kein gueltiger ISO-Zeitpunkt (erlaubt: JJJJ-MM-TT oder JJJJ-MM-TTThh:mm:ssZ)')
|
||||
process.exit(1)
|
||||
}
|
||||
takeoverData = { session, account, validUntil: validUntil.toISOString() }
|
||||
let iban = ''
|
||||
if (args.iban !== undefined) {
|
||||
iban = normalizeIban(args.iban)
|
||||
if (!iban) {
|
||||
console.error('--iban ist keine gueltige IBAN')
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
takeoverData = { session, account, validUntil: validUntil.toISOString(), iban }
|
||||
}
|
||||
|
||||
const endpoint = (process.env.APPWRITE_ENDPOINT || 'https://ticket.webklar.com/v1').replace(/\/$/, '')
|
||||
@@ -228,7 +262,7 @@ await ensureCollection(
|
||||
* financeSettings/main mit den Standardwerten anlegen, falls es fehlt. Die Sitzungs-ID wird weder
|
||||
* ausgegeben noch in Fehlermeldungen wiederholt.
|
||||
*/
|
||||
async function takeOverSession({ session, account, validUntil }) {
|
||||
async function takeOverSession({ session, account, validUntil, iban }) {
|
||||
const docs = (id) => `${col(id)}/documents`
|
||||
const exists = async (collectionId, documentId) => {
|
||||
try {
|
||||
@@ -245,6 +279,8 @@ async function takeOverSession({ session, account, validUntil }) {
|
||||
sessionId: session,
|
||||
accountUid: account,
|
||||
validUntil,
|
||||
// IBAN nur, wenn angegeben (sonst bleibt eine gespeicherte stehen); die Seite zeigt nur die ersten und letzten vier Zeichen
|
||||
...(iban ? { iban, ibanMasked: `${iban.slice(0, 4)}…${iban.slice(-4)}` } : {}),
|
||||
// neue Freigabe: Warnstufen und alte Fehler gelten nicht mehr
|
||||
authState: '',
|
||||
warnedThresholds: '',
|
||||
|
||||
Reference in new issue
Block a user