Commit Graph

9876 Commits

Author SHA1 Message Date
Mike Dalessio e12f3e3917 Add representation proxy Cache-Control test 2026-03-26 15:34:54 -04:00
Mike Dalessio 14e6832507 Add regression test for public blob Cache-Control 2026-03-26 15:22:21 -04:00
Mike Dalessio 628571fc79 Don't set public Cache-Control on proxied non-public blobs
Rails' ActiveStorage proxy controllers hardcode `http_cache_forever public: true`,
which sets `Cache-Control: public, immutable`. For non-public blobs behind auth,
this allows CDN caching that serves responses without authorization checks.

Override `http_cache_forever` in the Authorize concern to downgrade `public` to
`false` for non-public blobs.

See https://github.com/basecamp/fizzy/pull/2251 for context
2026-03-26 14:58:40 -04:00
Stanko Krtalić 09d5b8c92f Merge pull request #2756 from basecamp/friendly-error-message-on-duplicate-passkey
Show separate error message when adding a Passkey twice
2026-03-26 14:19:35 +01:00
Stanko Krtalić 527f2e07ff Merge pull request #2754 from basecamp/update-aws-gem
Update AWS SDK
2026-03-25 18:36:29 +01:00
Stanko K.R. 61580ec58f Update AWS SDK 2026-03-25 18:30:01 +01:00
Stanko Krtalić 01b4698e13 Merge pull request #2751 from basecamp/passkey-improvements
Passkey improvements
2026-03-25 18:19:09 +01:00
Stanko K.R. 6107d3cee1 Add margin ot error messages 2026-03-25 18:16:11 +01:00
Stanko K.R. 5820480c0c Update SAAS gemfile 2026-03-25 18:10:11 +01:00
Stanko K.R. 54cb1a140f Add a purpose to challanges 2026-03-25 17:57:37 +01:00
Stanko K.R. 37ff66d552 Fix gemfile drift 2026-03-25 17:42:27 +01:00
Stanko K.R. 01d66a9463 Change challange expiration based on purpose 2026-03-25 17:31:42 +01:00
Stanko K.R. 6ba1814f26 Update bcrypt and loofah 2026-03-25 17:30:39 +01:00
Stanko Krtalić dac4d9233c Merge pull request #2741 from basecamp/dependabot/bundler/aws-sdk-s3-1.216.0
Bump aws-sdk-s3 from 1.215.0 to 1.216.0
2026-03-25 17:28:50 +01:00
Stanko K.R. 5d0f52b57c Update as_json to return string keys 2026-03-25 17:26:50 +01:00
Stanko K.R. f5ae2f8076 Rename extract_passkey_component_options to partition_passkey_options 2026-03-25 17:26:50 +01:00
Stanko K.R. 693415bc71 Rename request options to authentication options 2026-03-25 17:26:49 +01:00
Stanko K.R. df7c2678f3 Rename create_options to registration_options 2026-03-25 17:26:49 +01:00
Stanko K.R. 8e4f9ce5e7 Cleanup form helpers 2026-03-25 17:26:49 +01:00
Stanko K.R. 1983014be6 Rely solely on the challange signature for verification
The cookie approach seems like the more secure aproach because it ties the authentication or registration attempt to the user's browser session, but it doesn't work reliably on Chrome for Windows. Also, a simila problem pops up on Chrome for Linux if the session is used instead of a separate cookie. It looks like the browser doesn't propagate the state change through fast enough which results in some requests contaiining the new/updated cookie, and others don't, which results in sporadic failures. Since we use a signed and expiring challange we still get protection from replay attacks and tampering which enables us to omit the cookie entierly and rely on the challange's signature to prove expiration and authenticity. The only thing we lose is the ability to tie and attemp to a single browser session.

See: https://github.com/w3c/webauthn/wiki/Explainer:-WebAuthn-challengeURL which proposes to add the same challange fetching logic as part of the standard

See: https://github.com/w3c/webauthn/issues/1856 which discusses issues that arise from having expiring challanges (which the spec recommends)

