Skip to content

Commit 369fc52

Browse files
Luca Forstneroioki
Luca Forstner
andauthored
feat(nextjs/v7): Support Hybrid Cloud DSNs with tunnelRoute option (#10958)
Co-authored-by: Alexander Tarasov <git@oioki.me> Fixes #10948
1 parent 7ad8957 commit 369fc52

File tree

3 files changed

+45
-6
lines changed

3 files changed

+45
-6
lines changed

packages/nextjs/src/client/tunnelRoute.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,14 @@ export function applyTunnelRouteOption(options: BrowserOptions): void {
1717
if (!dsnComponents) {
1818
return;
1919
}
20-
const sentrySaasDsnMatch = dsnComponents.host.match(/^o(\d+)\.ingest\.sentry\.io$/);
20+
const sentrySaasDsnMatch = dsnComponents.host.match(/^o(\d+)\.ingest(?:\.([a-z]{2}))?\.sentry\.io$/);
2121
if (sentrySaasDsnMatch) {
2222
const orgId = sentrySaasDsnMatch[1];
23-
const tunnelPath = `${tunnelRouteOption}?o=${orgId}&p=${dsnComponents.projectId}`;
23+
const regionCode = sentrySaasDsnMatch[2];
24+
let tunnelPath = `${tunnelRouteOption}?o=${orgId}&p=${dsnComponents.projectId}`;
25+
if (regionCode) {
26+
tunnelPath += `&r=${regionCode}`;
27+
}
2428
options.tunnel = tunnelPath;
2529
DEBUG_BUILD && logger.info(`Tunneling events to "${tunnelPath}"`);
2630
} else {

packages/nextjs/src/config/withSentryConfig.ts

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function setUpTunnelRewriteRules(userNextConfig: NextConfigObject, tunnelPath: s
9696
// This function doesn't take any arguments at the time of writing but we future-proof
9797
// here in case Next.js ever decides to pass some
9898
userNextConfig.rewrites = async (...args: unknown[]) => {
99-
const injectedRewrite = {
99+
const tunnelRouteRewrite = {
100100
// Matched rewrite routes will look like the following: `[tunnelPath]?o=[orgid]&p=[projectid]`
101101
// Nextjs will automatically convert `source` into a regex for us
102102
source: `${tunnelPath}(/?)`,
@@ -115,19 +115,43 @@ function setUpTunnelRewriteRules(userNextConfig: NextConfigObject, tunnelPath: s
115115
destination: 'https://o:orgid.ingest.sentry.io/api/:projectid/envelope/?hsts=0',
116116
};
117117

118+
const tunnelRouteRewriteWithRegion = {
119+
// Matched rewrite routes will look like the following: `[tunnelPath]?o=[orgid]&p=[projectid]?r=[region]`
120+
// Nextjs will automatically convert `source` into a regex for us
121+
source: `${tunnelPath}(/?)`,
122+
has: [
123+
{
124+
type: 'query',
125+
key: 'o', // short for orgId - we keep it short so matching is harder for ad-blockers
126+
value: '(?<orgid>\\d*)',
127+
},
128+
{
129+
type: 'query',
130+
key: 'p', // short for projectId - we keep it short so matching is harder for ad-blockers
131+
value: '(?<projectid>\\d*)',
132+
},
133+
{
134+
type: 'query',
135+
key: 'r', // short for region - we keep it short so matching is harder for ad-blockers
136+
value: '(?<region>\\[a-z\\]{2})',
137+
},
138+
],
139+
destination: 'https://o:orgid.ingest.:region.sentry.io/api/:projectid/envelope/?hsts=0',
140+
};
141+
118142
if (typeof originalRewrites !== 'function') {
119-
return [injectedRewrite];
143+
return [tunnelRouteRewriteWithRegion, tunnelRouteRewrite];
120144
}
121145

122146
// @ts-expect-error Expected 0 arguments but got 1 - this is from the future-proofing mentioned above, so we don't care about it
123147
const originalRewritesResult = await originalRewrites(...args);
124148

125149
if (Array.isArray(originalRewritesResult)) {
126-
return [injectedRewrite, ...originalRewritesResult];
150+
return [tunnelRouteRewriteWithRegion, tunnelRouteRewrite, ...originalRewritesResult];
127151
} else {
128152
return {
129153
...originalRewritesResult,
130-
beforeFiles: [injectedRewrite, ...(originalRewritesResult.beforeFiles || [])],
154+
beforeFiles: [tunnelRouteRewriteWithRegion, tunnelRouteRewrite, ...(originalRewritesResult.beforeFiles || [])],
131155
};
132156
}
133157
};

packages/nextjs/test/utils/tunnelRoute.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,15 @@ describe('applyTunnelRouteOption()', () => {
6464

6565
expect(options.tunnel).toBeUndefined();
6666
});
67+
68+
it('Correctly applies `tunnelRoute` option to region DSNs', () => {
69+
globalWithInjectedValues.__sentryRewritesTunnelPath__ = '/my-error-monitoring-route';
70+
const options: any = {
71+
dsn: 'https://11111111111111111111111111111111@o2222222.ingest.us.sentry.io/3333333',
72+
} as BrowserOptions;
73+
74+
applyTunnelRouteOption(options);
75+
76+
expect(options.tunnel).toBe('/my-error-monitoring-route?o=2222222&p=3333333&r=us');
77+
});
6778
});

0 commit comments

Comments
 (0)