diff --git a/cloudflare/motorsignal-r2-worker/src/index.ts b/cloudflare/motorsignal-r2-worker/src/index.ts index b1aee49..2b065af 100644 --- a/cloudflare/motorsignal-r2-worker/src/index.ts +++ b/cloudflare/motorsignal-r2-worker/src/index.ts @@ -2,7 +2,7 @@ import { createRemoteJWKSet, jwtVerify, type JWTPayload } from 'jose'; /** * MotorSignal — Cloudflare R2 Worker Gateway - * Secure authorization gateway for MotorSignal telemetry bundles on Cloudflare R2. + * Secure authorization gateway for MotorSignal telemetry bundle storage. * Firebase ID tokens are cryptographically verified before any R2 access. */ @@ -21,6 +21,7 @@ const CORS_HEADERS = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, POST, PUT, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization, X-Remote-Ride-Id, X-Bundle-Sha256, X-App-Version', + 'Access-Control-Expose-Headers': 'ETag, Content-Disposition, X-MotorSignal-Ride-Id, X-MotorSignal-Sha256', }; const FIREBASE_JWKS = new URL('https://www.googleapis.com/service_accounts/v1/jwk/securetoken@system.gserviceaccount.com'); @@ -126,6 +127,7 @@ async function verifyFirebaseToken(token: string, expectedProjectId: string): Pr interface OwnedRide { objectKey?: string; } type RideAuthorizationResult = OwnedRide | 'unauthorized' | 'not-found' | 'invalid'; +/** Reads the authenticated user's ride document through Firestore REST. */ async function fetchOwnedRide(projectId: string, uid: string, remoteRideId: string, idToken: string): Promise { const documentPath = encodeFirestorePath(`users/${uid}/rides/${remoteRideId}`); const endpoint = `https://firestore.googleapis.com/v1/projects/${encodeURIComponent(projectId)}/databases/(default)/documents/${documentPath}`;