Skip to content

[codex] Fix /updates private defaultChannel oracle#1993

Merged
riderx merged 4 commits into
mainfrom
codex/fix-updates-default-channel-oracle
May 1, 2026
Merged

[codex] Fix /updates private defaultChannel oracle#1993
riderx merged 4 commits into
mainfrom
codex/fix-updates-default-channel-oracle

Conversation

@riderx
Copy link
Copy Markdown
Member

@riderx riderx commented Apr 30, 2026

Summary (AI generated)

  • Restrict /updates named channel resolution to platform-compatible public or self-settable channels.
  • Add regression coverage for private no-self-set and platform-incompatible defaultChannel probes returning no_channel without version metadata.

Motivation (AI generated)

GHSA-pgmr-gw53-7f77 reported that unauthenticated callers could resolve private channel names through defaultChannel before privacy and platform checks ran.

Business Impact (AI generated)

This protects private rollout metadata from unauthenticated enumeration while preserving valid public and self-settable channel update flows.

Test Plan (AI generated)

  • bun run lint:backend
  • bunx eslint tests/updates.test.ts
  • bun run test:updates
  • Commit hook: bun run cli:build && vue-tsc --noEmit

Generated with AI

Summary by CodeRabbit

  • Bug Fixes

    • Improved channel matching so update checks respect platform compatibility and allow-device-self-set flags; private or incompatible channels are now consistently hidden, returning standardized "no_channel" responses when applicable.
  • Tests

    • Expanded tests for private/self-settable and platform-incompatible channel scenarios; added optional response fields to validate version/old/major behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

Warning

Rate limit exceeded

@riderx has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 7 minutes and 29 seconds before requesting another review.

To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e79f1f8d-6312-488e-af17-68ab8fda0d7a

📥 Commits

Reviewing files that changed from the base of the PR and between 2a9b065 and 091bb95.

📒 Files selected for processing (1)
  • tests/updates.test.ts
📝 Walkthrough

Walkthrough

Postgres selection for defaultChannel now requires platformQuery = true and accepts channels with channelAlias.allow_device_self_set in addition to channelAlias.public. Tests update the UpdateRes shape (add old? and major?) and adjust private-channel expectations to return error: 'no_channel' with no version/old/major.

Changes

Cohort / File(s) Summary
Backend Query Logic
supabase/functions/_backend/utils/pg.ts
Changed requestInfosChannelPostgres matching for defaultChannel to include eq(platformQuery, true) and allow channels where channelAlias.allow_device_self_set is true as well as channelAlias.public.
Test Updates
tests/updates.test.ts
Added optional old?: string and major?: boolean to test UpdateRes type; replaced (baseData as any).defaultChannel casts with direct assignments; updated private-channel assertions to expect error: 'no_channel' (no version/old/major) and added tests covering private channel permutations (self-settable/platform compatibility).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

"I nibble on queries, soft and fleet,
where platform flags and channels meet.
Private paths now hush and hide,
tests hop in to check and bide.
A tiny thump — the update's neat!" 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing the /updates endpoint's handling of private defaultChannel, which is the core security issue addressed by the PR.
Description check ✅ Passed The description includes a clear Summary, detailed Motivation, Business Impact, and comprehensive Test Plan with all required checks marked complete. It follows the template structure with substantive content.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-updates-default-channel-oracle

Review rate limit: 0/5 reviews remaining, refill in 7 minutes and 29 seconds.

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

@codspeed-hq
Copy link
Copy Markdown
Contributor

codspeed-hq Bot commented Apr 30, 2026

Merging this PR will not alter performance

✅ 28 untouched benchmarks


Comparing codex/fix-updates-default-channel-oracle (091bb95) with main (37063ae)

Open in CodSpeed

@riderx riderx marked this pull request as ready for review April 30, 2026 14:53
@riderx
Copy link
Copy Markdown
Member Author

riderx commented Apr 30, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 30, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

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

🧹 Nitpick comments (2)
tests/updates.test.ts (2)

540-587: ⚡ Quick win

Add a positive regression for private + self-settable + platform-compatible defaultChannel.

The new coverage is strong on deny-cases, but it doesn’t directly lock the allow-case introduced in backend logic. Add one companion test where public=false, allow_device_self_set=true, platform-compatible, and expect a valid update response (not no_channel).

Also applies to: 589-635

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

In `@tests/updates.test.ts` around lines 540 - 587, The test suite only covers the
deny-case for a private defaultChannel that is not self-settable; add a positive
regression test alongside 'hides private defaultChannel before major upgrade
checks' that creates a private channel with allow_device_self_set=true (and
platform flags matching the request), sets baseData.defaultChannel to that
channel, then calls postUpdate and asserts a successful update response (status
200) with a valid json.version (not 'no_channel') and non-undefined json.old or
json.major as appropriate; reuse helpers createAppVersions, getBaseData,
postUpdate and the channel construction in the existing test but set
allow_device_self_set=true and ensure platform compatibility
(ios/android/electron flags) so the backend returns a valid channel instead of
'no_channel'.

540-587: Use it.concurrent() for the changed tests.

These modified/added tests are still using it(...). In this repo, test files should use it.concurrent(...) for parallel execution.

♻️ Minimal change pattern
-  it('hides private defaultChannel before major upgrade checks', async () => {
+  it.concurrent('hides private defaultChannel before major upgrade checks', async () => {

-  it('hides platform-incompatible private defaultChannel before platform checks', async () => {
+  it.concurrent('hides platform-incompatible private defaultChannel before platform checks', async () => {

-  it('hides private channel that does not allow self-assignment', async () => {
+  it.concurrent('hides private channel that does not allow self-assignment', async () => {

As per coding guidelines "tests/**/*.test.ts: ... use it.concurrent() instead of it() to maximize parallelism within test files".

Also applies to: 589-635, 966-997

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

In `@tests/updates.test.ts` around lines 540 - 587, Replace the synchronous
Mocha/Jest tests with concurrent tests by changing the three occurrences of it(
... ) to it.concurrent( ... ); specifically update the test whose title starts
with "hides private defaultChannel before major upgrade checks" and the two
other modified/added tests noted in the review (the tests around the other
changed blocks) so they call it.concurrent(...) instead of it(...), keeping the
test names and bodies unchanged.
🤖 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`:
- Around line 623-627: The test relies on getBaseData(APP_NAME_UPDATE)'s
implicit platform; make the platform explicit to ensure the
platform-incompatible path is always exercised by setting the baseData.platform
(or baseData.os/platform field used in the test) to a concrete value like
"android" after obtaining baseData and before using it (alongside the existing
baseData.defaultChannel and version fields); update the test that references
baseData so it asserts incompatibility for that explicit platform.

---

Nitpick comments:
In `@tests/updates.test.ts`:
- Around line 540-587: The test suite only covers the deny-case for a private
defaultChannel that is not self-settable; add a positive regression test
alongside 'hides private defaultChannel before major upgrade checks' that
creates a private channel with allow_device_self_set=true (and platform flags
matching the request), sets baseData.defaultChannel to that channel, then calls
postUpdate and asserts a successful update response (status 200) with a valid
json.version (not 'no_channel') and non-undefined json.old or json.major as
appropriate; reuse helpers createAppVersions, getBaseData, postUpdate and the
channel construction in the existing test but set allow_device_self_set=true and
ensure platform compatibility (ios/android/electron flags) so the backend
returns a valid channel instead of 'no_channel'.
- Around line 540-587: Replace the synchronous Mocha/Jest tests with concurrent
tests by changing the three occurrences of it( ... ) to it.concurrent( ... );
specifically update the test whose title starts with "hides private
defaultChannel before major upgrade checks" and the two other modified/added
tests noted in the review (the tests around the other changed blocks) so they
call it.concurrent(...) instead of it(...), keeping the test names and bodies
unchanged.
🪄 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: 7b2f0e42-7d8d-429f-8fd2-c23ad8dea106

📥 Commits

Reviewing files that changed from the base of the PR and between 37063ae and 6115b29.

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

Comment thread tests/updates.test.ts
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

🧹 Nitpick comments (1)
tests/updates.test.ts (1)

1017-1109: ⚡ Quick win

Avoid mutating shared production state in tests; make these cases parallel-safe

These tests toggle shared production channel flags and device overrides, which makes them fragile under parallel execution and conflicts with the test guideline. Prefer dedicated per-test channels/fixtures, then switch to it.concurrent(...) once isolated.

As per coding guidelines: "Design all tests for parallel execution across files; use it.concurrent() instead of it() ... create dedicated seed data when tests modify resources or when resource state matters for assertions."

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

In `@tests/updates.test.ts` around lines 1017 - 1109, These tests mutate the
shared "production" channel; instead create a dedicated per-test channel (use a
unique name via randomUUID()) and operate on that channel instead of
'production' by calling updateChannel(<uniqueName>, {...}) and using that name
when building baseData.defaultChannel and when inserting into channel_devices
via supabase; ensure you clean up the channel and any channel_devices in the
finally block and then convert the test to it.concurrent(...) once isolated. Use
the existing helpers: randomUUID(), updateChannel, getBaseData, postUpdate,
APP_NAME_UPDATE and remove any references to the shared 'production' channel to
make the tests parallel-safe.
🤖 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`:
- Around line 682-686: The private-channel platform-incompatibility test in
tests/updates.test.ts currently asserts json.error, json.version, and json.old
but omits the `major` field; update the test that reads the response into `json:
UpdateRes` to also assert that `major` is not leaked (e.g., add the same
expect(json.major).toBeUndefined() used in the other privacy regression tests)
so metadata disclosure is fully enforced for the platform-incompatible case.

---

Nitpick comments:
In `@tests/updates.test.ts`:
- Around line 1017-1109: These tests mutate the shared "production" channel;
instead create a dedicated per-test channel (use a unique name via randomUUID())
and operate on that channel instead of 'production' by calling
updateChannel(<uniqueName>, {...}) and using that name when building
baseData.defaultChannel and when inserting into channel_devices via supabase;
ensure you clean up the channel and any channel_devices in the finally block and
then convert the test to it.concurrent(...) once isolated. Use the existing
helpers: randomUUID(), updateChannel, getBaseData, postUpdate, APP_NAME_UPDATE
and remove any references to the shared 'production' channel to make the tests
parallel-safe.
🪄 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: 7e0f91f4-6a53-4d08-8fa6-19b359c4aa8d

📥 Commits

Reviewing files that changed from the base of the PR and between 6115b29 and d1746c6.

📒 Files selected for processing (1)
  • tests/updates.test.ts

Comment thread tests/updates.test.ts
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

🧹 Nitpick comments (2)
tests/updates.test.ts (2)

540-687: ⚡ Quick win

Use it.concurrent for the newly added parallel-safe cases

These three tests create isolated channel names and do not mutate shared seeded channel state, so they should be it.concurrent(...) per test policy.

Suggested change
-  it('hides private defaultChannel before major upgrade checks', async () => {
+  it.concurrent('hides private defaultChannel before major upgrade checks', async () => {

-  it('allows private self-settable platform-compatible defaultChannel', async () => {
+  it.concurrent('allows private self-settable platform-compatible defaultChannel', async () => {

-  it('hides platform-incompatible private defaultChannel before platform checks', async () => {
+  it.concurrent('hides platform-incompatible private defaultChannel before platform checks', async () => {

As per coding guidelines "Design all tests for parallel execution across files; use it.concurrent() instead of it() to maximize parallelism within test files".

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

In `@tests/updates.test.ts` around lines 540 - 687, Replace the three standard
Jest tests that use it(...) with parallel-safe it.concurrent(...): specifically
change the tests with titles "hides private defaultChannel before major upgrade
checks", "allows private self-settable platform-compatible defaultChannel", and
"hides platform-incompatible private defaultChannel before platform checks" to
use it.concurrent(...) so they can run in parallel; no other logic needs
changing—just update the test declarations for those three it blocks to
it.concurrent.

1018-1049: ⚡ Quick win

Avoid mutating shared production channel state in this new test

This test flips shared production flags, which makes parallel execution harder and increases inter-test coupling. Prefer seeding a dedicated private channel for this scenario (like the other new oracle-regression tests), then target it via defaultChannel.

As per coding guidelines "Create dedicated seed data when tests modify resources or when resource state matters for assertions".

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

In `@tests/updates.test.ts` around lines 1018 - 1049, The test currently mutates
the shared 'production' channel via updateChannel, which breaks isolation;
instead create and use a dedicated seeded private channel (e.g., a new channel
name like 'private_no_self_set') for this scenario: seed or create the channel
with public: false and allow_device_self_set: false, call postUpdate with
baseData.defaultChannel set to that new channel name, and remove any
updateChannel calls that change 'production'; ensure any created test channel is
cleaned up after the test. Use the existing helpers mentioned (updateChannel,
postUpdate, getBaseData, APP_NAME_UPDATE, defaultChannel) to locate where to
switch from mutating 'production' to a dedicated seeded channel.
🤖 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`:
- Around line 1040-1042: The test currently asserts only that json.error is
'no_channel' and json.version is undefined; add assertions to ensure all
metadata fields are hidden by also asserting json.old and json.major are
undefined (mirroring the other "new hidden-channel" tests) so the test enforces
non-disclosure of all metadata fields when a channel is hidden.

---

Nitpick comments:
In `@tests/updates.test.ts`:
- Around line 540-687: Replace the three standard Jest tests that use it(...)
with parallel-safe it.concurrent(...): specifically change the tests with titles
"hides private defaultChannel before major upgrade checks", "allows private
self-settable platform-compatible defaultChannel", and "hides
platform-incompatible private defaultChannel before platform checks" to use
it.concurrent(...) so they can run in parallel; no other logic needs
changing—just update the test declarations for those three it blocks to
it.concurrent.
- Around line 1018-1049: The test currently mutates the shared 'production'
channel via updateChannel, which breaks isolation; instead create and use a
dedicated seeded private channel (e.g., a new channel name like
'private_no_self_set') for this scenario: seed or create the channel with
public: false and allow_device_self_set: false, call postUpdate with
baseData.defaultChannel set to that new channel name, and remove any
updateChannel calls that change 'production'; ensure any created test channel is
cleaned up after the test. Use the existing helpers mentioned (updateChannel,
postUpdate, getBaseData, APP_NAME_UPDATE, defaultChannel) to locate where to
switch from mutating 'production' to a dedicated seeded channel.
🪄 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: 588da44b-78d1-4729-9a34-ca98895ba205

📥 Commits

Reviewing files that changed from the base of the PR and between d1746c6 and 2a9b065.

📒 Files selected for processing (1)
  • tests/updates.test.ts

Comment thread tests/updates.test.ts
@sonarqubecloud
Copy link
Copy Markdown

@riderx riderx merged commit 1d8e92c into main May 1, 2026
38 checks passed
@riderx riderx deleted the codex/fix-updates-default-channel-oracle branch May 1, 2026 11:57
@coderabbitai coderabbitai Bot mentioned this pull request May 6, 2026
8 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant