Kontrolle: Bestaetigen per Link prueft Token und Ablauf in der Sperre erneut

Ein Token-Tausch durch die Erinnerung zwischen Pruefung und Sperre ergibt 404 wie bei
einem ungueltigen Link; das Portal ist nicht betroffen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-07 15:20:24 +00:00
1 parent c2245b6905
commit b6c1d81342
3 files changed
+32 -4

No files matched your search

+21 -2
View File
@@ -3,13 +3,13 @@ import assert from 'node:assert/strict'
import { startAppwriteMock } from './support/appwriteMock.js'
import { useTestEnv } from './support/testEnv.js'
import { mailSink } from './support/mailSink.js'
import { AUFTRAEGE_DATETIMES, AUFTRAEGE_SCHEMA, abDokument, kunde } from './auftraegeBestaetigungHilfe.js'
import { AUFTRAEGE_DATETIMES, AUFTRAEGE_SCHEMA, UNGUELTIG, TOKEN_NEU, abDokument, kunde } from './auftraegeBestaetigungHilfe.js'
// bestaetigung.js: Bestätigen (idempotent, unter Sperre) und Widerrufen einer AB; Mails über die Senke
const aw = await startAppwriteMock({ schema: AUFTRAEGE_SCHEMA, datetimes: AUFTRAEGE_DATETIMES, defaultLimit: 25 })
useTestEnv({ appwriteUrl: aw.url, stripeUrl: 'http://127.0.0.1:1' })
const { config } = await import('../server/config.js')
const { auftragToDoc, getAuftrag } = await import('../server/services/auftraege/auftragStore.js')
const { auftragToDoc, getAuftrag, updateAuftrag } = await import('../server/services/auftraege/auftragStore.js')
const { AuftragError } = await import('../server/services/auftraege/fehler.js')
const { FRUEHBEGINN_FASSUNG, FRUEHBEGINN_TEXT } = await import('../server/services/auftraege/texte.js')
const { sperreAuftrag } = await import('../server/services/auftraege/konstanten.js')
@@ -174,6 +174,25 @@ test('bestaetigeAuftrag: ungültiger Weg oder Zeitpunkt wirft TypeError, unbekan
assert.equal(sink.sent.length, 0)
})
test('bestaetigeAuftrag über den Link: ein Token-Tausch (Erinnerung) oder Ablauf zwischen Prüfung und Sperre ergibt 404 wie bei ungültigem Link', async () => {
const alt = seed()
const nichtsGeaendert = async () => {
assert.equal((await getAuftrag('ab1')).status, 'versendet')
assert.equal(sink.sent.length, 0)
}
// die Erinnerung tauscht den Token, nachdem die Route den alten geprüft hat
const { hashToken } = await import('../server/services/auftraege/token.js')
await updateAuftrag('ab1', { tokenHash: hashToken(TOKEN_NEU) })
await assert.rejects(bestaetigeAuftrag(alt, { ueber: 'link', fruehbeginn: false, jetzt: JETZT }), (err) => err instanceof AuftragError && err.status === 404 && err.message === UNGUELTIG)
await nichtsGeaendert()
// der Link ist inzwischen abgelaufen
await updateAuftrag('ab1', { tokenHash: alt.tokenHash, tokenGueltigBis: '2026-10-07T08:29:59.000Z' })
await assert.rejects(bestaetigeAuftrag(alt, { ueber: 'link', fruehbeginn: false, jetzt: JETZT }), (err) => err instanceof AuftragError && err.status === 404 && err.message === UNGUELTIG)
await nichtsGeaendert()
// das Portal braucht keinen Link: dort zaehlt der Token nicht
assert.equal((await bestaetigeAuftrag(alt, { ueber: 'portal', fruehbeginn: false, jetzt: JETZT })).status, 'bestaetigt')
})
// gesendet am 06.10.2026 12:00 Berlin: die Frist endet am 20.10.2026 um 24 Uhr (= 21:59:59,999 UTC)
const FRIST_ENDE = new Date('2026-10-20T21:59:59.999Z')