From 18def1710d2f80018fb1b34cfd5edc4e12b9d012 Mon Sep 17 00:00:00 2001
From: Vaibhav <117663341+7ttp@users.noreply.github.com>
Date: Fri, 10 Apr 2026 18:37:09 +0530
Subject: [PATCH] fix: provider badge (#44726)
## TL;DR
fixes the Auth Users provider badge for Web3 users so it reflects the
actual enabled provider state
## problem
Web3 authenticated users appeared `Disabled` in `Authentication -> Users
-> Provider Information`
This happened because the user provider is stored as `web3`, while the
actual enabled state is chain specific (`solana` / `ethereum`)
## solution
When the provider is `web3`, resolve the enabled badge from
`raw_user_meta_data.custom_claims.chain` (saw that in the payload while
testing) and map it to the correct Web3 config flag:
- `solana` -> `EXTERNAL_WEB3_SOLANA_ENABLED`
- `ethereum` -> `EXTERNAL_WEB3_ETHEREUM_ENABLED`
## ref:
- closes https://github.com/supabase/supabase/issues/44724
- closes https://github.com/supabase/supabase/issues/39568
- closes https://github.com/orgs/supabase/discussions/39563
## Summary by CodeRabbit
* **Bug Fixes**
* Corrected web3 provider enabled status detection by mapping user chain
configuration to provider settings.
* **Tests**
* Added test coverage for web3 user enabled status display.
---
.../interfaces/Auth/Users/UserOverview.tsx | 19 ++++-
e2e/studio/features/auth-users.spec.ts | 75 ++++++++++++++++++-
2 files changed, 90 insertions(+), 4 deletions(-)
diff --git a/apps/studio/components/interfaces/Auth/Users/UserOverview.tsx b/apps/studio/components/interfaces/Auth/Users/UserOverview.tsx
index f34750a103e..a1e86ff769f 100644
--- a/apps/studio/components/interfaces/Auth/Users/UserOverview.tsx
+++ b/apps/studio/components/interfaces/Auth/Users/UserOverview.tsx
@@ -224,9 +224,22 @@ export const UserOverview = ({ user, onDeleteSuccess }: UserOverviewProps) => {
(x) =>
('key' in x && x.key === provider.name) || x.title.toLowerCase() === provider.name
)
- const enabledProperty = Object.keys(providerMeta?.properties ?? {}).find((x) =>
- x.toLowerCase().endsWith('_enabled')
- )
+ const enabledProperty =
+ provider.name.toLowerCase() === 'web3'
+ ? (
+ {
+ solana: 'EXTERNAL_WEB3_SOLANA_ENABLED',
+ ethereum: 'EXTERNAL_WEB3_ETHEREUM_ENABLED',
+ } as const
+ )[
+ (
+ (user.raw_user_meta_data?.custom_claims as { chain?: string } | undefined)
+ ?.chain ?? ''
+ ).toLowerCase() as 'solana' | 'ethereum'
+ ]
+ : Object.keys(providerMeta?.properties ?? {}).find((x) =>
+ x.toLowerCase().endsWith('_enabled')
+ )
const providerName =
provider.name === 'email'
? provider.name.toLowerCase()
diff --git a/e2e/studio/features/auth-users.spec.ts b/e2e/studio/features/auth-users.spec.ts
index ddc1dd1b2e6..1dd0fc8ee97 100644
--- a/e2e/studio/features/auth-users.spec.ts
+++ b/e2e/studio/features/auth-users.spec.ts
@@ -1,8 +1,9 @@
import { expect, Page } from '@playwright/test'
+
+import { createUserViaUI, deleteUserViaUI, navigateToAuthUsers } from '../utils/auth-helpers.js'
import { test } from '../utils/test.js'
import { toUrl } from '../utils/to-url.js'
import { waitForApiResponse } from '../utils/wait-for-response.js'
-import { createUserViaUI, deleteUserViaUI, navigateToAuthUsers } from '../utils/auth-helpers.js'
test.describe('auth users list refresh', () => {
test.beforeEach(async ({ page, ref }) => {
@@ -46,3 +47,75 @@ test.describe('auth users list refresh', () => {
}
})
})
+
+test('should show web3 users as enabled when the matching web3 provider is enabled', async ({
+ page,
+ ref,
+}) => {
+ test.skip(
+ process.env.IS_PLATFORM !== 'true',
+ 'Provider enabled status is only resolved in platform mode'
+ )
+
+ const userId = '11111111-1111-4111-8111-111111111111'
+
+ await page.route('**/platform/pg-meta/*/query**', async (route) => {
+ const key = new URL(route.request().url()).searchParams.get('key')
+ if (key !== `user-${userId}`) return route.continue()
+
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify([
+ {
+ id: userId,
+ email: 'web3-user@example.com',
+ phone: null,
+ role: 'authenticated',
+ aud: 'authenticated',
+ created_at: '2025-10-15T10:00:00.000Z',
+ updated_at: '2025-10-15T10:05:00.000Z',
+ confirmed_at: '2025-10-15T10:01:00.000Z',
+ invited_at: null,
+ confirmation_sent_at: null,
+ last_sign_in_at: '2025-10-15T10:06:00.000Z',
+ banned_until: null,
+ is_sso_user: false,
+ is_anonymous: false,
+ providers: ['web3'],
+ raw_app_meta_data: {
+ provider: 'web3',
+ providers: ['web3'],
+ },
+ raw_user_meta_data: {
+ custom_claims: {
+ chain: 'solana',
+ },
+ },
+ user_metadata: {},
+ },
+ ]),
+ })
+ })
+
+ await page.route('**/platform/auth/*/config**', async (route) => {
+ await route.fulfill({
+ status: 200,
+ contentType: 'application/json',
+ body: JSON.stringify({
+ EXTERNAL_WEB3_SOLANA_ENABLED: true,
+ INDEX_WORKER_ENSURE_USER_SEARCH_INDEXES_EXIST: false,
+ MAILER_OTP_EXP: 0,
+ }),
+ })
+ })
+
+ await page.goto(toUrl(`/project/${ref}/auth/users?show=${userId}`))
+
+ const providerRow = page
+ .getByRole('link', { name: 'Configure web3 provider' })
+ .locator("xpath=ancestor::div[contains(@class, 'bg-surface-100')][1]")
+
+ await expect(providerRow).toContainText('Enabled')
+ await expect(providerRow).not.toContainText('Disabled')
+})