feat(planetscale): OAuth login + shared landing pages#467
Open
Mkassabov wants to merge 6 commits into
Open
Conversation
Contributor
|
Install the packages built from this commit: alchemy bun add alchemy@https://pkg.ing/alchemy/793a93b@alchemy.run/better-auth bun add @alchemy.run/better-auth@https://pkg.ing/@alchemy.run/better-auth/793a93b@alchemy.run/pr-package bun add @alchemy.run/pr-package@https://pkg.ing/@alchemy.run/pr-package/793a93b |
Contributor
Website Preview DeployedURL: https://alchemyeffectwebsite-worker-pr-467-r63v3jsdctsuvebd.testing-2b2.workers.dev Built from commit This comment updates automatically with each push. |
Move the OAuth success/error landing pages from async-alchemy onto this website, restyled with the design tokens and ThemeProvider. The CLI runs a localhost loopback server as the OAuth redirect_uri; after it exchanges the code for tokens it 302-redirects the browser to these pages purely as "you can close this window" UI. They are provider-agnostic (the loopback server already knows which provider it started for), so a single shared success/error pair covers all providers. - /auth/success credentials saved, return to the CLI - /auth/error authorization failed
Mirror the Cloudflare OAuth flow for PlanetScale. `alchemy login` now offers a browser-based OAuth method alongside env + service tokens. - OAuthClient.ts: authorize/exchange/refresh/callback over a localhost loopback (redirect URI http://localhost:9976/auth/callback), landing on the shared /auth/success + /auth/error pages. - AuthProvider.ts: `oauth` method wired through configure/login/resolve (with proactive refresh)/logout/prettyPrint. - Credentials.ts: resolves OAuth creds to a Bearer token. PlanetScale has no PKCE flow, so the app client_secret ships in the CLI (same exposure as a public client_id; rotate via release). Scopes are configured on the OAuth app, not requested per-authorization, and there is no token-revocation endpoint so logout just drops local tokens. Depends on Bearer support in @distilled.cloud/planetscale (alchemy-run/distilled#311) — catalog temporarily points at the branch build; repoint to the released version before merge.
End-to-end fixes for the PlanetScale OAuth flow after testing against the live auth server: - `authorize()` now sends `response_type=code` (PlanetScale rejects the request without it — "Missing required parameter: response_type"). - Scope names must carry tier prefixes (`user:`, `organization:`, `database:`, `branch:`) — bare `read_user` etc. are rejected with "The requested scope is invalid, unknown, or malformed." The public docs page's section headers are literally part of the scope id, not groupings. ALL_SCOPES now mirrors PlanetScale's full prefixed list (plus the OIDC trio); DEFAULT_SCOPES covers what Alchemy resources actually need. - Empty `scopes` skips the `scope=` param entirely so the user falls back to PlanetScale's implicit defaults. - Real OAuth app credentials baked in (replaces placeholders). - Credentials.ts annotates the Effect.map return as `Config` so the oauth | apiToken branches resolve cleanly against the distilled `ServiceTokenConfig | OAuthConfig` union. Verified: `alchemy login` opens consent, callback completes, tokens land in the store with the requested prefixed scopes.
sam-goodwin
reviewed
Jun 16, 2026
Comment on lines
+41
to
+42
| export const OAUTH_CLIENT_SECRET = | ||
| "pscale_app_secret_yyZ3Q8oe99GP9_yA5wrA5er6RuN6Lz9dC66Bj1OJzpg"; |
Contributor
There was a problem hiding this comment.
Is this safe to check in?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds browser-based OAuth login for PlanetScale, mirroring the Cloudflare flow, plus the shared OAuth landing pages on the website.
PlanetScale OAuth
alchemy loginnow offers OAuth alongside env vars and service tokens.Planetscale/OAuthClient.ts— authorize/exchange/refresh/callback over a localhost loopbackPlanetscale/AuthProvider.ts—oauthmethod through configure/login/resolve (proactive refresh)/logout/prettyPrintPlanetscale/Credentials.ts— resolves OAuth creds to aBearertokenPlanetScale differs from Cloudflare: no PKCE, so the app
client_secretships in the CLI (same exposure posture as a publicclient_id; rotate via release). Scopes are configured on the OAuth app, not requested per-authorization, and there's no revocation endpoint, so logout just drops local tokens.Website landing pages
Provider-agnostic — the CLI loopback already knows which provider it started, so one shared pair covers Cloudflare, PlanetScale, and future providers.
Before merge (draft)
@distilled.cloud/planetscale(feat(planetscale): support OAuth Bearer credentials distilled#311). The catalog temporarily points at the branch build (pkg.distilled.cloud/planetscale/5eecc8e); repoint to the released version once fix(build): remove deprecated libsodium wrapper types #311 ships.http://localhost:9976/auth/callbackredirect URI (domain registered asalchemy.run); if it rejects localhost, switch to a website-hosted callback.