Commit Graph

173 Commits

Author SHA1 Message Date
Stanko K.R. b92982b244 Cleanup & simplify sign in 2025-12-19 19:21:57 +01:00
Italo Matos cd4fbc011c Refactor: Replace reverse_merge with with_defaults for improved readability
Replace all occurrences of reverse_merge with with_defaults across the codebase.
The with_defaults method provides clearer intent and better readability when
setting default values for hash parameters.

Changes:
- app/helpers/columns_helper.rb: Update column_frame_tag method
- app/models/user/email_address_changeable.rb: Update generate_email_address_change_token method
- app/models/account.rb: Update create_with_owner method
- app/controllers/concerns/filter_scoped.rb: Update filter_params method

This refactoring maintains the same functionality while improving code clarity.
2025-12-14 14:22:06 -03:00
Jeremy Daer 82626f020d Tailscale serve support (#2126)
Ensure we can serve the app from multiple hosts without breaking links.
* Switch unnecessary full URLs to paths
* Drop default host/port URL options for controllers

Shell 1
```bash
bin/dev
```

Shell 2
```bash
tailscale serve http://fizzy.localhost:3006
```
2025-12-13 09:29:50 -08:00
Mike Dalessio 9cff236f66 Drop staff restriction in beta and staging
because it was preventing testing of signups.
2025-12-12 15:12:46 -05:00
Rosa Gutierrez 7f5fa6d715 Use Sec-Fetch-Site exclusively for CSRF protection
And close the gap with JSON requests, which shouldn't be allowed if
Sec-Fetch-Site is 'cross-site' or 'none', only if it's empty as this
wouldn't be coming from a browser.
2025-12-12 18:37:32 +01:00
Stanko Krtalić 23425cb67b Merge pull request #2086 from basecamp/harden-magic-links
Pin sign in attempts to the current session
2025-12-12 07:23:19 +01:00
Stanko K.R. abaed12124 Prohibit access to magic links unless an email address 2025-12-11 19:17:39 +01:00
Stanko K.R. b6edb93c47 Pin sign in attempts to the current session
This makes it way more difficult to brute-force a magic link.

Original implementation by udiudi. Ref: https://github.com/udiudi/fizzy/pull/1/files

Discussion: https://github.com/basecamp/fizzy/discussions/1981

Co-Authored-By: Udi <udi@udi.codes>
2025-12-11 19:05:54 +01:00
Mike Dalessio 3d523b84fc Explicitly use main_app for URL helpers
in controller concerns that are mixed into other engines' controllers. This prevents errors like:

> NoMethodError: undefined method 'session_menu_url' for an instance of ActiveStorage::DirectUploadsController

See also 912bb8a8 and 5ee10800
2025-12-11 12:55:32 -05:00
Stanko K.R. 259707bf70 Fix identity tests 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 0159f369f4 Only authenticate with bearer token if the header is present 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 79fc57a82a Use built-in authenticate_or_request_with_http_token
Hat tip to @adrienpoly
2025-12-10 09:23:52 +01:00
David Heinemeier Hansson efbd2cc3da Allow API JSON requests to sidestep csrf protection 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 0ce3a85778 Only allow writing when the access token has permission 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson caa4cd491e Smooth out the finder API 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 7d2c284726 Clarify 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 467843fe22 Inline now anemic helper methods 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 3329008dd8 Handle everything in the same method 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 660fcff558 Authenticate api requests without needing a session 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson db29562c4c Tie access token directly to session
We need to present them differently in the session list and prevent them
from being deleted
2025-12-10 09:23:52 +01:00
David Heinemeier Hansson a81c681a8d Add access token authentication via HTTP AUTHORIZATION bearer header 2025-12-10 09:23:52 +01:00
Mike Dalessio 0160f215f2 Validate email before creating identity during sign-up and sign-in
Avoid Sentry exceptions when attackers try to stuff invalid emails. The
browser performs form field validation that should normally prevent this
from occurring, so we just return 422 without validation error messages.

Also:

- extract redirect_to_session_magic_link helper
- some controller refactoring and cleanup
2025-12-06 16:52:16 -05:00
Jeremy Daer 9f6a4f1cc6 Fix unauthorized column reordering
Users could reorder columns they didn't have access to. Fixed by
limiting ColumnScoped to User::Accessor#accessible_columns.

References https://hackerone.com/reports/3449905
2025-12-03 13:00:49 -08:00
Jeremy Daer b755b3fead Robots, begone (#1812)
* robots.txt: "Please, don't come in." If a page is directly linked, the
  URL can still appear in search results, though.
* X-Robots-Tag: "If you're here, forget what you saw." Works even if the
  crawler ignores robots.txt or reaches a page via external link. Can
  remove already-indexed pages.
* Public boards may not be indexed. They're meant for "anyone with the
  link" private sharing, not worldwide publishing.
2025-12-02 13:35:58 -08:00
Jorge Manrubia c9ebb79dbd Add some protections around sharing the magic link in development 2025-12-02 10:51:14 +01:00
Rosa Gutierrez f8a1e0500d Switch from report-only to actually using Sec-Fetch-Site for CSRF protection
As a fallback for Rails's token-based mechanism. To use Sec-Fetch-Site
exclusively, we'll wait until Rails offers that (when we upstream this).
2025-11-28 16:26:03 +01:00
Jorge Manrubia 3223ba53c3 We need the check in both test/code 2025-11-28 15:53:58 +01:00
Jorge Manrubia 6ccf655597 Move yabeda/prometheus stuff to the gem 2025-11-28 15:53:58 +01:00
Jorge Manrubia 3b0ddf4cfb Move sentry to engine 2025-11-28 15:53:58 +01:00
Jorge Manrubia 1897cc238f Only staff can access beta/staging
https://app.fizzy.do/5986089/cards/3208
2025-11-28 15:53:58 +01:00
Jorge Manrubia 4e09352c09 Bring simple signup flow from the fizzy-saas gem
We skip the QB code and we fill external account ids automatically on creation with a sequence

See:
https://github.com/basecamp/fizzy-saas/pull/7
2025-11-28 15:53:58 +01:00
Jorge Manrubia e30709f6a7 Remove structured logging moved to the engine 2025-11-28 15:53:58 +01:00
Jorge Manrubia c1334f7ffe Don't choke if no structured logging
Temporary workaround, we need a better solution here.
2025-11-28 15:53:58 +01:00
Rosa Gutierrez 3e716bfa26 Fix a couple of typos 2025-11-26 13:16:44 +01:00
Rosa Gutierrez fac9f3c369 Clean up a little bit the CSRF reporting code
Small follow-up to https://github.com/basecamp/fizzy/pull/1721
2025-11-25 21:28:50 +01:00
Rosa Gutierrez d88949288c Check and report on Sec-Fetch-Site header for forgery protection
This is a great, solid alternative to CSRF tokens for CSRF protection
when we aren't worried about older browsers or other kind of actors
doing modifying requests in our app, and could be a good test for future
upstreaming to Rails (although there we'd need to continue using CSRF
tokens or at least letting people opt out manually).

Let's start checking the header and reporting on it when CSRF fails or
when it doesn't match the other checks Rails does, and then promote this
to be the only way to defend from CSRF.
2025-11-25 19:19:50 +01:00
Kevin McConnell bd259f7795 Add optimistic pausing to avoid stale reads
Instead of writer pinning, we'll track the last transaction ID of each
write in the session. Then on each read we'll wait for the replica to
report that this transaction is available.

If it doesn't become available within a reasonable timeout, we'll
proceed anyway, and accept the possibility of a stale read.

The hope here is that most of the time, the replica is caught up in the
time between a write request and the following read request. If it's
not, we now have a little tolerance to wait for it, which hopefully
proves enough to stale reads are not encountered in normal use.

We also disable the writer affinity opt-out mechanism that we had
before, since we will no longer be using writer affinity at the load
balancer.
2025-11-24 13:29:52 +00:00
Mike Dalessio 4636b31f06 Authorization ensure_staff uses identity.staff
for use on untenanted routes
2025-11-19 14:23:47 -05:00
Mike Dalessio f5305b2fe6 Use Card number as the model param
instead of the UUID `id`
2025-11-17 09:12:41 -05:00
Kevin McConnell 9615753e1f Add routing header to see who served request 2025-11-17 09:12:41 -05:00
Stanko K.R. e0693de7c3 Scope jobs and controllers by account 2025-11-17 09:12:41 -05:00
Mike Dalessio 5a7f08067a Move setting Current.account into the middleware
so that code called from the Rails controllers can use Current.account
2025-11-17 09:12:40 -05:00
Stanko K.R. edf837fed3 Drop memberships 2025-11-17 09:12:39 -05:00
Stanko K.R. 5c6b91ef77 Fix incorrect var setting 2025-11-17 09:12:36 -05:00
Stanko K.R. 71a332bb08 Remove dead code 2025-11-17 09:12:17 -05:00
Stanko K.R. db172bae4e Simplify authorization 2025-11-17 09:12:17 -05:00
Stanko K.R. 28a6dfce01 Simplify user deactivation 2025-11-17 09:12:17 -05:00
Stanko K.R. 6858b96619 Simplify join codes 2025-11-17 09:12:17 -05:00
Mike Dalessio 89d1299ec0 Fix authentication on "untenanted" controllers
trying out the name "disallow_account_scope" for this, but I don't
think it's quite right yet.
2025-11-17 09:11:47 -05:00
Mike Dalessio 086a9ceada Revert some auth pieces of "Account.sole → Current.account" 2025-11-17 09:11:45 -05:00