Terminplaner: Zellen nur unter der Ressourcensperre freigeben, gemeinsame Hilfsfunktionen
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e281db1b2b
commit
9ad8515d60
6 files changed
+284
-71
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { createHash, createHmac, randomBytes, timingSafeEqual } from 'node:crypto'
|
||||
import { config } from '../../config.js'
|
||||
import { pruefeNow, pruefeText } from './util.js'
|
||||
|
||||
/**
|
||||
* Terminplaner-Tokens (Spezifikation 2026-10-02-terminplaner-design.md, Abschnitte 4 und 8).
|
||||
@@ -33,16 +34,6 @@ function schluessel(zweck) {
|
||||
return createHmac('sha256', geheimnis).update(zweck).digest()
|
||||
}
|
||||
|
||||
function pruefeText(wert, name) {
|
||||
if (typeof wert !== 'string' || wert === '') throw new TypeError(`${name} fehlt`)
|
||||
}
|
||||
|
||||
function zeitMs(now, name) {
|
||||
const ms = now instanceof Date ? now.getTime() : now
|
||||
if (typeof ms !== 'number' || !Number.isFinite(ms)) throw new TypeError(`${name}: now fehlt`)
|
||||
return ms
|
||||
}
|
||||
|
||||
/** Neues Bestaetigungstoken: token geht in den Link, hash (SHA-256-Hex) in die Buchung. */
|
||||
export function neuesToken() {
|
||||
const token = randomBytes(32).toString('base64url')
|
||||
@@ -74,7 +65,7 @@ function formMac(siteKey, zeit) {
|
||||
/** Formular-Token fuer ein Widget dieses siteKeys, ausgestellt zum Zeitpunkt now. */
|
||||
export function formToken(siteKey, now = new Date()) {
|
||||
pruefeText(siteKey, 'siteKey')
|
||||
const zeit = zeitMs(now, 'formToken').toString(36)
|
||||
const zeit = pruefeNow(now, 'formToken').toString(36)
|
||||
return `${zeit}.${formMac(siteKey, zeit)}`
|
||||
}
|
||||
|
||||
@@ -90,7 +81,7 @@ export function pruefeFormToken(siteKey, token, now = new Date()) {
|
||||
const gegeben = Buffer.from(mac)
|
||||
if (gegeben.length !== erwartet.length || !timingSafeEqual(gegeben, erwartet)) return 'ungueltig'
|
||||
|
||||
const alter = zeitMs(now, 'pruefeFormToken') - parseInt(zeit, 36)
|
||||
const alter = pruefeNow(now, 'pruefeFormToken') - parseInt(zeit, 36)
|
||||
if (alter > FORM_MAX_ALTER_MS) return 'abgelaufen'
|
||||
if (alter < config.termine.formMinSekunden * 1000) return 'zu_schnell'
|
||||
return 'ok'
|
||||
|
||||
Reference in new issue
Block a user