22 Commits

Author SHA1 Message Date
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
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
c1edef8abd feat(magic): RebreakMagic device-binding + DNS profile
- backend: /api/magic/{register,devices,profile,release} + AdGuard provisioning + 24h cooldown
- prisma: magic_binding_fields migration (additive on UserDevice)
- mac-app: Phase 2 - Login + MacRegistration + Profile install
- marketing: landing section + /download/rebreakmagic + DMG
- lyra: forbidden phrases + RebreakMagic coach guidance
2026-06-02 09:15:19 +02:00
chahinebrini
578abfe3bb chore(release): v0.3.13 build 46 / vc36 — DM scroll fix + chat timestamps weekday/days/weeks/months 2026-05-31 07:33:06 +02:00
chahinebrini
f83a13ba60 chore(release): deploy.sh all-platform (MDM/TF/Android) + NEXT_RELEASE-Workflow
- deploy.sh: Android-Signing-Auto-Restore aus build-config/android-signing/
  (gitignored), getestet für MDM + TF + Android
- .gitignore: *.keystore + build-config/android-signing/
- NEXT_RELEASE.md wiederhergestellt mit Notes fürs WA-Chat-Popup + Comment-Likes
  (deploy.sh archiviert es in CHANGELOG + leert es danach)
- buildNumber 27→41, versionCode 18→31 (Release-State)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-30 11:34:57 +02:00
chahinebrini
4135e388ff ui(deploy): reorder progress bar so %, time stay visible on narrow terms
Old layout truncated the critical right-side (1m23s/~3m) on long labels.
New layout puts %, bar, and elapsed/eta on the LEFT, label+subtitle on
the RIGHT where truncation does no harm. Bar shrunk 20→15 chars.
2026-05-30 10:25:24 +02:00
chahinebrini
8f871611f1 feat(deploy): round ETA display (~8m statt ~8m00s)
Baseline aus tmp/.deploy-runtimes wird weiterhin per Run aktualisiert
(genauer Sekunden-Wert im Cache, nur Display gerundet).
2026-05-30 10:21:51 +02:00
chahinebrini
adc506291a fix(deploy): ERR-trap survives set -u (FUNCNAME may be unbound at top-level) 2026-05-30 10:16:11 +02:00
chahinebrini
6255006cad feat(deploy): clean Ctrl+C handler kills background xcodebuild
Without this, Ctrl+C would kill deploy.sh but leave xcodebuild
running as orphan, eating CPU and locking DerivedData.
2026-05-30 10:14:01 +02:00
chahinebrini
24a52a5bae fix(deploy): run_quiet works on bash 3.2 — drop subshell, toggle set -e around wait
- Background subshell '( cmd ) &' + 'wait' interacted badly with
  set -euo pipefail on macOS bash 3.2, killing the script silently
  before the progress-bar's error branch could run
- New approach: just 'cmd &' (no subshell), bracket the whole bg+wait
  region with 'set +e' / 'set -e', then check rc explicitly
- Also adds ERR-trap with call stack + RUN_QUIET_DEBUG=1 fallback
  (streams output directly via tee, useful for debugging build failures)
2026-05-30 10:12:10 +02:00
chahinebrini
9f8e99d287 fix(deploy): preserve rc under set -e (run_quiet swallowed errors silently)
'wait $pid' triggered 'set -e' before 'local rc=$?' could capture exit code,
so xcodebuild failures vanished without any log dump. Use 'wait $pid && rc=0 || rc=$?'
idiom to keep the script alive and let the error-dump branch run.
2026-05-30 10:05:10 +02:00
chahinebrini
061bd2d799 fix(deploy): allow flags before subcommand (./deploy.sh --skip-pods)
Treat $1 as subcommand only if it doesn't start with '-', else default to 'all'.
2026-05-30 10:03:11 +02:00
chahinebrini
77407f9d63 feat(deploy): --skip-pods flag + quiet clean-ios
- clean-ios.sh: new --skip-pods (or SKIP_PODS=1) skips prebuild+pod install
  (use when Pods are already fresh — saves ~30s)
- clean-ios.sh: new --quiet (or REBREAK_QUIET=1) suppresses end-of-run
  'Nächste Schritte' tips (cluttered deploy output)
- deploy.sh: new --skip-pods flag, auto-passes --quiet to clean-ios.sh
2026-05-30 10:01:41 +02:00
chahinebrini
b15ee42a85 fix(deploy): subtitle fallback + realistic runtime seeds
- subtitle now falls back to last non-empty log line when no Compile/Build
  action matched yet (so user sees activity during xcodebuild setup phase
  instead of empty bar at 0%)
- realistic seeds: 22min → 8min for xcarchive (typical RN archive)
2026-05-30 09:55:53 +02:00
chahinebrini
e6e1bab35a fix(deploy): single-line progress bar (no fragile cursor moves)
- previous 2-line render with \033[1A broke when xcodebuild crashed
  early — left mangled output and lost stderr
- new render_progress: ONE line, truncated to $COLUMNS, no cursor moves
- indeterminate mode (no baseline) shows ping-pong bar instead of spinner
- removes 2-line reserve + clear logic in run_quiet
2026-05-30 09:51:49 +02:00
chahinebrini
32d270ccad feat(deploy): brew-style time-based progress bar with runtime-cache
- new render_progress() draws ████████░░░░░░░░ 42% (1m23s / ~3m18s) bar
- runtime_lookup/save persist step durations in tmp/.deploy-runtimes
  (gitignored — auto-learns from successful runs)
- first run = spinner mode (no baseline yet), subsequent runs show real %
- still shows live xcodebuild action (Compiling X.swift) as subtitle
- format_duration helper: 45s / 1m23s readable output
2026-05-30 09:47:48 +02:00
chahinebrini
f48df2a968 chore(deploy): require ASC API-Key, drop app-specific-password fallback, brew-style spinner with live build action
- removes APPLE_APP_SPECIFIC_PASSWORD legacy branches (it never worked for xcodebuild -exportArchive anyway, only altool-upload)
- ASC API-Key now hard-required via require_asc_api_key preflight (fails fast with clear msg + path hint)
- run_quiet: spinner now tails the build log and shows current action (Compiling X.swift, Linking, CodeSign, etc.) as live subtitle — feels like brew/homebrew progress
- .env.deploy.local.example: drop unused fallback section
2026-05-30 09:46:38 +02:00
chahinebrini
b029c00413 chore(deploy): persist iOS auth via .env.deploy.local + ASC API-Key
- deploy.sh auto-sources apps/rebreak-native/.env.deploy.local (gitignored)
  and ~/.config/rebreak/deploy.env as fallback
- new helper xcodebuild_auth_args() injects -allowProvisioningUpdates +
  -authenticationKeyPath/ID/IssuerID into archive + both exportArchive calls
- ASC API-Key (free, .p8 from appstoreconnect.apple.com) is now the
  required path for exportArchive — app-specific-password no longer works
  for export since Xcode 14 (still used as altool-upload fallback)
- .env.deploy.local.example template added with one-time setup steps
- .gitignore: add *.p8 (.env*.local already covered)
2026-05-30 09:39:46 +02:00
chahinebrini
b31066a04c feat(chat): native action sheet + Insta-style heart for DM messages
- ChatBubble: useActionSheet replaces custom Modal (native iOS popup, Android bottom sheet)
- DM mode (isDM prop): hides like-count, shows Insta-style heart badge under bubble when liked
- Group chat unchanged
- Cleanup: remove unused Modal/Platform imports, sheet styles, actionsOpen state
- deploy.sh: auto-detect ANDROID_HOME + auto-create local.properties for local Gradle
- NEXT_RELEASE.md: DM reactions release note
- Includes other staged work across binder-mac, marketing, ops/mdm, ios/
2026-05-30 09:14:32 +02:00
chahinebrini
38df6fc79d feat(chat): push notifications for DMs + rooms
Backend:
- Prisma PushToken model + chat_push_enabled flag on profiles
- Migration 20260530_add_push_tokens (push_tokens table + profile flag)
- Service sendChatPush with expo-server-sdk (auto-disable invalid tokens)
- Fire-and-forget push trigger in sendDirectMessage + createRoomMessage
- API POST /users/me/push-token (upsert) + DELETE (soft-disable)

Client (rebreak-native):
- usePushTokenRegistration hook: permission, getExpoPushTokenAsync,
  Android channel 'chat', POST to backend; idempotent per session
- Notification tap deep-link: dm -> /dm?userId, room -> /room?roomId

Deploy:
- run_quiet spinner for silent altool/xcodebuild/gradle phases
- Release-notes pipeline (--notes flag / NEXT_RELEASE.md / interactive)
  archived to CHANGELOG.md, printed with ASC + Play Console links
- Default version bump ON (--no-bump opt-out), build cleanup
- NEXT_RELEASE.md with push-notification release note
2026-05-30 08:16:45 +02:00