diff --git a/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts b/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts new file mode 100644 index 0000000..7f1a969 --- /dev/null +++ b/apps/web/src/routes/.well-known/apple-app-site-association/+server.ts @@ -0,0 +1,53 @@ +import { env } from '$env/dynamic/public'; +import type { RequestHandler } from './$types'; + +/** + * Apple App-Site Association für die cards-native iOS-App. + * + * Apple holt diese Datei beim ersten App-Launch (und gelegentlich danach) + * von `https://cardecky.mana.how/.well-known/apple-app-site-association` + * und vergleicht sie mit dem `applinks:cardecky.mana.how`-Entitlement + * der App. Bei Match werden Links auf `/d/` direkt in die App + * geöffnet statt im Browser. + * + * **Pflichtbedingungen:** + * 1. Antwort MUSS `Content-Type: application/json` haben (nicht + * `application/json; charset=utf-8`, nicht `text/json`). + * 2. Antwort darf KEINE Redirects haben. + * 3. Pfad MUSS exakt `/.well-known/apple-app-site-association` lauten. + * + * Team-ID kommt via env `PUBLIC_APPLE_TEAM_ID`. Default ist Platzhalter + * `XXXXXXXXXX` — produktiv muss die echte Team-ID des mana-e.V.-Apple- + * Developer-Accounts gesetzt werden, sonst akzeptiert Apple die AASA + * nicht. + * + * Cross-Ref: `cards-native/docs/RELEASE_CHECKLIST.md` → "Server-seitige + * Vorbedingungen". + */ +export const GET: RequestHandler = async () => { + const teamId = env.PUBLIC_APPLE_TEAM_ID ?? 'XXXXXXXXXX'; + const bundleId = 'ev.mana.cards'; + + const payload = { + applinks: { + apps: [], + details: [ + { + appID: `${teamId}.${bundleId}`, + paths: ['/d/*', '/u/*'], + }, + ], + }, + }; + + return new Response(JSON.stringify(payload), { + status: 200, + headers: { + 'Content-Type': 'application/json', + // 1 Stunde Cache — Apple respektiert Cache, refetched aber auch + // bei App-Update und gelegentlich proaktiv. Längere TTLs würden + // Roll-Outs von Team-ID-Wechseln blockieren. + 'Cache-Control': 'public, max-age=3600', + }, + }); +};