Commit Graph

380 Commits

Author SHA1 Message Date
dependabot[bot]
f825995fc3 build(deps): bump github.com/getsentry/sentry-cocoa from 8.49.0 to 8.55.0 in /swift/apple/FirezoneKit (#10496)
Bumps
[github.com/getsentry/sentry-cocoa](https://github.com/getsentry/sentry-cocoa)
from 8.49.0 to 8.55.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/getsentry/sentry-cocoa/releases">github.com/getsentry/sentry-cocoa's
releases</a>.</em></p>
<blockquote>
<h2>8.55.0</h2>
<blockquote>
<p>[!Important]
Xcode 26 no longer allows individual frameworks to contain arm64e slices
anymore if the main binary doesn't contain them.
We have decided to split the Dynamic variant and
Sentry-WithoutUIKitOrAppKit of Sentry into two variants:</p>
<ul>
<li><code>Sentry-Dynamic</code>: Without ARM64e</li>
<li><code>Sentry-Dynamic-WithARM64e</code>: <em>With</em> ARM64e
slice</li>
<li><code>Sentry-WithoutUIKitOrAppKit</code>: Without ARM64e</li>
<li><code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code>: <em>With</em>
ARM64e slice</li>
</ul>
<p>If your app does not need arm64e, you don't need to make any changes.
But if your app <em>needs arm64e</em> please use
<code>Sentry-Dynamic-WithARM64e</code> or
<code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code> from 8.55.0 so you
don't have issues uploading to the App Store.</p>
</blockquote>
<h3>Features</h3>
<ul>
<li>Add a new prebuilt framework with arm64e and remove it from the
regular one (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5788">#5788</a>)</li>
<li>Add <code>beforeSendLog</code> callback to
<code>SentryOptions</code> (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5678">#5678</a>)</li>
<li>Structured Logs: Flush logs on SDK flush/close (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5834">#5834</a>)</li>
<li>Add a new prebuilt framework with ARM64e for WithoutUIKitOrAppKit
(<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5897">#5897</a>)</li>
<li>Add source context and vars fields to SentryFrame (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5853">#5853</a>)</li>
</ul>
<h3>Fixes</h3>
<ul>
<li>Add support for PDFKit views in session replay (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5750">#5750</a>)</li>
<li>Fix Infinite Session Replay Processing Loop (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5765">#5765</a>)</li>
<li>Fix memory leak in SessionReplayIntegration (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5770">#5770</a>)</li>
<li>Fix reporting of energy used while profiling (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5768">#5768</a>)</li>
<li>Fixed a build error in <code>SentryFeedback.swift</code> when
building with cocoapods on Xcode 14.2 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5917">#5917</a>)</li>
<li>Fix linking against Sentry on an app extension (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5813">#5813</a>)</li>
</ul>
<h2>8.54.1-alpha.2</h2>
<blockquote>
<p>[!Important]
Xcode 26 no longer allows individual frameworks to contain arm64e slices
anymore if the main binary doesn't contain them.
We have decided to split the Dynamic variant and
Sentry-WithoutUIKitOrAppKit of Sentry into two variants:</p>
<ul>
<li><code>Sentry-Dynamic</code>: Without ARM64e</li>
<li><code>Sentry-Dynamic-WithARM64e</code>: <em>With</em> ARM64e
slice</li>
<li><code>Sentry-WithoutUIKitOrAppKit</code>: Without ARM64e</li>
<li><code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code>: <em>With</em>
ARM64e slice</li>
</ul>
<p>If your app does not need arm64e, you don't need to make any changes.
But if your app <em>needs arm64e</em> please use
<code>Sentry-Dynamic-WithARM64e</code> or
<code>Sentry-WithoutUIKitOrAppKit-WithARM64e</code> from 8.55.0 so you
don't have issues uploading to the App Store.</p>
</blockquote>
<h3>Features</h3>
<ul>
<li>Structured Logs: Flush logs on SDK flush/close (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5834">#5834</a>)</li>
<li>Add a new prebuilt framework with ARM64e for WithoutUIKitOrAppKit
(<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5897">#5897</a>)</li>
<li>Add source context and vars fields to SentryFrame (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5853">#5853</a>)</li>
</ul>
<h3>Fixes</h3>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="3c2eee7773"><code>3c2eee7</code></a>
release: 8.55.0</li>
<li><a
href="3ec47ae715"><code>3ec47ae</code></a>
ci: Use iOS18.5 since 18.6 seems to be unavailable sometimes (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5944">#5944</a>)</li>
<li><a
href="1a34ddc00f"><code>1a34ddc</code></a>
ci: Bump iOS and tvOS versions to 18.6 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5942">#5942</a>)</li>
<li><a
href="67e8e3ecf0"><code>67e8e3e</code></a>
Merge branch 'release/8.54.1-alpha.2'</li>
<li><a
href="45482a6a1b"><code>45482a6</code></a>
fix: Build error on Xcode 14.2 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5917">#5917</a>)</li>
<li><a
href="9174496cdc"><code>9174496</code></a>
release: 8.54.1-alpha.2</li>
<li><a
href="891fd1d420"><code>891fd1d</code></a>
ref: Make SentryEventDecodable internal in V9 (<a
href="https://redirect.github.com/getsentry/sentry-cocoa/issues/5808">#5808</a>)</li>
<li><a
href="dba4ee8975"><code>dba4ee8</code></a>
Refactor SentryFeedback serialization to have 2 declarations depending
if SDK...</li>
<li><a
href="669f02ce7d"><code>669f02c</code></a>
Add changelog</li>
<li><a
href="4506bdb8b3"><code>4506bdb</code></a>
fix: Build error on Xcode 14.2</li>
<li>Additional commits viewable in <a
href="https://github.com/getsentry/sentry-cocoa/compare/8.49.0...8.55.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/getsentry/sentry-cocoa&package-manager=swift&previous-version=8.49.0&new-version=8.55.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)


</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-01 03:26:38 +00:00
Mariusz Klochowicz
4d2b592d65 chore: Clean up Xcode config (#10461)
- declary sentry as FirezoneKit dependency
- add config for non-Xcode LSP config 
- add some more info in README
2025-10-01 02:08:18 +00:00
Jamil
378586b057 fix(apple): sentry hang tracking for singleton (#10382)
Trying to knock out some low-hanging Sentry alert fruit.

Fixes #10381
2025-09-19 05:13:34 +00:00
Mariusz Klochowicz
b1ed2f8a5e chore: improve macos dev experience (#10363)
Quality of life improvements for macOS devs, mostly relevant when not
using Xcode as daily driver - although some convenience functions &
explicit sentry dependency should make it better there too.
2025-09-17 02:17:36 +00:00
Firezone Bot
d8079c869f chore: publish apple-client 1.5.8 (#10323) 2025-09-10 17:06:40 +00:00
Mariusz Klochowicz
963cc8ede0 fix(apple): Enforce single Firezone instance (#10313)
show an alert to the user and ask to quit previous Firezone instance
manually before starting a new one.

Resolves: #10295

---------

Signed-off-by: Mariusz Klochowicz <mariusz@klochowicz.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2025-09-10 01:54:58 +00:00
Jamil
9696d00cc3 fix(apple): flush dns cache on resource updates (#10224)
In the following sequence of events, a user will be unable to connect to
the DNS resource for a few seconds because macOS is caching the queries,
preventing connlib from seeing them.

1. User signs in
2. User has _no_ access to DNS Resource A
3. User queries for DNS Resource A - NXDOMAIN -> macOS caches this
4. Admin grants access to DNS Resource A
5. User tries query again -> connlib never sees the query -> cache hit
-> NXDOMAIN

To fix this, we call `networkSettings.apply()` whenever the resource
list has changed. This has been tested to trigger a DNS cache flush on
macOS.
2025-08-19 13:08:23 +00:00
Firezone Bot
95ee111e62 chore: publish apple-client 1.5.7 (#10159) 2025-08-07 04:38:03 +00:00
Jamil
b96ee526c1 fix(apple/ios): don't require hard link to __res_9_state (#10143)
In Xcode 16, how the compiler determines the size of C structs changed.

In Xcode 15 and below, when the compiler saw `__res_9_state()`, it
thought, "This is a C struct. I know its size and layout from the
system's header files. I will generate code to allocate that much memory
and zero it out." This was a type-based operation; it only needed the
"blueprint" for the struct.

In Xcode 16 and later, the compiler sees `__res_9_state()` and thinks,
"This is a C struct. To initialize it, I need to link to the actual
symbol named `___res_9_state` inside the libresolv library." This became
a symbol-based operation, creating a direct dependency that didn't exist
before.

To fix this, we initialize a raw pointer with a manual type
specification to the zeroed-out struct, which reverts to the prior
behavior.

Has been tested on iPhone 12, iOS 17.

Fixes #10108
2025-08-05 20:08:56 +00:00
Firezone Bot
acf52ccf1e chore: publish apple-client 1.5.6 (#10106) 2025-08-02 19:43:35 +00:00
Jamil
290b0c298f fix(apple/ios): less aggressive setDns to avoid update loops (#10075)
In
https://github.com/firezone/firezone/pull/10022/files#diff-a84e8f62a17ac67f781019e6ac0456567fd18ffa7c13b3248609d78debb6480eL342
we removed the path connectivity filter that prevented path update loops
on iOS. This was done to try and respond more aggressively to path
updates in order to set system DNS resolvers, because we can't glean
from the path's instance properties that any DNS configuration has
changed - we simply have to assume so.

Unfortunately, that caused an issue where we now enter a path update
loop and effectively never fully bring the tunnel up.

I've spent lots of time looking for a reliable work around that would
allow us to both, (1) respond to path updates for DNS configuration
changes on the system (we have to blindly react to these), and (2) avoid
path update loops, but alas, without a significant time investment,
there doesn't seem to be a way.

So, we only set system resolvers on iOS in the path update handler if
there was _also_ a detectable connectivity change, and settle on the
assumption that **most** DNS configuration changes will be accompanied
by a network connectivity change as well.
2025-08-01 06:20:24 +00:00
Jamil
442a85ac15 fix(apple): reset network on wake from sleep (#10059)
When a mac device goes to sleep, it typically does not turn off the WiFi
radio. If the mac never leaves the network it was on upon sleep, then
upon wake it will never receive a path update, and we would not have
performed a connlib network reset.

To fix this, we now properly detect a wake from sleep event and issue a
network reset.

Fixes #10056
2025-07-31 00:19:37 +00:00
Firezone Bot
e6fc7e62da chore: publish apple-client 1.5.5 (#10035) 2025-07-28 20:14:12 +00:00
Jamil
42de3ad144 fix(apple): save networkSettings var (#10022)
In 45466e3b78, the `networkSettings`
variable was no longer saved on the `adapter` instance, causing all
calls of the iOS-specific version of getting system resolvers to return
the connlib sentinels after the tunnel first came up.

This PR fixes that logic bug and also cleans this area of the codebase
up just a tiny bit so it's easier to follow.

Lastly, we also fix a bug where if the tunnel came up while Firezone was
already running, `networkSettings` would be `nil`, and we would read the
default system resolvers, which were the connlib sentinels.


Fixes https://github.com/firezone/firezone/issues/10017
2025-07-27 22:42:43 +00:00
Jamil
621028a998 fix(apple): use documents for tempfile (#10019)
On iOS, we were using the tempfile directory to stage the log export,
and then moving this into place from the share sheet presented to the
user.

For some reason, this has stopped working in iOS 18.5.0, and we need to
stage the file in the standard documents directory instead.


Fixes #10014
2025-07-26 22:05:10 +00:00
Jamil
13de2d303e fix(apple): reset network on path status changes (#9997)
Fixes an edge case where a WiFi interface could go offline, then come
back online with the same connectivity, preventing the path update
handler from reset connlib state.

This would cause an issue especially if the WiFi was disabled for more
than 30 seconds / 2 minutes.
2025-07-25 04:53:41 +00:00
Jamil
67b4dd86ea fix(apple): increase sensitivity of network reset (#9993)
On Apple platforms, we tried to be clever about filtering path updates
from the network connectivity change monitor, because there can be a
flurry of them upon waking from sleep or network roaming.

However, because of this, we had a bug that could occur in certain
situations (such as waking from sleep) where we could effectively "land"
on an empty DNS resolver list. This could happen if:


1. We receive a path update handler that meaningfully changes
connectivity, but its `supportsDNS` property is `false`. This means it
hasn't received any resolvers from DHCP yet. We would then setDns with
an empty resolver list.
2. We then receive a path update handler with the _only_ change being
`supportDNS=true`. Since we didn't count this change as a meaningful
path change, we skipped the `setDns` call, and connlib would be stuck
without DNS resolution.

To fix the above, we stop trying to be clever about connectivity
changes, and just use `oldPath != path`. That will increase reset a bit,
but it will now handle other edge cases such as an IP address changing
on the primary interface, any other interfaces change, and the like.

Fixes #9866
2025-07-24 22:35:01 +00:00
Jamil
e9a863dc0e fix(apple): use all found system resolvers (#9991)
When validating the found system resolvers on macOS and iOS, we would
stop after validating the first found resolver (usually IPv4) because
`break` was used instead of `continue`.

Fixes #9914

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2025-07-24 21:02:34 +00:00
Thomas Eizinger
5141817134 feat(connlib): add reason argument to reset API (#9878)
In order to provide more detailed logs, why `connlib`'s network state is
being reset, we add a `reason` parameter that is gets logged.

Resolves: #9867
2025-07-15 13:48:33 +00:00
Jamil
12351e5985 ci: publish apple 1.5.4 clients (#9842) 2025-07-11 16:35:25 +00:00
Thomas Eizinger
f211c9d46a feat(apple): use .zip for logs (#9536)
This PR replaces the use of Apple Archive with an API that allows us to
zip the log file contents. This API doesn't handle symlinks well so we
move the symlink out of the way before making the zip. The symlink is
then moved back after the process is completed. Any errors in this
process are ignored as the symlink itself is not a critical component of
Firezone.

The zip compression is marginally less efficient than the Apple Archive.
Instead of compressing ~2GB of logs to 11.8 MB we now get an archive of
12.4 MB. Considering how much easier zip files are to handle, this seems
like a fine trade-off.

<img width="774" alt="Screenshot 2025-06-16 at 00 04 52"
src="https://github.com/user-attachments/assets/8fb6bade-5308-40b9-a446-2a2c364cb621"
/>

Resolves: #7475

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
2025-06-23 22:25:57 +00:00
Thomas Eizinger
a2c122a3c0 refactor(apple): use guard for checking valid handle (#9614)
Follow-up to #9597
2025-06-21 21:17:01 +00:00
Jamil
ea0616e198 chore(apple): ignore generated swift bridge files (#9599)
Rust and Swift disagree about the formatting of these, leading to
constant git file dirtiness when working on Apple code.

These were originally added when we didn't have as much automation to
regeneration these on each build.
2025-06-20 18:40:48 +00:00
Jamil
5537b8cfe7 fix(apple): ensure log file exists before writing to it (#9597)
Similar to the issue for the gui clients, the log file handle needs to
be able to be rolled over after logs are cleared.

related: #6850
2025-06-20 17:03:59 +00:00
Jamil
081b075f2c chore: bump gui, apple, gateway (#9586)
The new publish automation still [has some
kinks](https://github.com/firezone/firezone/actions/runs/15764891111) so
publishing this manually.
2025-06-19 12:29:46 -07:00
Thomas Eizinger
47befe37f4 fix(apple): disable false-positive "App hang" reports (#9568)
As recommended by the Sentry team [0], "App hang" tracking should be
disabled before calling into certain system APIs like showing alerts to
prevent false-positives.

[0]: https://github.com/getsentry/sentry-cocoa/issues/3472
2025-06-18 22:44:03 +00:00
Thomas Eizinger
bb46c59f1d chore(apple): add .swift-format file (#9566)
When using alternative editors other than Xcode, Intellisense is usually
provided by `sourcekit-lsp`. The LSP server also uses `swift-format`
under the hood to format the code but appears to default to using 4
spaces for indentation. In order to standardise on how much indentation
is used, we add a `.swift-format` file that specifies is.
2025-06-18 22:40:58 +00:00
Thomas Eizinger
a06f270c7d chore(apple): un-format generated code (#9549)
It appears that the code generation in our `build.rs` generates the code
with different formatting and this therefore constantly shows up as
untracked changes in my editor.
2025-06-16 20:06:36 +00:00
Thomas Eizinger
01ad87b1c0 chore(apple): format swift code with formatter (#9535)
When working on the Swift codebase, I noticed that running the formatter
produced a massive diff. This PR re-formats the Swift code with `swift
format . --recursive --in-place` and adds a CI check to enforce it going
forward.

Resolves: #9534

---------

Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
2025-06-15 20:28:18 +00:00
Thomas Eizinger
dce7ffe4f0 fix(apple): drop Session in a new task (#9478)
Until we implement #3959 for the Apple client, we need to be careful
around how we de-initialise the Rust session. Callback-based designs are
difficult to get right across boundaries because they enable
re-entrances which then lead to runtime errors.

Specifically, freeing the session needs to cleanup the tokio runtime but
that is impossible if the callback is still executed from that exact
runtime. To workaround this, we need to free the session pointer from a
new task.

Moving to #3959 will solve this in a much more intuitive way because we
can ditch the callbacks and instead move to a stream of events that the
host app can consume.

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
2025-06-10 07:09:16 +00:00
Jamil
221ffc7e58 chore: publish Apple 1.5.2 (#9385) 2025-06-03 19:49:06 +00:00
Thomas Eizinger
b7b296a102 ci: apply prettier to all files (#9356)
Resolves: #8940
2025-06-02 11:12:54 +00:00
Jamil
0c0ab13b90 ci: Bump apple version to 1.5.1 (#9343) 2025-06-01 16:43:31 +00:00
Jamil
889c1a971c fix(apple): Correctly handle stopTunnel and completionHandlers (#9308)
This PR fixes two crashes related to lifetimes on Apple:

- `completionHandler` was being called from within a Task executor
context, which could be different from the one the IPC call was received
on
- The `getLogFolderSize` task could return and attempt to call
`completionHandler` after the PacketTunnelProvider deinit'd
- We were calling the completionHandler from `stopTunnel` manually.
Apple explicitly says not to do this. Instead, we must call
`cancelTunnelWithError(nil)` when we want to stop the tunnel from e.g.
the `onDisconnect`. Apple with then call our `stopTunnel` override. The
downside is that we have no control over the `NEProviderStopReason`
received in this callback, but we don't use it anyway. Instead, we write
the reason to a temporary file and read it from the GUI process when we
detect a status change to `disconnected`. When that occurs, we're able
to show a UI notification (macOS only - iOS can show this notification
from the PacketTunnelProvider itself).
2025-05-30 20:54:13 +00:00
Thomas Eizinger
c1cab32d7f feat(connlib): expose isAuthenticationError over Apple FFI (#9291)
The GUI client already uses the same function to check for
authentication errors. Therefore, this case is already handled there.

For Swift, we can easily expose this getter via the `swift-bridge`
module. For Android, we don't expose it for now. Once we tackle #3959,
this should be easier to do. In the meantime, the UX on Android is not
super terrible. The user gets signed out and we will then receive a 401
when we try to sign-in again the next time.

Resolves: #9289
2025-05-29 03:45:02 +00:00
Jamil
94b05a19f1 fix(apple): don't send connlib DNS server IPs that aren't IPs (#9242)
When pulling IPs from system resolvers, it's possible the IPv6 addresses
may contain scopes which will cause connlib to barf when parsing.

To fix these, we first convert to the Swift-native type `IPv4Address` or
`IPv6Address` and then use the string representation of those types,
which normalizes them to plain addresses.

Fixes #9055
2025-05-27 00:42:22 +00:00
Jamil
b7ec92e3aa chore(ci): Bump apple clients to 1.5.0 (#9239) 2025-05-26 08:20:05 -07:00
Jamil
b5c18db5e8 chore(ci): Bump next clients version to 1.5.0 (#9229)
We've decided we'll be bumping the minor with shipping managed
configurations support.
2025-05-26 04:24:35 +00:00
Jamil
ec682d5871 fix(apple): Don't throw when quitting with a stopped tunnel (#9231)
If the tunnel is already down when we try to quit the application, we
were throwing a harmless error because we mistakenly required a
connected status to send the `stopTunnel` command, which is just a no-op
if we're already connected.
2025-05-26 04:19:12 +00:00
Jamil
842fe8718d chore(apple): Remove managed enforcement of full-tunnel (#9230)
After discussing with @thomaseizinger, we realized this is better
supported with Polices.
2025-05-26 03:47:17 +00:00
Jamil
a7054b8f40 ci: Bump apple to 1.4.15 (#9217) 2025-05-24 12:51:27 +00:00
Jamil
e84ba4545e feat(apple): Add supportURL as managed config item (#9202)
Adds `supportURL` as a managed configuration item so that admins may
point their workforce towards their own support Resources.
2025-05-22 16:48:35 +00:00
Jamil
6fd3493ed0 refactor(apple): Consolidate configuration to host app (#9196)
On Apple platforms, `UserDefaults` provides a convenient way to store
and fetch simple plist-compatible data for your app. Unbeknownst to the
author at the time of original implementation was the fact this these
keys are already designed for managed configurations to "mask" any
user-configured equivalents.

This means we no longer need to juggle two dicts in UserDefaults, and we
can instead check which keys are forced via a simple method call.

Additionally, the implementation was simplified in the following ways:

- The host app is the "source of truth" for app configuration now. The
tunnel service receives `setConfiguration` which applies the current
configuration, and saves it in order to start up again without the GUI
connected. The obvious caveat here is that if the GUI isn't running,
configuration such as `internetResourceEnabled` applied by the
administrator won't take effect. This is considered an edge case for the
time being since no customers have asked for this. Additionally, admins
can be advised to ensure the Firezone GUI is running on the system at
all times to prevent this.
- Settings and ConfigurationManager are now able to be removed - these
became redundant after consolidating configuration to the containing
app.
2025-05-22 16:18:00 +00:00
Jamil
745b57218b chore(apple): Remove useless IPC error log (#9201)
This error case happens during normal operation, particularly when
exiting the application and can be dropped.
2025-05-22 07:19:05 +00:00
Jamil
e14c4e1eb8 refactor(apple): Only apply MDM config when changed (#9173)
In #9169 we applied MDM configuration from MDM upon _any_ change to
UserDefaults. This is unnecessary.

Instead, we can compare new vs old and only apply the new dict if
there's changes.

In this PR we also log the old and new dicts for debugging reasons.
2025-05-16 23:21:08 +00:00
Jamil
73f334e345 feat(apple): Add start on login functionality (#9168)
Adds a new settings/configuration item `startOnLogin` which simply adds
a "Login Item" which starts Firezone after signing into the Mac.

This feature is macOS 13 and above only because otherwise we will need
to bundle a helper application to register as a service to start the
app. Given our very small footprint of macOS 12 users, and how
unsupported it is, this is ok.

When it comes time to implement MDM for this feature, note that Apple
provides a means to enforce login items via the
[`ServiceManagementLoginItems`
payload](https://developer.apple.com/documentation/devicemanagement/servicemanagementmanagedloginitems)
which is outside the scope of `com.apple.configuration.managed`. This
enforces the login item in System Settings so that the user is unable to
disable it.

We also add functionality here, but bear in mind that even if we disable
the Toggle switch in our Settings page, the user could still disable the
item in system settings unless it is being set through MDM via the
service management key above.

Another thing to note is that this setting is applied on the GUI side of
the tunnel only, because it is inherently tied to the process it is
running as. We are not able to (nor does it make sense to) enable the
login item for the tunnel service. This should be fine.

Tested to ensure enabling/disabling appropriately adds and removes the
login item (and re-adds it if I manually remove it from system
settings).


Related: #8916 
Related: #2306

---------

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
2025-05-16 22:15:49 +00:00
Jamil
f138d86494 feat(apple): Apply MDM changes to Configuration (#9169)
When the MDM installs a configuration payload to
`dev.firezone.firezone.network-extension`, the tunnel service will now
be notified of a change to its `managedDict`, applying the configuration
and updating `packetTunnelProvider`'s local copy so that it'll be
returned on the next configuration fetch from the UI.

Related: #4505
2025-05-16 22:00:16 +00:00
Jamil
9951e82727 feat(apple): Disable the update checker for MDM and App store (#9167)
For App Store installed macOS clients, it doesn't make sense to run an
update checker, because the system is managing the updates, and will
notify the user if there's an update available for Firezone (the user
has configured the system to manage app updates).

Related: #7664 
Related: #4505
2025-05-16 09:27:57 +00:00
Jamil
e599eb2f09 fix(apple): Ensure system extension loads after upgrade (#9166)
On macOS, after upgrading the client, the new system extension fails to
respond to IPC commands until it receives a `startTunnel` call. After
that, subsequent IPC calls will succeed across relaunches of the app.

To fix this, we introduce a dummy `startTunnel` call on macOS that
attempts to bring life into the System extension whenever we receive
`nil` configuration.

We also tidy up a few other things to make this easier to follow.


Fixes #9156 
Fixes #8476

---------

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-05-16 07:17:12 +00:00
Jamil
7b4aa44f30 refactor(apple): Add Settings model (#9155)
The settings fields are getting tedious to manage individually, so a
helper class `Settings` is added which abstracts all of the view-related
logic applicable to user-defined settings.

When settings are saved, they are first applied to the `store`'s
existing Configuration, and then that configuration is saved via a new
consolidated IPC call `setConfiguration`.

`actorName` has been moved to a GUI-only cached store since it does not
need to live on `Configuration` any longer.

This greatly simplifies both the view logic and the IPC interface.

Notably, this does not handle the edge case where the configuration is
updated while the Settings window is open. That is saved for a later
time.
2025-05-15 23:25:00 +00:00