From 9ce94f8383b762caec7887302120de5d62074bcb Mon Sep 17 00:00:00 2001 From: Valentyne Stigloher Date: Tue, 27 Aug 2024 10:41:05 +0200 Subject: [PATCH] (sentry) use tunnel to circumvent tracker blocking see: https://docs.sentry.io/platforms/javascript/troubleshooting/, Dealing with Ad-Blockers code inspired from: https://github.com/BLOCKMATERIAL/sentry-tunnel-using-node/blob/main/routes/tunnel.js --- nuxt.config.ts | 3 +++ server/index.ts | 6 ++++++ server/routes/sentry.ts | 30 ++++++++++++++++++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 server/routes/sentry.ts diff --git a/nuxt.config.ts b/nuxt.config.ts index 0ae7caa98..b9ecc98f3 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -242,6 +242,9 @@ const nuxtConfig: NuxtConfig = { return event; }, }, + clientConfig: { + tunnel: '/api/sentry/tunnel', + }, }, publicRuntimeConfig: { ...config, diff --git a/server/index.ts b/server/index.ts index 6cc3f9899..54381e2c2 100644 --- a/server/index.ts +++ b/server/index.ts @@ -42,6 +42,7 @@ import calendarRoute from './routes/calendar.ts'; import translationsRoute from './routes/translations.ts'; import subscriptionRoute from './routes/subscription.ts'; import discord from './routes/discord.ts'; +import sentryRoute from './routes/sentry.ts'; const MemoryStore = memorystore(session); @@ -60,6 +61,10 @@ app.use(express.json({ }, })); app.use(express.urlencoded({ extended: true })); +app.use(express.raw({ + limit: '10 MB', + type: 'text/plain', +})); app.use(cookieParser()); app.use(session({ secret: process.env.SECRET!, @@ -179,6 +184,7 @@ app.use(calendarRoute); app.use(translationsRoute); app.use(subscriptionRoute); app.use(discord); +app.use(sentryRoute); app.use(Sentry.Handlers.errorHandler()); diff --git a/server/routes/sentry.ts b/server/routes/sentry.ts new file mode 100644 index 000000000..03d453a3f --- /dev/null +++ b/server/routes/sentry.ts @@ -0,0 +1,30 @@ +import { Router } from 'express'; + +import { handleErrorAsync } from '~/src/helpers.ts'; + +const router = Router(); + +router.post('/sentry/tunnel', handleErrorAsync(async (req, res) => { + const envelope = req.body.toString('utf-8'); + + const piece = envelope.slice(0, envelope.indexOf('\n')); + const header = JSON.parse(piece); + + if (header.dsn !== process.env.SENTRY_DSN) { + return res.status(400).send({ message: `Invalid Sentry DSN: ${header.dsn}` }); + } + + const dsn = new URL(header.dsn); + + const url = `https://${dsn.hostname}/api/${dsn.pathname.substring(1)}/envelope/`; + const response = await fetch(url, { + method: 'POST', + body: envelope, + headers: { + 'Content-Type': 'application/x-sentry-envelope', + }, + }); + return res.status(response.status).send(response.body); +})); + +export default router;