Skip to content

Commit

Permalink
feat: sentry proxy (#112)
Browse files Browse the repository at this point in the history
  • Loading branch information
AuHau authored Jun 20, 2022
1 parent 29b9f24 commit 39bf2b4
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 1 deletion.
44 changes: 43 additions & 1 deletion src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import Koa from 'koa'
import koaBodyparser from 'koa-bodyparser'
import serve from 'koa-static'
import fetch from 'node-fetch'
import { URL } from 'url'
import { join } from 'path'
import { getApiKey } from './api-key'
import { sendBzzTransaction, sendNativeTransaction } from './blockchain'
Expand All @@ -17,6 +18,8 @@ import { getPath } from './path'
import { port } from './port'
import { getStatus } from './status'
import { swap } from './swap'
import { captureException } from '@sentry/electron'
import { bufferRequest } from './utility'

export function runServer() {
const app = new Koa()
Expand All @@ -32,14 +35,52 @@ export function runServer() {
context.set('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS')
await next()
})
app.use(koaBodyparser())
app.use(koaBodyparser({ onerror: logger.error }))
const router = new Router()

// Open endpoints without any authentication
router.get('/info', context => {
context.body = { name: 'bee-desktop' }
})

/**
* This is proxy endpoint for Sentry to circumvent ad-blockers
* @see https://docs.sentry.io/platforms/javascript/troubleshooting/#using-the-tunnel-option
*/
router.all('/sentry', async context => {
// OPTION request is used to verify that Desktop can proxy the requests
if (context.request.method.toLowerCase() === 'options') {
context.status = 204

return
}

try {
// We can't use the `context.request.body` as the incoming request is not valid JSON
// It is multiline string where each line contain a JSON field and because of that the `koa-bodyparser`
// is not able to correctly detect and parse the body and because of that nothing is attached.
// So we need to Buffer the body into string ourselves.
const envelope = await bufferRequest(context.req)
const pieces = envelope.split('\n')
const header = JSON.parse(pieces[0])
const dnsUrl = new URL(header.dsn)
const projectId = dnsUrl.pathname.endsWith('/') ? dnsUrl.pathname.slice(0, -1) : dnsUrl.pathname
const url = `https://${dnsUrl.host}/api/${projectId}/envelope/`
const response = await fetch(url, {
method: 'POST',
body: envelope,
})

context.body = await response.json()
} catch (e) {
logger.error(e)
captureException(e)

context.status = 400
context.body = { status: 'invalid request' }
}
})

router.use(async (context, next) => {
const { authorization } = context.headers

Expand Down Expand Up @@ -122,6 +163,7 @@ export function runServer() {
await swap(privateKeyString, context.request.body.dai, '10000', swapEndpoint)
context.body = { success: true }
})

app.use(router.routes())
app.use(router.allowedMethods())
const server = app.listen(port.value)
Expand Down
11 changes: 11 additions & 0 deletions src/utility.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
import { Readable } from 'stream'

export async function wait(ms: number): Promise<void> {
return new Promise(resolve => {
setTimeout(resolve, ms)
})
}

export async function bufferRequest(red: Readable): Promise<string> {
const arr = []
for await (const redElement of red) {
arr.push(redElement)
}

return Buffer.concat(arr).toString('utf8')
}

0 comments on commit 39bf2b4

Please sign in to comment.