Session 10: Internal auth refactor, prefetch cascade keys, Sentry, welcome email (1286 tests)

This commit is contained in:
Kev
2026-06-10 20:45:05 -04:00
parent b55dcbd614
commit e5c45ecc8e
22 changed files with 3837 additions and 94 deletions
+119
View File
@@ -0,0 +1,119 @@
/**
* Sentry init for the Express backend (Session 10).
*
* Boot is GRACEFUL when SENTRY_DSN is unset: `initSentry()` no-ops and
* the module's exported `Sentry` is a stub whose every method is a
* noop. This lets callers wire `Sentry.captureException(...)` etc.
* unconditionally — when the DSN isn't configured (dev, CI, tests),
* nothing crashes and no events are sent.
*
* PII posture: `sendDefaultPii: false` plus an `events`-stage hook
* that strips `user.ip_address` and `request.cookies`. We log code
* paths and errors, not user identities.
*
* Sample rate: 10% traces (free tier friendly). 100% errors.
*/
const realSentry = require('@sentry/node');
// Initialized lazily so this module is safe to require even when the
// DSN is absent.
let _initialized = false;
function buildClient() {
return {
init: realSentry.init,
captureException: realSentry.captureException,
captureMessage: realSentry.captureMessage,
setupExpressErrorHandler: realSentry.setupExpressErrorHandler,
addBreadcrumb: realSentry.addBreadcrumb,
setUser: realSentry.setUser,
setTag: realSentry.setTag,
setContext: realSentry.setContext,
};
}
function buildNoop() {
// Every Sentry surface used in the codebase returns either undefined
// (most) or a no-op express middleware (`setupExpressErrorHandler`).
const noopMiddleware = (_req, _res, next) => next();
return {
init: () => {},
captureException: () => {},
captureMessage: () => {},
setupExpressErrorHandler: (_app) => {
// The real one mutates the app; the noop simply returns without
// attaching anything. The caller pattern is:
// Sentry.setupExpressErrorHandler(app);
// which evaluates the call for its side effects.
},
addBreadcrumb: () => {},
setUser: () => {},
setTag: () => {},
setContext: () => {},
Handlers: { errorHandler: () => noopMiddleware },
};
}
let Sentry = buildNoop();
function initSentry({ dsn = process.env.SENTRY_DSN, environment = process.env.NODE_ENV, release } = {}) {
if (_initialized) return Sentry;
if (!dsn) {
// Stay on the noop client.
return Sentry;
}
Sentry = buildClient();
Sentry.init({
dsn,
environment: environment || 'development',
release,
tracesSampleRate: 0.1,
sendDefaultPii: false,
beforeSend(event) {
// PII scrubbing. Sentry occasionally fills these via auto-context.
if (event.user) {
delete event.user.ip_address;
delete event.user.email;
}
if (event.request) {
delete event.request.cookies;
// Strip the Authorization header to avoid logging bearer tokens.
if (event.request.headers) {
delete event.request.headers.authorization;
delete event.request.headers.cookie;
delete event.request.headers['x-internal-key'];
delete event.request.headers['x-vyndr-internal-key'];
}
}
return event;
},
});
_initialized = true;
return Sentry;
}
function getSentry() {
return Sentry;
}
function isInitialized() {
return _initialized;
}
// Test helper — reset to the noop client so subsequent initSentry()
// calls re-run. Not exported via the main surface; live behind __internals.
function __resetForTests() {
_initialized = false;
Sentry = buildNoop();
}
module.exports = {
initSentry,
getSentry,
isInitialized,
// Convenience re-export so callers can do `const { Sentry } = require(...)`.
// Note: this is a live binding — mutated by initSentry() on first call.
get Sentry() { return Sentry; },
__internals: { __resetForTests, buildNoop, buildClient },
};