Adds a new field to `settings/identity_providers` that allows an Admin
to designate any non-email/otp provider as the `default` for client
authentication. Clients will then navigate directly to the provider's
`/redirect` endpoint when authenticating, which in many cases will
automatically sign them in.
No existing providers are updated in this PR.
https://github.com/user-attachments/assets/7b962a25-76fd-491f-a194-60ed993821fc
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
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#9156Fixes#8476
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Our bump-versions script did not consider that we also have the version
stored in the `.spec` file for rpm builds and hence this did not get
bumped in a while (or ever?).
Now that we have moved all files of the Tunnel service into the
`gui-client` crate, we can directly reference the `CARGO_PKG_VERSION`
env variable instead of having to hard-code the number in the
source-code.
The way the GUI client currently handles the commands and flags provided
via the CLI is somewhat confusing. There are various helper functions
that get called from the same place. We duplicate setup like the `tokio`
runtime in multiple places and the also loggers get initialised all over
the place.
To streamline this, we move global setup like `tokio` and telemetry to
the top-layer. From there, we delegate to a `try_main` function which
handles the various CLI commands. The default path from here is to run
the gui by delegating to the `gui` module. If not, we bail out early.
This structure is significantly easier to understand and provides error
and telemetry handling in a single place.
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.
I am not sure if this is currently breaking anything but it seems more
correct to flush all events first and then end the session.
---------
Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
The tunnel service of the GUI client can only handle one process at a
time. The OS however will happily connect multiple clients to the socket
/ pipe. They will simply idle until the previous process disconnects.
To avoid this situation, we introduce a `Hello` message from the tunnel
service to the GUI client. If the GUI client doesn't receive this
message within 5s, it considers the tunnel service be not responsive.
If our duplicate instance detection works as intended, users are not
expected to hit this.
We already have a pretty powerful IPC framework in place to communicate
between the GUI and the service process. The deeplink implemenation uses
the same IPC mechanisms (UDS / pipes), yet it is effectively a
re-implementation of what we already have, just with less functionality.
In order to provide a more sophisticated handling of the case where
Firezone is launched again while it is already running, we refactor the
deeplink module to reuse the existing IPC framework. This makes it quite
easy to then reuse this in order to ping the already running Firezone
process that a new instance was launched.
For now, this doesn't do anything other than writing a log entry. This
however lays enough ground-work for us to then implement a more
sophisticated handling of that case in the future, e.g. open new windows
etc.
One caveat here is that we are now trying to connect to an existing IPC
socket on every startup, even the first one. Our IPC code has a retry
loop of 10 iterations to be more resilient on Windows when connecting to
pipes. Without any further changes, this would now delay the start of
Firezone always by 1s because we would try to connect to the socket 10x
before concluding that we are the first instance. To fix this, we make
the number of attempts configurable and set it to 1 when attempting to
the GUI IPC socket to avoid unnecessary delays in starting up the
Client.
Related: #5143.
We already use `vite` as a bundling tool but only to rollup some of the
pre-built files. This setup (and therefore our buildscripts) can be
massively simplified by instructing `vite` to also build our TypeScript
code and compile tailwind.
This makes it much easier to develop locally because one only needs to
run `pnpm vite build --watch` to keep everything up to date.
Currently, one machines that have multiple routable egress interfaces,
`connlib` may bounce between the two instead of settling on one. This
happens because we have a dedicated `CandidateSet` that we use to filter
out "duplicate" candidates of the same type. Doing that is important
because if the other party is behind a symmetric NAT, they will send us
many server-reflexive candidates that all only differ by their port,
none of them will actually be routable though.
To prevent sending many of these candidates to the remote, we first
gather them locally in our `CandidateSet` and de-duplicate them.
This link repeatedly returns a 403 in our CI link checker, despite being
available.
Fixes: #9140Fixes: #9120
Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
If the user tries to start the tunnel from system settings without
launching the GUI after upgrading to >= 1.4.15, the new configuration
will be empty, and we'll fail to set the accountSlug, preventing the
tunnel from starting.
To fix this, we add a simple convenience function that returns the
legacy configuration, and we use this configuration to start the tunnel
in case the GUI hasn't started.
Once the GUI starts, the legacy configuration is migrated and deleted,
so this is more of an edge case. Still, given the hundreds/thousands of
Apple device installations we have, someone is bound to hit it, and it
would be better to spend a few minutes saving potentially man-hours of
troubleshooting later.
On macOS, the token is saved in the system keychain so that the `root`
user is able to manage it. `secd`, the daemon that responds to Keychain
requests, is very strict about which binaries can access Keychain items
created by other binaries.
In development, the Firezone system extension runs from an unprivileged
directory, and isn't release-signed, which means it is not able to
manage the Keychain token for the release binary, and vice-versa.
To fix this, we isolate the Keychain items from each other with
different labels for `debug` and `release`, where the latter is
unchanged.
This is only an issue on debug, so a Changelog entry is not created.
Fixes#8917Fixes#8642
Exposes a configuration toggle to connect on start, allowing it to be
overridden by MDM. Currently we assume this to be true.
Will need to refactor the settings soon to a dedicated
`ObservableObject` in the ViewModel to make these validations and field
checks less verbose.
related: #4505
Bumps the aya group in /rust with 5 updates:
| Package | From | To |
| --- | --- | --- |
| [aya](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157`` |
| [aya-build](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157``
|
| [aya-ebpf](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157``
|
| [aya-log](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157`` |
| [aya-log-ebpf](https://github.com/aya-rs/aya) | ``583709f`` |
``f74a157`` |
Updates `aya` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-build` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-ebpf` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-log` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-log-ebpf` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
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 <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
To simulate varying network conditions in our tests, each `Host` in our
test network has an "inbox" that contains all incoming network packets
with an added latency. When another hosts sends a packet, the packet
gets added to the inbox. Internally, the inbox has a binary heap that
sorts incoming `Transmits` by their latency and only delivers them to
the node when that delay is up.
Currently, this delivery doesn't always happen because we fail to take
into account the timestamp as when the next `Transmit` is due when we
figure out what to do next.
Instead of just looking at the inner state via `poll_transmit`, we now
also consult the inbox of messages as to when the next message is due
and wake up at the correct time.
Not doing this caused our state machine to think that packets got
dropped because `REFRESH` messages to the relays were timing out.
Resolves: #9118
Now that configuration is persisted in a more reasonable fashion, we can
expose a new `General` section to the Settings, allowing the user to
configure an account slug.
This field will automatically be populated upon the first sign in, so
that subsequent sign-ins will take the user directly to the account sign
in page.
Fixes#5119
Related #8919
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
In the UI, we need to use Strings to bind to the text inputs.
In the configuration dictionaries, we need to use Strings to save the
URLs.
It makes no sense to convert these to URLs in between. Instead, we can
validate upon save and then use them as Strings throughout.
All the MDM configuration to shadow the `internetResourceEnabled` state.
Related: #4505
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Why:
* During the account sign up flow, the email of the first admin was not
being populated in the `email` column on the auth_identities table. This
was due to atoms being passed in the attrs instead of strings to the
`create_identity` function. A migration was also created to backfill the
missing emails in the `auth_identities` table.
In order to harvest some of the fruits of our lobbying efforts upstream,
we bump `moka` to latest `main` whilst they are still preparing the next
release.
This removes several dependencies from our dependency tree & lockfile.
Related: https://github.com/moka-rs/moka/pull/509
As part of going through the changes since the last Client and Gateway
relies, I noticed that for several of the things we fixed, it might be
worth adding changelog entries.
To send UDP DNS queries to upstream DNS servers, we have a
`UdpSocket::handshake` function that turns a UDP socket into a
single-use object where exactly one datagram is expected from the
address we send a message to. The way this is enforced is via an
equality check.
It appears that this equality check fails if users run an upstream DNS
server on a link-local IPv6 address within a setup that utilises IPv6
scopes. At the time when we receive the response, the packet has already
been successfully routed back to us so we should accept it, even if we
didn't specify a scope as the destination address.
In order to avoid routing loops on Windows, our UDP and TCP sockets in
`connlib` embed a "source IP resolver" that finds the "next best"
interface after our TUN device according to Windows' routing metrics.
This ensures that packets don't get routed back into our TUN device.
Currently, errors during this process are only logged on TRACE and
therefore not visible in Sentry. We fix this by moving around some of
the function interfaces and forward the error from the source IP
resolver together with some context of the destination IP.
If `authURL`, `apiURL`, or `logFilter` are set in the managed
configuration, we disable each of these fields respectively from user
editing.
If all of them are overridden, we disable the `Apply` and `Reset to
Defaults` buttons.
Related #4505
As part of launching the Tauri GUI client, we need to observe a specific
initialisation order. In particular, we need to wait until Tauri sends
us a `RunEvent::Ready` before we can initialise things like the tray
menu.
To make this more convenient, Tauri offers a so-called "setup hook" that
can be set on the app builder. Unfortunately, Tauri internally panics if
this provided setup-hook returns an `Err`. Removing this is tracked
upstream: https://github.com/tauri-apps/tauri/issues/12815.
Until this is fixed, we stop using this "setup hook" and instead spawn
our own task that performs this work. This task needs to wait until
Tauri is ready. To achieve that, we introduce an additional mpsc channel
that sends a notification every time we receive a `RunEvent::Ready`.
That should only happen once. We only read from the receiver once, which
is why we ignore the error on the sending side in case the receiver has
already been dropped.
Resolves: #9101
When this crate is compiled by itself, these features are required. This
doesn't show up in CI because there we compile the entire workspace and
some crate somewhere already activates these features then.