Commit Graph

1035 Commits

Author SHA1 Message Date
Jorge Manrubia 0754b0e93c Test moved to the gem 2025-11-28 15:53:58 +01:00
Jorge Manrubia e1e9a01720 Make open source the default, and check for sass instead 2025-11-28 15:53:48 +01:00
Mike Dalessio 3f8d10d679 Merge pull request #1747 from basecamp/flavorjones/perf-20251127
Address some N+1 query situations
2025-11-27 12:46:56 -05:00
Stanko K.R. e3d91f4ba2 Fix join codes skipping user setup
If someone joined an account with the same identity as they were signed in with the old logic would skip the user setup step
2025-11-27 17:59:17 +01:00
Mike Dalessio 79c9ea2ce1 Remove a bunch of N+1s
related to notification and comment rendering
2025-11-27 11:08:45 -05:00
Mike Dalessio 7f46063c25 Introduce gitleaks to the codebase
- `bin/setup` installs gitleaks
- add `gitleaks dir` command to CI
- configure gitleaks to ignore tmp, log, and encrypted files
- tag existing false positives with `gitleaks:allow`
- add historical false positives to the ignore list
2025-11-26 15:46:47 -05:00
Donal McBreen 761f86d78d Revert unnecessary fixture change 2025-11-26 10:30:02 +00:00
Donal McBreen c4498212dc Merge branch 'main' into sqlite
* main: (116 commits)
  Ensure avatar thumbnails are square
  Update useragent to recognize twitterbot/facebot
  Add defensive styles for non-square avatar images
  Update test for copy changes
  Missed commit
  AI: standardize on https://agents.md
  Make it clear this is just notifications, not comprehensive activity
  AI: configure MCP servers for Chrome, Grafana, and Sentry (#1727)
  Allow requests from Google Image Proxy
  Update to basecamp's useragent fork
  Clean up a little bit the CSRF reporting code
  Claude: production observability guidance (#1725)
  Prevent autoscroll to the root columns container to prevent jump on page load
  Include full name string so you can type your name to filter
  Prioritize current user and assigned users in assignment dropdown
  Check and report on Sec-Fetch-Site header for forgery protection
  bundle update
  Bump bootsnap from 1.18.6 to 1.19.0
  Bump rails from `077c3ad` to `17f6e00`
  Fix cards getting stuck in edit mode
  ...
2025-11-26 10:07:41 +00:00
Donal McBreen 9c86205510 Enforce SQLite column limits via CHECK constraints
Patch the sqlite adapter to add CHECK constraints for string and text
column limits. We'll do them inline, so that any column changes
automatically update the constraints.
2025-11-26 09:50:29 +00:00
Mike Dalessio 60e1751cac Update useragent to recognize twitterbot/facebot
This UA was pulled from our logs.

ref: https://app.fizzy.do/5986089/cards/1775
2025-11-25 18:05:21 -05:00
Mike Dalessio 64a39b3139 Merge pull request #1726 from basecamp/flavorjones/better-useragent-behavior
Allow requests from Google Image Proxy
2025-11-25 17:15:38 -05:00
Jason Zimdars 88765f5244 Update test for copy changes 2025-11-25 16:10:34 -06:00
Mike Dalessio b767d6edcb Allow requests from Google Image Proxy
which should fix email notifications' avatars rendering as broken
images in GMail.

ref: https://app.fizzy.do/5986089/cards/1740
2025-11-25 16:26:15 -05:00
Mike Dalessio 0bf62ba4cf Update to basecamp's useragent fork
and assert it's working by testing for Baidu
2025-11-25 16:18:23 -05: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
Donal McBreen 97bcdf1853 Enforce column limits via concern
SQLite columns lengths are purely informational, so we'll enforce the
limits via a concern that checks the lengths from the schema.
2025-11-25 15:32:34 +00:00
Stanko K.R. f64a49dcc0 Determine staff members based on flag
This replaces the old system based on email addresses, the aim is to make it more generic and thus appropriate for OSS/self-hosting

See: https://3.basecamp.com/2914079/buckets/37331921/todos/9302705265#__recording_9320051455
2025-11-25 14:09:31 +01:00
Donal McBreen b571303385 Don't use Current.account for search records
It doesn't actually work, and even if we could make it work reliably
we are better off if the records always know to go to the right shard.

It does make the interface a bit more complicated as we need to select
the right shard class with `for(account_id)`.
2025-11-25 11:34:41 +00:00
Mike Dalessio 9f117159a6 Restore structured logging of queenbee_id
and clean up some other small remaining "plan b" to-dos.
2025-11-24 15:50:45 -05:00
Mike Dalessio e0aa1d257e Drop User.system and replace with Account#system_user 2025-11-24 13:23:57 -05:00
Jason Zimdars a9da44b575 Merge pull request #1663 from basecamp/not-now-polish
Not now polish
2025-11-24 10:33:25 -06: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
Stanko K.R. 46d80f2ca2 Serve system user avatar as an asset 2025-11-24 13:16:14 +01:00
Stanko K.R. e85c5736c9 Render system user avatars using redirects 2025-11-24 12:05:32 +01:00
Jason Zimdars 56aa3f2a5b Update test 2025-11-24 12:04:33 +01:00
Mike Dalessio 26ccbf6968 Merge pull request #1695 from basecamp/flavorjones/better-card-edit-form-behavior
Update card buttons dynamically
2025-11-23 23:36:10 -05:00
Mike Dalessio db51b616bb Handle notifs created before the current bundle starts_at 2025-11-22 22:38:23 -05:00
Mike Dalessio a29dd89683 Make sure Bundle#ends_at is set before validation
otherwise we risk creating overlapping bundles and not catching it.
2025-11-22 22:19:05 -05:00
Mike Dalessio b05ecb7809 Update card buttons dynamically
User flows when editing a card look like:
- Click "Edit" → the closure buttons are replaced by "Save changes"
- Submit card form → Saves and restores closure buttons
- Press ESC while editing → Cancels and restores closure buttons

Also, renamed for clarity:
- _title.html.erb → _content.html.erb

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-22 12:14:39 -05:00
Mike Dalessio 4dc28943da Don't let cloudflare cache avatars
The issue here is that anyone else who views my avatar will cause it
to be cached, and then I can't easily bust the cache if I change my
avatar.
2025-11-22 09:48:28 -05:00
Jason Zimdars 0482d3b5ba Update test 2025-11-21 17:08:04 -06:00
Mike Dalessio ec8974640f User avatar responses have cache-control "public"
ref: https://app.fizzy.do/5986089/cards/3125
2025-11-21 16:08:52 -06:00
Mike Dalessio af0e2488d0 Improve avatar image handling
- redirect avatar image requests to the rails_blob_url, instead of
  streaming them through the web app
- use a thumbnail variant for avatar images
- only put avatar initials behind the stale? check (not the image
  redirect, which would result in browsers rendering broken images when
  an avatar is changed, until max-age expires)
2025-11-21 16:08:52 -06:00
Stanko K.R. fe909d6dc5 Disable stale while revalidate for own avatar
Locally, having stale_while_revalidate works great, but in production when we are behind CloudFlare, this results in an old image being shown after you upload a new one

See: https://app.fizzy.do/5986089/cards/2978
2025-11-21 19:26:38 +01:00
Mike Dalessio 7a057b81af Merge pull request #1682 from basecamp/flavorjones/active-storage-cleanup
Drop the "max previewable file size" limit
2025-11-21 10:56:54 -05:00
Mike Dalessio b2e3c7b1c7 Drop the "max previewable file size" limit
which was originally introduced to work around timing issues causing
us to try (and fail) to generate previews on sqlite read replicas.
2025-11-21 10:55:20 -05:00
Donal McBreen d48eb523b8 Fix rubocop 2025-11-21 15:30:14 +00:00
Donal McBreen b1862733dd Merge branch 'main' into sqlite 2025-11-21 15:23:34 +00:00
Donal McBreen 525e53a2f7 Add FTS ActiveRecord model
Needs some special handling for the FTS virtual table format. Set the
primary key to rowid and manually specify the columns.
2025-11-21 15:21:11 +00:00
Donal McBreen 04c9d9268b Remove wrapper methods and kwargs 2025-11-21 14:53:17 +00:00
Donal McBreen ea06b2d46f Simplify and test highlighing 2025-11-21 14:25:38 +00:00
Donal McBreen 01d16f96d4 Remove Search::Record.for_account
Instead we'll compute the table name dynamically based on
Current.account where needed. Also we'll prevent searchable records
from being saved if Current.account is not set, otherwise the after
commit callbacks will fail.
2025-11-21 12:09:21 +00:00
Jorge Manrubia 93ee8899a0 More robust implementation to prevent method injection attacks 2025-11-21 10:38:16 +01:00
Donal McBreen 19b0e25eac Split sqlite/mysql record stuff 2025-11-21 09:15:19 +00:00
Donal McBreen bb36b4846f Support SQLite searching 2025-11-21 09:15:19 +00:00
Donal McBreen a2333d9a37 Add SQLite support
- UUID support
- Schema compatibility layer, ignore MySQL specific options
- Search not working yet
2025-11-21 09:15:19 +00:00
Jason Zimdars dca002bd64 Update test 2025-11-20 21:51:07 -06:00
Mike Dalessio 1bbb6d0c03 Fix race condition in Card::ActivitySpike::DetectionJob
The check-then-act pattern in `register_activity_spike` has been
replaced with `find_or_create_by!` to eliminate the race condition
that could lead to creating multiple activity spikes for a card. To
support this change, the `card_id` index on `cards_activity_spikes`
has been made unique.

ref: https://app.fizzy.do/5986089/cards/3063
2025-11-20 15:40:42 -05:00
Mike Dalessio 88750a3498 Prefer Time.current to Time.now 2025-11-20 09:13:17 -05:00
Stanko K.R. 8a1cbdd0ae Fix links in previews 2025-11-20 10:49:29 +01:00