Commit Graph

24 Commits

Author SHA1 Message Date
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 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
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
David Heinemeier Hansson 444d43f2ac Its been a few days 2025-11-18 14:52:07 +01:00
Kevin McConnell 9615753e1f Add routing header to see who served request 2025-11-17 09:12:41 -05:00
Kevin McConnell dc40d2b5b0 Remove custom read/writer routing 2025-11-17 09:11:28 -05:00
Stanko K.R. bbe74966a1 Extract saas helpers into a concern 2025-11-07 07:08:24 +01:00
Jorge Manrubia b2e2a5d959 Invalidate HTTP cache 2025-11-05 13:49:26 +01:00
Stanko K.R. ece9008459 Remove dead code 2025-10-31 16:28:08 +01:00
David Heinemeier Hansson 7bebea07b4 Simplify the error handling
Just use normal HTML + static CSS
2025-10-29 17:39:57 +01:00
David Heinemeier Hansson a0c6b8394a Split by layering 2025-10-29 13:51:41 +01:00
Kevin McConnell c1600a99e2 Populate writer and last transaction in responses
In order to control routing dynamically, we need to expose some Beamer
information to the proxy.

The `beamer_writer` value is used by the proxy to keep track of which
node should receive write requests. When it changes due to a failover,
the proxy will update after seeing a new value in this header. We
provide this to the proxy in the `X-Writer` response header.

The `beamer_last_txn` value will be used to control writer pinning.
Setting it in the cookie here is the first stage of this. The second
stage will be to catch situations where a reader gets a request where
this header value is set to a large value than the reader has seen; when
that happens if means there's a risk of reading stale data, so rather
than serve the request we should request the proxy to reproxy it back to
the writer.

We also set `X-Kamal-Target` in the response to match the
`X-Kamal-Target` that was set in the request; this lets us see which
proxy target served each request, which is useful for diagnostics.
2025-10-15 08:46:45 +01:00
Jorge Manrubia b177f92ec1 Prevent view transition animations on page refreshes
View transitions don't play great with page refreshes as they can make those
very noticeable
2025-10-14 15:38:35 +02:00
Stanko K.R. 25b2daad93 Limit access to webhooks to admins 2025-09-16 20:04:20 +02:00
Mike Dalessio 93c3730ec9 Fix handling of "406 unsupported browser" responses
Broken in 84b8bb0a
2025-09-09 17:07:24 -04:00
Mike Dalessio 988b20a36d Introduce turbo_stream_flash helper and use it for collection edit
The collections/{entropy,publications,workflows} controllers all
respond via turbo stream, and now also provide a flash message.
2025-08-07 15:04:45 -04:00
Mike Dalessio 319e4223e4 Add request details to Current 2025-06-20 15:16:56 -04:00
Kevin McConnell 63ddb23585 Opt out of writer affinity on readings controller 2025-06-16 15:05:47 +01:00
Jason Zimdars d17134cb5c Detect platform and label the correct hotkey shortcut
Yes, Platform Agent is overkill for just this but there isn't a one-size JS solution for updating both input placeholders and other HTML text and we're likely to need it later for other things like displaying platform-specific PWA prompts.
2025-05-27 12:14:24 -05:00
Kevin McConnell 94b2c256b9 Set request timezone to match browser 2025-01-27 14:16:15 +00:00
David Heinemeier Hansson 84a07343a4 Use stale_when_importmap_changes 2024-12-20 17:42:14 -08:00
Kevin McConnell c4fb1bdc76 Add minimal authentication flow to get started 2024-06-21 16:45:29 +01:00
Kevin McConnell 564a0f48ae New Rails app 2024-06-21 13:19:56 +01:00