See: https://github.com/OneUptime/oneuptime/security/advisories/GHSA-gjjc-pcwp-c74m which is an explot that can happen if the server isn't able to verify the authenticity of challanges that are sent outside of a cookie
2026-03-25 17:26:49 +01:00
Stanko K.R. 4fb1cddb4c Use WebComponents for buttons
This simplifies the loading and cleanup logic, while providing ubiquitous support across JS frameworks. Buttons can now be added in any way imaginable and still work without requiring additional initialization. The upside of this aproach is that it doesn't require a mutation observer nor a global click listener, and is supported by all browsers that also support passkeys.
2026-03-25 17:26:49 +01:00
Stanko Krtalić 70c08877b7 Merge pull request #2735 from basecamp/dependabot/bundler/bcrypt-3.1.22
Bump bcrypt from 3.1.21 to 3.1.22
2026-03-25 17:23:26 +01:00
Sean Mitchell 4b4454de89 Update colophon icons 2026-03-24 13:32:39 -07:00
Jason Fried 2c60ddb7c7 Added Basecamp + HEY icons/links 2026-03-24 12:12:33 -07:00
Stanko Krtalić 4551952d05 Merge pull request #2749 from basecamp/potential-windows-hello-on-chrome-fix
Use Same-site: Lax
2026-03-24 15:23:52 +01:00
Stanko K.R. c24d4fd7fd Use Same-site: Lax
This is a guess based on a few articles I read where Windows Hello doesn't play nice with Same-Site: Strict. I have no credible evidence to back this up.
2026-03-24 15:17:05 +01:00
Stanko Krtalić 1f63589d7e Merge pull request #2748 from basecamp/fix-passkey-buttons-not-triggering-sometimes
Fix Passkey buttons not triggering sometimes
2026-03-24 14:51:14 +01:00
Stanko K.R. 134a533e28 Fix Passkey buttons not triggering sometimes 2026-03-24 14:36:52 +01:00
Andy Smith 7632802f18 Merge pull request #2682 from nqst/delete-account-improvements
Delete account: design improvements
2026-03-23 09:38:23 -05:00
Stanko Krtalić e3cd789ede Merge pull request #2746 from basecamp/fix-exports
Permit variant records in imports
2026-03-23 12:50:24 +01:00
Stanko K.R. 49fbb82676 Permit variant records in imports 2026-03-23 12:30:40 +01:00
Zacharias Knudsen 6808250c8f Merge pull request #2745 from basecamp/excert-truncation
Pre-truncate excerpt before running replacement regexes
2026-03-23 10:24:58 +01:00
Zacharias Dyna Knudsen 6c771584d7 Pre-truncate excerpt before running replacement regexes
Also fixes <ol> normalization which was previously a noop.
2026-03-23 10:21:35 +01:00
Mike Dalessio bcf6e92131 Merge pull request #2740 from basecamp/autolink-skip-large-text-nodes
Skip auto-linking in very large text nodes
2026-03-20 20:02:57 -04:00
Mike Dalessio 8c3461a1d6 Remove @regexp_timeout_reported from AutoLinkScrubber
No longer needed since the scrubber is not memoized across calls and the
text node length guard prevents the performance issue.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 19:53:02 -04:00
github-actions[bot] 940fb2fafc Sync Gemfile.saas.lock 2026-03-20 20:24:28 +00:00
dependabot[bot] 4f0a51785e Bump aws-sdk-s3 from 1.215.0 to 1.216.0
Bumps [aws-sdk-s3](https://github.com/aws/aws-sdk-ruby) from 1.215.0 to 1.216.0.
- [Release notes](https://github.com/aws/aws-sdk-ruby/releases)
- [Changelog](https://github.com/aws/aws-sdk-ruby/blob/version-3/gems/aws-sdk-s3/CHANGELOG.md)
- [Commits](https://github.com/aws/aws-sdk-ruby/commits)

---
updated-dependencies:
- dependency-name: aws-sdk-s3
  dependency-version: 1.216.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-20 20:24:17 +00:00
Mike Dalessio 87c659cd67 Skip auto-linking in very large text nodes
A large comment body was causing Regexp::TimeoutError in production.
The URI regexp isn't catastrophically backtracking — it's linear — but
with a long enough string it exceeds the 1s Regexp.timeout set by
Rails.

Skip scanning text nodes over 10KB, which is well beyond any
reasonable content for auto-linking and still keeps us many orders of
magnitued under the timeout on an unloaded machine.

Fixes FIZZY-Q4

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:18:19 -04:00
Mike Dalessio 95a45aa651 Don't memoize AutoLinkScrubber across format_html calls
The scrubber was memoized on the view helper in b0fa6525 so that
@regexp_timeout_reported would stop scanning remaining text nodes
after a timeout. But memoizing on the helper leaks that flag across
all format_html calls for the entire request — if one comment triggers
a timeout, every subsequent comment on the page loses auto-linking.

Use a fresh scrubber per call. The @regexp_timeout_reported flag still
works within a single document's scrub, which is the intended scope.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 16:03:47 -04:00
Jorge Manrubia 8c46ff52b4 Bump Lexxy to 0.9.0.beta (#2739) 2026-03-20 17:37:09 +01:00
Zacharias Knudsen 743b60d393 Merge pull request #2737 from basecamp/remember-regexp-timeout
Stop scrubbing after first regexp timeout
2026-03-20 12:16:34 +01:00
Zacharias Dyna Knudsen b0fa6525fe Stop scrubbing after first regexp timeout 2026-03-20 12:13:17 +01:00
Zacharias Knudsen 8479be3976 Merge pull request #2736 from basecamp/rescue-regexp-timeout
Rescue regexp timeout
2026-03-20 11:58:14 +01:00
Zacharias Dyna Knudsen 7399ec5bd9 Rescue regexp timeout 2026-03-20 11:55:00 +01:00
github-actions[bot] 6097ac79cc Sync Gemfile.saas.lock 2026-03-19 18:58:13 +00:00
dependabot[bot] a0c0fd3b1f Bump bcrypt from 3.1.21 to 3.1.22
Bumps [bcrypt](https://github.com/bcrypt-ruby/bcrypt-ruby) from 3.1.21 to 3.1.22.
- [Release notes](https://github.com/bcrypt-ruby/bcrypt-ruby/releases)
- [Changelog](https://github.com/bcrypt-ruby/bcrypt-ruby/blob/master/CHANGELOG)
- [Commits](https://github.com/bcrypt-ruby/bcrypt-ruby/compare/v3.1.21...v3.1.22)

---
updated-dependencies:
- dependency-name: bcrypt
  dependency-version: 3.1.22
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 18:57:58 +00:00
dependabot[bot] 6538cf80a9 Bump json from 2.19.1 to 2.19.2 (#2730)
* Bump json from 2.19.1 to 2.19.2

Bumps [json](https://github.com/ruby/json) from 2.19.1 to 2.19.2.
- [Release notes](https://github.com/ruby/json/releases)
- [Changelog](https://github.com/ruby/json/blob/master/CHANGES.md)
- [Commits](https://github.com/ruby/json/compare/v2.19.1...v2.19.2)

---
updated-dependencies:
- dependency-name: json
  dependency-version: 2.19.2
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

* Sync Gemfile.saas.lock

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-03-19 09:35:47 -07:00
Jorge Manrubia 1c4bf3e1e0 Add per-account storage exceptions for SaaS (#2733)
Allow granting specific accounts more storage via an
account_storage_exceptions table in the saas DB, without
relying on the blanket staff bypass.
2026-03-19 15:36:36 +01:00
Alexander Zaytsev 6d6f94ce13 Merge branch 'main' into delete-account-improvements 2026-03-19 15:26:31 +01:00
Alexander Zaytsev 754e2e3673 Cancel → Delete 2026-03-19 15:06:37 +01:00