359 Commits

Author SHA1 Message Date
chahinebrini
f83e5bf914 Remove broken submodule entry
Some checks failed
ci/woodpecker/push/woodpecker Pipeline failed
Deploy Staging / Build backend (Nitro) (push) Has been cancelled
Deploy Staging / Deploy zu Hetzner (push) Has been cancelled
2026-06-18 07:38:07 +02:00
chahinebrini
c6035b97d9 feat(magic): inline enrollment in device card, remove preflight, align flag order 2026-06-18 07:25:43 +02:00
chahinebrini
e6fad4f51e fix(magic): always show supervised + lock profile true/false; company from exists 2026-06-18 07:10:12 +02:00
chahinebrini
0efdf2f8f1 fix(magic): show complete protection button for known disenrolled devices 2026-06-18 06:28:04 +02:00
chahinebrini
ac7bd800bc fix(magic): inline iPhone search in device card instead of detect page 2026-06-18 06:03:04 +02:00
chahinebrini
2919ce45b8 feat(magic): sync current ReBreak Magic app state
Include recent Magic app work: Tauri native shell, iOS device detection
via supervise-magic sidecar, MDM client, local HTTP server, new pages
(detect, enroll, supervise, sideload, pair, preflight, configure, done),
and updated device section/status UI.
2026-06-18 05:23:26 +02:00
chahinebrini
cb6dd0555a fix(magic): show backend MDM status even when iPhone is not connected via USB 2026-06-18 05:16:22 +02:00
chahinebrini
6245fc4573 fix(magic): real MDM supervised state, mdmId matching, MDM status for unknown USB devices 2026-06-17 23:47:33 +02:00
chahinebrini
75d1b06105 feat(magic): iOS device card warning badge, USB hint, split backend/local cards and auto-sync 2026-06-17 23:32:41 +02:00
chahinebrini
5b0a4d03d2 feat(magic): identify current device via hardwareId, migrate existing devices 2026-06-17 17:18:40 +02:00
chahinebrini
e4b28be5be feat(magic): dedicated iOS section in dashboard with on-demand sync 2026-06-17 07:44:24 +02:00
chahinebrini
48af756a86 tmp(magic): debug logging for current device matching 2026-06-17 03:19:10 +02:00
chahinebrini
b829f9ba3e fix(magic): match current device by session deviceId, remove confusing overall status card 2026-06-17 03:06:38 +02:00
chahinebrini
4c46ac69c9 fix(magic): remove device-release from Magic sheet, Magic does not remove devices 2026-06-17 02:59:05 +02:00
chahinebrini
81c516b831 fix(magic): robust hostname matching for current device detection 2026-06-17 02:52:00 +02:00
chahinebrini
026c319b30 fix(magic): robust device parsing, dashboard only protects current device 2026-06-17 02:29:35 +02:00
chahinebrini
2f1d5ec83c fix(magic): use solid heroicon for star rating 2026-06-16 20:55:25 +02:00
chahinebrini
298a0089bb feat(magic): redesign status dashboard with hero cards and device sheet 2026-06-16 20:53:39 +02:00
chahinebrini
b5e89b5973 feat(magic): add DeviceDetailSheet component 2026-06-16 20:49:39 +02:00
chahinebrini
0258c818f3 feat(magic): add DeviceHeroCard and DeviceListItem components 2026-06-16 20:45:43 +02:00
chahinebrini
118269a8c9 feat(magic): add IosStarRating and CooldownCountdown components 2026-06-16 20:42:59 +02:00
chahinebrini
8953e1f7d6 feat(magic): add useDeviceStatus composable 2026-06-16 20:41:53 +02:00
chahinebrini
8f5e34ae67 feat(magic): expose cooldown commands and extend device types 2026-06-16 20:35:20 +02:00
chahinebrini
2c33ba55a4 fix(backend): username (Login-Identifikator) aus öffentlichen Payloads entfernt
community/posts.get.ts + social/profile/[userId].get.ts lieferten neben
nickname auch username an fremde Clients — username ist der Login-
Identifikator ({username}@rebreak.internal) und verletzt die Nickname-
Anonymitäts-Invariante (REQ-COMM-005 / R-DATA-07) + exponiert das halbe
Login-Credential-Paar. Frontend rendert das Feld nirgends (verifiziert);
totes Typ-Feld in stores/community.ts entfernt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 06:36:16 +02:00
chahinebrini
63fae25531 fix(android-protection): explicit specialUse FGS type — Samsung/Android 16 crash loop
RebreakVpnService.onStartCommand crashed with SecurityException because Android 16's validateForegroundServiceType rejects the implicit 2-arg startForeground(). Now passes FOREGROUND_SERVICE_TYPE_SPECIAL_USE explicitly (Google's documented best practice) and guards the call so a failed foreground promotion stops the service cleanly instead of crashing the app. Verified vs reported Galaxy A54 / Android 16 signature (97% of crash events, 1-user crash loop).

