rebreak-monorepo/backend/server/api/protection/dev-force-disabled.post.ts
chahinebrini 56bb59915d feat(debug,protection): Force Reset for Android screenshot-capture
Bug-context: user reports nach Cooldown-Disable auf v0.2.1 Android-Build
reactiviert sich Schutz auto → a11y-Settings bleibt blockiert → keine Screenshots
möglich. v0.3.0 hat den Backend-protectionDisabledAt-Guard der das verhindert,
aber Test-Devices brauchen ein direktes Reset-Tool für Multi-Locale-Screenshots.

Backend:
- POST /api/protection/dev-force-disabled — sets protectionDisabledAt=NOW()
  ohne Cooldown-Vorlauf. Production-Guard (rebreak.org-non-staging → 403).

Frontend:
- /debug Android-Section refactored: "Force Reset + Settings öffnen" Button
- Bundle aus 3 Steps:
  1. native forceDisable (VPN stop + tamper disarm + filter_enabled=false)
  2. backend dev-force-disabled (Anti-Auto-Reactivation-Mark)
  3. Settings → Bedienungshilfen öffnen
- Danach: User toggled ReBreak-Service in Android-Settings manuell off
  → frischer a11y-deep-link-Trigger für nächste Screenshot-Iteration

Also: fix /onboarding/welcome → /onboarding (Duo-Rewrite hat den alten Pfad
gelöscht). Route 404 auf Android sichtbar wenn User in debug-toggle 'welcome'
oder 'nickname' tappt.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-17 22:33:40 +02:00

38 lines
1.2 KiB
TypeScript

import { requireUser } from "../../utils/auth";
import { usePrisma } from "../../utils/prisma";
/**
* POST /api/protection/dev-force-disabled
*
* DEV/STAGING-ONLY: Setzt protectionDisabledAt = NOW() ohne Cooldown-Vorlauf.
* Frontend-Debug-Button für Screenshot-Capture (Android-a11y-reset-flow).
*
* Production-Guard: appUrl enthält "rebreak.org" aber NICHT "staging" → 403.
*
* Sobald gesetzt:
* - /api/protection/state gibt protectionShouldBeActive=false zurück
* - Frontend's enforceProtection-Loop feuert KEINE Auto-Reactivation mehr
* - User kann a11y-Settings öffnen und manuell den ReBreak-Service off-toggeln
*
* Zum Wiedereinschalten: POST /api/protection/mark-active (clear flag).
*/
export default defineEventHandler(async (event) => {
const user = await requireUser(event);
const config = useRuntimeConfig(event);
const appUrl = (config.public?.appUrl as string) ?? "";
const isProductionUrl =
appUrl.includes("rebreak.org") && !appUrl.includes("staging");
if (isProductionUrl) {
throw createError({ statusCode: 403, message: "dev-only" });
}
const db = usePrisma();
await db.profile.update({
where: { id: user.id },
data: { protectionDisabledAt: new Date() },
});
return { success: true };
});