diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 8f48264e86e09..5ad8d8d0bf72b 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -53,6 +53,8 @@ Never hand-edit generated files: `packages/api-types/types/**`, `**/routeTree.ge **Language** — Use U.S. English everywhere. +**Public surfaces** — this repo is public: PR descriptions, issues, and code comments are world-readable. Keep internal content out of them: absolute production metrics (event counts, user counts, revenue figures: state percentages, ratios, or relative change instead), internal decision detail (vendor, legal, pricing, or strategy discussions), and competitor names (protocol identifiers such as user-agent strings are fine). Put that context in the Linear issue and link it. + ## Skills The skills in `.claude/skills/` are the source of truth for conventions — load the relevant ones before working, don't guess: diff --git a/.github/workflows/studio-e2e-test.yml b/.github/workflows/studio-e2e-test.yml index 9573189273d52..67da2f67312e2 100644 --- a/.github/workflows/studio-e2e-test.yml +++ b/.github/workflows/studio-e2e-test.yml @@ -44,6 +44,8 @@ jobs: filters: | studio: - 'packages/pg-meta/**' + - 'packages/ui/**' + - 'packages/ui-patterns/**' - 'apps/studio/**' - 'apps/ui-library/**' - 'apps/design-system/**' diff --git a/.github/workflows/studio-unit-tests.yml b/.github/workflows/studio-unit-tests.yml index bed6790239f47..65e65dabcf412 100644 --- a/.github/workflows/studio-unit-tests.yml +++ b/.github/workflows/studio-unit-tests.yml @@ -8,6 +8,8 @@ on: branches: [master, studio] paths: - 'apps/studio/**' + - 'packages/ui/**' + - 'packages/ui-patterns/**' - 'pnpm-lock.yaml' pull_request: branches: [master, studio] @@ -44,6 +46,8 @@ jobs: with: filters: | relevant: + - 'packages/ui/**' + - 'packages/ui-patterns/**' - 'apps/studio/**' - 'pnpm-lock.yaml' - uses: pnpm/action-setup@0ebf47130e4866e96fce0953f49152a61190b271 # v6.0.9 diff --git a/apps/docs/content/guides/functions/auth-headers.mdx b/apps/docs/content/guides/functions/auth-headers.mdx index 21d1ac59ef553..e0f982507ba74 100644 --- a/apps/docs/content/guides/functions/auth-headers.mdx +++ b/apps/docs/content/guides/functions/auth-headers.mdx @@ -16,7 +16,11 @@ Edge Functions care about two request headers. Sending the wrong credential in t | `Authorization` | `Bearer ` | A user signed in through Supabase Auth | | `apikey` | `sb_publishable_...` or `sb_secret_...` | Calls from clients or services | -A common mistake is sending a publishable or secret key as a bearer token: `Authorization: Bearer sb_publishable_...`. The new API keys are not JWTs. The platform check can't validate them, and your handler can't verify them as JWTs either. Instead, put API keys in the `apikey` header. + + +A common mistake is sending a publishable or secret key as a bearer token: `Authorization: Bearer sb_publishable_...`. The new API keys are not JWTs. The platform check still accepts them, but your handler can't verify them as JWTs. Instead, put API keys in the `apikey` header. + + You can send both headers together. A signed-in user calling your function through `supabase-js`, for example, sends their session JWT in `Authorization` and the project's publishable key in `apikey`. @@ -26,7 +30,13 @@ When `verify_jwt` is enabled (the default), the platform inspects the `Authoriza The check validates legacy HS256 JWTs and JWTs signed with the new asymmetric [signing keys](/docs/guides/auth/signing-keys). -The check does not accept an API key. Publishable and secret keys are not JWTs, so callers that send one in the `Authorization` header fail the check before their request reaches your handler. +Publishable and secret keys are not JWTs, but the check still accepts them in the `Authorization` header, so callers that send one there reach your handler. + + + +For migration compatibility, `verify_jwt` accepts publishable and secret keys on either header, so a key on `apikey` passes the check too. The check alone doesn't authenticate a caller that sends only an API key. Reserve `Authorization` for user tokens, and send API keys on `apikey`. To move off legacy keys entirely, migrate to the `@supabase/server` SDK as shown in [Securing Edge Functions](/docs/guides/functions/auth). + + Use the `verify_jwt` flag to match how the function is called: diff --git a/apps/studio/.claude/skills/explorer/SKILL.md b/apps/studio/.claude/skills/explorer/SKILL.md index 3a086025fe822..96af375105e2b 100644 --- a/apps/studio/.claude/skills/explorer/SKILL.md +++ b/apps/studio/.claude/skills/explorer/SKILL.md @@ -31,13 +31,13 @@ Compose the toolbar from slots rather than adding resource-specific props: {/* static or editable title */} {/* badges, source controls, display controls, and direct actions */} - } /> + } /> ``` - The row defaults to 40px and follows `--header-height` at the `md` breakpoint. -- Use `ExplorerToolbarAction` for compact direct actions. Icon-only actions are 28px wide automatically. +- Use `ExplorerToolbarAction` for compact direct actions. Icon-only actions are 28px wide automatically. It defaults to `text-tertiary-foreground` and `hover:text-foreground`. Pass `size={16} strokeWidth={2}` on Lucide icons. - Keep execution, persistence, source selection, and other resource state in the consuming Explorer surface. - Extend layouts with children and `className`; avoid boolean props for resource-specific variants. diff --git a/apps/studio/components/interfaces/Account/AccessTokens/Scoped/Form/TokenDetails.tsx b/apps/studio/components/interfaces/Account/AccessTokens/Scoped/Form/TokenDetails.tsx index 64a91e603df27..a57127f6b65be 100644 --- a/apps/studio/components/interfaces/Account/AccessTokens/Scoped/Form/TokenDetails.tsx +++ b/apps/studio/components/interfaces/Account/AccessTokens/Scoped/Form/TokenDetails.tsx @@ -61,7 +61,7 @@ export const TokenDetails = ({ control, setValue }: TokenDetailsProps) => { render={({ field }) => ( - + )} @@ -72,11 +72,11 @@ export const TokenDetails = ({ control, setValue }: TokenDetailsProps) => { name="expiresAt" control={control} render={({ field }) => ( - +
+ )} @@ -162,7 +162,7 @@ export const EditSecretModal = () => { labelOptional="Optional" > - + )} @@ -173,10 +173,9 @@ export const EditSecretModal = () => { control={form.control} render={({ field }) => ( - -
+
+