import type { RequestHandler } from '@sveltejs/kit'; import type { AuthLogger, RateLimitConfig } from '../../../types.js'; import type { PushSubscriptionRepository } from '../../adapters/types.js'; export interface PushSubscriptionHandlerOptions { /** * Restrict accepted push endpoints to hosts matching one of these suffixes * (e.g. `['fcm.googleapis.com', 'push.apple.com', 'updates.push.services.mozilla.com']`). * `'push.apple.com'` also matches `web.push.apple.com`. When omitted, any * HTTPS endpoint to a public host is accepted. The HTTPS + private-range SSRF * guard always applies regardless. */ allowedEndpointHosts?: string[]; /** * Rate limit for the mutating endpoints (POST and DELETE share one budget), * keyed by the authenticated user id — the endpoints require a session, and * a per-user key can't be dodged by rotating IPs. Subscribe/unsubscribe is a * rare user action, so the default of 10/min is generous for real use and a * wall for scripted abuse. Pass `null` to disable. */ rateLimit?: RateLimitConfig | null; /** * Upper bound on stored subscriptions per user — a cost guard: every stored * row is a network fetch on every push send to that user. The cap applies * only to endpoints not yet registered for the user; re-subscribing an * existing endpoint (the browser's normal case) always passes. Exceeding it * answers `409`. Default 10 (≈ a device fleet, not a script). The check is * read-then-write and therefore approximate under concurrency — fine for a * cost guard. */ maxSubscriptionsPerUser?: number; /** * Sink for the two write outcomes worth an operator's attention: * `'rejected'` (warn — an authenticated account presented a foreign * endpoint with non-matching keys, i.e. someone is replaying endpoint URLs * they don't own) and `'reassigned'` (a push channel moved between * accounts with key possession proven — legitimate, but the previous * owner's channel just went quiet, so it should be correlatable). * Defaults to `console`; calls are shielded. Endpoint URLs are never * logged (capability discipline) — only the acting user id. */ logger?: AuthLogger; } export declare function createPushSubscriptionHandler(repo: PushSubscriptionRepository, options?: PushSubscriptionHandlerOptions): { POST: RequestHandler; DELETE: RequestHandler; };