27 Commits

Author SHA1 Message Date
Brian Manifold
80e1c3255f refactor(portal): refactor billing event handler (#10064)
Why:

* There were intermittent issues with accounts updates from Stripe
events. Specifically, when an account would update it's subscription
from Starter to Team. The reason was due to the fact that Stripe does
not guarantee order of delivery for it's webhook events. At times we
were seeing and responding to an event that was a few seconds old after
processing a newer event. This would have the effect of quickly
transitioning an account from Team back to Starter. This commit
refactors our event handler and adds a `processed_stripe_events` DB
table to make sure we don't process duplicate events as well as prevent
processing an event that was created prior to the last event we've
processed for a given account.

* Along with refactoring the billing event handling, the Stripe mock
module has also been refactored to better reflect real Stripe objects.

Related: #8668
2025-08-05 16:56:52 +00:00
Jamil
f169746389 chore(portal): use local website url for versions in dev (#10057)
When starting a local client with a local portal, this URL is hit and
times out, causing noise in the local gateway log.

In order to develop against this API in local dev, it might be better to
use the local website URL as well.
2025-07-30 21:16:24 +00:00
Jamil
4a448e5517 fix(portal): separate dev and runtime Oban configs (#10027)
Oban includes its own configuration validation, which seems to prevent
`runtime.exs` from overriding any compile-time options. This prevents us
from using ENV vars to configure it, such as restricting job execution
to `domain` nodes by setting `queues: []`. To fix that, we make sure to
set Oban configuration in env-specific files `config/dev.exs` and
`config/test.exs`, and at runtime for prod with `config/runtime.exs`.

Fixes #10016
2025-07-28 15:13:52 +00:00
Jamil
c783b23bae refactor(portal): rename conditional->manual (#9612)
These only have one condition - to run manually. `manual migrations`
better implies that these migrations _must_ typically be run manually.
2025-06-21 21:17:33 +00:00
Jamil
a20989a819 feat(portal): conditional migrations on prod (#9562)
Some migrations take a long time to run because they require locks or
modify large amounts of data. To prevent this from causing issues during
deploy, we leverage Ecto's native support for loading migrations from
multiple directories to introduce a `conditional_migrations/` directory
that houses any conditional migrations we want to run.

To run these migrations, you'll need to do one of the following:

- `dev, test`: The `mix ecto.migrate` will run them by default because
we have aliased this to load conditional_migrations for dev
- `prod`: Set the `RUN_CONDITIONAL_MIGRATIONS` env var to `true` before
starting a prod server using the `bin/migrate` script.
- `dev, test, prod`: Run `Domain.Release.migrate(conditional: true)`
from an IEx shell.

If conditional migrations were found that weren't executed during
`Domain.Release.migrate`, a warning is logged to remind us to run them.

---------

Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
2025-06-18 18:08:25 +00:00
Jamil
ce82859cd4 fix(portal): Disable mock sync job in prod (#8606)
The adapter itself isn't enabled in the UI on prod, but the background
job to sync mock data was. This prevents the job from being started and
emitting log noise into production logs.
2025-04-01 18:24:48 +00:00
Jamil
28559a317f chore(portal): Optionally drop NotFoundError to sentry (#8183)
By specifying the `before_send` hook, we can easily drop events based on
their data, such as `original_exception` which contains the original
exception instance raised.

Leveraging this, we can add a `report_to_sentry` parameter to
`Web.LiveErrors.NotFound` to optionally ignore certain not found errors
from going to Sentry.
2025-02-18 21:55:23 +00:00
Brian Manifold
716623a993 feat(portal): Add IDP sync error email notifications (#6483)
This adds a feature that will email all admins in a Firezone Account
when sync errors occur with their Identity Provider.

In order to avoid spamming admins with sync error emails, the error
emails are only sent once every 24 hours. One exception to that is when
there is a successful sync the `sync_error_emailed_at` field is reset,
which means in theory if an identity provider was flip flopping between
successful and unsuccessful syncs the admins would be emailed more than
once in a 24 hours period.

### Sample Email Message
<img width="589" alt="idp-sync-error-message"
src="https://github.com/user-attachments/assets/d7128c7c-c10d-4d02-8283-059e2f1f5db5">
2024-09-18 15:29:50 +00:00
Andrew Dryga
835fc4c8eb chore(portal): Bump all deps related to portal (#6445) 2024-08-28 10:40:02 -06:00
Brian Manifold
e78737c4c8 fix(portal): Refactor API URL config for Web app (#6202)
Why:

* The Swagger UI is currently served from the API application. This
means that the Web application does not have access to the external URL
in the API configuration during/after compilation. Without the API
external URL, we cannot generate a proper link in the portal to the
Swagger UI. This commit refactors how the API external URL is set from
the environment variables and allows the Web app to have access to the
value of the API URL.

Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2024-08-07 19:30:18 +00:00
Brian Manifold
79c815fbbc feat(portal): Add REST API (#5579)
Why:

* In order to manage a large number of Firezone Sites, Resources,
Policies, etc... a REST API is needed as clicking through the UI is too
time consuming, as well as prone to error. By providing a REST API
Firezone customers will be able to manage things within their Firezone
accounts with code.
2024-07-20 04:20:43 +00:00
Andrew Dryga
8e4e7253e0 chore(portal): Split domains and set separate CAAs records (#5434) 2024-07-06 09:19:38 -07:00
Brian Manifold
26d8f7eab3 feat(portal): Add WorkOS/JumpCloud integration (#5269)
Why:

* JumpCloud directory sync was requested from customers. JumpCloud only
offers the ability to use it's API with an admin level access token that
is tied to a specific user within a given JumpCloud account. This would
require Firezone customers to give an access token with much more
permissions that needed for our directory sync. To avoid this, we've
decide to use WorkOS to provide SCIM support between JumpCloud and
WorkOS, which will allow Firezone to then easily and safely retrieve
JumpCloud directory info from WorkOS.

---------

Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2024-06-12 15:45:33 +00:00
Andrew Dryga
a7e54686b0 feat(portal): Track page views and sign ups using Mixpanel and HubSpot on public pages (#5050)
Fixes firezone/gtm#253
Fixes firezone/gtm#278
2024-05-21 10:34:56 -06:00
Andrew Dryga
13d7312738 chore(portal): Try new LoggerJSON implementation (#4595) 2024-04-11 17:54:44 -06:00
Andrew Dryga
5b1e3ea1d1 feat(portal): Billing system (#3642) 2024-02-20 15:01:17 -06:00
Jamil
0c25ad57cb Add link to status on website (#2974)
Fixes #2953
2023-12-20 22:56:40 +00:00
Andrew Dryga
1ab3fdd3b5 Ephemeral gateways (#2656)
- [x] Fixed docker run command to mount a volume at `/etc/firezone`
- [x] Fixed systemd unit file to prope setcap, create writeable
`/etc/firezone` directory, use non-root user, etc
- [x] Removed `FIREZONE_ID` from our terraform scripts

Now on Sites index we only show online gateways:
<img width="1728" alt="Screenshot 2023-11-15 at 18 04 12"
src="https://github.com/firezone/firezone/assets/1877644/b532f200-0420-4427-acff-a3b8623560c5">

On the Site view we also show only online ones with a link to see all:
<img width="1728" alt="Screenshot 2023-11-15 at 18 02 33"
src="https://github.com/firezone/firezone/assets/1877644/9774dfac-4340-41d4-8404-586e081505f5">

All can be seen on a separate page:
<img width="1728" alt="Screenshot 2023-11-15 at 18 02 27"
src="https://github.com/firezone/firezone/assets/1877644/5d135f60-c7af-4e48-9ebb-626ff7461316">

Some of the functions I've added are pretty dirty hacks, we really need
to implement filters from #2029 to properly implement those and remove
code duplicates.
2023-11-16 11:17:22 -06:00
Andrew Dryga
d1d07e8401 Hotfix merged typos, Sign In form content, Sign Up email content (#2645)
I fixed a few typos that slipped in in the last UX PR. Also a few minor
changes:

Sign In as a client doesn't show the "client" link in the bottom any
more:
<img width="1728" alt="Screenshot 2023-11-14 at 13 46 24"
src="https://github.com/firezone/firezone/assets/1877644/7226078c-7f66-41b5-9fd4-e6e44b56fd35">

Extra ---or--- separator is removed when there are no recently used
accounts:
<img width="1728" alt="Screenshot 2023-11-14 at 13 46 29"
src="https://github.com/firezone/firezone/assets/1877644/c2463ca5-0967-4fe7-ac60-5f5179ea30d8">

Emails send after you sign up don't include sign in link right away,
just a link to a form so that you won't loose in in future. Addresses
"Session token is expired/incognito windows" in #2631
<img width="1728" alt="Screenshot 2023-11-14 at 14 32 30"
src="https://github.com/firezone/firezone/assets/1877644/4f6d4c79-b5ed-448a-9915-2616ed71c9b9">

I've allowed email token to be used along with magic link when signing
in as @jefferenced requested multiple times:
<img width="1728" alt="Screenshot 2023-11-14 at 14 23 58"
src="https://github.com/firezone/firezone/assets/1877644/8b9b5afe-5c65-4893-b6ef-107a0b683c31">
<img width="1728" alt="Screenshot 2023-11-14 at 14 24 50"
src="https://github.com/firezone/firezone/assets/1877644/c02db5df-5158-4bf3-93ff-80d9d6c82cbe">

Closes #2299
2023-11-14 14:57:16 -06:00
Andrew Dryga
a7701c07de Override default API url in local/staging envs (#2611) 2023-11-09 11:41:38 -06:00
Jamil
72044cc065 refactor(android): Make app links more robust in the emulator (#2188)
Getting some weird behavior with AppLinks. They don't seem to work upon
first use and require a few tries to function correctly.

Edit: Found the issue: Android Studio doesn't like when the Manifest
contains variables for AppLinks. I added a note in the Manifest.

@conectado To test Applinks are working correctly, you can use the App
Link Assistant:

<img width="930" alt="Screenshot 2023-09-28 at 11 15 11 PM"
src="https://github.com/firezone/firezone/assets/167144/e4bd4674-d562-44ec-bdb8-3a5f97250b84">

Then from there you can click "Test App Links":

<img width="683" alt="Screenshot 2023-09-28 at 11 15 30 PM"
src="https://github.com/firezone/firezone/assets/167144/f3dc8e0d-f58a-4a4b-9855-62472096dc9e">
2023-09-29 18:09:04 +00:00
Andrew Dryga
fe06d2e42d Actor groups and group sync helpers (#1727) 2023-07-31 16:22:40 -06:00
Jamil
b50f6559d3 portal: Status indicator badge (#1703)
Did some research on status page providers to manage incidents.
statuspage.io seems to be easy to use and cost-effective, fairly popular
and provides a good amount of flexibility to customize emails,
notifications, etc.

Super easy to set up and use but am not married to it if anyone feels
strongly about using another incident management service.

https://firezone.statuspage.io

## Demo:

<img width="235" alt="Screenshot 2023-06-27 at 8 07 29 AM"
src="https://github.com/firezone/firezone/assets/167144/8ad12b9b-7345-4a5d-bf43-c8af798d85f9">
2023-06-27 14:19:31 -07:00
Andrew Dryga
e7d5d0579b Authentication for the live app (#1674)
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2023-06-27 13:11:36 -06:00
Andrew Dryga
89b7e3b474 Fix assets pipeline, add Elixir deps audit, add Android applink manifest (#1659) 2023-06-14 17:15:38 -06:00
Andrew Dryga
d9eb2d18df Deployment for the cloud version (#1638)
TODO:
- [x] Cluster formation for all API and web nodes
- [x] Injest Docker logs to Stackdriver
- [x] Fix assets building for prod

To finish later:
- [ ] Structured logging:
https://issuetracker.google.com/issues/285950891
- [ ] Better networking policy (eg. use public postmark ranges and deny
all unwanted egress)
- [ ] OpenTelemetry collector for Google Stackdriver
- [ ] LoggerJSON.Plug integration

---------

Signed-off-by: Andrew Dryga <andrew@dryga.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
2023-06-06 15:03:26 -06:00
Andrew Dryga
37a2d7b7f5 Move elixir code to a subfolder (#1631) 2023-05-24 15:46:51 -06:00