Commit Graph

9937 Commits

Author SHA1 Message Date
dependabot[bot] 0c30fa7937 Bump kamal from 2.10.1 to 2.11.0 (#2767)
* Bump kamal from 2.10.1 to 2.11.0

Bumps [kamal](https://github.com/basecamp/kamal) from 2.10.1 to 2.11.0.
- [Release notes](https://github.com/basecamp/kamal/releases)
- [Commits](https://github.com/basecamp/kamal/compare/v2.10.1...v2.11.0)

---
updated-dependencies:
- dependency-name: kamal
  dependency-version: 2.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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-04-09 13:19:30 -04:00
dependabot[bot] b64c1e8895 Bump aws-sdk-s3 from 1.216.0 to 1.218.0 (#2768) 2026-04-09 13:18:47 -04:00
Rob Zolkos e422d5b37e Add a JSON cards endpoint for workflow columns (#2800)
* Add JSON endpoint for cards in workflow columns

* Add cards URL to column JSON responses

* Add coverage for column cards authorization
2026-04-09 13:17:02 -04:00
Jorge Manrubia 1c6141c131 Update lexxy to 0.9.5.beta (#2820)
* Update lexxy to 0.9.5.beta

* Fix syntax highlight controller for lexxy 0.9.5.beta

The highlightAll export was renamed to highlightCode.

---------

Co-authored-by: Mike Dalessio <mike@37signals.com>
2026-04-09 13:06:59 -04:00
Rob Zolkos 69daae79f1 Add board membership read endpoint (#2799)
* Add board membership read endpoint

* Paginate board membership read endpoint
2026-04-09 12:54:25 -04:00
Mike Dalessio e70047ca0f Default development environment to app.fizzy.localhost (#2822)
Using fizzy.localhost causes CORS errors when using minio for Active
Storage because the minio endpoint is at minio.fizzy.localhost — a
sibling subdomain, not a subdomain of the app host. Switching to
app.fizzy.localhost makes both hosts subdomains of fizzy.localhost,
resolving the CORS issue. See #2814 for the related minio CORS fix.

fizzy.localhost will continue to work if people want to use it, but all
docs and scripts have been updated to point to app.fizzy.localhost.
2026-04-09 12:43:01 -04:00
Mike Dalessio b07f592aaf Fix broken background image after removal (#2817)
ActiveStorage::Record and ApplicationRecord used separate connection
pools (from separate `connects_to` calls). This meant `belongs_to
touch: true` on attachments silently failed — the card couldn't join the
attachment's transaction to receive the deferred touch, so fragment
caches were never invalidated after image removal.

Fix by delegating `connection_pool` from ActiveStorage::Record to
ApplicationRecord so they share a single pool.
2026-04-09 12:33:27 -04:00
Mike Dalessio 759e6079e8 Update bin/bundle-drift to catch dependency requirement diffs (#2821)
* Detect dependency requirement drift in bin/bundle-drift

The checker only compared resolved spec versions between Gemfile.lock
and Gemfile.saas.lock. When dependabot bumped solid_queue from ~> 1.3
to ~> 1.4, the forward command patched the resolved version but left
the stale dependency requirement. The checker didn't catch it because
both lockfiles resolved to the same version.

Now find_drift also compares dependency requirements for shared direct
dependencies, and forward patches the DEPENDENCIES section too.

Includes built-in self-test (bin/bundle-drift self-test).

* Sync solid_queue dependency requirement in Gemfile.saas.lock

Updates ~> 1.3 to ~> 1.4 to match Gemfile.lock.
2026-04-09 12:19:52 -04:00
dependabot[bot] 659ec1e6e6 Bump solid_queue from 1.3.2 to 1.4.0 (#2766)
* Bump solid_queue from 1.3.2 to 1.4.0

Bumps [solid_queue](https://github.com/rails/solid_queue) from 1.3.2 to 1.4.0.
- [Release notes](https://github.com/rails/solid_queue/releases)
- [Commits](https://github.com/rails/solid_queue/compare/v1.3.2...v1.4.0)

---
updated-dependencies:
- dependency-name: solid_queue
  dependency-version: 1.4.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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-04-09 11:16:29 -04:00
Mike Dalessio 3a30d7796f style: formalize preference for if/unless in rubocop (#2816) 2026-04-09 11:14:52 -04:00
Donal McBreen d562e79440 Merge pull request #2813 from robzolkos/fix/active-storage-bearer-downloads
Allow bearer auth for Active Storage download endpoints
2026-04-09 15:31:43 +01:00
Mike Dalessio 45d165749f Fix CORS issues when using minio in development (#2814)
Move MinIO from minio.localhost to minio.fizzy.localhost, which makes
it same-site with the app, so the CORS redirect succeeds.

The service worker fetches Active Storage URLs with `mode: "cors"` so
it can inspect response sizes for offline caching. Active Storage's
redirect controller returns a 302 to the MinIO presigned URL. When
that redirect crosses site boundaries (from fizzy.localhost to
minio.localhost), the browser sets the Origin header to "null" on the
redirected request per the Fetch spec, which fails the CORS check and
produces net::ERR_FAILED.
2026-04-08 16:06:38 -04:00
dependabot[bot] 7bd3df33b8 Bump rack from 3.2.5 to 3.2.6 (#2784)
* Bump rack from 3.2.5 to 3.2.6

Bumps [rack](https://github.com/rack/rack) from 3.2.5 to 3.2.6.
- [Release notes](https://github.com/rack/rack/releases)
- [Changelog](https://github.com/rack/rack/blob/main/CHANGELOG.md)
- [Commits](https://github.com/rack/rack/compare/v3.2.5...v3.2.6)

---
updated-dependencies:
- dependency-name: rack
  dependency-version: 3.2.6
  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-04-08 15:48:11 -04:00
dependabot[bot] 6ddb04766a Bump loofah from 2.25.0 to 2.25.1 (#2726)
* Bump loofah from 2.25.0 to 2.25.1

Bumps [loofah](https://github.com/flavorjones/loofah) from 2.25.0 to 2.25.1.
- [Release notes](https://github.com/flavorjones/loofah/releases)
- [Changelog](https://github.com/flavorjones/loofah/blob/main/CHANGELOG.md)
- [Commits](https://github.com/flavorjones/loofah/compare/v2.25.0...v2.25.1)

---
updated-dependencies:
- dependency-name: loofah
  dependency-version: 2.25.1
  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-04-08 15:47:08 -04:00
Mike Dalessio 8908ee46f8 Upgrade addressable to 2.9.0 (#2815)
* Upgrade addressable from 2.8.9 to 2.9.0

Security release fixing ReDoS vulnerabilities in Addressable::Template#match.
No application impact — fizzy does not use Addressable::Template directly.

* dep: fix saas drift
2026-04-08 15:45:23 -04:00
Rob Zolkos 4a91e45aa5 Cover bearer-authenticated export download URLs 2026-04-08 15:03:25 -04:00
Rob Zolkos 5e154a767f Allow bearer auth on Active Storage downloads 2026-04-08 14:37:24 -04:00
Rob Zolkos dd67f4171d Add regression tests for bearer-authenticated blob downloads 2026-04-08 14:36:34 -04:00
Zoltán Hosszú 0ef9c56bf5 Merge pull request #2811 from basecamp/lexxy-toolbar-fixes
Fix icon color and chevron size
2026-04-08 15:13:15 +02:00
Rob Zolkos 1975a04f14 Add JSON API support for email address changes (#2807) 2026-04-08 09:09:36 -04:00
Zoltan Hosszu d7040388fa Fix icon color and chevron size 2026-04-08 15:09:29 +02:00
Rob Zolkos d08aa11bfb Add JSON API support for timezone update (#2806)
* Add JSON API support for timezone update

* Simplify timezone controller to just head :no_content

* Use PUT instead of PATCH in timezone tests to match docs

* Use PATCH instead of PUT for timezone endpoint

Reverts tests to use patch and updates docs heading to PATCH
for consistency.
2026-04-08 08:41:34 -04:00
Rob Zolkos 6a71856b3d Add JSON activities API endpoint (#2783)
* Add JSON events API endpoint

* Add regression test for event particulars defaults

* Move JSON events API to a dedicated ActivitiesController

The events endpoint served both the HTML day timeline and the JSON API
feed, but the two paths shared no data or behavior — the HTML side uses
DayTimelinesScoped while the JSON side built its own query. Splitting
into ActivitiesController gives the API its own home at
GET /:account/activities.json without dragging in the timeline
before_actions.

Also preloads comment creator in Event.preloaded to avoid an N+1 when
rendering comment eventables in the JSON feed.
2026-04-08 08:39:36 -04:00
Rob Zolkos 2a4adf3a2b Add board settings fields to board JSON responses (#2788)
* Add board settings fields to board JSON responses

* Move public_description fields to board partial, gate on published

* Add index test for public_description fields on published boards

* Update app/views/boards/show.json.jbuilder

Prefer `unless` to `if !`

---------

Co-authored-by: Mike Dalessio <mike.dalessio@gmail.com>
2026-04-08 08:31:52 -04:00
Rob Zolkos 8201c2a4bd Add JSON API support for user data exports (#2786) 2026-04-08 08:17:24 -04:00
Rob Zolkos 98b6bdcfb7 Document undocumented API endpoints (#2805)
* Document avatar removal API endpoint

* Document notification settings API endpoints

* Document access token list and delete API endpoints

* Document join code API endpoints

* Fix access token delete URL parameter name in docs
2026-04-07 15:56:43 -04:00
Rob Zolkos 21981898d2 Add JSON API for webhook deliveries (#2785)
* Add JSON API for webhook deliveries

* Extract sanitized_request method on Webhook::Delivery

* Extract response_summary method on Webhook::Delivery
2026-04-07 15:08:27 -04:00
dependabot[bot] f3bacffe2b Bump lexxy from 0.9.0.beta to 0.9.1.beta (#2796)
* Bump lexxy from 0.9.0.beta to 0.9.1.beta

Bumps [lexxy](https://github.com/basecamp/lexxy) from 0.9.0.beta to 0.9.1.beta.
- [Release notes](https://github.com/basecamp/lexxy/releases)
- [Commits](https://github.com/basecamp/lexxy/compare/v0.9.0.beta...v0.9.1.beta)

---
updated-dependencies:
- dependency-name: lexxy
  dependency-version: 0.9.1.beta
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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-04-07 11:36:12 -07:00
dependabot[bot] b2021e1e74 Bump trilogy from 2.10.0 to 2.11.1 (#2794)
* Bump trilogy from 2.10.0 to 2.11.1

Bumps [trilogy](https://github.com/trilogy-libraries/trilogy) from 2.10.0 to 2.11.1.
- [Release notes](https://github.com/trilogy-libraries/trilogy/releases)
- [Changelog](https://github.com/trilogy-libraries/trilogy/blob/main/CHANGELOG.md)
- [Commits](https://github.com/trilogy-libraries/trilogy/compare/v2.10.0...v2.11.1)

---
updated-dependencies:
- dependency-name: trilogy
  dependency-version: 2.11.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

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-04-07 10:09:41 -07:00
dependabot[bot] dc6139a75e Bump sigstore/cosign-installer in the github-actions group (#2795)
Bumps the github-actions group with 1 update: [sigstore/cosign-installer](https://github.com/sigstore/cosign-installer).


Updates `sigstore/cosign-installer` from 4.1.0 to 4.1.1
- [Release notes](https://github.com/sigstore/cosign-installer/releases)
- [Commits](https://github.com/sigstore/cosign-installer/compare/ba7bc0a3fef59531c69a25acd34668d6d3fe6f22...cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003)

---
updated-dependencies:
- dependency-name: sigstore/cosign-installer
  dependency-version: 4.1.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: github-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-07 10:09:30 -07:00
dependabot[bot] adc1b02d7a Bump thruster from 0.1.19 to 0.1.20 (#2797)
* Bump thruster from 0.1.19 to 0.1.20

Bumps [thruster](https://github.com/basecamp/thruster) from 0.1.19 to 0.1.20.
- [Changelog](https://github.com/basecamp/thruster/blob/v0.1.20/CHANGELOG.md)
- [Commits](https://github.com/basecamp/thruster/compare/v0.1.19...v0.1.20)

---
updated-dependencies:
- dependency-name: thruster
  dependency-version: 0.1.20
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

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-04-07 10:08:59 -07:00
Rob Zolkos cdd13c1a61 Split API docs into per-resource sections under docs/api/ (#2793)
* Split docs/API.md into per-resource sections under docs/api/

* Move API endpoints index above authentication in docs/api/README.md

* Fix trailing comma in boards.md JSON example

* Fix trailing comma in cards.md, add Response label to identity.md, add Rich Text to endpoint index
2026-04-06 14:00:17 -04:00
Donal McBreen 00a5c6ef14 Merge pull request #2804 from basecamp/fix-account-destroy-cascade-gaps
Fix account destroy cascade gaps
2026-04-06 10:15:31 +01:00
Donal McBreen e51f0bfee7 Fix account destroy cascade gaps
Account incineration could leave orphaned records due to missing cascade
declarations and async jobs failing when the account was already gone.

Cascade fixes:
- Add Account::Searchable concern to clean up Search::Query (delete_all)
  and Search::Record (destroy_all, respects SQLite FTS dependent: :destroy)
- Add before_destroy in Account::Storage to delete storage entries
- Suppress storage entry recording during incineration so attachment
  purge callbacks don't create entries or enqueue materialize jobs
- Guard Access#clean_inaccessible_data_later with unless user.destroyed?
  to avoid enqueuing pointless jobs during user cascade

Job tenancy:
- Extract AccountTenanted concern from the global ActiveJob initializer
  into ApplicationJob (include) with targeted prepends for
  ActionMailer::MailDeliveryJob and Turbo broadcast jobs
- Defer account resolution from deserialize to perform so that missing
  accounts raise DeserializationError inside the execution path where
  discard_on can handle it

Tests:
- Comprehensive incineration test covering 35 model types with
  before/after assertions and full enqueued job processing
- Mailer deliver_later test verifying account context survives job
  serialization for multi-account users
- Turbo broadcast test verifying account-scoped URLs in rendered partials
2026-04-06 10:04:24 +01:00
Donal McBreen d9f176aeb0 Merge pull request #2803 from basecamp/fix-timezone-date-display
Fix timezone handling for day timeline and card dates
2026-04-06 09:27:49 +01:00
Donal McBreen 6d71385846 Fix timezone handling for day timeline and card dates
Revert beginningOfDay() to use local timezone methods — the UTC change
from #2790 caused cards created earlier the same day to show "yesterday"
for users in UTC-negative timezones after their local 7 PM.

Add Time.zone.name to day timeline fragment cache keys so
timezone-different renders don't collide.
2026-04-06 09:21:03 +01:00
Donal McBreen e1426af06c Merge pull request #2791 from basecamp/fix-export-column-colors
Fix export/import losing custom column colors
2026-04-03 10:08:37 +01:00
Donal McBreen b79c7897e6 Fix export/import losing custom column colors
record.to_json serializes through model accessors. Column::Colored
overrides the color accessor to return a Color struct, which serializes
as {"name":"Blue","value":"var(--color-card-default)"} instead of the
raw CSS string.

Two fixes:
- Export raw DB values via record.attributes.slice(*attributes).to_json
- Color.for_value parses legacy JSON format so columns imported from
  old exports self-heal when read
2026-04-03 10:05:11 +01:00
Donal McBreen 752237abab Merge pull request #2790 from basecamp/fix-utc-date-off-by-one
Fix off-by-one date display for UTC-negative timezone users
2026-04-03 09:06:46 +01:00
Donal McBreen c2d693fc9a Fix off-by-one date display for UTC-negative timezone users
beginningOfDay() used local timezone methods (getFullYear, getMonth,
getDate) to snap timestamps to midnight. Since the server sends UTC
timestamps, this caused day boundary calculations to be off by one
for users in UTC-negative timezones — cards created after UTC midnight
but before local midnight showed as "yesterday" instead of "today".

Switch to UTC methods (getUTCFullYear, getUTCMonth, getUTCDate) so day
boundaries are calculated consistently with the server's UTC timestamps.

Affects DaysAgoFormatter, DaysAgoOrWeekdayFormatter, TimeOrDateFormatter,
InDaysFormatter, and bubble controller stalled/entropy calculations.
2026-04-03 08:50:25 +01:00
Donal McBreen 7ab6b43e04 Merge pull request #2776 from basecamp/bearer-token-json-only
Restrict bearer token authentication to JSON requests
2026-04-01 09:14:05 +01:00
Donal McBreen b4c4a32205 Return 401 for bearer tokens on non-JSON requests
Rather than silently ignoring bearer tokens on HTML requests
(which breaks the audit console's error handling), explicitly
reject them with 401. Bearer tokens on JSON requests continue
to authenticate normally.
2026-04-01 09:09:00 +01:00
Donal McBreen 13e2c74929 Restrict bearer token authentication to JSON requests
Bearer tokens are for API/SDK/CLI access — they should only
authenticate JSON requests.
2026-04-01 08:55:04 +01:00
Donal McBreen d63801eae3 Merge pull request #2775 from basecamp/queenbee-account-callbacks
Implement Queenbee account callbacks
2026-04-01 08:09:25 +01:00
Donal McBreen 98d06947cb Implement Queenbee account callbacks
Add Account::QueenbeeIntegration concern (SaaS-only) that bridges
Fizzy's external_account_id to Queenbee's find_by_queenbee_id lookup,
and adapts the bang lifecycle methods to Fizzy's Cancellable module.

Remove dead billing conditional from cancellation mailer — Fizzy is
free-only, there's no charge to stop.
2026-03-31 15:14:49 +01:00
Jay Ohms e04182786c Merge pull request #2762 from basecamp/mobile/hide-profile-links
Mobile: hide profile links in native apps
2026-03-31 09:42:55 -04:00
Adrien Maston 7c3682ec93 Merge pull request #2773 from basecamp/mobile/fix-missing-golden-effect
Mobile / Fix missing golden effect
2026-03-30 16:44:46 +02:00
Adrien Maston a5cc2e8ab5 Change CSS selector 2026-03-30 16:38:32 +02:00
Adrien Maston f11bb18d93 Tweak alignments 2026-03-30 13:53:14 +02:00
Donal McBreen fed2996b7c Merge pull request #2772 from basecamp/provision-queenbee-secret
Provision QUEENBEE_SECRET env var
2026-03-30 11:25:20 +01:00