Skip to content

fix(cli): windows logout credentials#5913

Open
7ttp wants to merge 7 commits into
supabase:developfrom
7ttp:fix/windows-logout-persistence
Open

fix(cli): windows logout credentials#5913
7ttp wants to merge 7 commits into
supabase:developfrom
7ttp:fix/windows-logout-persistence

Conversation

@7ttp

@7ttp 7ttp commented Jul 20, 2026

Copy link
Copy Markdown
Member

TL;DR

Fixes stale Windows credentials surviving logout
Go handles this by never decoding the blob before deleting, but the TS port used a decode based existence check that threw on non-UTF16 bytes and treated present credentials as absent.

Now it uses a plain enumeration read with no decode step, so it's back to deleted or not, nothing else
(go parity: matches Go's own delete path exactly)

ref:

@7ttp
7ttp requested a review from a team as a code owner July 20, 2026 21:17

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

Copy link
Copy Markdown

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: dad653f8b4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated
@7ttp
7ttp marked this pull request as draft July 20, 2026 21:50
@7ttp
7ttp marked this pull request as ready for review July 21, 2026 06:56
@7ttp
7ttp marked this pull request as draft July 21, 2026 06:57
Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated

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

Copy link
Copy Markdown

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: 6d3594087d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated
@7ttp
7ttp force-pushed the fix/windows-logout-persistence branch from 6d35940 to 9c58701 Compare July 21, 2026 07:32
@7ttp

7ttp commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@codex review

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

Copy link
Copy Markdown

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: 9c58701c5f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated
…n logout

Go writes the Windows CredentialBlob as raw bytes that aren't always valid
UTF-8/UTF-16. napi-rs/keyring's getPassword/findCredentials marshal that
blob into a JS string and throw on those bytes, so the legacy TS port
treated a present-but-opaque credential as absent and skipped deletion,
leaving it behind after `supabase logout` reported success.

Check existence via findCredentials with an exact target instead: a
genuinely absent credential yields an empty result, while a throw means
the target was found but couldn't be decoded, i.e. it exists. This
deliberately avoids Entry.withTarget() for the probe itself, since
constructing it writes an empty placeholder credential as a side effect
on Windows (napi-rs/keyring), which would otherwise fabricate the very
credential being checked for.
@7ttp
7ttp force-pushed the fix/windows-logout-persistence branch from 9c58701 to 60c1faf Compare July 21, 2026 08:09
@7ttp 7ttp changed the title fix(cli): delete win credentials fix(cli): windows logout credentials Jul 21, 2026
@7ttp
7ttp marked this pull request as ready for review July 21, 2026 08:20
@7ttp 7ttp self-assigned this Jul 21, 2026
Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

passwords.set(goWindowsKey("abcdefghijklmnopqrs1"), "secret-1");

P2 Badge Fix the mock so Windows sweeps match production

This new Windows sweep scenario passes only because the mock's no-target findCredentials branch includes Supabase CLI:<ref> keys; the real @napi-rs/keyring 1.3.0 Windows implementation enumerates *.${service}, while Go keyring writes targets as Supabase CLI:<account>. With only Go-written project DB-password credentials present, production deleteAllKeyringEntries never discovers this target-only entry, so logout can still leave the credential behind even though this test is green.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated
Three Windows-only correctness gaps in the credential layer, all matching
Go's behavior:

- Probe existence with a side-effect-free `findCredentials` read instead of
  `Entry.withTarget`, whose constructor writes an empty placeholder credential
  and would fabricate the target being probed for.
- Distinguish a confirmed-absent target from an ambiguous probe failure
  (undecodable blob or enumeration error): only a confirmed-present target
  whose delete does not succeed becomes a hard error, and `deleteCredential`'s
  boolean is now checked rather than ignored, so a failed delete can no longer
  report a successful logout.
- Sweep project credentials by enumerating Go's `Supabase CLI:<account>`
  namespace, mirroring Go's `DeleteAll` prefix match. napi's default
  enumeration filters the `<account>.<service>` form Go never writes on
  Windows, so the previous sweep left Go-written project credentials behind.
Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated

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

Copy link
Copy Markdown

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: 12e8b3fa60

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated
The win32 sweep enumerated Supabase CLI:* to catch project database
passwords, but findCredentials decodes every matched blob and throws for
the whole call on one undecodable entry (the same failure mode this patch
fixes for single-target lookups), aborting the sweep entirely.

Verified against apps/cli-go: the only production keyring write is the
access token (access_token.go:77, keyed by profile name) — link and every
other command never write a project-ref-keyed credential. deleteAccessToken
already removes both token forms before this sweep runs, so there is
nothing in the Windows target form left to find. The sweep reverts to a
plain, decode-only-what-you-write enumeration.

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

Copy link
Copy Markdown

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: 20420bfa37

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated
…tate

Entry.withTarget's constructor unconditionally writes an empty placeholder
credential on Windows (verified in napi-rs/keyring's entry.rs), so by the
time deleteCredential() runs, something always exists at that target —
gating the failure path on a confirmed-present probe was withholding a
real error signal whenever the probe was merely ambiguous. Any non-success
delete outcome is now surfaced, since construction itself already resolved
the existence question.

Corrected two tests built on the same inaccurate assumption: an enumeration
hiccup alone no longer implies not-logged-in (construction leaves something
deletable regardless), and a failed Windows target write can leave an empty
placeholder behind rather than nothing.
Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated

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

Copy link
Copy Markdown

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: 5b69a47a83

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts Outdated
Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts
…ders

Two corrections, verified against apps/cli-go and the napi-rs/keyring source:

- Restore the Windows-specific project-credential sweep in logout. Go's
  windowsKeychain.DeleteAll prefix-matches Supabase CLI: unconditionally
  (logout_test.go's "removes all Supabase CLI credentials" seeds and expects
  removal of project-keyed entries) — removing this sweep entirely broke
  that contract. findCredentials still decodes every matched blob and can
  abort the whole call on one undecodable entry; that's an upstream library
  constraint with no available workaround, so it stays best-effort.

- probeWindowsTarget now requires a non-empty password before treating a
  match as present. Entry.withTarget's placeholder write means a prior
  failed save can leave an empty credential behind; matching on account
  name alone treated that placeholder as a real session and reported a
  fabricated successful logout.

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

Copy link
Copy Markdown

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: e751666cef

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts
…entry

The prior test only checked that logout doesn't fail; it didn't assert
whether the credentials actually survive. Now it does, making the known
findCredentials all-or-nothing decode limitation explicit rather than
implied.

Verified there's no fix available to route around: diffed napi-rs/keyring's
published 1.3.0 against its unreleased main branch (entry.rs is byte-identical)
and confirmed no version exposes a decode-free bulk enumeration. The decode
happens inside the Rust FFI boundary before results ever reach JS, unlike the
raw CredEnumerateW Win32 API itself, which returns target names and blob
bytes with no decode step at all.
Comment thread apps/cli/src/legacy/auth/legacy-credentials.layer.ts
@7ttp

7ttp commented Jul 21, 2026

Copy link
Copy Markdown
Member Author

@Coly010 can u have a look at this!? :)

@7ttp
7ttp requested review from Coly010 and avallete July 21, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant