Commit Graph
110 Commits
Author SHA1 Message Date
esefxdzandClaude Opus 5 9d67679fa8 fix(app): do not throw from ConnectionSettings.initialize
The migration write is best-effort again. `_mode` is already the safe TUN
default in memory by the time it runs, so a failed write leaves nothing
insecure -- it only means the migration is retried on the next launch.

Throwing there was a startup brick rather than a fail-closed guard.
`initialize()` is awaited from `main()` at lib/main.dart:19, before
`runApp()`, with no try/catch and no `runZonedGuarded`; `FlutterError.onError`
and `PlatformDispatcher.onError` are installed later and would not catch it
either. The branch also runs on every fresh install, since `storedMode` is null
and `null != 'tun'`. A `setString` returning false would therefore have meant a
black screen with no error UI, repeating every launch, in exchange for no
security benefit.

Also restores two comments this PR removed from code it does not otherwise
touch -- the `_reconnect` note on why the repair path shows no rewarded ad, and
the explanation of how an orphaned proxy outlives the app process -- and drops
a stray 'ass' from the legacy-values comment.

The `setMode` half of the PR is unchanged: persisting before mutating memory
and surfacing failures to the UI is the right behaviour.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019HT2x2JvJNg7XNsJubfHFf
2026-09-06 11:51:52 +03:00
Naveax 3f7aead263 fix(app): fail closed on invalid connection mode state
Restore SOCKS5 only from the current proxy value and keep UI state unchanged when persistence fails.
2026-09-06 11:51:52 +03:00
Naveax b6ed976346 fix(app): harden Hivemind control-plane trust boundaries (#8)
Bound and nonce-bind control responses, reject redirects, and pin session tunnel coordinates so control-plane compromise cannot redirect VPN traffic.
2026-09-06 11:34:06 +03:00
esefxdzandClaude Opus 5 bd41a3c693 refactor(app): drop Dart wrappers whose native handlers no longer exist
#17 removed the `setSessionExpiry` and `isVpnRuntimeAlive` MethodChannel
handlers from MainActivity, and #18 removed their last callers. The Dart
wrappers stayed behind.

Both swallow their errors, so a future caller would not fail loudly — it would
get a silent no-op from `setSessionExpiry` and a permanent
`processAlive: false` from `runtimeState()`, which previously read as "the
tunnel is dead". Deleting them keeps that trap out of the codebase.

`VpnRuntimeState` goes with them; runtime liveness now arrives through the
native status stream, which is generation-scoped. The battery-optimisation
methods are untouched and still used by background_reliability.dart.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019HT2x2JvJNg7XNsJubfHFf
2026-09-06 11:28:52 +03:00
esefxdzandClaude Opus 5 061bd41920 Merge pull request #19 from Naveax/pr/add-android-supply-chain-ci
build: add reproducible Android release verification

Resolved a conflict in android/app/build.gradle.kts. #19 was written against
the pre-#10 file and re-added the pub-cache patch tasks that #10 deleted; only
`sha256Hex()` was kept from that block, since `verifyReleaseAppConfig` needs it.

Also restored `import java.io.File`, which #10 removed along with the patch
tasks. #19's `sha256Hex(file: File)` names the type in its signature, and
Kotlin does not auto-import `java.io.File`, so the release build would have
failed at Gradle configuration without it.

Verified after resolution: no orphaned references to `projectRootDir`,
`localProperties`, `flutterSdkPath` or `patchFlutterVless`; both tests in
test/release_verification_regression_test.dart pass; `flutter analyze` reports
no errors or warnings.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019HT2x2JvJNg7XNsJubfHFf
2026-09-06 11:27:28 +03:00
Naveax ba89e35442 fix(app): harden session runtime lifecycle (#18)
Scope asynchronous connect, disconnect, sync, and reattachment work to the active session so stale work cannot mutate newer VPN state.
2026-09-06 11:24:03 +03:00
Naveax 321bbae44d fix(app): align Android VPN runtime integration (#17)
Remove obsolete UI-process runtime plumbing and reuse the native service-owned notification and generation-scoped control path.
2026-09-06 11:23:55 +03:00
Naveax 5f851f3485 build: vendor pinned flutter_vless Android runtime (#10)
Replace build-time pub-cache mutation with a repository-owned pinned runtime so reviewed native source is the source compiled into the app.
2026-09-06 11:23:48 +03:00
esefxdzandClaude Opus 5 e818d54b0e build(config): delete orphaned assets instead of narrowing the manifest
#16 replaced the `assets/` wildcard with three explicit paths. That is correct
today but makes the failure mode for a forgotten registration an `Unable to load
asset` exception at runtime rather than at build time, which neither
`flutter analyze` nor the build would catch.

Restore the wildcard and delete the three files it was working around instead.
All are unreferenced in tracked source: `logo.png` has no callers and no
`flutter_launcher_icons` config, while `notification_icon.png` and
`notification_banner.png` are stale copies of the real Android drawables in
`android/app/src/main/res/`, which the notification reaches via
`R.drawable.notification_status_icon` and never through the Flutter bundle.

Same APK-size win, no hand-maintained list, and the dead files leave the repo.

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_019HT2x2JvJNg7XNsJubfHFf
2026-09-06 11:20:08 +03:00
Naveax 74e522e982 build(config): remove unused Flutter dependencies (#16)
Remove dependencies and asset declarations that are no longer referenced so the resolved package graph stays smaller and easier to verify.
2026-09-06 11:18:43 +03:00
Naveax d2283c07cc fix(app): enforce authenticated ephemeral local SOCKS5 (#9)
Require the active per-session loopback SOCKS credentials and remove unauthenticated fallback behavior from the client diagnostic path.
2026-09-06 11:18:35 +03:00
Naveax ecdf6e549f refactor(app): remove unsupported server selector state (#6)
Remove UI and provider state that does not control the authoritative tunnel destination while preserving the existing connection-health status behavior.
2026-09-06 11:18:28 +03:00
Naveax 6da601b565 fix(app): persist disclosure acknowledgement after acceptance (#5)
Write the disclosure preference only after explicit confirmation so failed persistence does not create a false accepted state.
2026-09-06 11:18:24 +03:00
Naveax 14403e1d76 fix(app): make ConnectButton listener lifecycle-safe (#4)
Keep the exact VpnConnection instance used for listener registration so lifecycle cleanup does not depend on a deactivated BuildContext.
2026-09-06 11:17:19 +03:00
Naveax 915f8260d5 build: add reproducible Android release verification
Pin Gradle inputs and dependency metadata, then enforce analyze, lint, build, R8, immutability, and focused regression gates in CI.
2026-09-04 02:01:21 +03:00
esefxdz 9ac236a981 feat(app): OS session-expiry enforcement, session persistence, support sync
Enforce session expiry at the OS level (AlarmManager + handler) so the tunnel dies even if the UI process is killed; persist the session so a START_STICKY restart re-establishes it; sync immediately after a support top-up; slow the session beacon 5s/30s -> 60s/60s; drop the Always-on-VPN deep-link and the legacy 'ass' migration. Docs: CHANGELOG 3.3.4, privacy-policy log disclosure, README.
v3.3.4
2026-09-02 20:33:33 +03:00
esefxdzandClaude Opus 5 dfeb7f161c fix(app): resume the session clock when attaching to a live tunnel
The clock sat at 00:00:00 on a connected tunnel, and the notification
countdown froze with it.

SessionTimer is built lazily, so when the app reattaches to a tunnel that
outlived its UI process, VpnConnection had already reported CONNECTED
before the timer existed. A change listener does not replay events it was
not present for, so the timer never learned it should be running. The
notification text is pushed by that same timer, which is why the countdown
froze at the same moment -- one cause, both symptoms.

The timer now evaluates the current connection state once at construction
rather than waiting for a transition, and is created eagerly alongside
VpnConnection so it is listening from the start.

Resuming also no longer requires adoptedRunningRuntime or a previous
successful sync. Both are false in a freshly started process, which is
exactly the case that needed to work. A connected tunnel with a stopped
clock is now always resumed.

Version 3.3.3+29.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-09-01 00:39:22 +03:00
esefxdzandClaude Opus 5 186dc906da feat(app): keep the tunnel alive via the OS, drop the workarounds
3.3.1 could display "connected" against a tunnel that was no longer
running, with a frozen countdown and no traffic. Three causes, and the
fix for each removes more code than it adds.

Liveness was read from getConnectedServerDelay(), which measures through
AppConfigs.V2RAY_CONFIG?.LOCAL_SOCKS5_PORT ?: 10807. AppConfigs lives in
the :RunSoLibXrayDaemon process, so from the UI process it is always null
and the port always fell back to 10807 -- accidentally correct while the
SOCKS port was fixed, permanently wrong once 3.3.1 made it ephemeral.
Liveness now comes from the OS: is our service process running, and is a
VPN transport actually present.

The foreground notification (id 1) is owned by XrayVPNService via
startForeground, but MainActivity was posting to the same id from the UI
process. When that process died its notification stayed on screen with
nothing left to update it. MainActivity now refuses to post for a dead
runtime and clears the stale notification instead.

Nothing ever asked Android for permission to stay alive. Adds the
battery-optimisation exemption prompt and a deep link to Always-on VPN --
the two sanctioned mechanisms for background survival, each needing one
user tap.

Removes Standard/Extreme resilience and the runtime-restart machinery:
recovery ran off a disconnect broadcast delivered to the app process, so
it could never fire when Android killed that process. Removes startup
restoration and the config-snapshot rebuild along with it; with the OS
keeping the tunnel up there is nothing to restore.

Version 3.3.2+28.

Co-Authored-By: Claude Opus 5 <[email protected]>
v3.3.2
2026-09-01 00:16:05 +03:00
esefxdzandClaude Opus 5 ac52681452 docs(changelog): rewrite 3.3.1 against the shipped tree
The notes described PR #2 as opened, not what is being merged. Removed the
entries for per-app routing, the installed-apps bridge and the app picker
-- all dropped in the debloat -- and moved the rationale to a Removed
section. Replaced the overstated validation claims with measured ones, and
documented the startup-restoration fixes.

Co-Authored-By: Claude Opus 5 <[email protected]>
v3.3.1
2026-08-31 23:31:51 +03:00
esefxdzandClaude Opus 5 ebaa2fc516 chore(test): remove the regression test suite
Removed at the maintainer's request. The four tests covered the auto->tun
and ass->proxy preference migrations, secure SOCKS session generation, and
the patched Xray SOCKS authentication schema.

Note that nothing now guards the build-time patchers against schema drift;
their fail-closed anchors are the only remaining check.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 23:31:51 +03:00
esefxdzandClaude Opus 5 6fcde9dd7b refactor(app): debloat 3.3.1 and fix startup restoration
Maintainer changes on top of PR #2 (Naveax). Reduces the release to two
deliberate connection modes and resolves the issues found in review:

- Lock-screen privacy: move VISIBILITY_PRIVATE and a generic publicVersion
  into MainActivity.updateVpnNotification. The PR's fix lived in an
  unreferenced class and never reached the live notification.
- Haptics: restore the default to off, and reduce HapticSettings to a
  single success() on connect/disconnect via the native channel.
- SOCKS5: make it a real proxyOnly local-proxy mode rather than a TUN
  connection under a different label. TUN stays the default.
- Health probe: restore the idle-only guard so /health is no longer polled
  every 30s while connected.
- Recovery: add a _connectionEpoch counter so connect() aborts an
  in-flight Extreme recovery.
- Startup restoration: rebuild the recovery snapshot from the still-active
  session after an app-process restart (TUN), and surface an honest
  orphaned state with a Reconnect action in proxy mode.

Drops per-app routing entirely. It only ever functioned in TUN --
addDisallowedApplication lives inside the VPN-interface setup that
proxyOnly skips -- and its allowlist half had no Dart caller.

Also removes flutter_local_notifications, the global tap-haptic surface,
and unused runtime telemetry.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-31 23:31:51 +03:00
esef a71161e7e5 Merge pull request #2 from Naveax/release/3.3.1
feat(app): release 3.3.1 with secure routing and runtime resilience
2026-08-31 23:30:43 +03:00
Naveax da82a833cb docs: document 3.3.1 release changes
Document the client routing, secure SOCKS5, runtime resilience, lifecycle, notification and migration changes so reviewers can compare the 3.3.1 release against 3.3.0 without reconstructing the behavior from implementation commits.
2026-08-31 20:31:35 +03:00
Naveax 0ab008b80b fix(app): hide session metadata from public lock screen
Keep the ongoing VPN notification visible while marking its timer and speed content private so Android does not expose session metadata in public lock-screen previews.
2026-08-31 20:24:04 +03:00
Naveax f7f425517c build(config): increase gradle heap for release builds
Raise the Gradle heap to 4 GB and cap workers at two so Jetifier and Kotlin release compilation do not exhaust memory while processing Flutter engine artifacts.
2026-08-31 20:22:05 +03:00
Naveax 76bf84453f build(config): bump app version to 3.3.1
Set the release version to 3.3.1+27 for the upstream 3.3.0 follow-up release.
2026-08-31 19:47:23 +03:00
Naveax 6c99366602 test(app): cover routing and secure socks migrations
Cover legacy Auto and ASS preference migration, authenticated SOCKS session generation and the stock-runtime Xray SOCKS schema so future runtime changes cannot silently restore the old fixed-port/no-auth behavior.
2026-08-31 19:47:05 +03:00
Naveax 8ead3ff249 feat(app): add secure routing and runtime resilience
Add explicit TUN and SOCKS5 connection modes, app routing controls, authenticated per-session local SOCKS5, Android network monitoring, persistent haptics, resilient session recovery, notification hardening and client-side Hivemind cleanup.

Keep the hosted flutter_vless_android 1.1.5 runtime as the base and apply the Android compatibility/security patches at build time instead of restoring the unstable vendored runtime.
2026-08-31 19:31:12 +03:00
esefxdz 371db8da9f docs: make app_config.example github owner/repo placeholders unambiguous 2026-08-30 15:43:39 +03:00
esefxdz 8a89af3c62 docs: mark 3.3.0 as released in CHANGELOG v3.3.0 2026-08-30 15:30:14 +03:00
esefxdzandNaveax 62104d5730 chore: release 3.3.0 (sidebar nav fix, notification countdown, hardening)
Co-authored-by: Naveax <[email protected]>
2026-08-30 14:01:52 +03:00
esefxdz 4eb1fca666 Merge branch 'main' of https://github.com/esefxdz/ReVoltVPN 2026-08-22 11:34:39 +03:00
esefxdz 71468f7594 frontend polish and security review changes 2026-08-22 11:34:17 +03:00
esef 6adf03f920 Update README.md 2026-08-11 17:46:32 +03:00
esefxdz 5642b0b811 Merge branch 'main' of https://github.com/esefxdz/ReVoltVPN 2026-08-08 14:32:40 +03:00
esefxdz 096fbf5a97 docs: update privacy policy for V3 model and in-app disclosure 2026-08-08 14:31:54 +03:00
esef 6c137245fd Revise obfuscation details in README
Updated obfuscation description to generalize the TLS spoofing. because we no longer use github
2026-08-08 14:30:09 +03:00
esefxdz cc819abc41 chore: bump to 3.2.2+25 (discord link fix, apk release) 2026-08-08 14:23:13 +03:00
esefxdz d696bda63f discord link fixed v3.2.2 2026-08-08 14:21:53 +03:00
esefxdz 61c72b2200 feat: first-launch data disclosure dialog (v3.2.1+24) 2026-08-08 13:49:00 +03:00
esefxdz 54f949ca8e v3.2.0 — DPI hardening, notification consolidation, disconnect refactor
User-Agent spoofed to Chrome on Android (was Dart/3.x). Domain renamed to userevolt.app. Branding to Revolt VPN. Removed duplicate notification, patched flutter_vless for custom icon + dark background. Merged 5 disconnect paths into single idempotent gate, fixed stopVless timeout silently lying about state. Removed kDebugMode guard from AdMob bypass.
2026-08-08 13:06:19 +03:00
esefxdz cf50c3a01b chore: bump version to 3.1.0+22 2026-08-06 23:09:56 +03:00
esefxdz 04ec8ac5d1 feat: settings screen, haptic toggle, rain/lightning toggles, review docs 2026-08-06 23:08:26 +03:00
esefxdz 56ea53e73b fix: RenderFlex overflow, circular import, remove timer spinner 2026-08-06 22:09:14 +03:00
esefxdz 143f5f4eff Merge branch 'main' of https://github.com/esefxdz/ReVoltVPN 2026-08-06 21:48:18 +03:00
esefxdz abcb41fb06 splash screen and status bar color polish 2026-08-06 21:47:58 +03:00
esef e2359419bc Delete SERVER_DEPLOYMENT.md 2026-08-02 20:20:31 +03:00
esefxdz 2d0628c5bb docs: update SERVER_DEPLOYMENT.md for V2 domain-free architecture 2026-08-02 15:38:42 +03:00
esefxdz 4fde4a9217 v3.0.0: domain-free client, bootstrap tunnel, tunnel-internal API 2026-08-02 14:00:38 +03:00
esefxdz 75cf59f22c cleaning up 2026-08-02 00:56:55 +03:00