a a vibe-coded abomination experiment of a fragrance review platform built on the atmosphere. drydown.social

another attempt

+44 -27
-1
public/client-metadata.json
··· 6 6 "tos_uri": "https://drydown.pages.dev/tos", 7 7 "policy_uri": "https://drydown.pages.dev/policy", 8 8 "redirect_uris": [ 9 - "http://127.0.0.1:5173", 10 9 "https://drydown.pages.dev/", 11 10 "https://drydown.social/" 12 11 ],
+44 -26
src/auth.ts
··· 1 1 import { BrowserOAuthClient, type OAuthClientMetadataInput } from '@atproto/oauth-client-browser' 2 2 3 3 // The metadata must match what is served at the client_id URL 4 - const clientMetadata: OAuthClientMetadataInput = { 5 - client_id: 'https://drydown.pages.dev/client-metadata.json', 6 - client_name: 'Drydown App', 7 - client_uri: 'https://drydown.pages.dev', 8 - logo_uri: 'https://drydown.pages.dev/vite.svg', 9 - tos_uri: 'https://drydown.pages.dev/tos', 10 - policy_uri: 'https://drydown.pages.dev/policy', 11 - redirect_uris: [ 12 - 'http://127.0.0.1:5173', 13 - 'https://drydown.pages.dev/', 14 - 'https://drydown.social/', 15 - ], 16 - scope: 'atproto transition:generic', 17 - grant_types: ['authorization_code', 'refresh_token'], 18 - response_types: ['code'], 19 - token_endpoint_auth_method: 'none', 20 - application_type: 'web', 21 - dpop_bound_access_tokens: true, 22 - } 4 + const clientMetadata = (() => { 5 + const isLocal = ['127.0.0.1', 'localhost'].includes(window.location.hostname) 6 + 7 + if (isLocal) { 8 + return { 9 + client_id: 'http://localhost?redirect_uri=http%3A%2F%2F127.0.0.1%3A5173&scope=atproto%20transition%3Ageneric', 10 + client_name: 'Drydown App (Dev)', 11 + client_uri: 'http://127.0.0.1:5173', 12 + logo_uri: 'http://127.0.0.1:5173/vite.svg', 13 + tos_uri: 'http://127.0.0.1:5173/tos', 14 + policy_uri: 'http://127.0.0.1:5173/policy', 15 + redirect_uris: ['http://127.0.0.1:5173'], 16 + scope: 'atproto transition:generic', 17 + grant_types: ['authorization_code', 'refresh_token'], 18 + response_types: ['code'], 19 + token_endpoint_auth_method: 'none', 20 + application_type: 'web', 21 + dpop_bound_access_tokens: true, 22 + } satisfies OAuthClientMetadataInput 23 + } 24 + 25 + return { 26 + client_id: 'https://drydown.pages.dev/client-metadata.json', 27 + client_name: 'Drydown App', 28 + client_uri: 'https://drydown.pages.dev', 29 + logo_uri: 'https://drydown.pages.dev/vite.svg', 30 + tos_uri: 'https://drydown.pages.dev/tos', 31 + policy_uri: 'https://drydown.pages.dev/policy', 32 + redirect_uris: [ 33 + 'https://drydown.pages.dev/', 34 + 'https://drydown.social/', 35 + ], 36 + scope: 'atproto transition:generic', 37 + grant_types: ['authorization_code', 'refresh_token'], 38 + response_types: ['code'], 39 + token_endpoint_auth_method: 'none', 40 + application_type: 'web', 41 + dpop_bound_access_tokens: true, 42 + } satisfies OAuthClientMetadataInput 43 + })() 23 44 24 45 let client: BrowserOAuthClient | undefined 25 46 ··· 48 69 export async function login(handle: string) { 49 70 const c = await getClient() 50 71 51 - // Find the redirect URI that matches the current origin 52 - // This handles the case where the list has a trailing slash but window.location.origin does not 53 - const currentOrigin = window.location.origin 54 - const redirectUri = clientMetadata.redirect_uris?.find(uri => 55 - uri.startsWith(currentOrigin) || (uri.endsWith('/') && uri.slice(0, -1) === currentOrigin) 56 - ) 72 + // Explicitly use the first redirect_uri from the active configuration 73 + // This ensures consistency whether in Dev or Prod 74 + const redirectUri = clientMetadata.redirect_uris?.[0] 57 75 58 76 return await c.signIn(handle, { 59 77 state: undefined, 60 78 prompt: 'login', 61 - redirect_uri: redirectUri as any, // Explicitly pass the matching URI, cast to any to avoid strict type issues 79 + redirect_uri: redirectUri as any, 62 80 }) 63 81 } 64 82