Skip to content

fix: stop /updates from serving deleted bundles#1879

Merged
riderx merged 7 commits intomainfrom
fix/advisory-ghsa-hqq2-deleted-bundle-updates
Apr 16, 2026
Merged

fix: stop /updates from serving deleted bundles#1879
riderx merged 7 commits intomainfrom
fix/advisory-ghsa-hqq2-deleted-bundle-updates

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented Mar 31, 2026

Summary

(AI generated)

  • exclude deleted app_versions from both /updates channel-selection joins so soft-deleted bundles are no longer returned
  • keep the deleted-bundle guard on the existing channel-to-version primary-key join path and document the hot-path performance rationale
  • revert the supabaseAdmin Authorization-header override so shared service-role client behavior stays unchanged
  • add regression coverage for both deleted-bundle selection paths in /updates:
    • default-channel resolution
    • device-override resolution with fallback to the normal channel version

Test plan

(AI generated)

  • Review supabase/functions/_backend/utils/pg.ts to confirm the deleted filter remains on the existing join path
  • Review supabase/functions/_backend/utils/supabase.ts to confirm the supabaseAdmin Authorization override was reverted
  • Run targeted backend coverage for tests/updates.test.ts once dependencies are available
  • Note: local lint/test reruns were blocked in this sandbox because dependency installation failed on blocked registry access to npm.jsr.io

Screenshots

(AI generated)

  • N/A — backend-only change

Checklist

(AI generated)

  • My code follows the code style of this project and passes
    bun run lint:backend && bun run lint.
  • My change requires a change to the documentation.
  • I have updated the documentation
    accordingly.
  • My change has adequate E2E test coverage.
  • I have tested my code manually, and I have provided steps how to reproduce
    my tests

Summary by CodeRabbit

Release Notes

  • Bug Fixes

    • Exclude deleted app versions from channel queries.
    • Deleted bundles referenced by a channel now produce a clear "no_channel" response; device-override deletions fall back to normal channel selection.
    • Updating a channel to the built-in version returns "already_on_builtin" when applicable.
  • Tests

    • Expanded tests for deletion and channel-update scenarios, added channel-update helpers, and updated i18n fallback assertions.

@riderx riderx added the codex label Mar 31, 2026
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 31, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d45f6364-d5b7-4182-a217-93d14717cb03

📥 Commits

Reviewing files that changed from the base of the PR and between f9f5c1a and 89544c5.

📒 Files selected for processing (3)
  • supabase/functions/_backend/utils/pg.ts
  • tests/i18n-fallback.unit.test.ts
  • tests/updates.test.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • supabase/functions/_backend/utils/pg.ts
  • tests/updates.test.ts

📝 Walkthrough

Walkthrough

Excludes deleted app-version rows from channel→version JOINs via a new activeChannelVersionJoin helper, centralizes retrieval of the Supabase service-role key when creating the admin client, and refactors update tests to use an HTTP-based updateChannel helper with new scenarios for deleted bundles and builtin targets.

Changes

Cohort / File(s) Summary
Database query joins
supabase/functions/_backend/utils/pg.ts
Added activeChannelVersionJoin(...) and replaced direct eq(channelAlias.version, versionAlias.id) joins in requestInfosChannelDevicePostgres and requestInfosChannelPostgres with the helper to exclude rows where versionAlias.deleted = true while preserving select/project/where/group/limit semantics.
Supabase admin client
supabase/functions/_backend/utils/supabase.ts
Read SUPABASE_SERVICE_ROLE_KEY into a local serviceRoleKey and pass it to createClient<Database> instead of calling getEnv(...) inline.
Update tests & helpers
tests/updates.test.ts, tests/test-utils.ts
Added updateChannel(channel, patch) helper; switched tests to call the HTTP /channel endpoint instead of direct channels.update(...); added tests for deleted bundles, deleted device-override behavior, builtin-target responses; refactored setup/cleanup and payload field names.
i18n unit test
tests/i18n-fallback.unit.test.ts
Adjusted locale message retrieval and assertions for English/French templates and updated expected rendered French text delimiter.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐇 I nibble joins and chase the keys,

I leave behind the deleted leaves.
One service key, neat as a stream,
Tests hop in—what a gleam!
🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: excluding deleted bundles from the /updates endpoint responses, which is the primary objective of this PR.
Description check ✅ Passed The description covers the main changes, test plan, and checklist, but lacks verification that all checklist items have been reviewed or completed before submission.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/advisory-ghsa-hqq2-deleted-bundle-updates

Comment @coderabbitai help to get the list of available commands and usage tips.

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq bot commented Mar 31, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing fix/advisory-ghsa-hqq2-deleted-bundle-updates (89544c5) with main (ed16dd2)

Open in CodSpeed

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b004950977

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/functions/_backend/utils/pg.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
tests/updates.test.ts (1)

689-718: ⚠️ Potential issue | 🟡 Minor

Wrap the shared production channel cleanup in try/finally.

These cases restore production only after the assertions pass. If either test exits early, later cases inherit the private/no-self-set state and start failing for the wrong reason.

As per coding guidelines, "Create dedicated seed data for tests that modify shared resources; do not reuse seed data if your test modifies it."

