mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 15:02:04 +00:00
fix(api): narrow swallowed database errors and redact the incident URL
The incident forwarder stripped the query string but not path-segment secrets from the reported URL; route it through the same redaction the message and stack already use. Several delete-and-swallow paths caught every error as the expected unique/absent-row case, masking real failures on security-notification, logout, and integration-disconnect paths and the Telegram reply-consume guard; narrow each to the specific Prisma code and let real failures surface.
This commit is contained in:
1 parent
9aa0a3597a
commit
336ce5aef3
10 files changed
+136
-22
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { timingSafeEqual } from "node:crypto";
|
||||
import { prisma } from "@/lib/db";
|
||||
import { isP2025 } from "@/lib/prisma-errors";
|
||||
import { decrypt } from "@/lib/crypto";
|
||||
import {
|
||||
answerTelegramCallbackQuery,
|
||||
@@ -945,11 +946,19 @@ async function handleTextMessage(update: TelegramUpdate) {
|
||||
context.userId === user.id &&
|
||||
(context.kind === "mood_note" || context.kind === "measure_value")
|
||||
) {
|
||||
// Consume the context row regardless of outcome so a reply can't be
|
||||
// replayed onto the entry twice.
|
||||
await prisma.telegramPromptContext
|
||||
.delete({ where: { id: context.id } })
|
||||
.catch(() => {});
|
||||
// The delete IS the replay guard: consuming the context row is what
|
||||
// stops a redelivered reply from being applied to the entry twice. Make
|
||||
// it authoritative — if the delete fails for any reason OTHER than the
|
||||
// row already being gone (P2025), do NOT apply the reply; abort and let
|
||||
// Telegram redeliver against a still-present row. P2025 means the row
|
||||
// was already consumed, which is the guard succeeding, so proceed.
|
||||
try {
|
||||
await prisma.telegramPromptContext.delete({
|
||||
where: { id: context.id },
|
||||
});
|
||||
} catch (err) {
|
||||
if (!isP2025(err)) return;
|
||||
}
|
||||
const userMsgId = message?.message_id;
|
||||
if (context.expiresAt.getTime() < Date.now()) {
|
||||
const resp = await sendTelegramMessage(
|
||||
|
||||
Reference in new issue
Block a user