diff --git a/apps/vpnmanager/package.json b/apps/vpnmanager/package.json index dbc49f65a..4b45a1e2b 100644 --- a/apps/vpnmanager/package.json +++ b/apps/vpnmanager/package.json @@ -22,7 +22,7 @@ "@mui/utils": "^5.14.20", "@next/env": "^14.1.4", "@sendgrid/mail": "^8.1.1", - "@sentry/nextjs": "^7.105.0", + "@sentry/nextjs": "^7.106.1", "@svgr/webpack": "^8.1.0", "@types/jest": "^29.5.12", "googleapis": "^133.0.0", diff --git a/apps/vpnmanager/scripts/processGsheet.ts b/apps/vpnmanager/scripts/processGsheet.ts index 2a137d0df..2fb3639b8 100644 --- a/apps/vpnmanager/scripts/processGsheet.ts +++ b/apps/vpnmanager/scripts/processGsheet.ts @@ -1,6 +1,8 @@ import { processNewUsers } from "@/vpnmanager/lib/processUsers"; import { loadEnvConfig } from "@next/env"; +import { initSentry } from "../sentry.server.config"; +initSentry(); const projectDir = process.cwd(); loadEnvConfig(projectDir); diff --git a/apps/vpnmanager/sentry.client.config.ts b/apps/vpnmanager/sentry.client.config.ts index d4ca649c7..63d96bd47 100644 --- a/apps/vpnmanager/sentry.client.config.ts +++ b/apps/vpnmanager/sentry.client.config.ts @@ -3,7 +3,7 @@ import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: process.env.SENTRY_DSN, tracesSampleRate: 1, - environment: process.env.SENTRY_ENV, + environment: process.env.SENTRY_ENV ?? "local", debug: false, replaysOnErrorSampleRate: 1.0, replaysSessionSampleRate: 0.1, diff --git a/apps/vpnmanager/sentry.edge.config.ts b/apps/vpnmanager/sentry.edge.config.ts index 458a9f886..5a5ad8d6d 100644 --- a/apps/vpnmanager/sentry.edge.config.ts +++ b/apps/vpnmanager/sentry.edge.config.ts @@ -2,7 +2,7 @@ import * as Sentry from "@sentry/nextjs"; Sentry.init({ dsn: process.env.SENTRY_DSN, - environment: process.env.SENTRY_ENV, + environment: process.env.SENTRY_ENV ?? "local", tracesSampleRate: 1, debug: false, }); diff --git a/apps/vpnmanager/sentry.server.config.ts b/apps/vpnmanager/sentry.server.config.ts index 458a9f886..869ae5737 100644 --- a/apps/vpnmanager/sentry.server.config.ts +++ b/apps/vpnmanager/sentry.server.config.ts @@ -1,8 +1,13 @@ import * as Sentry from "@sentry/nextjs"; -Sentry.init({ +const options = { dsn: process.env.SENTRY_DSN, - environment: process.env.SENTRY_ENV, + environment: process.env.SENTRY_ENV ?? "local", tracesSampleRate: 1, - debug: false, -}); +}; + +Sentry.init(options); + +export function initSentry() { + Sentry.init(options); +} diff --git a/apps/vpnmanager/src/lib/email/sender.ts b/apps/vpnmanager/src/lib/email/sender.ts index 63f8aae28..8bbcc4bf7 100644 --- a/apps/vpnmanager/src/lib/email/sender.ts +++ b/apps/vpnmanager/src/lib/email/sender.ts @@ -4,11 +4,12 @@ import * as Sentry from "@sentry/nextjs"; import { emailKeyTemplate } from "./templates"; interface MailSender { - recipient: string; + to: string; key: string; + name: string; } -export async function sendVpnKeyEmail({ recipient: to, key }: MailSender) { +export async function sendVpnKeyEmail({ to, key, name }: MailSender) { try { const sendGridApiKey = process.env.VPN_MANAGER_SENDGRID_API_KEY as string; if (!sendGridApiKey) { @@ -25,9 +26,20 @@ export async function sendVpnKeyEmail({ recipient: to, key }: MailSender) { to, from, subject, - html: emailKeyTemplate(key), + html: emailKeyTemplate(key, name), }; await sgMail.send(message); + Sentry.withScope((scope) => { + scope.setLevel("info"); + scope.setUser({ + email: to, + }); + scope.addAttachment({ + filename: "email.html", + data: emailKeyTemplate("*hidden*", name), + }); + Sentry.captureMessage("Outline key sent"); + }); } catch (error) { Sentry.captureException(error); } diff --git a/apps/vpnmanager/src/lib/email/templates.ts b/apps/vpnmanager/src/lib/email/templates.ts index 6cd42d702..90e11261a 100644 --- a/apps/vpnmanager/src/lib/email/templates.ts +++ b/apps/vpnmanager/src/lib/email/templates.ts @@ -1,14 +1,23 @@ -export function emailKeyTemplate(key: string) { - return `
-

- Follow the instructions on your Invitation Link to download the Outline app and get connected. -

-

Having trouble accessing the invitation link?

-
    -
  1. Copy your access key: ${key}
  2. -
  3. Follow our invitation instructions on GitHub: https://github.com/Jigsaw-Code/outline-client/blob/master/docs/invitation_instructions.md
  4. -
-
`; +export function emailKeyTemplate(key: string, name: string) { + return ` +
+ +

Hi ${name},

+

Use the following instructions to set up Outline VPN on your devices:

+ +
    +
  1. Download and install the Outline app for your device:
  2. + +
  3. Copy your Access key ${key}
  4. +
  5. Open the Outline client app. If your access key is auto-detected, tap 'Connect'. If your access key is not auto-detected, paste it in the field, then tap 'Connect'. You are good to go!
  6. +
+

NOTE: The same key can be used for multiple devices.

+
`; } diff --git a/apps/vpnmanager/src/lib/processUsers.ts b/apps/vpnmanager/src/lib/processUsers.ts index 269570426..680b92123 100644 --- a/apps/vpnmanager/src/lib/processUsers.ts +++ b/apps/vpnmanager/src/lib/processUsers.ts @@ -30,8 +30,9 @@ export async function processUser(item: SheetRow) { } } await sendVpnKeyEmail({ - recipient: user?.name ?? "", + to: user?.name ?? "", key: user?.accessUrl ?? "", + name: item?.member ?? user?.name, }); return { ...item, diff --git a/apps/vpnmanager/src/types.d.ts b/apps/vpnmanager/src/types.d.ts index 15ec3fb97..98c2736c8 100644 --- a/apps/vpnmanager/src/types.d.ts +++ b/apps/vpnmanager/src/types.d.ts @@ -33,7 +33,7 @@ export interface OutlineServerMetrics { export interface SheetRow { emailAddressCreated: string; emailAddress: string; - name: string; + member: string; outlineKeyCreated: string; startDate: string; endDate: string; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9d00cce1f..8c8ea16f9 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -978,7 +978,7 @@ importers: specifier: ^8.1.1 version: 8.1.1 "@sentry/nextjs": - specifier: ^7.105.0 + specifier: ^7.106.1 version: 7.106.1(next@14.1.3)(react@18.2.0)(webpack@5.89.0) "@svgr/webpack": specifier: ^8.1.0