774 Commits

Author SHA1 Message Date
Jay Ohms 26fc9ecad4 Add an /identity.json endpoint to obtain the identity accounts and users 2025-12-10 09:23:52 +01:00
Jay Ohms 680f9c0c4d Add top-level API index support for tags 2025-12-10 09:23:52 +01:00
David Heinemeier Hansson 88902485e1 Access tokens are strictly personal 2025-12-10 09:23:52 +01:00
Jason Zimdars 073d1af862 List, create, and revoke access tokens 2025-12-10 09:23:52 +01:00
Adam Haris 0780b5168f add env variable to disable multi-tenancy 2025-12-09 15:40:01 +01:00
Kevin McConnell 0430ce0620 Merge pull request #1911 from harisadam/main
Configure email delivery in production using environment variables
2025-12-09 12:56:03 +00:00
Kevin McConnell 99bee0e0e0 Make SMTP config conditional on SMTP_ADDRESS
- If `SMTP_ADDRESS` is set, configure Action Mailer to use it, along
  with additional optional SMTP-related settings.
- Otherwise, don't set config (for compatibility with engines like
  fizzy-saas).
- Remove sendmail env setup, since by default there is no sendmail in
  the container, and custom deployment can use whatever config the want
  directly. If we end up needing this, we can bring it back via its
  own env.
2025-12-09 12:44:36 +00:00
Adam Haris 9de59ca37b default to smtp 2025-12-09 11:54:45 +00:00
Adam Haris 1d5654cafa configurable actionmailer settings (ENV) 2025-12-09 11:54:44 +00:00
Jorge Manrubia da2bd2f2ec Merge pull request #2024 from basecamp/immediate-variant-locally
Process blob variants using local files
2025-12-09 12:17:12 +01:00
Lewis Buckley a2d4f3431e Merge pull request #2018 from basecamp/ssl-config
Allow configuring SSL in production with ENV vars
2025-12-09 00:51:08 -08:00
Jeremy Daer 8eb01da057 Process blob variants using local files
Rails does post-upload variant processing using the same file upload
in https://github.com/rails/rails/pull/56327

