@@ -98,6 +98,24 @@ async function getOwnedTunnel(params: {
9898 return rows [ 0 ] ?? null ;
9999}
100100
101+ function readNumberParam ( value : string | undefined , fallback : number ) : number {
102+ if ( value === undefined ) {
103+ return fallback ;
104+ }
105+
106+ const parsed = Number ( value ) ;
107+ return Number . isNaN ( parsed ) ? fallback : parsed ;
108+ }
109+
110+ function readOptionalNumberParam ( value : string | undefined ) : number | undefined {
111+ if ( value === undefined ) {
112+ return undefined ;
113+ }
114+
115+ const parsed = Number ( value ) ;
116+ return Number . isNaN ( parsed ) ? undefined : parsed ;
117+ }
118+
101119function buildPullableDeliveryWhere ( params : {
102120 includeFailedBefore ?: number ;
103121 retryWindowMs : number ;
@@ -142,7 +160,9 @@ async function pruneDeliveries(params: {
142160 const maxDeliveries = getNumericVar ( params . env . MAX_DELIVERIES_PER_TUNNEL , 5000 ) ;
143161 const cutoff = now ( ) - retentionDays * 24 * 60 * 60 * 1000 ;
144162
145- await params . db . delete ( delivery ) . where ( lt ( delivery . receivedAt , cutoff ) ) ;
163+ await params . db
164+ . delete ( delivery )
165+ . where ( and ( eq ( delivery . tunnelId , params . tunnelId ) , lt ( delivery . receivedAt , cutoff ) ) ) ;
146166
147167 const rows = await params . db
148168 . select ( { count : count ( ) } )
@@ -181,9 +201,11 @@ app.post("/api/tunnels/ensure", async (c) => {
181201 return c . text ( "providerId, providerAccountId, and environment are required" , 400 ) ;
182202 }
183203
184- const retryWindowMs = Math . max ( 0 , Number ( body . retryWindowMs ?? 0 ) ) ;
204+ const retryWindowMs = Math . max ( 0 , readNumberParam ( String ( body . retryWindowMs ?? "0" ) , 0 ) ) ;
185205 const includeFailedBefore =
186- typeof body . includeFailedBefore === "number" ? body . includeFailedBefore : undefined ;
206+ typeof body . includeFailedBefore === "number" && ! Number . isNaN ( body . includeFailedBefore )
207+ ? body . includeFailedBefore
208+ : undefined ;
187209
188210 const createIfMissing = body . createIfMissing !== false ;
189211 const existing = await db
@@ -265,9 +287,12 @@ app.get("/api/tunnels/:tunnelId/welcome", async (c) => {
265287 return c . text ( "Tunnel not found" , 404 ) ;
266288 }
267289
268- const retryWindowMs = Math . max ( 0 , Number ( c . req . query ( "retryWindowMs" ) ?? 0 ) ) ;
269- const includeFailedBeforeRaw = c . req . query ( "includeFailedBefore" ) ;
270- const includeFailedBefore = includeFailedBeforeRaw ? Number ( includeFailedBeforeRaw ) : undefined ;
290+ if ( current . status === "disabled" ) {
291+ return c . text ( "Tunnel disabled" , 410 ) ;
292+ }
293+
294+ const retryWindowMs = Math . max ( 0 , readNumberParam ( c . req . query ( "retryWindowMs" ) , 0 ) ) ;
295+ const includeFailedBefore = readOptionalNumberParam ( c . req . query ( "includeFailedBefore" ) ) ;
271296
272297 return c . json ( {
273298 pendingCount : await getPullableCount ( db , {
@@ -292,6 +317,10 @@ app.post("/api/tunnels/:tunnelId/provider-webhook", async (c) => {
292317 return c . text ( "Tunnel not found" , 404 ) ;
293318 }
294319
320+ if ( current . status === "disabled" ) {
321+ return c . text ( "Tunnel disabled" , 410 ) ;
322+ }
323+
295324 const body = ( await c . req . json ( ) ) as { providerWebhookEndpointId ?: string } ;
296325 if ( ! body . providerWebhookEndpointId ) {
297326 return c . text ( "providerWebhookEndpointId is required" , 400 ) ;
@@ -318,11 +347,14 @@ app.get("/api/tunnels/:tunnelId/pull", async (c) => {
318347 return c . text ( "Tunnel not found" , 404 ) ;
319348 }
320349
321- const limit = clamp ( Number ( c . req . query ( "limit" ) ?? 30 ) , 1 , 100 ) ;
322- const offset = clamp ( Number ( c . req . query ( "offset" ) ?? 0 ) , 0 , 10_000 ) ;
323- const retryWindowMs = Math . max ( 0 , Number ( c . req . query ( "retryWindowMs" ) ?? 0 ) ) ;
324- const includeFailedBeforeRaw = c . req . query ( "includeFailedBefore" ) ;
325- const includeFailedBefore = includeFailedBeforeRaw ? Number ( includeFailedBeforeRaw ) : undefined ;
350+ if ( current . status === "disabled" ) {
351+ return c . text ( "Tunnel disabled" , 410 ) ;
352+ }
353+
354+ const limit = clamp ( readNumberParam ( c . req . query ( "limit" ) , 30 ) , 1 , 100 ) ;
355+ const offset = clamp ( readNumberParam ( c . req . query ( "offset" ) , 0 ) , 0 , 10_000 ) ;
356+ const retryWindowMs = Math . max ( 0 , readNumberParam ( c . req . query ( "retryWindowMs" ) , 0 ) ) ;
357+ const includeFailedBefore = readOptionalNumberParam ( c . req . query ( "includeFailedBefore" ) ) ;
326358 const deliveries = await db
327359 . select ( )
328360 . from ( delivery )
@@ -371,6 +403,10 @@ app.get("/api/deliveries/:deliveryId", async (c) => {
371403 return c . text ( "Delivery not found" , 404 ) ;
372404 }
373405
406+ if ( currentTunnel . status === "disabled" ) {
407+ return c . text ( "Tunnel disabled" , 410 ) ;
408+ }
409+
374410 return c . json ( {
375411 body : currentDelivery . body ,
376412 deliveredAt : currentDelivery . deliveredAt ,
@@ -405,6 +441,10 @@ app.post("/api/deliveries/:deliveryId/ack", async (c) => {
405441 return c . text ( "Delivery not found" , 404 ) ;
406442 }
407443
444+ if ( currentTunnel . status === "disabled" ) {
445+ return c . text ( "Tunnel disabled" , 410 ) ;
446+ }
447+
408448 await db
409449 . update ( delivery )
410450 . set ( { deliveredAt : now ( ) , error : null , failedAt : null } )
@@ -436,6 +476,10 @@ app.post("/api/deliveries/:deliveryId/fail", async (c) => {
436476 return c . text ( "Delivery not found" , 404 ) ;
437477 }
438478
479+ if ( currentTunnel . status === "disabled" ) {
480+ return c . text ( "Tunnel disabled" , 410 ) ;
481+ }
482+
439483 const body = ( await c . req . json ( ) ) as { error ?: string } ;
440484 await db
441485 . update ( delivery )
0 commit comments