clone

push a directory of html from the terminal and get a four-character url back. a deno cli on cloudflare

main
nzip / worker / src / notify_public.ts
notify_public.ts 2.7K
1import {2 activateEnrollment,3 attachSubscription,4 authorizeNotificationClaim,5 createEnrollment,6 detachSubscription,7 getCurrentEnrollment,8 getPairingWindow,9 type NotifyEnv,10 notifyErrorResponse,11 readNotifyJsonObject,12 renewEnrollment,13} from "./notify_enrollment.ts";14import { json } from "./env.ts";15import { validateClickTarget } from "./notify.ts";16import { notifyAssetResponse } from "./notify_ui.ts";1718/**19 * Claim-cookie authenticated notification router. This must be called before20 * the ordinary public GET/HEAD gate, and must never sit under `/api/*`.21 */22export async function handleNotifyPublic(23 request: Request,24 env: NotifyEnv,25 url = new URL(request.url),26): Promise<Response> {27 try {28 const method = request.method;29 const path = url.pathname;3031 if (method === "GET" || method === "HEAD") {32 const asset = notifyAssetResponse(request, env, url);33 if (asset) return asset;34 }35 if (path === "/_notify/enrollments" && method === "POST") {36 return await createEnrollment(request, env);37 }38 if (path === "/_notify/pairing" && method === "GET") {39 return await getPairingWindow(request, env);40 }41 if (path === "/_notify/enrollments/current" && method === "GET") {42 return await getCurrentEnrollment(request, env);43 }44 if (path === "/_notify/enrollments/activate" && method === "POST") {45 return await activateEnrollment(request, env);46 }47 if (path === "/_notify/enrollments/renew" && method === "POST") {48 return await renewEnrollment(request, env);49 }50 if (path === "/_notify/subscriptions" && method === "POST") {51 return await attachSubscription(request, env);52 }53 if (path === "/_notify/subscriptions/current" && method === "DELETE") {54 return await detachSubscription(request, env);55 }56 if (path === "/_notify/click-target" && method === "POST") {57 if (!await authorizeNotificationClaim(request, env)) {58 return json({ error: "pairing unavailable" }, 404, {59 "cache-control": "no-store",60 });61 }62 const body = await readNotifyJsonObject(request);63 if (64 typeof body.eventId !== "string" ||65 !/^[0-9a-f-]{36}$/i.test(body.eventId)66 ) {67 return json({ error: "invalid event" }, 400, {68 "cache-control": "no-store",69 });70 }71 const target = await validateClickTarget(env, body.eventId);72 return json(target ? { path: target } : { expired: true }, 200, {73 "cache-control": "no-store",74 "vary": "Cookie",75 });76 }77 return json({ error: "not found" }, 404, { "cache-control": "no-store" });78 } catch (error) {79 return notifyErrorResponse(error);80 }81}