Buchungskalender: Abschluss – S7 Buchungslink-Gueltigkeit (90 Tage nach Abreise, 30 Tage nach Absage), tokenHash beim Anonymisieren leeren
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
17400cac1f
commit
4f9fb6b109
6 files changed
+57
-12
No files matched your search
@@ -9,7 +9,7 @@ import * as mails from './mails.js'
|
||||
import { berechnePreis, preiseVollstaendig, pruefePosten, summiere } from './preis.js'
|
||||
import { stelleAus } from './rechnungen.js'
|
||||
import { aktualisiereAnfrage, ladeAnfrage, findeRechnung, ladeEinstellungen, ladePreise, ladeRechnung, ladeUnterkunft, legeAnfrageDokAn, listeAnfragen, listeAnfragenAlle } from './speicher.js'
|
||||
import { neuesToken, tokenPasst } from './token.js'
|
||||
import { linkGueltig, neuesToken, tokenPasst } from './token.js'
|
||||
import * as zahlung from './zahlung.js'
|
||||
|
||||
export const UEBERGAENGE = {
|
||||
@@ -194,7 +194,7 @@ export async function bucheVerbindlich(ctx, anfrageId, token, { rechnungsadresse
|
||||
if (!pre || pre.featureId !== ctx.featureId) throw new UkFehler(404, 'nicht_gefunden')
|
||||
const r = await withLocks(withLocksKey(pre.unterkunftId), async () => {
|
||||
const a = await ladeAnfrage(anfrageId)
|
||||
if (!a || a.featureId !== ctx.featureId || !tokenPasst(a.tokenHash, token)) throw new UkFehler(404, 'nicht_gefunden')
|
||||
if (!a || a.featureId !== ctx.featureId || !tokenPasst(a.tokenHash, token) || !linkGueltig(a, now)) throw new UkFehler(404, 'nicht_gefunden')
|
||||
if (a.status === 'gebucht' || a.status === 'bezahlt') {
|
||||
return { anfrage: a, rechnung: a.rechnungId ? await ladeRechnung(a.rechnungId) : null, neu: false }
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ const ANONYM_JAHRE = () => config.unterkunft.anonymisierenJahre ?? 3
|
||||
const RECHNUNG_JAHRE = () => config.unterkunft.rechnungJahre ?? 8
|
||||
const MARKER = 'Buchungsdaten gelöscht am '
|
||||
const MARKER_RE = /Buchungsdaten gelöscht am (\d{4}-\d{2}-\d{2})/
|
||||
const ANFRAGE_ANONYM = { gast: {}, nachrichtVermieter: '', ipHash: '' }
|
||||
const ANFRAGE_ANONYM = { gast: {}, nachrichtVermieter: '', ipHash: '', tokenHash: '' } // tokenHash leer: der Buchungslink ist mit der Anonymisierung tot
|
||||
|
||||
const zeitMs = (v) => {
|
||||
const t = Date.parse(v)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { createHash, createHmac, randomBytes, timingSafeEqual } from 'node:crypto'
|
||||
import { config } from '../../config.js'
|
||||
import { ipSchluessel } from '../termine/limits.js'
|
||||
import { heute } from '../termine/zeit.js'
|
||||
import { plusTage } from './datum.js'
|
||||
|
||||
/**
|
||||
* Tokens des Buchungskalenders. Buchungslink-Token: 32 Byte zufaellig (base64url), gespeichert wird nur der SHA-256-Hash.
|
||||
@@ -28,6 +30,28 @@ export function tokenPasst(hash, token) {
|
||||
return erwartet.length === gegeben.length && timingSafeEqual(erwartet, gegeben)
|
||||
}
|
||||
|
||||
const LINK_TAGE_NACH_ABREISE = 90
|
||||
const LINK_TAGE_NACH_ABSAGE = 30
|
||||
const TAG_RE = /^\d{4}-\d{2}-\d{2}/
|
||||
|
||||
/**
|
||||
* Gilt der Buchungslink noch? Bis 90 Tage nach der Abreise (bis, einschliesslich dieses Tages, Berliner Tag); bei abgelehnten und abgelaufenen
|
||||
* Anfragen (nicht zustande gekommen) nur 30 Tage nach dem Statuswechsel. Danach antwortet die Buchungsseite wie bei einem unbekannten Link (404).
|
||||
* Ohne lesbares Datum gilt der Link (kein Grund, ihn zu sperren).
|
||||
*/
|
||||
export function linkGueltig(anfrage, now = new Date()) {
|
||||
const heuteTag = heute(now instanceof Date ? now : new Date(Number(now)))
|
||||
const status = anfrage?.status
|
||||
if (status === 'abgelehnt' || status === 'abgelaufen') {
|
||||
const seit = String((status === 'abgelehnt' ? anfrage.abgelehntAt : anfrage.abgelaufenAt) || anfrage.$updatedAt || '')
|
||||
if (!TAG_RE.test(seit)) return true
|
||||
return heuteTag <= plusTage(heute(new Date(seit)), LINK_TAGE_NACH_ABSAGE)
|
||||
}
|
||||
const bis = String(anfrage?.bis ?? '')
|
||||
if (!TAG_RE.test(bis)) return true
|
||||
return heuteTag <= plusTage(bis.slice(0, 10), LINK_TAGE_NACH_ABREISE)
|
||||
}
|
||||
|
||||
export const formMinSekunden = () => {
|
||||
const wert = config.unterkunft?.formMinSekunden
|
||||
return Number.isFinite(wert) && wert >= 0 ? wert : MIN_STANDARD_SEKUNDEN
|
||||
|
||||
Reference in new issue
Block a user