Fix OAuth redirect_uri for local dev

- client_id always points to production so PDS can fetch metadata
- redirect_uri is dynamic (window.location.origin) so dev login
  redirects back to localhost instead of production
- Add localhost:5173/5174 to allowed redirect_uris in metadata

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Julien Calixte
2026-03-28 23:14:11 +01:00
parent a40108ea04
commit eaa151dbe9
2 changed files with 14 additions and 8 deletions

View File

@@ -2,7 +2,11 @@
"client_id": "https://coffee.apoena.dev/client-metadata.json", "client_id": "https://coffee.apoena.dev/client-metadata.json",
"client_name": "Coffee Map", "client_name": "Coffee Map",
"client_uri": "https://coffee.apoena.dev", "client_uri": "https://coffee.apoena.dev",
"redirect_uris": ["https://coffee.apoena.dev/oauth/callback"], "redirect_uris": [
"https://coffee.apoena.dev/oauth/callback",
"http://localhost:5173/oauth/callback",
"http://localhost:5174/oauth/callback"
],
"grant_types": ["authorization_code", "refresh_token"], "grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"], "response_types": ["code"],
"scope": "atproto transition:generic", "scope": "atproto transition:generic",

View File

@@ -1,9 +1,12 @@
import { BrowserOAuthClient } from '@atproto/oauth-client-browser' import { BrowserOAuthClient } from '@atproto/oauth-client-browser'
import { Agent } from '@atproto/api' import { Agent } from '@atproto/api'
// The client_id must equal the public URL of client-metadata.json. // client_id must always point to the publicly accessible metadata file
// Update VITE_APP_URL in your environment or set it here directly. // so the PDS can fetch it — even in local dev.
const APP_URL = import.meta.env.VITE_APP_URL ?? 'https://coffee.apoena.dev' const PROD_URL = 'https://coffee.apoena.dev'
// redirect_uri is dynamic so local dev redirects back to localhost
const ORIGIN = window.location.origin
let _client: BrowserOAuthClient | null = null let _client: BrowserOAuthClient | null = null
@@ -11,10 +14,10 @@ export function getOAuthClient(): BrowserOAuthClient {
if (!_client) { if (!_client) {
_client = new BrowserOAuthClient({ _client = new BrowserOAuthClient({
clientMetadata: { clientMetadata: {
client_id: `${APP_URL}/client-metadata.json`, client_id: `${PROD_URL}/client-metadata.json`,
client_name: 'Coffee Map', client_name: 'Coffee Map',
client_uri: APP_URL, client_uri: PROD_URL,
redirect_uris: [`${APP_URL}/oauth/callback`], redirect_uris: [`${ORIGIN}/oauth/callback`],
grant_types: ['authorization_code', 'refresh_token'], grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'], response_types: ['code'],
scope: 'atproto transition:generic', scope: 'atproto transition:generic',
@@ -22,7 +25,6 @@ export function getOAuthClient(): BrowserOAuthClient {
token_endpoint_auth_method: 'none', token_endpoint_auth_method: 'none',
application_type: 'web', application_type: 'web',
}, },
// Use the public ATProto resolver — for full privacy use your own PDS
handleResolver: 'https://bsky.social', handleResolver: 'https://bsky.social',
}) })
} }