Also applies to: 720-777

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/updates.test.ts` around lines 689 - 718, The test mutates the shared
'production' channel and currently restores it only after assertions, so wrap
the channel state changes and assertions in a try/finally: call
updateChannel('production', {...public:false...}) before the try, run
postUpdate/getBaseData and all expects inside the try, and move the restoration
updateChannel('production', {public:true, allow_device_self_set:true}) into the
finally block to guarantee cleanup; apply the same try/finally pattern to the
similar test block around lines 720-777 to ensure shared state is always
restored.
🧹 Nitpick comments (1)
tests/updates.test.ts (1)

102-156: Consider a channel_devices variant of this regression too.

This new case only protects the default-channel lookup. A future regression in the device-override join would still slip through unless that path is covered elsewhere.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/updates.test.ts` around lines 102 - 156, Add a second test variant that
covers the device-override path: in the existing test "does not resolve deleted
bundles that are still referenced by a channel" create a device id (e.g.,
randomUUID()), insert a record into the channel_devices table linking that
device_id to the same channelName (use the same fields as channels insert but
just channel_id/name and device_id), then call postUpdate with the same baseData
plus the device identifier field used by postUpdate (e.g., device_id or device)
and assert the response.status is 200 and json.error === 'no_channel' and
json.version is undefined; this ensures the device-override join path
(channel_devices) is covered in addition to the default-channel lookup.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@tests/updates.test.ts`:
- Around line 689-718: The test mutates the shared 'production' channel and
currently restores it only after assertions, so wrap the channel state changes
and assertions in a try/finally: call updateChannel('production',
{...public:false...}) before the try, run postUpdate/getBaseData and all expects
inside the try, and move the restoration updateChannel('production',
{public:true, allow_device_self_set:true}) into the finally block to guarantee
cleanup; apply the same try/finally pattern to the similar test block around
lines 720-777 to ensure shared state is always restored.

---

Nitpick comments:
In `@tests/updates.test.ts`:
- Around line 102-156: Add a second test variant that covers the device-override
path: in the existing test "does not resolve deleted bundles that are still
referenced by a channel" create a device id (e.g., randomUUID()), insert a
record into the channel_devices table linking that device_id to the same
channelName (use the same fields as channels insert but just channel_id/name and
device_id), then call postUpdate with the same baseData plus the device
identifier field used by postUpdate (e.g., device_id or device) and assert the
response.status is 200 and json.error === 'no_channel' and json.version is
undefined; this ensures the device-override join path (channel_devices) is
covered in addition to the default-channel lookup.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f46a18b7-fec9-4f3a-bb1b-9d3a8aab820f

📥 Commits

Reviewing files that changed from the base of the PR and between 3fd1ec7 and b004950.

📒 Files selected for processing (3)
  • supabase/functions/_backend/utils/pg.ts
  • supabase/functions/_backend/utils/supabase.ts
  • tests/updates.test.ts

@riderx
Copy link
Copy Markdown
Member Author

riderx commented Apr 6, 2026

@copilot fix comments also ensure this new query will not destroy our perf because it's most critical one, revert change on supabaseAdmin unless you justify it's necessity

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 03710e9308

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/functions/_backend/utils/pg.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 6, 2026

@copilot fix comments also ensure this new query will not destroy our perf because it's most critical one, revert change on supabaseAdmin unless you justify it's necessity

Addressed in 2aeb652 and 9947504. I reverted the supabaseAdmin Authorization override, kept the deleted-bundle guard on the existing channel->version PK join path (with an inline note explaining the hot-path perf rationale), and added regressions for both the default-channel and device-override /updates paths. I couldn’t rerun the targeted Vitest suite in this sandbox because dependency install is blocked on npm.jsr.io.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • npm.jsr.io
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/_temp/ghcca-node/node/bin/npm install --no-fund --no-audit (dns block)
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/_temp/ghcca-node/node/bin/npm install --legacy-peer-deps --no-fund --no-audit (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/updates.test.ts`:
- Line 5: Replace hardcoded BASE_URL usage in the test fetches with
getEndpointUrl(): update the import in tests/updates.test.ts to include
getEndpointUrl (and remove BASE_URL if no longer used), then change the fetch
calls that currently concatenate BASE_URL to instead call getEndpointUrl() when
building the request URL (e.g., replace BASE_URL + '/path' with getEndpointUrl()
+ '/path') so the test harness routing (USE_CLOUDFLARE_WORKERS) is respected for
the affected requests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 417b7441-c347-4d75-ba8e-21409bf30c76

📥 Commits

Reviewing files that changed from the base of the PR and between 03710e9 and f9f5c1a.

📒 Files selected for processing (3)
  • supabase/functions/_backend/utils/pg.ts
  • supabase/functions/_backend/utils/supabase.ts
  • tests/updates.test.ts
✅ Files skipped from review due to trivial changes (1)
  • supabase/functions/_backend/utils/supabase.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • supabase/functions/_backend/utils/pg.ts

Comment thread tests/updates.test.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9f5c1a752

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread supabase/functions/_backend/utils/pg.ts Outdated
@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit 51d5d5d into main Apr 16, 2026
15 checks passed
@riderx riderx deleted the fix/advisory-ghsa-hqq2-deleted-bundle-updates branch April 16, 2026 19:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants