From b74e6106e5da76bb0e7615bfb855affdc3254296 Mon Sep 17 00:00:00 2001 From: Jeremy Ortiz Date: Thu, 18 Jan 2024 19:45:08 +1100 Subject: [PATCH] feat(logging): add verification api response --- apps/site/src/app/api/logs/route.ts | 50 +++++++++++++++++++++++++++++ apps/site/src/middleware.ts | 13 +------- turbo.json | 2 +- 3 files changed, 52 insertions(+), 13 deletions(-) create mode 100644 apps/site/src/app/api/logs/route.ts diff --git a/apps/site/src/app/api/logs/route.ts b/apps/site/src/app/api/logs/route.ts new file mode 100644 index 000000000..6c701633a --- /dev/null +++ b/apps/site/src/app/api/logs/route.ts @@ -0,0 +1,50 @@ +import crypto from 'crypto'; + +import { sql } from '@vercel/postgres'; +import { NextResponse } from 'next/server'; + +export async function POST(request: Request) { + const response = NextResponse.json({}); + // eslint-disable-next-line turbo/no-undeclared-env-vars + response.headers.set('x-vercel-verify', process.env.LOG_DRAIN_VERIFY || ''); + + return response; + // if (process.env.NODE_ENV === 'production') { + // if (typeof process.env.VERCEL_LOG_DRAIN_SECRET != 'string') { + // throw new Error('No integration secret found'); + // } + + // if (!verifySignature(request)) { + // return NextResponse.json({ + // code: 'invalid_signature', + // error: "signature didn't match", + // }); + // } + + // try { + // const logs = await request.json(); + + // for (const log of logs) { + // const { + // id, + // timestamp, + // proxy: { clientIp, referer }, + // } = log; + + // await sql`INSERT INTO logs_drain(log_id, time, request_ip, request_url) VALUES (${id}, TO_TIMESTAMP(${timestamp}::bigint/1000), ${clientIp}, ${referer})`; + // } + // } catch (error) { + // return NextResponse.json({ error }, { status: 500 }); + // } + // } + + // return NextResponse.json({ message: 'Logged successfully' }); +} + +async function verifySignature(request: Request) { + const signature = crypto + .createHmac('sha1', process.env.VERCEL_LOG_DRAIN_SECRET || '') + .update(JSON.stringify(request.body)) + .digest('hex'); + return signature === request.headers.get('x-vercel-signature'); +} diff --git a/apps/site/src/middleware.ts b/apps/site/src/middleware.ts index 93781089e..c0aa36d56 100644 --- a/apps/site/src/middleware.ts +++ b/apps/site/src/middleware.ts @@ -1,17 +1,6 @@ -import { sql } from '@vercel/postgres'; import { NextRequest, NextResponse } from 'next/server'; -export async function middleware(request: NextRequest) { - // logging - if (process.env.NODE_ENV === 'production') { - try { - sql`INSERT INTO logs(url, ip) VALUES (${request.url}, ${request.ip || ''})`; - } catch (error) { - // eslint-disable-next-line no-console - console.log(error); - } - } - +export function middleware(request: NextRequest) { const nonce = Buffer.from(crypto.randomUUID()).toString('base64'); // We need unsafe-inline for style-src in order to make nextjs/image to work diff --git a/turbo.json b/turbo.json index ed2c4b4f2..47f10cb6c 100644 --- a/turbo.json +++ b/turbo.json @@ -1,6 +1,6 @@ { "$schema": "https://turbo.build/schema.json", - "globalEnv": ["NODE_ENV", "NEXT_PUBLIC_GIT_REPO_OWNER", "NEXT_PUBLIC_GIT_REPO_SLUG"], + "globalEnv": ["NODE_ENV", "NEXT_PUBLIC_GIT_REPO_OWNER", "NEXT_PUBLIC_GIT_REPO_SLUG", "VERCEL_LOG_DRAIN_SECRET"], "pipeline": { "build": { "dependsOn": ["^build"],