// AT Protocol OAuth client metadata (served at /client-metadata.json). The client_id is // this URL; the auth server fetches it, so it must be reachable over HTTPS in production. // Dev uses a loopback client instead (see src/lib/oauth.ts). // // ORIGIN is THIS build's scope, never hardcoded: the browser's clientId is // `${window.location.origin}/client-metadata.json`, so on atproto.be the served metadata must also // say atproto.be, including its redirect_uris. Hardcoding atproto.nl made every .be/.eu/.no login // bounce the user back to atproto.nl after auth (and mismatched the client_id against its own URL). import type { APIRoute } from 'astro'; import { OAUTH_SCOPE } from '../lib/oauth-scope'; import { getScope, resolveScopeId } from '../config/scopes'; export const prerender = true; const scope = getScope(resolveScopeId(import.meta.env.PUBLIC_SITE_SCOPE)); const ORIGIN = scope.site.replace(/\/$/, ''); const NAME = new URL(scope.site).host; // atproto.nl | atproto.be | atproto.eu | atproto.no export const GET: APIRoute = () => { const metadata = { client_id: `${ORIGIN}/client-metadata.json`, client_name: NAME, client_uri: ORIGIN, logo_uri: `${ORIGIN}/brand/avatar-${scope.cc}-512.png`, redirect_uris: [`${ORIGIN}/`], scope: OAUTH_SCOPE, grant_types: ['authorization_code', 'refresh_token'], response_types: ['code'], token_endpoint_auth_method: 'none', application_type: 'web', dpop_bound_access_tokens: true, }; return new Response(JSON.stringify(metadata, null, 2), { headers: { 'content-type': 'application/json' }, }); };