mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
fix: error-only Sentry telemetry, storm-proof capture, and crash fixes (#476)
Removes Sentry tracing entirely (BullMQ idle polling burned 4.8M transactions in 2 days at the baked 0.1 rate), decouples PostHog sampling, and replaces the type-only error scrub with a vetted-field sanitizer plus SafeError/ToolInputError contracts. One classified capture path with per-signature throttles and a per-process ceiling makes storms impossible (NODE-1E was 4,541 events from one 30s loop). Browser errors move to a dedicated web Sentry project with their own source maps. Adds the SNAPOTTER_TELEMETRY runtime kill switch and silences test fleets. Crash fixes: remote 204/304 SSRF process kill (NODE-20), conversion-preset boot crash loop (NODE-21), Redis version preflight + unhandled subscribe rejection (NODE-1T), Sign PDF on plain-http origins (NODE-1K/1M), wavesurfer/pdf.js teardown rejections (NODE-1P/1N), bundle-import ZlibError to 400 (NODE-1Z), chart-maker input errors declassified (NODE-1H/1J), asset requests skip the session DB lookup (NODE-1D).
This commit is contained in:
@@ -6,6 +6,7 @@ const deliverWebhookMock = vi.hoisted(() => vi.fn());
|
||||
const decryptMock = vi.hoisted(() => vi.fn());
|
||||
const isEncryptedMock = vi.hoisted(() => vi.fn());
|
||||
const getActiveLicenseMock = vi.hoisted(() => vi.fn());
|
||||
const isFeatureEnabledMock = vi.hoisted(() => vi.fn());
|
||||
const selectMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
function queryChain<T>(result: T) {
|
||||
@@ -24,6 +25,8 @@ async function loadAlertEvaluator() {
|
||||
decryptMock.mockReset();
|
||||
isEncryptedMock.mockReset();
|
||||
getActiveLicenseMock.mockReset();
|
||||
isFeatureEnabledMock.mockReset();
|
||||
isFeatureEnabledMock.mockReturnValue(true);
|
||||
selectMock.mockReset();
|
||||
|
||||
vi.doMock("node:fs/promises", () => ({
|
||||
@@ -71,6 +74,7 @@ async function loadAlertEvaluator() {
|
||||
|
||||
vi.doMock("@snapotter/enterprise", () => ({
|
||||
getActiveLicense: getActiveLicenseMock,
|
||||
isFeatureEnabled: isFeatureEnabledMock,
|
||||
}));
|
||||
|
||||
return import("../../../../apps/api/src/jobs/alert-evaluator.js");
|
||||
@@ -81,6 +85,17 @@ describe("alert evaluator behavior", () => {
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("returns before reading settings when the admin_alerts feature is unlicensed", async () => {
|
||||
const { evaluateAlerts } = await loadAlertEvaluator();
|
||||
isFeatureEnabledMock.mockReturnValue(false);
|
||||
|
||||
await expect(evaluateAlerts()).resolves.toBeUndefined();
|
||||
|
||||
expect(getSettingStringMock).not.toHaveBeenCalled();
|
||||
expect(statfsMock).not.toHaveBeenCalled();
|
||||
expect(deliverWebhookMock).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns early when webhook destination settings are invalid JSON", async () => {
|
||||
const { evaluateAlerts } = await loadAlertEvaluator();
|
||||
getSettingStringMock.mockResolvedValueOnce("{invalid");
|
||||
|
||||
@@ -5,6 +5,7 @@ const deliverWebhookMock = vi.hoisted(() => vi.fn());
|
||||
const upsertSettingMock = vi.hoisted(() => vi.fn());
|
||||
const decryptMock = vi.hoisted(() => vi.fn());
|
||||
const isEncryptedMock = vi.hoisted(() => vi.fn());
|
||||
const isFeatureEnabledMock = vi.hoisted(() => vi.fn());
|
||||
const selectMock = vi.hoisted(() => vi.fn());
|
||||
|
||||
function queryChain<T>(result: T, terminalWhere = false) {
|
||||
@@ -24,6 +25,8 @@ async function loadSiemForward() {
|
||||
upsertSettingMock.mockReset();
|
||||
decryptMock.mockReset();
|
||||
isEncryptedMock.mockReset();
|
||||
isFeatureEnabledMock.mockReset();
|
||||
isFeatureEnabledMock.mockReturnValue(true);
|
||||
selectMock.mockReset();
|
||||
|
||||
vi.doMock("drizzle-orm", () => ({
|
||||
@@ -75,6 +78,10 @@ async function loadSiemForward() {
|
||||
readSiemConfig: readSiemConfigMock,
|
||||
}));
|
||||
|
||||
vi.doMock("@snapotter/enterprise", () => ({
|
||||
isFeatureEnabled: isFeatureEnabledMock,
|
||||
}));
|
||||
|
||||
return import("../../../../apps/api/src/jobs/siem-forward.js");
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user