Add user tagging for logged-in staff users
This commit is contained in:
@@ -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 }) {
|
||||||
|
|||||||
18
app/root.tsx
18
app/root.tsx
@@ -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 />
|
||||||
|
|||||||
@@ -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
23
functions/api/st.ts
Normal 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,
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user