Skip to content

Commit f01ca30

Browse files
authored
fix(v10/tanstackstart-react): Reject non-POST requests to the managed tunnel route (#24617)
Backport of: #24615
1 parent 79e6e95 commit f01ca30

3 files changed

Lines changed: 22 additions & 0 deletions

File tree

‎dev-packages/e2e-tests/test-applications/tanstackstart-react/tests/tunnel.test.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ test('Sends client-side errors through the configured tunnel route', async ({ pa
6262
expect(errorEvent.transaction).toBe('/');
6363
});
6464

65+
test('Rejects non-POST requests to the managed tunnel route instead of rendering the app', async ({ request }) => {
66+
test.skip(tunnelRouteMode !== 'static', 'Requires a known managed tunnel path');
67+
68+
const response = await request.get('/monitor');
69+
70+
expect(response.status()).toBe(405);
71+
expect(response.headers()['allow']).toBe('POST');
72+
});
73+
6574
function pathnameMatchesTunnelRoute(pathname: string): boolean {
6675
return typeof expectedTunnelPathMatcher === 'string'
6776
? pathname === expectedTunnelPathMatcher

‎packages/tanstackstart-react/src/vite/tunnelRoute.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,10 @@ export const Route = createFileRoute(${serializedTunnelRoute})({
194194
const Sentry = await import('@sentry/tanstackstart-react');
195195
return Sentry.createSentryTunnelRoute(${serializedAllowedDsns ? `{ allowedDsns: ${serializedAllowedDsns} }` : `{}`}).handlers.POST({ request });
196196
},
197+
// Without a handler for a method, TanStack Start falls back to SSR-rendering the app (running root loaders).
198+
ANY() {
199+
return new Response(null, { status: 405, headers: { Allow: 'POST' } });
200+
},
197201
},
198202
},
199203
});

‎packages/tanstackstart-react/test/vite/tunnelRoute.test.ts‎

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,15 @@ describe('tunnelRoute vite plugin', () => {
139139
expect(virtualRouteModule).toContain('createSentryTunnelRoute({})');
140140
});
141141

142+
it('rejects non-POST requests in the virtual managed tunnel route module', async () => {
143+
const plugin = makeTunnelRoutePlugin('/monitor');
144+
145+
const virtualRouteModule = plugin.load && (await plugin.load('\0virtual:sentry-tanstackstart-react/tunnel-route'));
146+
147+
expect(virtualRouteModule).toContain('ANY()');
148+
expect(virtualRouteModule).toContain("status: 405, headers: { Allow: 'POST' }");
149+
});
150+
142151
it('treats an empty string `path` like omitted and uses a generated tunnel route', () => {
143152
const plugin = makeTunnelRoutePlugin({ path: '' });
144153

0 commit comments

Comments
 (0)