Add user tagging for logged-in staff users

This commit is contained in:
2026-03-12 02:20:16 -04:00
parent 97d84bdc17
commit f5e2110ff4
4 changed files with 70 additions and 4 deletions

View File

@@ -22,6 +22,7 @@ Sentry.init({
replaysSessionSampleRate: 0.02, replaysSessionSampleRate: 0.02,
sendDefaultPii: true, sendDefaultPii: true,
tracesSampleRate: 0.1, tracesSampleRate: 0.1,
tunnel: "/api/st",
}); });
function ClientCacheProvider({ children }: { children: ReactNode }) { function ClientCacheProvider({ children }: { children: ReactNode }) {

View File

@@ -27,7 +27,11 @@ import Navigation from "../components/Navigation.js";
import { type ReactNode, StrictMode, useContext, useEffect } from "react"; import { type ReactNode, StrictMode, useContext, useEffect } from "react";
import theme from "../theme.js"; import theme from "../theme.js";
import { withEmotionCache } from "@emotion/react"; import { withEmotionCache } from "@emotion/react";
import { captureRemixErrorBoundaryError, withSentry } from "@sentry/remix"; import {
captureRemixErrorBoundaryError,
setUser,
withSentry,
} from "@sentry/remix";
export function ErrorBoundary() { export function ErrorBoundary() {
const error = useRouteError() as ErrorResponse; const error = useRouteError() as ErrorResponse;
@@ -226,6 +230,18 @@ function DocumentWrapper(props: {
function App() { function App() {
const loaderData = useLoaderData<typeof loader>(); const loaderData = useLoaderData<typeof loader>();
if (
loaderData.id &&
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].find(
(p) => loaderData.permissions & (1 << p),
)
)
setUser({
email: loaderData.email,
id: loaderData.id,
username: loaderData.username,
});
return ( return (
<DocumentWrapper loaderData={loaderData}> <DocumentWrapper loaderData={loaderData}>
<Outlet /> <Outlet />

View File

@@ -31,8 +31,21 @@ async function generateTokenHash(token: string) {
async function refreshAuth(context: RequestContext) { async function refreshAuth(context: RequestContext) {
const { current_user: currentUser } = context.data; const { current_user: currentUser } = context.data;
if (!currentUser || currentUser.refresh_at > Date.now()) if (!currentUser) return await context.next();
return await context.next();
if (currentUser.refresh_at > Date.now()) {
if (
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].find(
(p) => currentUser.permissions & (1 << p),
)
)
Sentry.setUser({
email: currentUser.email,
id: currentUser.id,
ip_address: context.request.headers.get("cf-connecting-ip"),
username: currentUser.username,
});
}
const oauthData = await context.env.DATA.get( const oauthData = await context.env.DATA.get(
`oauthcredentials_${currentUser.id}`, `oauthcredentials_${currentUser.id}`,
@@ -95,6 +108,18 @@ async function refreshAuth(context: RequestContext) {
: undefined, : undefined,
); );
if (
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12].find(
(p) => currentUser.permissions & (1 << p),
)
)
Sentry.setUser({
email: currentUser.email,
id: currentUser.id,
ip_address: context.request.headers.get("cf-connecting-ip"),
username: currentUser.username,
});
const tokenHash = await generateTokenHash(context.data.sid); const tokenHash = await generateTokenHash(context.data.sid);
await context.env.DATA.put(`auth_${tokenHash}`, JSON.stringify(userData), { await context.env.DATA.put(`auth_${tokenHash}`, JSON.stringify(userData), {
@@ -273,7 +298,8 @@ async function setAuth(context: RequestContext) {
async function setBody(context: RequestContext) { async function setBody(context: RequestContext) {
if ( if (
["PATCH", "POST", "PUT"].includes(context.request.method) && ["PATCH", "POST", "PUT"].includes(context.request.method) &&
!context.request.url.endsWith("/api/infractions/new") !context.request.url.endsWith("/api/infractions/new") &&
!context.request.url.endsWith("/api/st")
) { ) {
if ( if (
!context.request.headers !context.request.headers

23
functions/api/st.ts Normal file
View File

@@ -0,0 +1,23 @@
import { jsonError } from "../common.js";
export async function onRequestPost(context: RequestContext) {
const dsn = context.request.headers.get("dsn");
if (!dsn || dsn !== context.env.DSN) return jsonError("Bad or no DSN", 400);
const sentryUrl = new URL(dsn);
await fetch(`https://${sentryUrl.host}/api${sentryUrl.pathname}/envelope`, {
body: context.request.body,
headers: {
"content-type": "application/x-sentry-envelope",
"x-forwarded-for": context.request.headers.get(
"cf-connecting-ip",
) as string,
},
method: "POST",
});
return new Response(null, {
status: 204,
});
}