diff --git a/apps/journal/Dockerfile b/apps/journal/Dockerfile index 3a74835..f5ee27e 100644 --- a/apps/journal/Dockerfile +++ b/apps/journal/Dockerfile @@ -11,6 +11,7 @@ COPY packages/ui/package.json packages/ui/ COPY packages/map/package.json packages/map/ COPY packages/gpx/package.json packages/gpx/ COPY packages/i18n/package.json packages/i18n/ +COPY packages/sentry-config/package.json packages/sentry-config/ COPY packages/api/package.json packages/api/ COPY packages/map-core/package.json packages/map-core/ COPY packages/db/package.json packages/db/ diff --git a/apps/journal/app/components/Footer.tsx b/apps/journal/app/components/Footer.tsx index 1542c1c..f1f242d 100644 --- a/apps/journal/app/components/Footer.tsx +++ b/apps/journal/app/components/Footer.tsx @@ -5,7 +5,7 @@ export function Footer() { return ( ); diff --git a/apps/journal/app/lib/sentry.client.ts b/apps/journal/app/lib/sentry.client.ts index a4f3546..f4ea454 100644 --- a/apps/journal/app/lib/sentry.client.ts +++ b/apps/journal/app/lib/sentry.client.ts @@ -23,3 +23,16 @@ export function initSentryClient() { ...browserSentryConfig("journal client", import.meta.env), }); } + +/** + * Tear down the Sentry client on logout. After this call, `Sentry.captureException` + * and other hub methods become no-ops until `initSentryClient` is called again. + * + * Fire-and-forget: the close flush happens async, but we don't want to block the + * logout UI on it. + */ +export function stopSentryClient() { + if (!initialized) return; + initialized = false; + void Sentry.close(); +} diff --git a/apps/journal/app/root.tsx b/apps/journal/app/root.tsx index d8967b0..09b32ec 100644 --- a/apps/journal/app/root.tsx +++ b/apps/journal/app/root.tsx @@ -9,7 +9,7 @@ import { getSessionUser } from "~/lib/auth.server"; import { LocaleProvider } from "~/components/LocaleContext"; import { AlphaBanner } from "~/components/AlphaBanner"; import { Footer } from "~/components/Footer"; -import { initSentryClient } from "~/lib/sentry.client"; +import { initSentryClient, stopSentryClient } from "~/lib/sentry.client"; import stylesheet from "@trails-cool/ui/styles.css?url"; export const links: LinksFunction = () => [{ rel: "stylesheet", href: stylesheet }]; @@ -123,6 +123,7 @@ export default function App({ loaderData }: Route.ComponentProps) { Sentry.setUser({ id: user.id }); } else { Sentry.setUser(null); + stopSentryClient(); } }, [user]); diff --git a/apps/planner/Dockerfile b/apps/planner/Dockerfile index 52b221d..6693d8c 100644 --- a/apps/planner/Dockerfile +++ b/apps/planner/Dockerfile @@ -11,6 +11,7 @@ COPY packages/ui/package.json packages/ui/ COPY packages/map/package.json packages/map/ COPY packages/gpx/package.json packages/gpx/ COPY packages/i18n/package.json packages/i18n/ +COPY packages/sentry-config/package.json packages/sentry-config/ COPY packages/api/package.json packages/api/ COPY packages/map-core/package.json packages/map-core/ COPY packages/db/package.json packages/db/ diff --git a/e2e/auth.test.ts b/e2e/auth.test.ts index ce19e79..8989fb5 100644 --- a/e2e/auth.test.ts +++ b/e2e/auth.test.ts @@ -30,6 +30,8 @@ async function registerUser(page: Page, email: string, username: string) { // Verify both fields retained values before submitting await expect(page.getByLabel("Email")).toHaveValue(email); await expect(page.getByLabel("Username")).toHaveValue(username); + // Accept the Terms of Service (required) + await page.getByRole("checkbox").check(); await page.getByRole("button", { name: /Register with Passkey/ }).click(); }