Unrelated Lexxy bump:
Pulls in https://github.com/basecamp/lexxy/pull/493 to work around `dom_id`
removal from ActionText tag in https://github.com/rails/rails/pull/51238
2025-12-08 23:41:15 -08:00
Jeremy Daer 08896deb32 bin/ci: run OSS suite in SAAS mode for full coverage (#2029) 2025-12-08 23:33:46 -08:00
Hosmel Quintana 2eeeda9bad rename Active Storage service to s3 and add checksum env 2025-12-08 18:33:27 -06:00
Hosmel Quintana ac1f935d53 Update config/environments/production.rb
Co-authored-by: Alex Ghiculescu <alex@tanda.co>
2025-12-08 18:33:27 -06:00
Hosmel Quintana b3bc0bb2ff allow configuring Active Storage service and add AWS S3 definition 2025-12-08 18:33:27 -06:00
Jeremy Daer 49c4f2adc6 Fix ActiveStorage FileNotFoundError with immediate variant processing (#2022)
When ActiveStorage::Record uses `connects_to` for read replica support,
it creates a separate connection pool from ApplicationRecord. This causes
`after_commit` callbacks to fire in non-deterministic order - the
Attachment's `create_variants` callback can fire before the User model's
upload callback completes, resulting in FileNotFoundError.

The fix removes replica connection configuration from ActiveStorage::Record
so it shares the same connection pool as application models, ensuring
proper callback ordering.

Also reverts test workarounds that were added to work around this issue,
since the root cause is now fixed.

See: https://github.com/rails/rails/issues/53694
2025-12-08 14:44:49 -08:00
Jorge Manrubia cb0e9b9962 Immediate avatar and embed variants (#2002)
Reverts #2001
Restores #1955
2025-12-08 14:17:06 -08:00
Lewis Buckley 50be611f01 Allow configuring SSL in production with ENV vars 2025-12-08 20:57:01 +00:00
Jeremy Daer dcc005be34 Add lazy error context for Rails error reporter (#2014)
Register a middleware with Rails.error that adds identity_id and
account_id from Current attributes. Only evaluated when an error
is actually reported, avoiding the cost on successful requests.
2025-12-08 11:00:40 -08:00
Jeremy Daer b88182c3ad Autotuner: use structured logging instead of Sentry (#2011)
Move thousands of info-level Sentry events to logs. Query Loki rather
than downsampling events: `event.action = "run.ruby-script",
script.name = "autotuner"`
2025-12-08 10:01:28 -08:00
Jorge Manrubia c8c91259c7 Revert "Immediate avatar and embed variants" 2025-12-07 12:06:03 +01:00
Jorge Manrubia 2ef0377f56 Merge pull request #1966 from ari-party/main
Add WEB_CONCURRENCY env support for Puma worker count
2025-12-07 11:59:15 +01:00
Jorge Manrubia 568783efd1 Merge pull request #1905 from basecamp/web-push-ssrf
Security: Web Push SSRF
2025-12-07 11:58:14 +01:00
Jorge Manrubia 91017c9208 Merge pull request #1955 from basecamp/immediate-variants
Immediate avatar and embed variants
2025-12-07 11:50:02 +01:00
Stanko K.R. 73c2b00211 Rever to using Ssrf instead of SSRF
Ref: https://github.com/basecamp/fizzy/pull/1967#discussion_r2593750027
2025-12-06 11:04:55 +01:00
Jeremy Daer af14feb8fc CSP gives env config precedence (#1976)
Bit clearer, and simpler config wrangling: presence of ENV → use it.
2025-12-05 20:49:41 -08:00
Jeremy Daer ab5964a375 Tune CSP: allow required external sources and user tools (#1977)
External sources:
- challenges.cloudflare.com for Turnstile (script-src, frame-src)
- storage.basecamp.com for Active Storage (connect-src)

User tools: loosen style/img/font/media/worker-src to avoid fighting
accessibility extensions, privacy tools, and custom fonts.
2025-12-05 20:45:48 -08:00
Mike Dalessio 4602cd3cdd Add verified_at timestamp to use for spam prevention
User are marked as verified after a join code is redeemed. The user is
redirected to Users::VerificationsController, either:

- after submitting a valid magic link code,
- or immediately after redeeming the join code (if they're already
  authenticated with the correct identity)

Account owners are automatically verified when the account is
created (because they have already provided a magic link code at that
point).

This sets up for later commits that will backfill existing users and
require verification before sending notification emails.

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 21:51:44 -05:00
Jeremy Daer 345f457513 Tune CSP for user extensions and close implicit-allow gaps (#1974)
Loosen font-src and add media-src to allow browser extensions like
accessibility fonts (OpenDyslexic) and user style managers to work
without CSP violations.

Add default-src and connect-src directives to close security gaps where
unspecified directives were implicitly allowing all sources.
2025-12-05 16:57:03 -08:00
Jeremy Daer 6006491ab4 Content Security Policy (#1964)
Default to a very narrow policy since there are no CDNs or third-party
resources to contend with.

Configurable via:
- config.x.content_security_policy.* for fizzy-saas gem overrides
- DISABLE_CSP to skip entirely
- CSP_REPORT_ONLY to enable report-only mode
- CSP_REPORT_URI for violation reporting
2025-12-05 14:57:50 -08:00
astrid fcce276dc9 Update JOB_CONCURRENCY to match upstream Rails 2025-12-05 20:20:13 +01:00
Stanko K.R. cd3751f4c1 Fix Resolv::DNS always returning no results 2025-12-05 20:09:39 +01:00
ari 430a0c612b Update config/puma.rb (commit suggestion)
Co-authored-by: Jeremy Daer <jeremydaer@gmail.com>
2025-12-05 19:57:55 +01:00
astrid 3acc58ff41 Add WEB_CONCURRENCY env support for Puma worker count 2025-12-05 19:26:54 +01:00
Kevin McConnell 04153038f0 Document deployment
- Update the README with detailed information about how to deploy a
  Fizzy instance
- Reduce the example deploy config
- Add example SMTP configuration in production.rb
2025-12-05 17:03:07 +00:00
Jeremy Daer 21f3f72647 Immediate avatar and embed variants
Process variants synchronously on attachment to close the window between
image upload and variant availability, guaranteeing that we won't have
lazy variant processing attempts in GET requests.

Tradeoff is that we do variant processing in upload requests, which is
actually desirable. We're working with images that should take
milliseconds to resize given that we'll already have the file on hand.

References https://github.com/rails/rails/pull/51951
2025-12-04 23:54:37 -08:00
Jeremy Daer 496851b255 Security: Web Push SSRF and IP range bypass
Add SSRF protection for web push endpoints:
- Resolve endpoint IP once and pin it for connection
- Validate endpoints resolve to public IPs
- Whitelist permitted push service hosts

Add missing IP ranges to SsrfProtection:
- 100.64.0.0/10 (Carrier-grade NAT, RFC6598)
- 198.18.0.0/15 (Benchmark testing, RFC2544)

Note: link-local (169.254.0.0/16) is already covered by ip.link_local?
2025-12-04 21:35:55 -08:00
Kevin McConnell 08c380cc71 Remove trailing whitespace
Appease the Rubocop
2025-12-04 13:32:47 +00:00
David Heinemeier Hansson b3481b10a8 Move legacy out of sight 2025-12-04 03:34:30 -08:00
Stanko Krtalić 6050f187ca Merge pull request #1895 from jbnunn/remove-legacy-join-pattern
Removed legacy join link
2025-12-04 09:21:08 +01:00
umarhadi 374fa1b5d0 Add production queue and cache database config 2025-12-04 09:50:45 +07:00
J. Nunn 383033b9d0 Removed legacy join link 2025-12-03 18:06:38 -08:00
Donal McBreen 13db384648 Auto default for UUID primary keys
Patch load_schmema! to set the default value for UUID primary keys. This
removes the need to patch ApplicationRecord + Rails models individually.

It also means we no longer need to patch the default in for the integer
primary key in Search::Record::SQLite.
2025-12-03 14:27:52 +00:00
Dave Kimura 4c669b26fb Updated database.sqlite.yml 2025-12-02 16:11:10 -05:00
Kevin McConnell 60e7e9ffd8 Merge pull request #1733 from basecamp/allow-all-signups
Remove basic auth restriction on signup
2025-12-02 15:46:04 +00:00
Kevin McConnell d24726c1d3 Merge pull request #1768 from basecamp/data-exports
Add "data export" feature
2025-12-02 09:56:40 +00:00
Kevin McConnell 9ae9e67d24 Remove all credentials files 2025-12-02 09:11:37 +01:00
David Heinemeier Hansson 28371e10c8 Turn off the help notice 2025-12-01 16:25:23 +01:00
Kevin McConnell e16cc21b0a Add "data export" feature
- Adds a button in Account Settings where you can request a ZIP export of your
  Fizzy data
- Export files are created in the background. When ready, a link to
  download them is sent to the requester.
- Exports expire after 24 hours. And are limited to 10 per day.
2025-12-01 15:23:26 +00:00