Bundles pending working-tree work across native/marketing/locales/mac + graphify-out rebuild. gitignore: google-services.json + /screenshots/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 22:33:28 +02:00
chahinebrini
c4fe7d356f fix(rebreak-native): iOS app-lock freeze (Face ID stuck, needs hard-quit)
LockScreen could latch on the locked screen with no working Face ID
prompt until a hard-quit. Two coupled causes:
- inFlight/busy could stay latched if authenticateAsync hung when called
  mid active↔inactive transition → gate tryUnlock on AppState 'active'
  and release the latch on background (iOS tears down the sheet anyway).
- foreground recovery missed background→inactive→active (prev was
  'inactive' at the active event) → track "was backgrounded since last
  active" instead, so re-prompt fires reliably (this is why only
  hard-quit recovered it). The Face ID sheet's own active→inactive→active
  no longer re-triggers (only real 'background' arms the flag).
- appLock.authenticate wraps authenticateAsync in try/catch so a native
  reject always settles (the LockScreen finally relies on it).

cancelAuthenticate() is Android-only (no iOS native impl) — fix works by
prevention + self-heal, not cancellation. Frontend-only; needs a native
rebuild, no deploy.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 15:11:12 +02:00
chahinebrini
80b6e2399b fix(marketing): leere /preview-Seite (nacktes <template> rendert nicht)
Beim Entfernen des Client-Gates blieb ein <template> ohne Direktive als Wrapper
um den gesamten Inhalt stehen. Vue 3 rendert ein direktivenloses <template> an
dieser Stelle nicht → komplett leere Seite. Wrapper entfernt, Inhalt liegt jetzt
direkt im Root-<div>. Verifiziert: Header + Hero rendern in Safari.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 05:27:24 +02:00
chahinebrini
5fb441817f feat(magic): RE-hardening Quick Wins (ACL, #if DEBUG guards, rate-limit)
Härtung der öffentlich downloadbaren Magic-Apps gegen Reverse Engineering
(Assessment: docs/specs/magic-re-hardening.md):
- Windows: protection.json per ACL auf SYSTEM+Admins (DNS-Token nicht mehr von
  Standard-Usern lesbar) — setup.rs
- Mac: MacProfileInstaller.remove() + Debug-Supervision-Modi/Reset nur noch
  #if DEBUG (kein Removal-/Debug-Pfad im Release-Binary)
- Mac: staging-URL einmal als Konstante statt 4x Literal; interne Infra-Notizen
  aus String-Literalen raus
- Backend: Rate-Limit (10/IP/min) auf /api/magic/pair/redeem

NUR Backend-Teil deployt via Push; Mac/Win brauchen Xcode-/Cargo-Release-Build
(zied) + Smoke-Tests vor Release. MagicAPIClient.swift trägt etwas vorbestehenden
WIP mit (gleiche Magic-Client-Domäne).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 05:19:10 +02:00
chahinebrini
8da782339e refactor(marketing): /preview-Zugriffsschutz via nginx Basic-Auth statt Client-Gate
Client-seitiges Passwort-Gate entfernt: schrieb das Passwort ins offen
erreichbare JS-Bundle (= Leak, identisch zum nginx-PW) und verursachte doppelte
Passworteingabe. Schutz läuft jetzt serverseitig via nginx auf /preview (Seite +
Bilder). Ein Passwort, kein Leak.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 05:03:14 +02:00
chahinebrini
9fdb0d3a2e feat(marketing): passwortgeschützte /preview App-Vorschau für FAGS/Ilona
Private, noindex App-Tour mit Client-seitigem Passwort-Gate (Cookie). 16 echte
Screenshots (Onboarding, Blocker, Block-Seite, Lyra, Atemübung, Mail-Schutz +
-Connect, Community-Feed/Chat/Anruf, Streak, Geräte, Eigene Domains, Admin-
Moderation) via PreviewPhone-Mockups. Admin-Shot als Handy-Rahmen (PreviewPhone).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 04:39:02 +02:00
chahinebrini
4987d05f10 fix(native): per-device bypass gate + 300k copy + locale/marketing polish
- protection.ts: gate recoveringFromBypass on a local 'everActiveHere' flag,
  set after a successful activateUrlFilter(). The 'protection off' sheet + tamper
  push no longer fire on fresh devices/sims where protection was never activated
  locally. Root cause: backend protectionShouldBeActive is the account DEFAULT
  (only false after a held cooldown), not an 'ever active' signal.
- locales: blocklist size 208k -> 300k (native de/en/fr/ar + marketing de/en).
- bundles already-deployed prior polish living in these files: native wording
  (clean->spielfrei, DiGA wording), marketing de-AI pass (live on prod).
- NEXT_RELEASE.md seeded for the next app release.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 03:05:16 +02:00
chahinebrini
579eb5b5e0 fix(deploy): ENOTEMPTY-Halbwipe von android/ verhindern
clean-ios.sh rief 'expo prebuild --clean' ohne --platform → wollte auch android/
löschen. Hält ein Gradle-Daemon android/build|.gradle offen, failt 'rmdir android'
mit ENOTEMPTY und hinterlässt ein halb-gewischtes android/ (Source weg, gelocktes
build/ bleibt) → späterer Release-Build failt mit "autolinking.json doesn't exist".

- clean-ios.sh: 'prebuild --clean --platform ios' → android/ wird beim iOS-Clean
  gar nicht mehr angefasst.
- deploy.sh: release_android_locks() (gradlew --stop + GradleDaemon-kill + rm
  build/.gradle) läuft vor dem android-prebuild --clean in ensure_native_dir.

Ergänzt den ensure_native_dir-Self-Healing-Fix (fe6a63b): jetzt wird der Halbwipe
nicht nur erkannt+repariert, sondern an der Quelle verhindert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 08:00:20 +02:00
chahinebrini
fe6a63bd8d chore(release): v0.4.4 (versionCode 70) + deploy.sh self-healing
- Release 0.4.4 zu Play Internal Testing (Android Tamper-Lock-Präzision +
  a11y-Onboarding-Guide), Notes ins CHANGELOG archiviert.
- deploy.sh ensure_native_dir jetzt self-healing: prüft Marker-Datei
  (android/app/build.gradle bzw. ios/Podfile) statt nur ob der Ordner
  existiert. Ein halb-gewischtes native-Verzeichnis (nur build/-Output) wird
  erkannt und via 'expo prebuild --clean' sauber regeneriert, statt mit
  "autolinking.json doesn't exist" zu failen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 07:52:10 +02:00
chahinebrini
4a013bc43b feat(android-protection): präzise Tamper-Lock + a11y-Onboarding-Guide
Tamper-Lock von Keyword-Scanning auf präzise Einzel-Surfaces umgebaut:
blockt nur ReBreaks eigene Screens (Admin-Deaktivierung via DeviceAdminAdd,
a11y-Ausschalten, VPN-Trennen/Surface), nie Listen oder fremde Apps.

- Deny-Removal = Admin-only: OS graut Uninstall+Force-Stop für aktiven
  Device-Admin aus; einziger Bypass (Admin deaktivieren) bleibt a11y-gesperrt.
  Andere Apps verwalten/force-stoppen/deinstallieren bleibt komplett frei.
- a11y-Onboarding: passiver Bottom-Overlay-Hinweis + Settings-Reset auf
  Startseite nach Aktivierung + 1s-Delay vor App-Rückkehr.
- VPN-Trennen-Dialog + a11y-Ausschalten neu abgedeckt.
- a11y-Service-Icon im Plugin (klar als ReBreak erkennbar).

Verifiziert auf A50 per logcat: alle 4 Surfaces blocken, Listen + fremde
Apps frei, keine False-Positives.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 04:05:41 +02:00
chahinebrini
ca72437f18 fix(native): zwei Circles + animierter Gesamt-Verteilungs-Balken drunter
Statt Half-Donut (Höhen-Mismatch mit Circles): zwei volle Circles (Mobil/Computer)
+ darunter ein eigener animierter Balken (grün/blau-Segmente, gleiche Easing/Dauer
wie die Ringe) mit Legende. Kein native-Default.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:36:04 +02:00
chahinebrini
c3478f4743 fix(native): Gesamt-Verteilung als Half-Donut, 2 Circles + 1 Donut (gleiche Größe)
DeviceSlotDonut bekommt half-Modus. Reihenfolge: Mobil-Circle, Computer-Circle,
Gesamt-Half-Donut (Mobil/Computer-Anteil als zwei Bögen). Alle SIZE×SIZE.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:30:08 +02:00
chahinebrini
77ce5e5a80 feat(native): dritter 'Gesamt'-Ring mit Mobil/Computer-Verteilung
DeviceSlotDonut auf Segment-API umgestellt (Mehr-Segment-Bögen). Gesamt-Ring
zeigt belegte Slots gesamt + farbliche Verteilung (Mobil grün / Computer blau).
Labels gekürzt (Mobil/Gesamt/Computer) für 3-across-Layout.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:25:40 +02:00
chahinebrini
227c30c3c9 fix(native): Slot-Ringe kleiner+dicker+langsamer, 'Lückenloser Schutz'-Text raus
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:18:41 +02:00
chahinebrini
e2e5a1003c feat(native): Geräte-Slots als Progress-Ringe + Status-Pill in der Liste
- Slots: zwei animierte volle Progress-Circles (Mobil/Computer) statt Balken,
  via react-native-svg (keine neue Lib)
- Status-Zeile pro Gerät: Online (grün) / Cooldown · noch Xh (amber, aus
  releaseRequestedAt) / Ungeschützt (rot) — ersetzt Footer + StatusBadge

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:17:05 +02:00
chahinebrini
e0eb1711db feat(native): Geräte-Liste informativ — Trash/Menü raus, chevron-forward → Detail
Entfernen passiert am Gerät selbst (Cooldown, win-App/Mac), nicht aus der
Liste gesteuert. Row-Pfeil öffnet nur das Info-/Detail-Sheet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-08 00:05:23 +02:00
chahinebrini
4dfcfc4012 feat(marketing): 14-Tage-Trial-Klarheit + OS-aware Magic-Download
- Hero/Final-CTA: 'kostenlos starten' -> '14 Tage kostenlos testen' + Subline
  'danach ab 3,99€/Monat, jederzeit kündbar' (löst free-vs-Preis-Verwirrung;
  Trial existiert bereits Stripe-seitig + Pricing nennt ihn)
- useOS()-Composable + OS-aware RebreakMagic-Download: Windows-Besucher ->
  /download/windows, Mac/sonst -> /download/rebreakmagic

Deployed: rebreak.org via deploy-marketing.sh

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 23:03:37 +02:00
chahinebrini
e0cb0517fc feat(marketing): cross-device pricing-hero + Header-Nav statt Tabbar (live prod)
- Pricing: Device-Hero-Reihe (iPhone/Android/Mac/Windows) + Tagline 'ein Abo,
  alle Geräte' — heroicons (offline gebündelt)
- Layout: Floating-Tabbar raus -> Header-Nav (Desktop) / Hamburger (mobil)
- Locales: cross_device_tagline + Geräte-Matrix-Texte

Deployed: rebreak.org (marketing-prod) via deploy-marketing.sh

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 22:56:14 +02:00
chahinebrini
7ad8625d8e feat(marketing): Windows-PC-Schutz Download-Seite + Installer
- /download/windows: eigene, korrekt geframte Windows-Seite (PC-DNS-Schutz,
  nicht iPhone-Supervision)
- Installer in public/downloads/RebreakMagic-Setup.exe (3,7 MB, aus CI-Artefakt)
- deploy-marketing.sh: --info=progress2 -> --progress (macOS-rsync-kompatibel)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 22:40:25 +02:00
chahinebrini
2c1eecd1f7 feat(native): geräte-spezifische PNG-Icons (iphone/android/macbook/computer)
deviceImage()-Helper mappt Plattform→assets/devices/*.png; ersetzt Ionicons
in Geräte-Rows, MagicSheet und Detail-Sheet.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 22:40:25 +02:00
chahinebrini
a95e66560d feat(magic): Hard-Lock + Geräte-UX (Push, Realtime, Detail-Sheet, Offline-Removal)
Devices/Magic:
- Offline-Profil-Enroll deaktiviert (410) — Lock-PW würde im Klartext im
  Download landen; stationärer Schutz läuft jetzt nur über Rebreak Magic
- Mac-DNS-Template: ProhibitDisablement (Filter nicht abschaltbar)
- Push "Neues Gerät verbunden" an mobile Geräte bei neuer Bindung
- Realtime auf user_devices → Settings aktualisiert Magic-Bindings live
- Geräte-Detail-Sheet (Tap auf Gerät): Status, verbunden-seit, Schutz-Donut

Hard-Lock (server-gehaltenes Removal-PW, User sieht es nie):
- magic_removal_password generiert/gespeichert + in Profil injiziert (Lazy-Backfill)
- Reveal NUR bei Account-Löschung (user/delete) + Kündigung (stripe webhook),
  per Resend-Mail + in-Response
- Signing config-gated (inaktiv ohne Cert; Lock greift auch unsigniert)

Migrations: user_devices-Realtime-Publication + magic_removal_password-Spalten

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 22:26:25 +02:00
chahinebrini
869d8afd30 fix(magic-win): keyring plattform-spezifisch (apple-native bricht Windows-Build)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:45:04 +02:00
chahinebrini
4b4b9fc63b feat(magic-win): ReBreak Magic Windows-App (Tauri) + CI-Build
Tauri 2 DoH-Schutz für Windows: PowerShell-DoH-Takeover, Tamper-Service
(SYSTEM, windows-service), Browser-Policies (Chromium built-in-DNS + eigenes
DoH aus → OS-Resolver), 24h-Cooldown via bestehende magic/*-Endpoints.
GitHub-Actions baut den x64-NSIS-Installer auf windows-latest.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:39:52 +02:00
chahinebrini
96e1b8368c feat(lyra): deterministisches Krisen-Sicherheitsnetz (R-LYRA-01)
LLM-unabhaengiges Sicherheitsnetz fuer Lyras SOS-Pfad, schliesst das
Top-Risiko der Risiko-Akte (verpasste Krise, ISO 14971 R-LYRA-01).

Backend:
- crisis-filter.ts: deterministische Krisen-/Suizid-Erkennung (DE primaer,
  EN/FR/AR Grundabdeckung) auf den letzten User-Nachrichten, synchron, kein LLM
- sos-session.post: liefert crisisLevel sofort an die App (vor Stream-Start)
- sos-stream: sendet bei Krise zuerst 'crisis_chips' (BZgA/112/Telefonseelsorge);
  Fallback an 3 Stellen (LLM-Fehler/Abbruch/keine Chips) -> nie leerer Screen
- 43/43 Unit-Tests (crisis.json positiv, harmless.json False-Positive-Guard)

Frontend (urge.tsx):
- permanente rote Krisen-Bar oben, durch LLM-Chips nicht ueberschreibbar
  (eigener State-Slot), Hotline-Chips als tel:-Links
- neue Locale-Strings DE/EN

Risiko-Akte: R-LYRA-01 Restrisiko HOCH -> MITTEL.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 07:56:34 +02:00
chahinebrini
c7fc237dfd feat(android-protection): device-admin uninstall-block + boot-receiver + config plugin
Android self-bind protection auf nahezu MDM-Niveau ohne Device-Owner:
- Device-Admin (RebreakDeviceAdminReceiver) blockt Uninstall OS-seitig, aktiv ab
  Boot ohne Prozess/a11y. Deaktivierung nur via 24h-Cooldown (removeDeviceAdmin in
  forceDisable). a11y blockt die DeviceAdminAdd-Settings-Seite (Class-Match, auf
  Samsung One UI per Logcat verifiziert).
- Boot-Receiver (RebreakVpnBootReceiver) startet VPN+a11y nach Reboot, damit der
  Tamper-Lock ohne manuellen App-Start hochkommt.
- Manifest-Wiring (Device-Admin-Receiver, Boot-Receiver, RECEIVE_BOOT_COMPLETED,
  device_admin.xml) ins with-rebreak-protection-android Config-Plugin verlagert →
  ueberlebt 'expo prebuild' (android/ ist gitignored).
- a11y-Detection zurueck auf die funktionierende Version: zu breites 'loeschen'-
  Uninstall-Keyword raus (blockte halbe Settings); a11y-Label jetzt 'ReBreak Schutz'.
- a11y-Deeplink behaelt den Samsung-Step-Guide (openAccessibilitySettings).

Session-Frontend in diesem Batch:
- Avatar-Placeholder: neutrales clarity-avatar-line SVG statt dominantem Blau.
- DiGA-Milestone folgt kumulativen protectedDays (erreicht rueckfall-anfaellige User).
- Dev-Build crasht nicht mehr ohne CallKit-Native-Modul.
- VPN-Permission-Dialog nur noch im Bypass-Fall.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 04:52:49 +02:00
chahinebrini
6a3c1e13da feat(lyra): admin DiGA-reminder post category
New 'erinnerung' topic for manual Lyra community posts that gently remind
users they can add optional, anonymous profile details. Wording stays
jargon-free (no 'DiGA'/'data'/'study'). Manual-only, not in the auto-cron
catalog.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 00:11:01 +02:00