Commit Graph
73 Commits
Author SHA1 Message Date
Danny White ec53175b8a refactor(ui): rename text-brand to text-primary (#50564)
## What kind of change does this PR introduce?

Refactor. Follow-up to #49871.

## What is the current behavior?

Branded (green) text still uses the `text-brand` classname while the
colour comes from `--primary`.

## What is the new behavior?

**Rename-only:** `text-brand` → `text-primary` across callsites and
docs. Leftover `bg-brand` / `border-brand` alias to `brand-default`. No
intentional colour changes in this PR.

This better matches how we treat our green in other components and
props, like `variant="primary"` for green buttons.

## To test

On light mode: smoke-test that branded text still looks like #49871
(readable green, not the bright fill).

-
[Homepage](https://zone-www-dot-com-git-dnywh-depr-316-text-brand-de2380-supabase.vercel.app/):
“Scale to millions” uses `text-primary`
- [Docs
homepage](https://docs-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/docs):
branded links like “More on self-hosting” are still readable
- [Typography
docs](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/typography):
documents `text-primary`
- [Colour
usage](https://design-system-git-dnywh-depr-316-text-brand-to-primary-supabase.vercel.app/design-system/docs/color-usage):
`text-primary` is visibly darker than `bg-brand-default` _on light mode_
- [Studio auth
providers](https://studio-staging-git-dnywh-depr-316-text-brand-to-60fa6c-supabase.vercel.app/dashboard/project/_/auth/providers):
enabled provider badge text readable; status dot stays bright green

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Style**
* Updated branded text, link hover states, icons, badges, indicators,
and highlighted content across the Design System, Docs, Studio, Learn,
UI Library, and marketing experiences to use the primary theme color.
* Updated syntax highlighting and table-of-contents styling for
consistent primary-color presentation.
  * Refined brand color fallback behavior for bright fills and borders.

* **Documentation**
* Updated color-usage and typography guidance to recommend the primary
text utility.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-22 16:19:03 +10:00
Danny White 476d4a5851 refactor(ui): drop redundant Button variant="default" props (#50161)
## What kind of change does this PR introduce?

Mechanical cleanup on top of the Button default-variant change (#50160).

## What is the current behavior?

Many callsites still pass `variant="default"` even though that is now
the component default.

## What is the new behavior?

Removes redundant static `variant="default"` from legacy `Button` and
`ButtonTooltip` callsites. Keeps explicit defaults where they document
the API:

- `button-default.tsx` and `button-sizes.tsx` demos
- `DocsButton`, which pins neutral styling at the wrapper boundary

## To test

Studio:

- [Auth → Rate
Limits](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/auth/rate-limits):
dirty the form so Cancel appears; Cancel stays neutral, Save stays green
- [Project Settings → API
Keys](https://studio-staging-2s957kwc4-supabase.vercel.app/dashboard/project/_/settings/api-keys):
`DocsButton` in the header actions stays neutral

Design system:

- [Design system →
Button](https://design-system-git-dnywh-dc924ac1-supabase.vercel.app/design-system/docs/components/button):
`button-default` / `button-sizes` still show explicit default styling;
Primary (green) is restricted to the Primary section (and `asChild`)

WWW:

- [www → Brand
assets](https://zone-www-dot-com-git-dnywh-dc924ac1-supabase.vercel.app/brand-assets):
Download logo kit / Download button kit stay neutral
2026-09-11 17:05:26 +10:00
Danny White 1131e3e2ce fix(ui): default Button variant to default instead of primary (#50160)
## What kind of change does this PR introduce?

Bug fix / design-system alignment for the legacy `Button` from `ui`.

## What is the current behavior?

Omitting `variant` on the legacy `Button` falls back to brand-green
`primary`. That makes accidental greens easy, and it is hard to spot the
real main action on busy pages.

## What is the new behavior?

- Legacy `Button` now defaults to neutral `default`
- Intentional primary CTAs (create, save, submit, marketing CTAs, and
matching `ButtonTooltip` usages) now set `variant="primary"` so their
appearance is unchanged
- Neutral actions that previously relied on the old fallback (cancel,
close, back, dashboard nav, and similar) become grey/white
- Design-system docs updated; regression tests cover the new default

`Button_Shadcn_` is unchanged. It already uses its own CVA default.

This is PR 1 of 2 in a stack. PR 2 drops now-redundant
`variant="default"` props.

## To test

Studio (http://localhost:8082):

- `/sign-in`: Sign in stays green
- Open a project → Database → Tables: New table stays green
- Auth → Users → Invite: Invite user stays green; Cancel / dismiss
controls stay neutral
- Project Settings → General: edit a field so Cancel and Save appear.
Cancel is neutral, Save is green

Design system (http://localhost:3003):

- Components → Button: default demo is neutral; primary demo is green;
featured preview is the default variant

Marketing (optional):

- www header: Start your project stays green; logged-in Dashboard is
neutral

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **Style**
- Buttons now default to a neutral style, while primary actions across
Studio, documentation, marketing pages, forms, dialogs, and error states
use prominent primary styling.
- Updated button examples and previews clarify the distinction between
default and primary variants.
  - Event registration now includes a directional arrow icon.

- **Tests**
- Added coverage confirming default button styling and explicit primary
styling behave as expected.
- Updated related test fixtures to use primary styling where
appropriate.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-10 11:23:17 +10:00
Gildas Garcia 95ca302439 OAuth Apps Scoped Grants: refactor to ease future implementation (#49958)
## Problem

We're working on OAuth Apps Scoped Grants and want to display an
alternative UI for Authorized apps depending on a feature flag. However,
the `/apps` page currently contains the code of both the _Publishable
apps_ and _Authorized apps_ sections.

## Solution

No functional nor design changes.

- Extract both sections into their own components to ease the
introduction of the alternative UI
- Improve a11y

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Added separate views for managing publishable and authorized OAuth
applications.
- Users can publish, update, and delete applications, with convenient
credential-copy controls.
- Authorized applications can be sorted and revoked through a
confirmation dialog.

- **User Experience**
- Added clear loading, empty, error, and permission-denied states for
OAuth application lists.
  - Improved organization settings layout for OAuth app management.
- Added consistent sorting behavior when selecting and toggling table
columns.
- Improved accessibility for credential notifications and dismissal
controls.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-09-03 16:09:15 +02:00
2bc6144aec fix(studio): guard unguarded requester.name reads on the OAuth authorize and apps pages (#49267)
<!-- ccr-slack-attribution -->
_Requested by **Ali Waseem** · [Slack
thread](https://supabase.slack.com/archives/C063LNYJJKS/p1787146439389169)_

## I have read the
[CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md)
file.

YES

## What kind of change does this PR introduce?

Bug fix.

## What is the current behavior?

Opening `/authorize` for an OAuth app whose `name` the platform API
omitted crashed the entire page with `TypeError: Cannot read properties
of undefined (reading 'toLowerCase')`
([SUPABASE-APP-K7E](https://supabase.sentry.io/issues/7679644991/)). The
user got a full-page error instead of a consent screen, and could
neither authorize nor decline.

The same class of crash hit the project-level OAuth apps list
([SUPABASE-APP-JB1](https://supabase.sentry.io/issues/7502074939/)).
Typing in the search box called `.toLowerCase()` on `client_name` for
every app, so one app registered without a name broke search for the
whole list.

The project-claim page crashed the same way, reading the first character
of the name for the fallback avatar.

## What is the new behavior?

The trusted-partner helpers treat a missing name as "no trusted partner
matched" and return `null`. The apps filter treats a missing name or
client ID as "does not match the search string". The claim page falls
back to a placeholder initial instead of indexing into `undefined`.

The authorize page now renders normally, minus the optional
partner-impersonation caution, which cannot be evaluated without a name.

Three changes:

-
`apps/studio/components/interfaces/Organization/OAuthApps/OAuthApps.utils.ts`
— `findTrustedPartnerByName` accepts `string | null | undefined` and
returns `null` early on a falsy name; `getOAuthImpersonationWarning`'s
`name` param widened to match (its existing `if (!namedPartner) return
null` already handles the rest).
- `apps/studio/components/interfaces/Auth/OAuthApps/oauthApps.utils.ts`
— `filterOAuthApps` optional-chains `client_name` and `client_id` before
`.toLowerCase()`, defaulting each match to `false`.
-
`apps/studio/components/interfaces/Organization/ProjectClaim/confirm.tsx`
— `{requester.name?.[0] ?? '?'}` for the fallback avatar initial.

Each is a separate commit so any one can be dropped independently.

## Additional context

### Root cause, not fixed here

`apps/studio/data/api-authorization/api-authorization-query.ts:37`
returns `data as ApiAuthorizationResponse`, an unchecked cast with no
runtime validation, even though the openapi-fetch client already types
the endpoint from the generated schema. Both the generated
`GetOAuthAuthorizationResponse` and the hand-written local type declare
`name: string` as required, so this was invisible to TypeScript.

The durable fix is to derive the type from the schema and drop the cast,
which is the house pattern elsewhere in `apps/studio/data`, and to
correct the OpenAPI spec at source if the API can legitimately omit
`name`. Left out deliberately to keep this cherry-pickable.

### Not in scope

`requester.scopes` is optional in the schema but required in the local
type, and is read unguarded in several places. Defaulting it to `[]`
would tell a user an app requested no permissions on a live consent
screen, so it needs a product decision rather than a drive-by guard.

### Testing

No local checks were run. This clone has no `node_modules` and `pnpm
install` is blocked in the environment, so `npm run build`, typecheck,
lint, Prettier and tests were all left to CI. Please treat CI as the
verification for this PR.

There is also a coverage gap worth noting:
`apps/studio/tests/components/ApiAuthorization.test.tsx:48-62` hardcodes
`name: 'Test App'` in `createMockAuthResponse`, and no test omits the
field, which is why none of these crashes were caught.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01P489vrPdHcJfMfzCGM9rZ5)_

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-08-19 14:23:54 -06:00
Danny White f7454cf94e feat(studio): oauth impersonation warning on authorize (#48162)
## What kind of change does this PR introduce?

Feature + docs. Stacked on #48161 (logo contract /
[DEPR-604](https://linear.app/supabase/issue/DEPR-604/define-connect-logo-asset-and-variant-contract)).

## What is the current behavior?

After #48161, curated logos only resolve from allowlisted `redirect_uri`
hosts. A requester can still present a trusted partner **name** (e.g.
Claude) while redirecting to an unrelated remote host; the UI shows
Supabase alone but does not call out the mismatch.

## What is the new behavior?

- Shows a caution admonition when the requester name looks like a
trusted partner (Claude, Cursor, ChatGPT/OpenAI, Perplexity) but
`redirect_uri` is a **remote** host outside that partner's allowlist.
- Skips localhost / loopback redirects for the caution (common for local
MCP clients); those still get curated logos when the name matches a
trusted partner.
- Highlights the footer redirect URL in warning colour when the caution
is shown.
- Documents the behaviour in the Connect interstitials pattern.

### To test

Real MCP clients (Claude, Cursor, etc.) only send users to
**production** `/authorize`, so you cannot drive a local or preview
Studio build from those tools. Use a Network override instead:

1. Start Studio and sign in (`pnpm dev:studio`, or use the [Vercel
preview](https://studio-staging-git-danny-oauth-impersonation-warning-supabase.vercel.app/)).
2. Open `/dashboard/authorize?auth_id=foo` (any `auth_id` is fine; the
real response may 404) ([Vercel
preview](https://studio-staging-git-danny-oauth-impersonation-warning-supabase.vercel.app/dashboard/authorize?auth_id=foo)).
3. DevTools → **Network** → find `GET
…/platform/oauth/authorizations/foo` (or whatever id you used).
4. Right-click → **Override content** (enable Local Overrides / pick a
folder if prompted).
5. Paste one of the payloads below (status **200**), save, then reload
the authorize page.
6. Keep `expires_at` in the future so the request does not look expired.

#### Impersonation caution (trusted name + remote non-allowlisted
redirect)

Expect:

- Supabase alone (no curated Claude mark)
- Caution: “Redirect does not match this app name”
- Footer redirect URL in warning colour

```json
{
  "name": "Claude",
  "website": "https://claude.ai",
  "icon": null,
  "domain": "claude.ai",
  "redirect_uri": "https://evil.com/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "dynamic"
}
```

| Preview |
| --- |
| <img width="764" height="958" alt="Authorize Claude Supabase"
src="https://github.com/user-attachments/assets/e6eee016-5710-41ba-9925-87511e009e22"
/> |

#### Localhost MCP: no caution

Expect curated Claude + Supabase pair (name match + loopback), **no**
caution, normal footer colour. Local MCP clients often use loopback
redirects.

```json
{
  "name": "Claude",
  "website": "https://claude.ai",
  "icon": null,
  "domain": "claude.ai",
  "redirect_uri": "http://127.0.0.1:42813/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "dynamic"
}
```

| Preview |
| --- |
| <img width="764" height="958" alt="Authorize Claude Supabase"
src="https://github.com/user-attachments/assets/79f36865-3c8e-43e5-9490-24288efc74aa"
/> |

#### Legitimate curated partner: no caution

Expect curated Cursor + Supabase pair, no admonition, normal footer
colour.

```json
{
  "name": "Cursor",
  "website": "https://cursor.com",
  "icon": null,
  "domain": "cursor.com",
  "redirect_uri": "https://cursor.com/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "dynamic"
}
```

| Preview |
| --- |
| <img width="764" height="958" alt="56164"
src="https://github.com/user-attachments/assets/412333a3-a74f-42eb-9f63-d56b6a26bf91"
/> |

#### Unrelated name + remote redirect: no caution

Expect Supabase alone (no icon), no admonition.

```json
{
  "name": "Acme Tools",
  "website": "https://evil.com",
  "icon": null,
  "domain": "evil.com",
  "redirect_uri": "https://evil.com/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "dynamic"
}
```

| Preview |
| --- |
| <img width="764" height="958" alt="Authorize Acme Tools Supabase"
src="https://github.com/user-attachments/assets/dab24817-5c26-4aa1-a447-796c4af5868b"
/> |

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Added an OAuth caution when a requester name matches a known partner
but uses an unapproved remote redirect host.
- Improved trusted partner logo selection for localhost/loopback
redirects while preserving safe fallbacks for untrusted redirects.

- **Documentation**
- Updated Connect interstitial guidance for redirect mismatches and
localhost/loopback behavior.

- **Tests**
- Expanded coverage for caution visibility, messaging, localhost logo
pairing, and trusted redirect scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-02 23:57:27 +00:00
Alaister YoungandAlaister Young ca2b50a0a7 chore(ui-patterns): collapse the admonition shim into ui-patterns/Admonition (#48377)
Follow-up to #48344: collapses the two resolution paths for the
Admonition module into one.

`src/admonition.tsx` was a back-compat shim re-exporting
`src/Admonition/`. Two ways to resolve one module is exactly what
produced the macOS self-import bug fixed in #48344, and the local
typecheck errors that #48374 worked around. This removes the shim and
standardizes on the PascalCase subpath, matching every other export in
the package.

**Changed:**

- Codemodded all 246 `ui-patterns/admonition` imports to
`ui-patterns/Admonition` (240 `.tsx`, 5 `.mdx`, 1 `.ts` across studio,
docs, www, design-system, and lite-studio)
- Pointed the 5 internal `'../admonition'` imports back at the
`'../Admonition'` directory

**Removed:**

- `packages/ui-patterns/src/admonition.tsx`, and its `./admonition`
entry in the exports map (regenerated with `pnpm gen:exports`)

## To test

- `grep -r "ui-patterns/admonition" --include='*.ts*'` → no hits
- `pnpm test:case-hazards` → passes
- `pnpm typecheck` → all 15 tasks green
- `pnpm --filter studio run lint:ratchet` → passes
- `pnpm --filter ui-patterns vitest run src/Admonition` → 11 tests pass

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Standardized Admonition component imports across the application and
documentation.
* Improved compatibility with case-sensitive environments by using the
canonical component path.
  * Removed the legacy Admonition import entry point.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-29 00:48:56 +08:00
Francesco Sansalvadore e4f75bf74c chore(studio): update copywriting on integrations pages (#48197) 2026-07-22 22:22:54 +02:00
Danny WhiteandJoshen Lim e19cd1863d feat(studio): connect logo contract for authorize (#48161)
## What kind of change does this PR introduce?

Feature + docs. Closes
[DEPR-604](https://linear.app/supabase/issue/DEPR-604/define-connect-logo-asset-and-variant-contract).

## What is the current behavior?

`/authorize` logo resolution trusted self-asserted requester `name` (and
similar) for curated MCP marks, fell back to a letter tile when there
was no usable icon, and always used theme-reactive tile chrome. This
includes the scenario when pairing against unclassified uploaded OAuth
app bitmaps.

## What is the new behavior?

- [Documents the Connect logo asset/variant
contract](https://design-system-git-danny-depr-604-connect-logo-contract-supabase.vercel.app/design-system/docs/ui-patterns/connect-interstitials#logos)
(default to light, keep pairs matched, no theme-recolour of vendor
SVGs).
- Resolves curated partner logos from allowlisted `redirect_uri` hosts
only (`claude.ai` / `anthropic.com`, `cursor.com` / `cursor.sh`,
`chatgpt.com` / `openai.com`, `perplexity.ai`).
- Unknown / missing / failed requester icons show `SupabaseLogo` alone
(no letter tile).
- Uploaded organisation OAuth app icons (unclassified bitmaps) pair with
fixed light tile chrome (`border-black/10 bg-white` / `SupabaseLogo
forceLight`) on both sides across Studio themes.
- Curated partners keep theme-reactive tiles and may use dark assets
when available.

### To test

Real MCP clients (Claude, Cursor, etc.) only send users to
**production** `/authorize`, so you cannot drive a local or preview
Studio build from those tools. Use a Network override instead:

1. Start Studio and sign in (`pnpm dev:studio`, or use the Vercel
preview once available).
2. Open `/dashboard/authorize?auth_id=foo` (any `auth_id` is fine — the
real response may 404).
3. DevTools → **Network** → find `GET
…/platform/oauth/authorizations/foo` (or whatever id you used).
4. Right-click → **Override content** (enable Local Overrides / pick a
folder if prompted).
5. Paste one of the payloads below (status **200**), save, then reload
the authorize page.
6. Keep `expires_at` in the future so the request does not look expired.

The fields that matter for this PR are `name`, `icon`, and
`redirect_uri`.

#### Curated pair (allowlisted redirect)

Expect Cursor mark + Supabase pair. Toggle light/dark: curated dark
assets may swap; tiles stay theme-reactive (`bg-surface-75`).

```json
{
  "name": "Cursor",
  "website": "https://cursor.com",
  "icon": null,
  "domain": "cursor.com",
  "redirect_uri": "https://cursor.com/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "dynamic"
}
```

#### Unknown → Supabase alone

Expect Supabase bolt alone. No letter tile. No curated mark even if
`name` says Claude.

```json
{
  "name": "Acme",
  "website": "https://acme.example",
  "icon": null,
  "domain": "acme.example",
  "redirect_uri": "https://acme.example/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "dynamic"
}
```

#### Spoofed trusted name, non-allowlisted redirect (logo only)

Expect Supabase alone (no Claude mark). This PR does **not** show the
impersonation caution (that is coming in #48162).

```json
{
  "name": "Claude",
  "website": "https://claude.ai",
  "icon": null,
  "domain": "claude.ai",
  "redirect_uri": "https://evil.com/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "dynamic"
}
```

#### Uploaded OAuth app icon → forced-light pair

Expect remote icon + Supabase pair with forced-light tiles
(`border-black/10 bg-white`) on both sides in light and dark Studio
themes. The icon URL below is the checked-in solid-colour Acme bitmap on
this branch.

```json
{
  "name": "Acme",
  "website": "https://acme.example",
  "icon": "https://raw.githubusercontent.com/supabase/supabase/danny/depr-604-connect-logo-contract/apps/design-system/public/img/icons/acme-oauth-icon.png",
  "domain": "acme.example",
  "redirect_uri": "https://acme.example/callback",
  "expires_at": "2099-01-01T00:00:00.000Z",
  "scopes": ["organizations:read", "projects:read"],
  "approved_at": null,
  "registration_type": "static"
}
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Improved authorization interstitial branding with trusted requester
logos and safer fallback behavior.
* Added support for consistent light-theme treatment of uploaded OAuth
app icons.
* Added examples and documentation for unknown requesters, uploaded
logos, and wrong-account states.
* **Bug Fixes**
* Prevented unverified or unavailable requester icons from being
presented as trusted.
* Ensured logo pairing remains visually consistent across light and dark
themes.
* **Tests**
* Added coverage for trusted-host validation, fallback branding, icon
loading failures, and theme behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-07-23 02:20:42 +10:00
Francesco Sansalvadore 9f5e75183c chore(studio): add bullet-point to integration uninstall modal (#48139)
## What is the current behavior?

<img width="533" height="394" alt="Screenshot 2026-07-21 at 11 55 05"
src="https://github.com/user-attachments/assets/4e5e8fde-5823-4ad2-849e-abad90bfa72a"
/>

## What is the new behavior?

<img width="501" height="430" alt="Screenshot 2026-07-21 at 12 43 17"
src="https://github.com/user-attachments/assets/2888d815-8c2c-47db-a058-dc60b208d6b1"
/>

## Additional context

Also fixed font-weight for strong text in studio to be `font-bold`.
2026-07-21 17:21:18 +02:00
Gildas Garcia b30db91d71 chore: cleanup UI patterns exports (#47406)
## Problem

We now export components under a subpath in ui-patterns to avoid barrel
files as they slow down every tools (from IDE to linters, etc.) and may
also affect bundles our users have to download.

## Solution

- Remove the UI patterns index file
- Fix invalid impors
2026-06-30 09:23:17 +02:00
Gildas Garcia c6fc456910 chore: cleanup duplicate exports studio (#47387)
## Problem

Knip reports many duplicate exports (both named and default). Besides,
we're moving away from default exports and even have an eslint rule to
enforce it on new code.

## Solution

- Cleanup those exports
- Update imports when necessary

No functional changes. If it builds, it's fine
2026-06-29 15:46:16 +02:00
Danny WhiteandCopilot Autofix powered by AI 032bd09b0c feat(studio): use theme-aware OAuth requester logos (#47138)
## What kind of change does this PR introduce?

Bug fix. 

- Follow-up work to FE-3640
- Contributes to DEPR-604

## What is the current behavior?

Known dynamic OAuth requesters on `/dashboard/authorize` relied on
OAuth-specific hard-coded icon assets that were dark-mode only.

Cursor did not have separate light/dark assets in the shared MCP icon
registry, Perplexity only had a light tile asset with baked-in padding,
and OpenAI used the older blossom mark.

## What is the new behavior?

Known OAuth requester logos now resolve through the shared MCP icon
registry while preserving the existing `SupabaseLogo` treatment for
paired authorisation screens.

Cursor uses transparent SVG light/dark variants, Perplexity has cropped
transparent SVG light/dark variants, and OpenAI/ChatGPT uses the newer
monoblossom SVG in black/white variants. Claude remains static until a
suitable variant is available.

Unknown requester icons still render from the provided URL and fall back
to the requester initial if the image fails.

| Before | After |
| --- | --- |
| <img width="828" height="636" alt="Authorize OpenAI
Supabase-E2A05664-589F-458F-8452-9CEE008D558A"
src="https://github.com/user-attachments/assets/140021b1-ff05-4092-98ef-2eae94ff2ddb"
/> | <img width="828" height="636" alt="Authorize OpenAI
Supabase-EC7E00BD-439A-45D1-8E55-240B227C6897"
src="https://github.com/user-attachments/assets/93e603f2-5cbf-4219-b692-d36ac98e8d2a"
/> |
| <img width="828" height="636" alt="66 Authorize OpenAI
Supabase-CB31FF76-86DB-43A6-A426-46B99B8B1B91"
src="https://github.com/user-attachments/assets/b261416e-39b8-40b3-87fd-461653aa0334"
/> | <img width="828" height="636" alt="Authorize OpenAI
Supabase-EAFCF2F2-5CEA-4FE6-8AC0-819F764B414E"
src="https://github.com/user-attachments/assets/35ad7525-0fa9-4438-b117-4e70b78eb719"
/> |

## To test

1. Navigate to `http://localhost:8082/authorize?auth_id=test-auth-id`
2. Open DevTools → Network
3. Find `/platform/oauth/authorizations/test-auth-id`
4. Right-click → Override content
5. Replace the response body with:
	```js
	{
	  "name": "Perplexity",
	  "website": "https://perplexity.ai",
	  "icon": null,
	  "domain": "perplexity.ai",
	  "scopes": [],
	  "expires_at": "2026-12-31T23:59:59.000Z",
	  "approved_at": null,
	  "registration_type": "dynamic"
	}
	```
6. Then change "name" to Cursor, Claude, ChatGPT, or OpenAI and refresh
to inspect each logo

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* OAuth app requester logos now dynamically adapt to light and dark
themes, with improved logo selection for known requesters.
  * Cursor now uses a distinct dark icon variant.
  * Added Perplexity client icon support.

* **Bug Fixes**
* Improved logo rendering robustness: if a logo can’t be loaded, the UI
falls back to the requester’s initial.

* **Tests**
* Expanded coverage for theme-aware logo rendering and icon variant
handling, including unknown-icon and fallback scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-24 09:30:48 -06:00
Matt Linkous 171ca026b5 feat(studio): Add integration settings page with connected resources (#46961)
Adds integrations settings page to each oauth integration to show
associated resources (e.g. API keys, config, oauth apps, etc)

<img width="1150" height="892" alt="Screenshot 2026-06-16 at 2 44 31 PM"
src="https://github.com/user-attachments/assets/035cc602-886d-43bc-a5a7-e14f76dd37c3"
/>



<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary

* **New Features**
* Added a Marketplace “Settings” tab with a grouped **Connected
resources** view (OAuth apps, API keys, Edge Function secrets, SMTP),
including loading/empty/missing-resource states and per-kind removal
actions.
* Added a resource-group section UI plus integration-aware grouping/copy
customization and missing-kind zero-states.
* **Bug Fixes**
* Improved installed-state detection for Grafana and Doppler by
broadening conditions.
* Added an orphaned-resources warning when expected OAuth apps are
missing.
* **Refactor**
* Unified connected-resource removal into a single flow with
OAuth-specific revoke handling.
* **Tests**
* Added comprehensive UI and utility coverage for grouping, states, and
destructive removal behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-22 20:51:14 +00:00
Ivan Vasilov f8e682c443 fix: Add custom icon overrides for specific MCP apps (#47130)
This PR hardcodes icons for most used AI apps (`Claude`, `Perplexity`,
`ChatGPT` and `Cursor`) because their icons are coming from other
domains which we don't want to add CORS exemptions for.

<img width="534" height="638" alt="Screenshot 2026-06-19 at 16 44 12"
src="https://github.com/user-attachments/assets/258cfb7b-e0fa-4408-bc2d-911c197f097d"
/>
<img width="499" height="676" alt="Screenshot 2026-06-19 at 16 44 48"
src="https://github.com/user-attachments/assets/67004935-bad1-4cf9-8d4c-edbb5c466288"
/>
<img width="667" height="753" alt="Screenshot 2026-06-19 at 16 48 59"
src="https://github.com/user-attachments/assets/cd12677f-dfde-438b-bc54-4be36c7c0fa2"
/>
<img width="608" height="715" alt="Screenshot 2026-06-19 at 16 49 21"
src="https://github.com/user-attachments/assets/d2b642ca-598d-4ac8-8177-179ef249cb58"
/>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

## Release Notes

* **Bug Fixes**
* Improved OAuth app authorization detail logos by adding app-specific
fallback icons for known app identifiers, ensuring the correct logo
shows when the original icon is missing or fails to load.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-06-19 17:23:32 +02:00
Danny WhiteandCursor 3211d52a2a fix(studio): fallback to initial when OAuth logo fails to load (#46953)
## What kind of change does this PR introduce?

Bug fix. Resolves DEPR-594.

## What is the current behavior?

On Studio, when an OAuth app provides an `icon` URL that fails to load
(e.g. Cursor MCP’s logo on Vercel Blob is blocked by CSP `img-src`),
`RequesterLogo` renders an empty gray box on `/authorize` even though a
letter fallback already exists when `icon` is null.

## What is the new behavior?

`RequesterLogo` tracks image load failures via `onError` and falls back
to the app name initial—the same treatment used when no icon URL is
provided. Applies to the authorize interstitial and approved state.

This is graceful degradation, not a logo-delivery fix. Partner logos
that load successfully (e.g. Figma on `*.supabase.co`) are unchanged.

## Additional context

**Proper fix (later):** Mirror partner logos to Supabase-controlled
storage at dynamic registration time. This is tracked in
[DEPR-596](https://linear.app/supabase/issue/DEPR-596).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Improvements**
* OAuth app requester logos now feature enhanced error handling. If a
logo image fails to load, the system automatically displays a fallback
text-based avatar using the requester's initials. Logo displays refresh
correctly when you update app icons, ensuring a consistent and reliable
user experience throughout your application management.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-18 00:28:09 +10:00
Gildas GarciaandIvan Vasilov 96d43099bb chore: refactor Button API so that it can be used a standard button (#46880)
## Problem

Our `<Button>` component breaks the default `button` contract by
redefining the `type` prop to set its variant (`primary`, `default`,
etc) instead of the button type (`submit`, `button`, etc).
This is confusing and forces to write more code when using it with
shadcn components that expect/inject the standard button props.

## Solution

- rename the `type` prop to `variant`
- rename the `htmlType` prop to `type`
- propagate the changes where necessary
- format code

## How to test

As this is just prop renaming, if it builds it's ok

---------

Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-06-16 23:59:58 +02:00
35df570342 feat(studio): move /authorize to connect interstitial (#46359)
> [!CAUTION]
> The `do-not-merge` label has been applied because this contains mocks
for easier review and testing. I'll remove those mocks before merging.

## What kind of change does this PR introduce?

Feature. Part of the shared Connect UI (interstitial) rollout. Previous
slices: #46058, #45909, #45862.

## What is the current behavior?

The `/authorize` MCP/OAuth consent screen uses the old `Card`/`Alert`
layout.

## What is the new behavior?

- Wraps all `/authorize` states in `InterstitialLayout` (the shared
full-screen centered card used across Connect flows)
- Shows a quiet footnote below the Cancel button ("Authorizing will
redirect you to \<url\>") for non-localhost redirect URIs, so users can
verify the destination before approving. No extra friction for localhost
flows (local MCP servers)

| Before | After |
| --- | --- |
| <img width="692" height="997" alt="Authorize API access
Supabase-F6C3747A-5077-43D8-A509-3E16B1DDC168"
src="https://github.com/user-attachments/assets/e86dde34-94cb-48ef-b026-66aac9122df6"
/> | <img width="692" height="997" alt="Authorize API Access
Supabase-FE6FD8B3-1159-4EA5-94D7-EA5CEA7A25F3"
src="https://github.com/user-attachments/assets/c1a94a44-51d9-40d8-8046-f3104a27b929"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-86742351-3521-4B62-AF87-403CB7E7F4F5"
src="https://github.com/user-attachments/assets/41cff7af-b9e4-4a20-a979-7148b4220265"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-B665B4A4-600F-462B-8C97-84B171EC3103"
src="https://github.com/user-attachments/assets/804286f2-ce51-45ab-bb3f-315f8ac62445"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-C73DC3D0-8646-4E6E-A259-3E84AE46DAF2"
src="https://github.com/user-attachments/assets/8f285edb-438f-4262-9faa-f1133c679ed4"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-FEA86625-27D5-4DB5-B4D4-1A2CB804E56E"
src="https://github.com/user-attachments/assets/b54f2ceb-e1cf-4c7e-be3f-8e1b0942e9a4"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-48E0C7CB-DDDD-4305-B821-F3BEB52C4A4E"
src="https://github.com/user-attachments/assets/7d123c57-e05d-408c-8df9-d747a3afd714"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-CE8F9905-FAE0-4C06-B77A-9F269B2100FE"
src="https://github.com/user-attachments/assets/9f403b83-5de3-43c8-a592-c3022e041243"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-E37D2CD5-476F-4F49-A5FB-631B265025DC"
src="https://github.com/user-attachments/assets/3d235315-d7c0-4279-b23f-e8b595888511"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-DF078AEB-BB78-4647-9FA2-5D5403CCA5D6"
src="https://github.com/user-attachments/assets/53d51718-8707-4b97-9cbe-8e523f4ce0e0"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-D6F6817F-D8DD-4D55-85BB-A15100814AAB"
src="https://github.com/user-attachments/assets/c80c5579-772a-4dfe-a247-b0b9772b9690"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-E457B580-9786-43AD-9CF9-FE4F5BB8E785"
src="https://github.com/user-attachments/assets/30c47b05-edf5-4380-a2f1-aedb99482540"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-4F3D6AA4-E2E3-4526-B391-49B6E0861911"
src="https://github.com/user-attachments/assets/ffbe5b65-6eef-49d7-95f1-c29072c320b8"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-CA9FFCC9-4CA2-4718-AD49-B02D86C6EF6A"
src="https://github.com/user-attachments/assets/8fd7ff39-19f5-4414-af13-3821290735b2"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-E507B7A5-9AD0-4F17-8743-63A7B47D171A"
src="https://github.com/user-attachments/assets/1639b5cc-69c4-4a43-b049-6f989e2cdbb1"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-9844BB27-2429-4BA6-BD36-1AB54099F44F"
src="https://github.com/user-attachments/assets/a94b88e2-9c2f-4941-840a-5182342bb335"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-27684173-9DBB-4F6E-9F7F-87EFD4E10A5F"
src="https://github.com/user-attachments/assets/91794c96-8a81-4d83-9c97-01d134639676"
/> | <img width="692" height="997" alt="Authorize Cursor
Supabase-04E31F7B-D098-4814-A394-01CE3D3E5A51"
src="https://github.com/user-attachments/assets/ba0284a3-363c-4aa5-9e4a-c378aed9c42c"
/> |
| <img width="692" height="997" alt="Authorize API access
Supabase-207CBC69-4957-499C-92E8-163F2B34C8AD"
src="https://github.com/user-attachments/assets/1bafedd2-bba8-473c-ba57-637289f1c940"
/> | <img width="692" height="997" alt="Authorize API Access
Supabase-C1627071-4AE2-4012-8F7C-4E6D883618A3"
src="https://github.com/user-attachments/assets/a6fc6125-3c1e-4b8c-821a-c3c9f32f3cc0"
/> |

## To test

A mock toolbar is included for easy local testing. Navigate to
`/authorize?mock=loading` and then switch between the following
variants:

| State | What to check |
| --- | --- |
| `loading` | Shimmer skeleton inside the card |
| `ready` | Regular waiting state |
| `approving` | Authorize button shows spinner, both buttons disabled |
| `approved` | Success admonition: "Authorization approved" |
| `expired` | Warning admonition: "Authorization request expired", no
action buttons |
| `organizations-loading` | Org selector shimmer, no action buttons |
| `organizations-error` | "Unable to load organizations" admonition, no
action buttons |
| `empty` | "No organizations found" admonition, no action buttons |
| `not-member` | "Organization unavailable" admonition, no action
buttons |
| `error` | "Unable to load authorization" error screen |

Then please test the `organization_slug` prefill:
`/authorize?mock=ready&organization_slug=<your-org-name-here>`. That org
selector should be pre-selected and locked.

To test against a real OAuth app, use a registered app on
`supabase.green` — the mock states cover all edge cases but a live
round-trip confirms the approve/decline API calls.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

## Release Notes

* **New Features**
* Added mock preview functionality for testing API authorization and
Connect flows
* Introduced collapsible, grouped permissions view for OAuth
authorization requests

* **Refactor**
* Redesigned API authorization screens with improved layout and
messaging
  * Restructured permissions display for better organization and clarity

* **Bug Fixes**
  * Fixed inline link underline decoration color

* **Tests**
  * Updated authorization flow test assertions to match new UI behavior

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46359?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-06-08 10:51:04 -06:00
Alex Hall 3e3496ef6c fix(studio): copy updates to revoke oauth modal (#46687) 2026-06-05 18:10:49 -04:00
b2b5cba287 feat(studio): add organization shortcuts (#46356)
## What kind of change does this PR introduce?

Feature. Resolves FE-3470.

## What is the current behavior?

Organization surfaces have a `G then ,` shortcut to enter org settings,
but once inside there is no keyboard navigation, sidebar tooltips, or
action shortcuts for the various org pages.

| Area | Current behaviour |
| --- | --- |
| Org Settings sidebar | Routes are click-only once users are inside
Settings. |
| OAuth Apps | Publish / confirm actions have no keyboard shortcuts. |
| Private Apps | Create app has no keyboard shortcut. |
| Team | Invite / send actions have no keyboard shortcuts. |
| Integrations | Add project connection has no keyboard shortcut. |
| Org Projects | New project and search have no keyboard shortcuts. |
| Audit Logs | Refresh has no keyboard shortcut. |

## What is the new behavior?

Mirrors the Project Settings shortcut pattern (#46352) across all
Organization surfaces.

| Area | New shortcut coverage |
| --- | --- |
| Org Settings sidebar | `S then G/C/S/A/P/W/L/D` for General, Security,
SSO, OAuth apps, Private apps, Webhooks, Audit logs, Legal documents.
Shortcut badge appears on hover in the sidebar. |
| Org Settings entry | `G then ,` (remapped from `G then O`) to match
the Project Settings chord. |
| OAuth Apps | `Shift+N` opens Publish app panel; `Mod+Enter` confirms
the open panel. |
| Private Apps | `Shift+N` opens Create app sheet (works in both
empty-state and list-state). |
| Team | `Shift+N` opens Invite members dialog; `Mod+Enter` sends the
invitation(s). |
| Integrations | `Shift+N` triggers Add project connection when
permitted. |
| Org Projects | `Shift+N` navigates to new project; `Shift+F` focuses
the search input. |
| Audit Logs | `Shift+R` refreshes the log list. |

### Implementation notes

- Threads `shortcutId` through the `WithSidebar` pipeline (`SidebarLink`
→ `SubMenuSection` → `ProductMenuGroup`) so tooltip display is automatic
— no new rendering logic.
- Layout-scoped chords mount only while `OrganizationSettingsLayout` is
active, so `S then G` in org settings does not conflict with `S then G`
in project settings.
- Cheatsheet reference groups promoted to typed constants with readable
labels (was: bare strings like `'org-oauth-apps'`).

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* System-wide keyboard shortcuts for org areas: project search & new
project, private app creation, OAuth app publish/confirm, add GitHub
integration, invite members (open/submit), and refresh audit logs.
* Sidebar and product menu now show assigned shortcuts for faster
navigation; org settings navigation shortcut remapped.

* **Tests**
* Added coverage for org shortcut registry behavior, sequences, and
ordering.

* **Chores**
* New shortcut reference groups and ordering for improved
discoverability.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46356?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Ali Waseem <waseema393@gmail.com>
2026-05-28 15:48:32 +00:00
Gildas Garcia 838fe7f976 chore: migrate Organization settings Modal to Dialog (#46332)
## Problem

Organization settings still uses the deprecated `Modal` for:
- downgrading subscription
- requesting feedback after downgrading
- showing an alert about members limit
- requesting feedback after upgrading
- deleting a published OAuth app
- showing preview of a new OAuth app
- Revoking an OAuth app

## Solution

- use `Dialog` instead

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Replaced legacy modal UI with the app's modern dialog/alert-dialog
components across billing and OAuth settings (upgrade/downgrade, exit
survey, members-limit, delete/revoke, preview), keeping existing content
and flows.
* Confirm/cancel flows updated for more reliable async handling and
clearer loading/disabled states during actions.

<!-- review_stack_entry_start -->

[![Review Change
Stack](https://storage.googleapis.com/coderabbit_public_assets/review-stack-in-coderabbit-ui.svg)](https://app.coderabbit.ai/change-stack/supabase/supabase/pull/46332?utm_source=github_walkthrough&utm_medium=github&utm_campaign=change_stack)

<!-- review_stack_entry_end -->
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-05-25 17:51:19 +02:00
Gildas Garcia 0713a1efc1 chore: remove shadcn suffix for Input, Textarea, Alert and Collapsible (#45867)
## Problem

Now that we migrated old components to their new shadcn alternatives, we
don't need the `_Shadcn_` suffix anymore.

## Solution

Remove it

<img width="659" height="609" alt="image"
src="https://github.com/user-attachments/assets/2d7271a9-066a-4dcc-92fe-729b106d2c2f"
/>
2026-05-15 14:55:37 +02:00
Ivan VasilovandJordi Enric 56de26fe22 chore: Migrate the monorepo to use Tailwind v4 (#45318)
This PR migrates the whole monorepo to use Tailwind v4:
- Removed `@tailwindcss/container-queries` plugin since it's included by
default in v4,
- Bump all instances of Tailwind to v4. Made minimal changes to the
shared config to remove non-supported features (`alpha` mentions),
- Migrate all apps to be compatible with v4 configs,
- Fix the `typography.css` import in 3 apps,
- Add missing rules which were included by default in v3,
- Run `pnpm dlx @tailwindcss/upgrade` on all apps, which renames a lot
of classes
- Rename all misnamed classes according to
https://tailwindcss.com/docs/upgrade-guide#renamed-utilities in all
apps.

---------

Co-authored-by: Jordi Enric <jordi.err@gmail.com>
2026-04-30 10:53:24 +00:00
Ivan Vasilov 308cd791a2 chore: Prep work for migrating to Tailwind v4 (#45285)
This PR preps the monorepo for a migration to Tailwind v4:
- Bump all Tailwind dependencies and libraries to the latest possible
version, while still compatible with Tailwind 3.
- Cleans up obsolete Tailwind 3 specific options and configs.
- Cleans up unused CSS files and fixes the CSS imports.
- Migrates all `important` uses in `@apply` lines to using the `!`
prefix.
- Move `typography.css` to the `config` package and import it from the
apps.
- Migrated all occurrences of `flex-grow`, `flex-shrink`,
`overflow-clip` and `overflow-ellipsis` since they're deprecated and
will be removed in Tailwind 4.
- Make the default theme object typesafe in the `ui` package.
- Migrate all `bg-opacity`, `border-opacity`, `ring-opacity` and
`divider-opacity` to the new format where they're declared as part of
the property color.
- Bump and unify all imports of `postcss` dependency.
2026-04-28 11:33:53 +02:00
Gildas Garcia 0facd341a6 chore: remove UI form components _Shadcn_ suffix (#45212)
## Problem

We used to have a `_Shadcn_` suffix for all the shadcn form components
because we also had `formik` form components.
This is not needed anymore.

## Solution

- Remove the suffix
- Update all usages
2026-04-24 12:14:15 +02:00
Alex Hall d70ed2ef76 chore: Add new OAuth scopes for analytics config to studio (#44826)
## Summary

Adds support for new OAuth scopes for reading and writing analytics
config to the app creation dialog and consent screen.

Depends on https://github.com/supabase/platform/pull/31539
2026-04-15 15:59:43 -04:00
Gildas Garcia 054e44f7e6 fix: improve oauth apps callback urls UX (#44714)
## Problem

#44677 modified the previous behaviour on callback URLs. It used to
prevent users to remove the URL if only one was provided.

## Solution

Restore the previous behaviour.

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed the Remove button behavior for OAuth callback URLs. The button
now only appears when multiple callback URLs are configured, preventing
accidental deletion of the only redirect URI.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-09 18:30:24 +00:00
Gildas Garcia 2538b56b71 chore: migrate oauth apps form to react-hook-form (#44677)
## Problem

Foreign wrapper forms still use `formik` but we now use
`react-hook-form` everywhere and we'd like to reduce our dependencies.

## Solution

This PR focuses on migrating the OAuth apps form to `react-hook-form`


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Refactor**
* Reworked the OAuth app publish form to use schema-driven validation
and managed callback URL fields.
* Replaced bespoke URL state/handlers with add/remove field array logic;
consolidated error rendering.
* Submission, loading and preview now reflect real-time form state and
reset correctly when the panel or selection changes.

* **Bug Fixes**
* Improved URL validation to handle localhost cases and optional
HTTPS-only enforcement.

* **Tests**
* Extended URL validation tests to cover localhost, HTTP/HTTPS and
HTTPS-only scenarios.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-09 17:06:03 +02:00
4a0bb36ca8 style: require sorted imports in studio/components (#44408)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Ivan Vasilov <vasilov.ivan@gmail.com>
2026-04-01 10:22:37 +02:00
Danny WhiteandJoshen Lim 503c01b5bc chore(studio): refactor oauth apps page and table (#43366)
## What kind of change does this PR introduce?

UI update.

## What is the current behavior?

The org’s /apps page is glaringly out of date compared to similar pages.
It uses old page and layout components.

## What is the new behavior?

- Refactored /apps to use latest
[layout](https://supabase.com/design-system/docs/ui-patterns/layout) and
[table](https://supabase.com/design-system/docs/components/table)
components

Unrelated minor changes snuck in:

- Global `pnpm format` to properly format recurring annoyances elsewhere
- Minor polish on org tiles (pictured)

| Before | After |
| --- | --- |
| <img width="1728" height="997" alt="OAuth Apps
Supabase-30B6CDAE-4954-40F8-886A-939797999AA6"
src="https://github.com/user-attachments/assets/163c2787-f6ab-4a0b-80aa-af81260bdf9f"
/> | <img width="1728" height="997" alt="OAuth Apps
Supabase-7DD241E0-262A-4817-91B2-D2A299F8EB93"
src="https://github.com/user-attachments/assets/29928305-9110-4256-8663-c3821e696587"
/> |
| <img width="1728" height="997" alt="OAuth Apps
Supabase-9870816A-8022-479D-8011-236A813249AB"
src="https://github.com/user-attachments/assets/32e41835-59bc-4d83-92eb-635b98c5f4a5"
/> | <img width="1728" height="997" alt="OAuth Apps
Supabase-21CFBC16-E850-44A6-BEFF-C4FBED8ACB43"
src="https://github.com/user-attachments/assets/6999e2a0-ea17-44cb-99f2-42f985354589"
/> |
| <img width="1152" height="664"
alt="Supabase-9DD87028-2D46-47D0-8546-240184E1711B"
src="https://github.com/user-attachments/assets/2c7d8b2a-280f-48d6-9f78-19c519cf4654"
/> | <img width="1152" height="664"
alt="Supabase-F1C92F66-C602-4DC9-B3B4-AE3FB673276E"
src="https://github.com/user-attachments/assets/0a24a98e-386f-4ada-b282-0a59b159bbab"
/> |

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2026-03-06 12:23:33 +11:00
Danny White 706207436f chore(studio): move organization settings nav to sidebar layout (#43228)
## What kind of change does this PR introduce?

UI change

## What is the current behavior?

Organization settings are currently spread across a NavMenu. This is
getting unweildy as the amount of children within Organization settings
grows.

## What is the new behavior?

Organization settings are now on a sidebar, just like Project Settings
and most other surfaces.

| Before | After |
| --- | --- |
| <img width="1024" height="563" alt="Supabase"
src="https://github.com/user-attachments/assets/3889858c-157a-4deb-8714-71fe9cf002e6"
/> | <img width="1024" height="563" alt="General Supabase"
src="https://github.com/user-attachments/assets/1b4eb2c3-a67c-4eda-ab3c-e6610dd5ccf4"
/> |

## Additional context

@fsansalvadore and the design team have have other efforts going on to
reduce interface clutter, e.g. nested sidebars.
2026-03-03 10:15:40 +11:00
Ivan Vasilov cc47bcfa6d chore: Migrate studio to use ui-patterns/shimmeringLoader (#41405)
* Add shimmering-loader CSS to ui-patterns.

* Import the shimmering-loader classes from the ui-patterns component.

* Remove ShimmeringLoader from studio.

* Migrate studio to use ui-patterns/ShimmeringLoader.

* Migrate away from using default import for ShimmeringLoader.

* Fix the css imports in docs and studio.
2025-12-17 14:54:07 +01:00
Ivan Vasilov 0d5be306ef chore: Bump React Query to v5 (#40174)
* Bump the deps, refactor deprecated code.

* Migrate keepPreviousData usage.

* Migrate all uses of InfiniteQuery.

* Fix refetchInterval in queries.

* Migrate all use of isLoading to isPending in mutations.

* Fix accessing location in claim-project.

* Fix a bug in duplicate query keys.

* Migrate all queries to use isPending.

* Revert "Fix accessing location in claim-project."

This reverts commit 2a07df64b5.

* Revert the rss.xml file to master.
2025-12-10 10:10:29 +01:00
Danny WhiteandJoshen Lim 031b227165 studio(chore): badge component defrag (#40118)
* component clean up

* optically center

* docs and type size

* code badge variant

* sensible defaults

* fix product menu flex

* badge sweep

* new project badges

* logs

* compute badge

* studio badge sweep

* www sweep

* docs sweep

* clean up

* fixes

* cleanup

* fixes

* better docs

* fixes

* misc fixes

* consistency

* Minor fixes for issues i found

* simplify mt-0

* mt simplification

* remaining optical alignment

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-12-02 11:15:50 +11:00
Ivan Vasilov 43cc61818c chore: Migrate all isPending uses in react-query (#40642)
* Bump react-query. Minor type and logic fixes.

* Migrate all use of isLoading to isPending in mutations.

* Fix type errors.
2025-11-20 16:44:53 +01:00
5f533247e1 Update docs url to env var (#38772)
* Update Supabase docs URLs to use env variable

Co-authored-by: a <a@alaisteryoung.com>

* Refactor: Use DOCS_URL constant for documentation links

This change centralizes documentation links using a new DOCS_URL constant, improving maintainability and consistency.

Co-authored-by: a <a@alaisteryoung.com>

* Refactor: Use DOCS_URL constant for all documentation links

This change replaces hardcoded documentation URLs with a centralized constant, improving maintainability and consistency.

Co-authored-by: a <a@alaisteryoung.com>

* replace more instances

* ci: Autofix updates from GitHub workflow

* remaining instances

* fix duplicate useRouter

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: alaister <10985857+alaister@users.noreply.github.com>
2025-09-26 10:16:33 +00:00
Joshen Lim d46525eac1 Chore/swap use check permissions with use async check project permissions part 8 (Season Finale) (#38619)
* Update perms checking in audit logs

* Deprecate useCheckPermissions, useIsPermissionsLoaded and useCheckProjectPermissions as they're no longer used

* Rename useAsyncCheckProjectPermissions to useAsyncCheckPermissions

* Fix TS
2025-09-16 17:05:57 +08:00
Joshen Lim 7650926b77 Chore/swap use check permissions with use async check project permissions part 7 (#38581)
* Wrap up remaining swapping of useCheckPermissions

* remove OrganizationSettingsLayout on billing, team, integrations and usage org pages

* Fix missing loading state in usage page

* Add comments for next step
2025-09-10 18:09:18 +08:00
Drake CostaandJoshen Lim b5a79f9ec5 Replace deprecated components on /authorize page (#37965)
* replace deprecated components on `/authorize` route

* Minor clean ups

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-08-26 14:47:32 +08:00
Raúl Barroso 29ee6a2992 style: use GitHub's right product name (#38099)
* style: use GitHub's right product name

* fix: use correct kotlin provider
2025-08-22 13:43:47 +02:00
Ivan VasilovandClaude 6b5abce83b feat: Display OAuth client secret last used time (#37510)
Add display of last_used_at timestamp for OAuth client secrets in Studio.
Shows relative time (e.g., "Last used 2 hours ago") when available,
or "Never used" for unused secrets.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-authored-by: Claude <noreply@anthropic.com>
2025-07-29 17:53:01 +08:00
Joshen Lim 1d85aa632b Consolidate oauth apps perms descriptions, and make project perms clearer (#37525) 2025-07-29 17:27:07 +08:00
Ivan VasilovandJoshen Lim 586a829828 feat: Project claim (#35992)
* Add another page for claiming a project.

* Fix a misspell.

* Minor fixes.

* Comment some test code.

* Update the design on the confirm step.

* Reorganize the authorize page. Bunch of design fixes for the claim page.

* Fix

* Delete added files my mistake.

* Separate claim-project and authorize pages. Minor design fixes.

* Add more logs to the generate claim button.

* snapshot.

* Add more copy to the three steps.

* Make the claim URL button better.

* Add missing comma.

* Fix unneeded changes.

* Make the header full width.

* Fix all comments by Joshen.

* Clean up extra code.

* Forgotten some things to clean.

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-06-10 11:49:23 +03:00
Joshen Lim 7d01bfb6db Tiny fix for copy client id (#35097) 2025-04-17 23:21:16 +08:00
Joshen Lim a4d5af48c8 Downgrade and fix radix dialog version to 1.0.5, and remove unnecessary modal props from all usages of DropdownMenu (#35027)
* Downgrade and fix radix dialog version to 1.0.5, and remove unnecessary modal props from all usages of DropdownMenu

* Downgrade and fix radix dialog version to 1.0.5, and remove unnecessary modal props from all usages of DropdownMenu

* Fix PopoverPOrtal

* Fix
2025-04-15 17:29:32 +08:00
Alaister Young 9fbbc8b12a fix: oauth scopes dropdown bug (#34899) 2025-04-10 13:22:02 +00:00
Jonathan Summers-MuirandJoshen Lim aefb34fd9c Feat: Adds Oauth client management (#34591)
* adds Oauth client update

* moar

* Update OAuthSecrets.tsx

* Fix TS issues

* moar

* Minor refactors

* Minor refactors

* Tidy up

* Clean up

* Clean up

---------

Co-authored-by: Joshen Lim <joshenlimek@gmail.com>
2025-04-07 17:43:46 +08:00
Kamil Ogórek 034435234f ref: Remove redundant oauth apps icon workaround (#34471) 2025-03-27 14:16:37 +01:00
Joshen Lim 8dcf326223 Authorized apps in org settings add copy action for App ID (#34321)
Authorized apps in org settings add copy action for add ip
2025-03-21 19:36:14 +08:00
Kamil Ogórek 315a189577 feat: Add created_by and app_id to approved oauth apps table (#34045)
* feat: Add created_by to approved apps table

* feat: Add app_id to approved apps table
2025-03-14 10:43:28 +01:00