Commit Graph

70 Commits

Author SHA1 Message Date
Davide
75de2029ff
Always refresh app features onForeground() (#1022)
Even if they haven't changed since the app was last sent to the
background.

Regression from #1019 where the initial .reloadReceipt() call was
wrapped in a Task to make it asynchronous.
2024-12-17 20:57:10 +01:00
Davide
fbfa600d67
Use tagged PassepartoutKit packages (#1021)
Closes #956
2024-12-17 18:57:45 +01:00
Davide
a81b615261
Bump version 2024-12-17 18:50:27 +01:00
Davide
6255a273fe
Add recurring products to paywall (#1019)
Suggest whenever .fullTV is suggested. For this reason, subscriptions
are not suggested to existing full version purchasers, because they only
miss the one-time .appleTV purchase. Group purchases by feature products
and full version products, e.g.:

- Features
  - Apple TV
- Full version
  - Yearly
  - Monthly
  - Full
  - Full + TV

Additionally, fix reloadReceipt() slowing down onLaunch() sometimes. The
warning sign would appear on restricted profiles until the receipt is
loaded.
2024-12-17 18:23:27 +01:00
Davide
ef59dcc08e
Reword strings in "Purchased" view
Title: "Purchases"
Products header: "Products"
2024-12-16 21:57:05 +01:00
Davide
789f6ad515
Unify paywall and eligibility (#1018)
- Present paywall only on save/connect because PurchaseRequiredButton
instances were presenting paywalls with partial requirements
- Retain PurchaseRequiredButton just to flag paid features visually, but
do nothing on tap
- Suggest paywall products via IAPManager and required features, rather
than from views
- Handle .sharing/.appleTV requirements in ProfileCoordinator, rather
than in StorageSection
- Discontinue platform purchases, but treat as full if iOS + macOS
2024-12-16 21:45:36 +01:00
Davide
ffb8829f4f
Reorganize Core Data containers (#1017)
Before anything, remove any code related to App Group containers from
tvOS target because they are not available. Include the beta receipt
override, it's broken for that reason.

In short:

- Store all Core Data containers locally. Do not use the App Group for
Core Data for consistency across platforms.
- Store logs in the App Group on iOS/macOS, but locally on tvOS (see
`urlForCaches`).

Then, rather than one container per model, merge models into:

- Local: Providers
- Remote: Profiles + Preferences (now in the same CloudKit container)

Reuse the remote model for backups too.

This change is safe because:

- Local profiles are stored via Network Extension in the keychain, not
Core Data
- Remote profiles are re-imported via CloudKit sync
- Providers are re-downloaded on first use
- Preferences are lost, but they are "cheap" data
- Profile backups are lost, but they were hidden anyway
2024-12-15 20:20:33 +01:00
Davide
3a1ef87b95
Fix ProfileManagerTests waiting for wrong event 2024-12-15 14:06:17 +01:00
Davide
8ad71b2980
Bump version 2024-12-15 13:52:05 +01:00
Davide
a04c1072c8
Allow Ethernet on-demand on all platforms (#1012)
Fixes #1010
2024-12-14 21:59:25 +01:00
Davide
b9353a6b02
Temporarily disable auto-deletion of migrated profiles (#1013)
Leave room for downgrade until 3.0.0 is stable.
2024-12-14 21:58:39 +01:00
Davide
1837d0576e
Update README (#1008)
- Simplify badges
- Drop app description, annoying to maintain (refer to the website)
- Drop screenshots (refer to the App Store)
- Update Credits
- Inform about private PassepartoutKit

Fixes #613
2024-12-14 09:44:10 +01:00
Davide
f82bf92a51
Update library to uniform version 2024-12-12 23:53:01 +01:00
Davide
d0f25d6d6e
Add translations for the former 12 languages (#1005)
Closes #588
2024-12-12 23:32:27 +01:00
Davide
88c53bed2e
Regroup views/logic of VPNProviderServerView 2024-12-12 18:44:14 +01:00
Davide
2075f109f2
Fix unselectable presets (#1004)
Revert #996 and do something midway:

- When set, use preset filter as selection (disambiguate compatible
presets)
- Set initial preset filter with current selected server preset

Server selection still picks a random preset if:

- Preset filter is "Any"
- More than one preset is compatible
2024-12-12 18:38:16 +01:00
Davide
ed45e5d2e4
Fix a Core Data crash on Apple TV (#1003)
Could not create the Preferences Core Data container in the App Group
because sub-directories did not exist. Create them upfront when using
App Group URLs.

This was not an issue with other Core Data containers because they are
stored in the app directories, where "Library/Documents" already exists.
2024-12-12 12:48:58 +01:00
Davide
81aa3a2714
Skip onboarding migration if no migratable profiles (#1002)
Annoying!
2024-12-11 22:20:14 +01:00
Davide
ff88b3562d
Clean up dangling module preferences (#999)
Erase on module removal, reference is otherwise lost forever.
2024-12-10 20:33:35 +01:00
Davide
d8447ddb38
Fix a few things about screenshots
- Postpone "Connected" screenshot
- Disable "Only favorites" to avoid iOS failure
- Prefix screenshot filename with device name and "0"
2024-12-10 18:37:53 +01:00
Davide
f441a2eed0
Autogenerate screenshots for all platforms (#998)
Unframed for now.

- Split Main/TV targets
- Extend ProfileManager for screenshot scenarios
- Rename UITesting to UIAccessibility

Active profile looks very big on TV simulator, temporarily commented
`.padding(.top, 50)` in ActiveProfileView.

Closes #974
2024-12-10 18:06:23 +01:00
Davide
a626722224
Fix TV active toggle color when on-demand 2024-12-10 17:31:33 +01:00
Davide
ddd45c1855
Bump version 2024-12-10 15:30:45 +01:00
Davide
2b3c28832b
Migrate provider favorites to Core Data entities (#997)
Rather than a Codable array.
2024-12-10 15:19:07 +01:00
Davide
c7bba033fe
Fix incorrect selection of VPN preset (#996)
Drop "Any" to rather make the preset filter an explicit preset
selection.

Regardless of `filtersWithSelection`, _always_ enforce the preset filter
to:

- The preset of the currently selected entity
- The first among available presets (normally non-empty)

Fixes #995
2024-12-10 14:45:07 +01:00
Davide
6f9c78b257
Track module preferences history in Core Data (#994)
Restore CDModulePreferencesV3 to track the history of module prefrences.

This way, excluded endpoints may be saved globally to Core Data as a
starting point. Then in Profile.userInfo we only save the relevant
exclusions for the current configuration.

The .excludedEndpoints relationship is therefore moved out of
CDProviderPreferencesV3.

Further refactoring:

- ModuleViewParameters now includes a ModulePreferences observable that
module views can observe
- Tunnel doesn't need access to PreferencesManager anymore (exclusions
are in Profile.userInfo)
2024-12-10 14:13:10 +01:00
Davide
aeec943c58
Move ModulePreferences to Profile.userInfo (#993)
Store module preferences in the Profile.userInfo field for atomicity.
Access and modification are dramatically simplified, and synchronization
comes for free.

On the other side, fix provider preferences synchronization by using
viewContext for the CloudKit container.

Fixes #992
2024-12-10 11:18:52 +01:00
Davide
912f62b29e
Revert "Unobserve ProfileEditor"
This reverts commit f1a0ecadfa.
2024-12-09 20:35:42 +01:00
Davide
a642b27d2b
Deduplicate preferences by last update (#991)
Fixes #990
2024-12-09 09:13:16 +01:00
Davide
93a15cd766
Review incorrect behavior in preferences (#989)
- Save/rollback was done outside of MOC
- Use different contexts for module/provider preferences
  - Save providers → also saves modules
  - Discard modules → also discards providers
- Use background context because it's not automatically merged (can
rollback)
- Expose ModulePreferences in OpenVPNView as StateObject
- Rework Blacklist to a more reusable ObservableList
- Reapply #988
2024-12-09 08:44:13 +01:00
Davide
c72a69829b
Fix compile error on TV 2024-12-09 07:59:37 +01:00
Davide
fae0200995
Exclude OpenVPN endpoints (#987)
Exclude endpoints from OpenVPN modules and providers with the generic
Blacklist<T> observable. Eventually, rebuild the Profile in
PacketTunnelProvider (via DefaultTunnelProcessor) with the applied
exclusions from preferences.

Revisit approach to preferences:

- Module preferences
  - Tied to the module and therefore to the parent profile
- Load/save in ProfileEditor on request (rather than on
ProfileEditor.load)
- Provider preferences
  - Shared globally across profiles
  - Load/save in module view if needed

For more consistency with Core Data:

- Revert to observables for both module and provider preferences
- Treat excluded endpoints as relationships rather than a serialized
Array
- Add/remove single relationships over bulk delete + re-add
- Do not map the relationships, Blacklist only needs exists/add/remove:
  - isExcludedEndpoint
  - addExcludedEndpoint
  - removeExcludedEndpoint

Some clean-up:

- Move the importer logic to OpenVPNView.ImportModifier
- Move the preview data to OpenVPN.Configuration.Builder.forPreviews
- Drop objectWillChange.send() on .repository didSet to avoid potential
recursion during SwiftUI updates

Closes #971
2024-12-09 02:00:55 +01:00
Davide
5f20d791c2
Show module UUID in DEBUG 2024-12-09 01:01:01 +01:00
Davide
52bda60b05
Fix missing animations in profiles list (#986)
The list was not animating e.g. on iCloud updates. Move
.themeAnimation() from ProfileContainerView (ContainerModifier) to
ProfileListView/ProfileGridView.
2024-12-09 00:53:46 +01:00
Davide
f1a0ecadfa
Unobserve ProfileEditor 2024-12-09 00:25:54 +01:00
Davide
e2402007c9
Select preset matching current filter (#985)
E.g. Mullvad was not selecting "Custom DNS".
2024-12-09 00:25:09 +01:00
Davide
f7013a98a9
Separate App/Tunnel responsibilities (#984)
Sort out the increasing mess coming from:

- AppContext*
- Dependencies
- Shared*

by doing the following:

- Keep in the "Shared" folder only the entities actually shared by
App/Tunnel
  - Create TunnelContext
  - Move AppContext and related to the App/Context folder
  - Move TunnelContext and related to the Tunnel/Context folder
- Delete Shared+* extensions, use AppContext/TunnelContext singletons
from the app
- Create a Dependencies factory singleton to create entities in a single
place
  - Split extensions by domain
- Make it clear with `func` vs `var` when a dependency method returns a
new instance
2024-12-08 18:56:39 +01:00
Davide
aac04c4008
Move processor implementations to concrete objects (#983)
Formerly via blocks, now with final classes.

App:

- ProfileProcessor
- AppTunnelProcessor
- Implemented by DefaultAppProcessor in app
- Implemented by MockAppProcessor in UILibrary (for previews)

Tunnel:

- PacketTunnelProcessor
- Implemented by DefaultTunnelProcessor
2024-12-08 16:24:23 +01:00
Davide
a4ebea1f95
Handle load/save preferences inside ProfileEditor (#982)
Simplify preferences model by doing a bulk load/save together with
load/save Profile. ModulePreferences is now a struct rather than an
ObservableObject, because it doesn't need ad hoc observation. It's just
a binding to ProfileEditor.preferences

Fix:

- Disable CloudKit in tunnel singleton of PreferencesManager
(.sharedForTunnel)

Additionally:

- Replace MainActor in PreferencesManager with Sendable (immutable)
- Replace MainActor from ProviderPreferencesRepository with Sendable
(syncs on NSManagedObjectContext)
- Drop ModuleMetadata for good
2024-12-08 16:05:23 +01:00
Davide
14847b2de5
Fix missing test targets 2024-12-06 15:52:25 +01:00
Davide
d4eed89e9f
Allow "Routing" module in beta 2024-12-06 15:31:01 +01:00
Davide
36b8024e5b
Fix deadlock regression in DNS resolution 2024-12-06 15:25:45 +01:00
Davide
e663f48bc3
Update library
- Make userInfo AnyHashable
- Prepare for profile processing in tunnel
2024-12-06 11:25:54 +01:00
Davide
dfae6afcb4
Store complex preferences to Core Data (#981)
Replace favorites entities with a PreferencesManager, that returns
observables for:

- Module preferences (by module UUID)
- Provider preferences (by ProviderID)

Automate preferences availability in:

- Module views (empty for now)
- VPN server view (favorites)

Synchronize preferences by making this a CloudKit container. Preferences
are also available in the Tunnel by storing the container in the App
Group.
2024-12-06 11:24:51 +01:00
Davide
f8655b09af
Move error handler to AppCoordinator 2024-12-06 10:29:50 +01:00
Davide
0fd544348f
Disclose details about selected provider server configuration (#980)
Like in v2.
2024-12-04 20:50:51 +01:00
Davide
d8f5caa2f7
Improve "Purchased" view (#979)
- Show eligible features first
- Render ineligible features as secondary
2024-12-04 17:38:13 +01:00
Davide
4ef47dfd77
Bump version 2024-12-04 14:21:29 +01:00
Davide
79bb6e6bdb
Update library again
- Drop -Type suffixes from associated types
- Rename to IdentifiableConfiguration
2024-12-04 13:47:26 +01:00
Davide
355974292e
Update library with provider entities (#978) 2024-12-04 12:40:47 +01:00