A calm place to write long-form, and publish it to the open social web.
skypress.blog/
1import type { APIRoute } from 'astro';
2
3/**
4 * The atproto OAuth client metadata document (Decision 0004).
5 *
6 * Served by the WORKER (`prerender = false`), not as a static asset — static `.json`
7 * serving on Cloudflare proved unreliable at the deployed origin, and the worker route is
8 * guaranteed to run. Generated from the REQUEST origin so `client_id` always equals the
9 * URL it's fetched from (works on the apex domain, www, or any preview origin), and the
10 * `redirect_uri` matches the editor's canonical path `/editor/` (trailing slash — see
11 * docs/specs/sp7-deploy.md).
12 *
13 * In dev (loopback) the browser client builds its own metadata and never fetches this;
14 * this is the production/hosted client.
15 */
16export const prerender = false;
17
18export const GET: APIRoute = ( { url } ) => {
19 const origin = url.origin;
20 const metadata = {
21 client_id: `${ origin }/client-metadata.json`,
22 client_name: 'SkyPress',
23 client_uri: origin,
24 redirect_uris: [ `${ origin }/editor/` ],
25 scope: 'atproto transition:generic',
26 grant_types: [ 'authorization_code', 'refresh_token' ],
27 response_types: [ 'code' ],
28 token_endpoint_auth_method: 'none',
29 application_type: 'web',
30 dpop_bound_access_tokens: true,
31 };
32 return new Response( JSON.stringify( metadata, null, 2 ), {
33 headers: {
34 'content-type': 'application/json; charset=utf-8',
35 'cache-control': 'public, max-age=300',
36 },
37 } );
38};