@vibes.diy/api-svc 13.1.12 → 13.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/create-handler.js +2 -0
- package/create-handler.js.map +1 -1
- package/evento-handler-manifest.js +2 -0
- package/evento-handler-manifest.js.map +1 -1
- package/intern/backend-egress.d.ts +1 -0
- package/intern/backend-egress.js +24 -10
- package/intern/backend-egress.js.map +1 -1
- package/intern/components/vibe-page.js +29 -1
- package/intern/components/vibe-page.js.map +1 -1
- package/intern/egress-read-lane.js.map +1 -1
- package/intern/egress-request-log.d.ts +14 -0
- package/intern/egress-request-log.js +16 -0
- package/intern/egress-request-log.js.map +1 -0
- package/intern/render-vibe.js +2 -0
- package/intern/render-vibe.js.map +1 -1
- package/intern/ssr-theme-css.d.ts +1 -0
- package/intern/ssr-theme-css.js +12 -0
- package/intern/ssr-theme-css.js.map +1 -1
- package/package.json +12 -11
- package/public/report-egress.d.ts +19 -0
- package/public/report-egress.js +168 -0
- package/public/report-egress.js.map +1 -0
- package/usage-report/egress-abuse-alert-util.d.ts +100 -0
- package/usage-report/egress-abuse-alert-util.js +246 -0
- package/usage-report/egress-abuse-alert-util.js.map +1 -0
- package/usage-report/egress-abuse-alert.d.ts +1 -0
- package/usage-report/egress-abuse-alert.js +94 -0
- package/usage-report/egress-abuse-alert.js.map +1 -0
package/intern/ssr-theme-css.js
CHANGED
|
@@ -59,6 +59,18 @@ export async function ssrStyleCss(style) {
|
|
|
59
59
|
return undefined;
|
|
60
60
|
return api.renderStyleCss(style.palette, structural);
|
|
61
61
|
}
|
|
62
|
+
export const SAFE_AREA_CSS = ":root{" +
|
|
63
|
+
"--vibes-safe-top:env(safe-area-inset-top,0px);" +
|
|
64
|
+
"--vibes-safe-right:env(safe-area-inset-right,0px);" +
|
|
65
|
+
"--vibes-safe-bottom:env(safe-area-inset-bottom,0px);" +
|
|
66
|
+
"--vibes-safe-left:env(safe-area-inset-left,0px)" +
|
|
67
|
+
"}" +
|
|
68
|
+
".vibe-app-container{" +
|
|
69
|
+
"padding-top:var(--vibes-safe-top,env(safe-area-inset-top,0px));" +
|
|
70
|
+
"padding-right:var(--vibes-safe-right,env(safe-area-inset-right,0px));" +
|
|
71
|
+
"padding-bottom:var(--vibes-safe-bottom,env(safe-area-inset-bottom,0px));" +
|
|
72
|
+
"padding-left:var(--vibes-safe-left,env(safe-area-inset-left,0px))" +
|
|
73
|
+
"}";
|
|
62
74
|
export function __resetSsrThemeCssForTests() {
|
|
63
75
|
apiPromise = undefined;
|
|
64
76
|
cssBySlug.clear();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssr-theme-css.js","sourceRoot":"","sources":["../../jsr/intern/ssr-theme-css.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ssr-theme-css.js","sourceRoot":"","sources":["../../jsr/intern/ssr-theme-css.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibes.diy/api-svc",
|
|
3
|
-
"version": "13.1.
|
|
3
|
+
"version": "13.1.13",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./index.js",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"db:inspect": "tsx ./usage-report/inspect-db.ts",
|
|
10
10
|
"journey": "tsx ./usage-report/user-journey.ts",
|
|
11
11
|
"new-user-alert": "tsx ./usage-report/new-user-alert.ts",
|
|
12
|
+
"egress-abuse-alert": "tsx ./usage-report/egress-abuse-alert.ts",
|
|
12
13
|
"warm:measure": "tsx ./usage-report/warm-vibe-cache.ts",
|
|
13
14
|
"db:inspect-report": "tsx ./usage-report/inspect-db-report.ts",
|
|
14
15
|
"db:admin": "tsx ./usage-report/admin-db.ts",
|
|
@@ -28,18 +29,18 @@
|
|
|
28
29
|
"@libsql/client": "~0.17.4",
|
|
29
30
|
"@neondatabase/serverless": "~1.1.0",
|
|
30
31
|
"@noble/hashes": "~2.3.0",
|
|
31
|
-
"@vibes.diy/api-pkg": "13.1.
|
|
32
|
-
"@vibes.diy/api-sql": "13.1.
|
|
33
|
-
"@vibes.diy/api-types": "13.1.
|
|
34
|
-
"@vibes.diy/call-ai-v2": "13.1.
|
|
35
|
-
"@vibes.diy/identity": "13.1.
|
|
36
|
-
"@vibes.diy/prompts": "13.1.
|
|
37
|
-
"@vibes.diy/vibe-db-explorer": "13.1.
|
|
38
|
-
"@vibes.diy/vibe-runtime": "13.1.
|
|
39
|
-
"@vibes.diy/vibe-types": "13.1.
|
|
32
|
+
"@vibes.diy/api-pkg": "13.1.13",
|
|
33
|
+
"@vibes.diy/api-sql": "13.1.13",
|
|
34
|
+
"@vibes.diy/api-types": "13.1.13",
|
|
35
|
+
"@vibes.diy/call-ai-v2": "13.1.13",
|
|
36
|
+
"@vibes.diy/identity": "13.1.13",
|
|
37
|
+
"@vibes.diy/prompts": "13.1.13",
|
|
38
|
+
"@vibes.diy/vibe-db-explorer": "13.1.13",
|
|
39
|
+
"@vibes.diy/vibe-runtime": "13.1.13",
|
|
40
|
+
"@vibes.diy/vibe-types": "13.1.13",
|
|
40
41
|
"acorn": "~8.17.0",
|
|
41
42
|
"arktype": "~2.2.3",
|
|
42
|
-
"call-ai": "13.1.
|
|
43
|
+
"call-ai": "13.1.13",
|
|
43
44
|
"charwise": "~3.0.1",
|
|
44
45
|
"cookie": "~2.0.1",
|
|
45
46
|
"csv-parse": "~7.0.2",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { EventoHandler } from "@adviser/cement";
|
|
2
|
+
import { MsgBase, ReqReportEgress, ResReportEgress, ResReportEgressGateRow, ResReportEgressHostRow, ResReportEgressVibeRow, VibesDiyError, W3CWebSocketEvent } from "@vibes.diy/api-types";
|
|
3
|
+
export interface EgressSampleRow {
|
|
4
|
+
readonly host: string;
|
|
5
|
+
readonly finalHost: string;
|
|
6
|
+
readonly outcome: string;
|
|
7
|
+
readonly ownerHandle: string;
|
|
8
|
+
readonly appSlug: string;
|
|
9
|
+
readonly lane: string;
|
|
10
|
+
readonly gate: string;
|
|
11
|
+
readonly cached: number;
|
|
12
|
+
readonly ts: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function aggregateEgress(rows: readonly EgressSampleRow[]): {
|
|
15
|
+
byHost: ResReportEgressHostRow[];
|
|
16
|
+
byVibe: ResReportEgressVibeRow[];
|
|
17
|
+
byGate: ResReportEgressGateRow[];
|
|
18
|
+
};
|
|
19
|
+
export declare const reportEgressEvento: EventoHandler<W3CWebSocketEvent, MsgBase<ReqReportEgress>, ResReportEgress | VibesDiyError>;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Result, Option, EventoResult } from "@adviser/cement";
|
|
2
|
+
import { reqReportEgress, resReportEgress, } from "@vibes.diy/api-types";
|
|
3
|
+
import { type } from "arktype";
|
|
4
|
+
import { sql, asc, desc, eq, and, or, gte } from "drizzle-orm";
|
|
5
|
+
import { unwrapMsgBase } from "../unwrap-msg-base.js";
|
|
6
|
+
import { checkAuth } from "../check-auth.js";
|
|
7
|
+
import { cachedReport, hasReport } from "./report-cache.js";
|
|
8
|
+
const WINDOW_DAYS = 14;
|
|
9
|
+
const SAMPLE_ROW_CAP = 20000;
|
|
10
|
+
const SUSPECT_GROUP_CAP = 500;
|
|
11
|
+
export function aggregateEgress(rows) {
|
|
12
|
+
const hosts = new Map();
|
|
13
|
+
const vibes = new Map();
|
|
14
|
+
const gates = new Map();
|
|
15
|
+
for (const row of rows) {
|
|
16
|
+
const denied = row.outcome === "denied";
|
|
17
|
+
const failed = row.outcome === "transport-error";
|
|
18
|
+
const vibeKey = `${row.ownerHandle}/${row.appSlug}`;
|
|
19
|
+
const reachedHost = row.finalHost === "" ? row.host : row.finalHost;
|
|
20
|
+
const host = hosts.get(reachedHost) ?? {
|
|
21
|
+
host: reachedHost,
|
|
22
|
+
requests: 0,
|
|
23
|
+
admitted: 0,
|
|
24
|
+
denied: 0,
|
|
25
|
+
failed: 0,
|
|
26
|
+
cacheHits: 0,
|
|
27
|
+
vibes: new Set(),
|
|
28
|
+
lastSeen: "",
|
|
29
|
+
};
|
|
30
|
+
host.requests++;
|
|
31
|
+
if (denied)
|
|
32
|
+
host.denied++;
|
|
33
|
+
else if (failed)
|
|
34
|
+
host.failed++;
|
|
35
|
+
else
|
|
36
|
+
host.admitted++;
|
|
37
|
+
if (row.cached === 1)
|
|
38
|
+
host.cacheHits++;
|
|
39
|
+
host.vibes.add(vibeKey);
|
|
40
|
+
if (row.ts > host.lastSeen)
|
|
41
|
+
host.lastSeen = row.ts;
|
|
42
|
+
hosts.set(reachedHost, host);
|
|
43
|
+
const vibe = vibes.get(vibeKey) ?? {
|
|
44
|
+
ownerHandle: row.ownerHandle,
|
|
45
|
+
appSlug: row.appSlug,
|
|
46
|
+
requests: 0,
|
|
47
|
+
hosts: new Set(),
|
|
48
|
+
denied: 0,
|
|
49
|
+
lastSeen: "",
|
|
50
|
+
};
|
|
51
|
+
vibe.requests++;
|
|
52
|
+
if (row.host !== "")
|
|
53
|
+
vibe.hosts.add(row.host);
|
|
54
|
+
if (denied)
|
|
55
|
+
vibe.denied++;
|
|
56
|
+
if (row.ts > vibe.lastSeen)
|
|
57
|
+
vibe.lastSeen = row.ts;
|
|
58
|
+
vibes.set(vibeKey, vibe);
|
|
59
|
+
if (row.gate !== "")
|
|
60
|
+
gates.set(row.gate, (gates.get(row.gate) ?? 0) + 1);
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
byHost: Array.from(hosts.values())
|
|
64
|
+
.map((h) => ({
|
|
65
|
+
host: h.host,
|
|
66
|
+
requests: h.requests,
|
|
67
|
+
admitted: h.admitted,
|
|
68
|
+
denied: h.denied,
|
|
69
|
+
failed: h.failed,
|
|
70
|
+
cacheHits: h.cacheHits,
|
|
71
|
+
distinctVibes: h.vibes.size,
|
|
72
|
+
lastSeen: h.lastSeen,
|
|
73
|
+
}))
|
|
74
|
+
.sort((a, b) => b.requests - a.requests),
|
|
75
|
+
byVibe: Array.from(vibes.values())
|
|
76
|
+
.map((v) => ({
|
|
77
|
+
ownerHandle: v.ownerHandle,
|
|
78
|
+
appSlug: v.appSlug,
|
|
79
|
+
requests: v.requests,
|
|
80
|
+
distinctHosts: v.hosts.size,
|
|
81
|
+
denied: v.denied,
|
|
82
|
+
lastSeen: v.lastSeen,
|
|
83
|
+
}))
|
|
84
|
+
.sort((a, b) => b.distinctHosts - a.distinctHosts || b.requests - a.requests),
|
|
85
|
+
byGate: Array.from(gates.entries())
|
|
86
|
+
.map(([gate, requests]) => ({ gate, requests }))
|
|
87
|
+
.sort((a, b) => b.requests - a.requests),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
async function computeEgress(vctx, hostFilter) {
|
|
91
|
+
const t = vctx.sql.tables;
|
|
92
|
+
const cutoff = new Date(Date.now() - WINDOW_DAYS * 24 * 60 * 60 * 1000).toISOString();
|
|
93
|
+
const windowFilter = gte(t.egressEvents.ts, cutoff);
|
|
94
|
+
const where = hostFilter !== undefined
|
|
95
|
+
? and(windowFilter, or(eq(t.egressEvents.host, hostFilter), eq(t.egressEvents.finalHost, hostFilter)))
|
|
96
|
+
: windowFilter;
|
|
97
|
+
const sample = await vctx.sql.db
|
|
98
|
+
.select({
|
|
99
|
+
host: t.egressEvents.host,
|
|
100
|
+
finalHost: t.egressEvents.finalHost,
|
|
101
|
+
outcome: t.egressEvents.outcome,
|
|
102
|
+
ownerHandle: t.egressEvents.ownerHandle,
|
|
103
|
+
appSlug: t.egressEvents.appSlug,
|
|
104
|
+
lane: t.egressEvents.lane,
|
|
105
|
+
gate: t.egressEvents.gate,
|
|
106
|
+
cached: t.egressEvents.cached,
|
|
107
|
+
ts: t.egressEvents.ts,
|
|
108
|
+
})
|
|
109
|
+
.from(t.egressEvents)
|
|
110
|
+
.where(where)
|
|
111
|
+
.orderBy(desc(t.egressEvents.ts))
|
|
112
|
+
.limit(SAMPLE_ROW_CAP);
|
|
113
|
+
const suspectWindow = gte(t.egressSuspectEvents.ts, cutoff);
|
|
114
|
+
const suspectWhere = hostFilter !== undefined ? and(suspectWindow, eq(t.egressSuspectEvents.host, hostFilter)) : suspectWindow;
|
|
115
|
+
const suspects = await vctx.sql.db
|
|
116
|
+
.select({
|
|
117
|
+
host: t.egressSuspectEvents.host,
|
|
118
|
+
ownerHandle: t.egressSuspectEvents.ownerHandle,
|
|
119
|
+
appSlug: t.egressSuspectEvents.appSlug,
|
|
120
|
+
reasons: t.egressSuspectEvents.reasons,
|
|
121
|
+
occurrences: sql `cast(count(*) as int)`,
|
|
122
|
+
lastSeen: sql `max(${t.egressSuspectEvents.ts})`,
|
|
123
|
+
})
|
|
124
|
+
.from(t.egressSuspectEvents)
|
|
125
|
+
.where(suspectWhere)
|
|
126
|
+
.groupBy(t.egressSuspectEvents.host, t.egressSuspectEvents.ownerHandle, t.egressSuspectEvents.appSlug, t.egressSuspectEvents.reasons)
|
|
127
|
+
.orderBy(desc(sql `count(*)`), asc(t.egressSuspectEvents.host))
|
|
128
|
+
.limit(SUSPECT_GROUP_CAP);
|
|
129
|
+
const { byHost, byVibe, byGate } = aggregateEgress(sample);
|
|
130
|
+
return {
|
|
131
|
+
type: "vibes.diy.res-report-egress",
|
|
132
|
+
generatedAt: new Date().toISOString(),
|
|
133
|
+
windowDays: WINDOW_DAYS,
|
|
134
|
+
sampled: sample.length === SAMPLE_ROW_CAP,
|
|
135
|
+
sampleRows: sample.length,
|
|
136
|
+
byHost: byHost.slice(0, 100),
|
|
137
|
+
byVibe: byVibe.slice(0, 100),
|
|
138
|
+
byGate,
|
|
139
|
+
suspects,
|
|
140
|
+
suspectsTruncated: suspects.length === SUSPECT_GROUP_CAP,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
export const reportEgressEvento = {
|
|
144
|
+
hash: "vibes.diy.req-report-egress",
|
|
145
|
+
validate: unwrapMsgBase(async (msg) => {
|
|
146
|
+
const ret = reqReportEgress(msg.payload);
|
|
147
|
+
if (ret instanceof type.errors)
|
|
148
|
+
return Result.Ok(Option.None());
|
|
149
|
+
return Result.Ok(Option.Some({ ...msg, payload: ret }));
|
|
150
|
+
}),
|
|
151
|
+
handle: checkAuth(async (ctx) => {
|
|
152
|
+
const req = ctx.validated.payload;
|
|
153
|
+
const vctx = ctx.ctx.getOrThrow("vibesApiCtx");
|
|
154
|
+
if (hasReport(req._auth.verifiedAuth.claims, "attribution") === false) {
|
|
155
|
+
await ctx.send.send(ctx, {
|
|
156
|
+
type: "vibes.diy.res-error",
|
|
157
|
+
error: { message: "not authorized for attribution report", code: "report-not-authorized" },
|
|
158
|
+
});
|
|
159
|
+
return Result.Ok(EventoResult.Continue);
|
|
160
|
+
}
|
|
161
|
+
const hostFilter = req.host;
|
|
162
|
+
const cacheKey = hostFilter !== undefined ? `egress:${encodeURIComponent(hostFilter)}` : "egress";
|
|
163
|
+
const res = await cachedReport(vctx, cacheKey, resReportEgress, () => computeEgress(vctx, hostFilter));
|
|
164
|
+
await ctx.send.send(ctx, res);
|
|
165
|
+
return Result.Ok(EventoResult.Continue);
|
|
166
|
+
}),
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=report-egress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report-egress.js","sourceRoot":"","sources":["../../jsr/public/report-egress.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
export declare function sanitizeForDiscord(value: string): string;
|
|
2
|
+
export declare const DEFAULT_HOST_REQUESTS = 500;
|
|
3
|
+
export declare const DEFAULT_HOST_VIBES = 5;
|
|
4
|
+
export declare const DEFAULT_VIBE_HOSTS = 20;
|
|
5
|
+
export declare const DEFAULT_TRANSPORT_REQUESTS = 50;
|
|
6
|
+
export declare const DEFAULT_TRANSPORT_SHARE = 0.5;
|
|
7
|
+
export declare const DEFAULT_SUSPECT_EVENTS = 3;
|
|
8
|
+
export declare const TOP_N = 8;
|
|
9
|
+
export declare const DISCORD_DESCRIPTION_LIMIT = 4096;
|
|
10
|
+
export interface Thresholds {
|
|
11
|
+
readonly hostRequests: number;
|
|
12
|
+
readonly hostVibes: number;
|
|
13
|
+
readonly vibeHosts: number;
|
|
14
|
+
readonly transportRequests: number;
|
|
15
|
+
readonly transportShare: number;
|
|
16
|
+
readonly suspectEvents: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const EGRESS_ALERT_ENV_VARS: readonly string[];
|
|
19
|
+
export interface ThresholdEnv {
|
|
20
|
+
readonly EGRESS_ALERT_HOST_REQUESTS?: string;
|
|
21
|
+
readonly EGRESS_ALERT_HOST_VIBES?: string;
|
|
22
|
+
readonly EGRESS_ALERT_VIBE_HOSTS?: string;
|
|
23
|
+
readonly EGRESS_ALERT_TRANSPORT_REQUESTS?: string;
|
|
24
|
+
readonly EGRESS_ALERT_TRANSPORT_SHARE?: string;
|
|
25
|
+
readonly EGRESS_ALERT_SUSPECT_EVENTS?: string;
|
|
26
|
+
}
|
|
27
|
+
export declare function resolveThresholds(env: ThresholdEnv): Thresholds;
|
|
28
|
+
export declare const PG_UNDEFINED_TABLE = "42P01";
|
|
29
|
+
export declare function isUndefinedTableError(e: unknown): boolean;
|
|
30
|
+
export interface EgressEventRow {
|
|
31
|
+
readonly outcome: string;
|
|
32
|
+
readonly host: string;
|
|
33
|
+
readonly finalHost: string;
|
|
34
|
+
readonly ownerHandle: string;
|
|
35
|
+
readonly appSlug: string;
|
|
36
|
+
}
|
|
37
|
+
export interface EgressSuspectRow {
|
|
38
|
+
readonly host: string;
|
|
39
|
+
readonly ownerHandle: string;
|
|
40
|
+
readonly appSlug: string;
|
|
41
|
+
readonly reasons: string;
|
|
42
|
+
}
|
|
43
|
+
export interface DestinationRow {
|
|
44
|
+
readonly host: string;
|
|
45
|
+
readonly requests: number;
|
|
46
|
+
readonly vibes: number;
|
|
47
|
+
readonly transportErrors: number;
|
|
48
|
+
}
|
|
49
|
+
export interface FanOutRow {
|
|
50
|
+
readonly ownerHandle: string;
|
|
51
|
+
readonly appSlug: string;
|
|
52
|
+
readonly requestedHosts: number;
|
|
53
|
+
readonly requests: number;
|
|
54
|
+
}
|
|
55
|
+
export interface TransportErrorRow {
|
|
56
|
+
readonly host: string;
|
|
57
|
+
readonly transportErrors: number;
|
|
58
|
+
readonly requests: number;
|
|
59
|
+
readonly share: number;
|
|
60
|
+
}
|
|
61
|
+
export interface SuspectGroupRow {
|
|
62
|
+
readonly host: string;
|
|
63
|
+
readonly vibes: number;
|
|
64
|
+
readonly events: number;
|
|
65
|
+
readonly reasons: readonly string[];
|
|
66
|
+
}
|
|
67
|
+
export interface EgressAbuseSummary {
|
|
68
|
+
readonly requests: number;
|
|
69
|
+
readonly admitted: number;
|
|
70
|
+
readonly denied: number;
|
|
71
|
+
readonly transportErrors: number;
|
|
72
|
+
readonly distinctHosts: number;
|
|
73
|
+
readonly distinctVibes: number;
|
|
74
|
+
readonly suspectEvents: number;
|
|
75
|
+
readonly destinations: readonly DestinationRow[];
|
|
76
|
+
readonly fanOut: readonly FanOutRow[];
|
|
77
|
+
readonly transportErrorHosts: readonly TransportErrorRow[];
|
|
78
|
+
readonly suspects: readonly SuspectGroupRow[];
|
|
79
|
+
readonly tripped: readonly string[];
|
|
80
|
+
}
|
|
81
|
+
export declare function vibeUrl(ownerHandle: string, appSlug: string): string;
|
|
82
|
+
export declare function summarizeEgress(events: readonly EgressEventRow[], suspects: readonly EgressSuspectRow[], thresholds: Thresholds): EgressAbuseSummary;
|
|
83
|
+
export interface DiscordEmbedBody {
|
|
84
|
+
readonly content?: string;
|
|
85
|
+
readonly allowed_mentions?: {
|
|
86
|
+
readonly parse: readonly string[];
|
|
87
|
+
};
|
|
88
|
+
readonly embeds?: readonly {
|
|
89
|
+
readonly title?: string;
|
|
90
|
+
readonly description?: string;
|
|
91
|
+
readonly color?: number;
|
|
92
|
+
}[];
|
|
93
|
+
}
|
|
94
|
+
export interface EgressAlertInput {
|
|
95
|
+
readonly summary: EgressAbuseSummary;
|
|
96
|
+
readonly sinceHours: number;
|
|
97
|
+
readonly sampled: boolean;
|
|
98
|
+
}
|
|
99
|
+
export declare function buildMissingTablesEmbed(sinceHours: number): DiscordEmbedBody;
|
|
100
|
+
export declare function buildEgressAlertEmbed(input: EgressAlertInput): DiscordEmbedBody;
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
const DISCORD_MARKUP_RE = /[\\`*_~|>#[\]()]/g;
|
|
2
|
+
export function sanitizeForDiscord(value) {
|
|
3
|
+
return value.replaceAll(DISCORD_MARKUP_RE, (c) => `\\${c}`);
|
|
4
|
+
}
|
|
5
|
+
export const DEFAULT_HOST_REQUESTS = 500;
|
|
6
|
+
export const DEFAULT_HOST_VIBES = 5;
|
|
7
|
+
export const DEFAULT_VIBE_HOSTS = 20;
|
|
8
|
+
export const DEFAULT_TRANSPORT_REQUESTS = 50;
|
|
9
|
+
export const DEFAULT_TRANSPORT_SHARE = 0.5;
|
|
10
|
+
export const DEFAULT_SUSPECT_EVENTS = 3;
|
|
11
|
+
export const TOP_N = 8;
|
|
12
|
+
export const DISCORD_DESCRIPTION_LIMIT = 4096;
|
|
13
|
+
const COLOR_TRIPPED = 15548997;
|
|
14
|
+
const COLOR_QUIET = 3447003;
|
|
15
|
+
const COLOR_DARK = 16776960;
|
|
16
|
+
export const EGRESS_ALERT_ENV_VARS = [
|
|
17
|
+
"NEON_DATABASE_URL",
|
|
18
|
+
"DISCORD_WEBHOOK_URL",
|
|
19
|
+
"EGRESS_ALERT_HOST_REQUESTS",
|
|
20
|
+
"EGRESS_ALERT_HOST_VIBES",
|
|
21
|
+
"EGRESS_ALERT_VIBE_HOSTS",
|
|
22
|
+
"EGRESS_ALERT_TRANSPORT_REQUESTS",
|
|
23
|
+
"EGRESS_ALERT_TRANSPORT_SHARE",
|
|
24
|
+
"EGRESS_ALERT_SUSPECT_EVENTS",
|
|
25
|
+
];
|
|
26
|
+
function num(raw, fallback) {
|
|
27
|
+
if (raw === undefined || raw.trim() === "")
|
|
28
|
+
return fallback;
|
|
29
|
+
const parsed = Number(raw);
|
|
30
|
+
return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
|
|
31
|
+
}
|
|
32
|
+
export function resolveThresholds(env) {
|
|
33
|
+
return {
|
|
34
|
+
hostRequests: num(env.EGRESS_ALERT_HOST_REQUESTS, DEFAULT_HOST_REQUESTS),
|
|
35
|
+
hostVibes: num(env.EGRESS_ALERT_HOST_VIBES, DEFAULT_HOST_VIBES),
|
|
36
|
+
vibeHosts: num(env.EGRESS_ALERT_VIBE_HOSTS, DEFAULT_VIBE_HOSTS),
|
|
37
|
+
transportRequests: num(env.EGRESS_ALERT_TRANSPORT_REQUESTS, DEFAULT_TRANSPORT_REQUESTS),
|
|
38
|
+
transportShare: num(env.EGRESS_ALERT_TRANSPORT_SHARE, DEFAULT_TRANSPORT_SHARE),
|
|
39
|
+
suspectEvents: num(env.EGRESS_ALERT_SUSPECT_EVENTS, DEFAULT_SUSPECT_EVENTS),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
export const PG_UNDEFINED_TABLE = "42P01";
|
|
43
|
+
export function isUndefinedTableError(e) {
|
|
44
|
+
return typeof e === "object" && e !== null && e.code === PG_UNDEFINED_TABLE;
|
|
45
|
+
}
|
|
46
|
+
function vibeKey(ownerHandle, appSlug) {
|
|
47
|
+
return `${ownerHandle}/${appSlug}`;
|
|
48
|
+
}
|
|
49
|
+
export function vibeUrl(ownerHandle, appSlug) {
|
|
50
|
+
return `https://vibes.diy/vibe/${ownerHandle}/${appSlug}`;
|
|
51
|
+
}
|
|
52
|
+
function bump(m, k) {
|
|
53
|
+
m.set(k, (m.get(k) ?? 0) + 1);
|
|
54
|
+
}
|
|
55
|
+
function add(m, k, v) {
|
|
56
|
+
const s = m.get(k) ?? new Set();
|
|
57
|
+
s.add(v);
|
|
58
|
+
m.set(k, s);
|
|
59
|
+
}
|
|
60
|
+
export function summarizeEgress(events, suspects, thresholds) {
|
|
61
|
+
const perHost = new Map();
|
|
62
|
+
const perHostVibes = new Map();
|
|
63
|
+
const perHostTransportErrors = new Map();
|
|
64
|
+
const perVibe = new Map();
|
|
65
|
+
const perVibeHosts = new Map();
|
|
66
|
+
const allVibes = new Set();
|
|
67
|
+
let admitted = 0;
|
|
68
|
+
let denied = 0;
|
|
69
|
+
let transportErrors = 0;
|
|
70
|
+
for (const e of events) {
|
|
71
|
+
const reached = e.finalHost !== "" ? e.finalHost : e.host;
|
|
72
|
+
const vibe = vibeKey(e.ownerHandle, e.appSlug);
|
|
73
|
+
allVibes.add(vibe);
|
|
74
|
+
bump(perHost, reached);
|
|
75
|
+
add(perHostVibes, reached, vibe);
|
|
76
|
+
bump(perVibe, vibe);
|
|
77
|
+
add(perVibeHosts, vibe, e.host);
|
|
78
|
+
if (e.outcome === "admitted")
|
|
79
|
+
admitted += 1;
|
|
80
|
+
else if (e.outcome === "denied")
|
|
81
|
+
denied += 1;
|
|
82
|
+
else if (e.outcome === "transport-error") {
|
|
83
|
+
transportErrors += 1;
|
|
84
|
+
bump(perHostTransportErrors, reached);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const destinations = [...perHost.entries()]
|
|
88
|
+
.map(([host, requests]) => ({
|
|
89
|
+
host,
|
|
90
|
+
requests,
|
|
91
|
+
vibes: perHostVibes.get(host)?.size ?? 0,
|
|
92
|
+
transportErrors: perHostTransportErrors.get(host) ?? 0,
|
|
93
|
+
}))
|
|
94
|
+
.sort((a, b) => b.requests - a.requests || a.host.localeCompare(b.host));
|
|
95
|
+
const fanOut = [...perVibeHosts.entries()]
|
|
96
|
+
.map(([vibe, hosts]) => {
|
|
97
|
+
const [ownerHandle = "", appSlug = ""] = vibe.split("/");
|
|
98
|
+
return { ownerHandle, appSlug, requestedHosts: hosts.size, requests: perVibe.get(vibe) ?? 0 };
|
|
99
|
+
})
|
|
100
|
+
.sort((a, b) => b.requestedHosts - a.requestedHosts || b.requests - a.requests);
|
|
101
|
+
const transportErrorHosts = destinations
|
|
102
|
+
.filter((d) => d.transportErrors > 0)
|
|
103
|
+
.map((d) => ({ host: d.host, transportErrors: d.transportErrors, requests: d.requests, share: d.transportErrors / d.requests }))
|
|
104
|
+
.sort((a, b) => b.transportErrors - a.transportErrors || a.host.localeCompare(b.host));
|
|
105
|
+
const suspectHosts = new Map();
|
|
106
|
+
const suspectVibes = new Map();
|
|
107
|
+
const suspectReasons = new Map();
|
|
108
|
+
for (const s of suspects) {
|
|
109
|
+
bump(suspectHosts, s.host);
|
|
110
|
+
add(suspectVibes, s.host, vibeKey(s.ownerHandle, s.appSlug));
|
|
111
|
+
for (const r of s.reasons.split(",").map((t) => t.trim())) {
|
|
112
|
+
if (r !== "")
|
|
113
|
+
add(suspectReasons, s.host, r);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
const suspectGroups = [...suspectHosts.entries()]
|
|
117
|
+
.map(([host, events2]) => ({
|
|
118
|
+
host,
|
|
119
|
+
events: events2,
|
|
120
|
+
vibes: suspectVibes.get(host)?.size ?? 0,
|
|
121
|
+
reasons: [...(suspectReasons.get(host) ?? new Set())].sort(),
|
|
122
|
+
}))
|
|
123
|
+
.sort((a, b) => b.events - a.events || a.host.localeCompare(b.host));
|
|
124
|
+
const tripped = [];
|
|
125
|
+
for (const d of destinations) {
|
|
126
|
+
if (d.requests >= thresholds.hostRequests || d.vibes >= thresholds.hostVibes) {
|
|
127
|
+
tripped.push(`Destination concentration — ${sanitizeForDiscord(d.host)} took ${d.requests} request${d.requests === 1 ? "" : "s"} from ${d.vibes} vibe${d.vibes === 1 ? "" : "s"}.`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
for (const f of fanOut) {
|
|
131
|
+
if (f.requestedHosts >= thresholds.vibeHosts) {
|
|
132
|
+
tripped.push(`Fan-out — ${sanitizeForDiscord(vibeKey(f.ownerHandle, f.appSlug))} asked for ${f.requestedHosts} distinct hosts in ${f.requests} request${f.requests === 1 ? "" : "s"}.`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
for (const t of transportErrorHosts) {
|
|
136
|
+
if (t.requests >= thresholds.transportRequests && t.share >= thresholds.transportShare) {
|
|
137
|
+
tripped.push(`Transport errors — ${Math.round(t.share * 100)}% of ${t.requests} requests to ${sanitizeForDiscord(t.host)} failed in transport.`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
for (const s of suspectGroups) {
|
|
141
|
+
if (s.events >= thresholds.suspectEvents) {
|
|
142
|
+
tripped.push(`Suspect responses — ${sanitizeForDiscord(s.host)} returned ${s.reasons.join("/")} to ${s.vibes} vibe${s.vibes === 1 ? "" : "s"} (${s.events} flagged).`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
requests: events.length,
|
|
147
|
+
admitted,
|
|
148
|
+
denied,
|
|
149
|
+
transportErrors,
|
|
150
|
+
distinctHosts: perHost.size,
|
|
151
|
+
distinctVibes: allVibes.size,
|
|
152
|
+
suspectEvents: suspects.length,
|
|
153
|
+
destinations,
|
|
154
|
+
fanOut,
|
|
155
|
+
transportErrorHosts,
|
|
156
|
+
suspects: suspectGroups,
|
|
157
|
+
tripped,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function truncate(description) {
|
|
161
|
+
if (description.length <= DISCORD_DESCRIPTION_LIMIT)
|
|
162
|
+
return description;
|
|
163
|
+
const ellipsis = "\n…(truncated)";
|
|
164
|
+
return `${description.slice(0, DISCORD_DESCRIPTION_LIMIT - ellipsis.length)}${ellipsis}`;
|
|
165
|
+
}
|
|
166
|
+
function section(title, lines) {
|
|
167
|
+
return lines.length === 0 ? undefined : `**${title}**\n${lines.join("\n")}`;
|
|
168
|
+
}
|
|
169
|
+
export function buildMissingTablesEmbed(sinceHours) {
|
|
170
|
+
return {
|
|
171
|
+
content: `⚠️ Backend egress: the signal tables are missing`,
|
|
172
|
+
allowed_mentions: { parse: [] },
|
|
173
|
+
embeds: [
|
|
174
|
+
{
|
|
175
|
+
title: `Backend egress (last ${sinceHours}h)`,
|
|
176
|
+
description: [
|
|
177
|
+
`\`EgressEvents\` / \`EgressSuspectEvents\` do not exist in this database, so nothing could be read.`,
|
|
178
|
+
``,
|
|
179
|
+
`Two readings, and this job cannot tell them apart:`,
|
|
180
|
+
`• **Expected** — the lane is merged but not deployed yet. The tables arrive with the next \`vibes-diy@p*\`; nothing to do but ship.`,
|
|
181
|
+
`• **A fault** — the tables were dropped, the deploy's schema push did not run, or this job is pointed at the wrong database. The egress abuse signals are unwatched until it is fixed.`,
|
|
182
|
+
].join("\n"),
|
|
183
|
+
color: COLOR_DARK,
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
export function buildEgressAlertEmbed(input) {
|
|
189
|
+
const { summary: s, sinceHours } = input;
|
|
190
|
+
if (s.requests === 0) {
|
|
191
|
+
return {
|
|
192
|
+
content: `🕳️ Backend egress: the telemetry chain reported nothing in ${sinceHours}h`,
|
|
193
|
+
allowed_mentions: { parse: [] },
|
|
194
|
+
embeds: [
|
|
195
|
+
{
|
|
196
|
+
title: `Backend egress (last ${sinceHours}h)`,
|
|
197
|
+
description: [
|
|
198
|
+
`No EgressEvents rows at all in the window.`,
|
|
199
|
+
``,
|
|
200
|
+
`That is either a genuinely quiet window or a dead pipeline, and the database cannot tell them apart — the rows arrive over BackendDO console → Workers Trace Events Logpush → R2 → logpush-etl → Neon, and that transport has never been confirmed against a real R2 object. If backends did make outbound calls in this window, check the R2 objects before touching the reader.`,
|
|
201
|
+
].join("\n"),
|
|
202
|
+
color: COLOR_DARK,
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
const destinations = s.destinations
|
|
208
|
+
.slice(0, TOP_N)
|
|
209
|
+
.map((d) => ` ${sanitizeForDiscord(d.host)} — ${d.requests} req / ${d.vibes} vibe${d.vibes === 1 ? "" : "s"}`);
|
|
210
|
+
const fanOut = s.fanOut
|
|
211
|
+
.slice(0, TOP_N)
|
|
212
|
+
.map((f) => ` ${vibeUrl(f.ownerHandle, f.appSlug)} — ${f.requestedHosts} host${f.requestedHosts === 1 ? "" : "s"} / ${f.requests} req`);
|
|
213
|
+
const transport = s.transportErrorHosts
|
|
214
|
+
.slice(0, TOP_N)
|
|
215
|
+
.map((t) => ` ${sanitizeForDiscord(t.host)} — ${t.transportErrors} of ${t.requests} (${Math.round(t.share * 100)}%)`);
|
|
216
|
+
const suspects = s.suspects
|
|
217
|
+
.slice(0, TOP_N)
|
|
218
|
+
.map((g) => ` ${sanitizeForDiscord(g.host)} — ${g.events} flagged / ${g.vibes} vibe${g.vibes === 1 ? "" : "s"} · ${g.reasons.join(", ")}`);
|
|
219
|
+
const denominator = `${s.requests} request${s.requests === 1 ? "" : "s"} across ${s.distinctHosts} host${s.distinctHosts === 1 ? "" : "s"} from ${s.distinctVibes} vibe${s.distinctVibes === 1 ? "" : "s"} — ${s.admitted} admitted, ${s.denied} denied, ${s.transportErrors} transport errors.`;
|
|
220
|
+
const lead = s.tripped.length > 0 ? s.tripped.map((t) => `⚠️ ${t}`).join("\n") : `Nothing tripped a threshold. ${denominator}`;
|
|
221
|
+
const capNote = input.sampled
|
|
222
|
+
? `\n\n_Read hit its row cap: these are the most recent events in the window, not all of them. Every count here is a floor._`
|
|
223
|
+
: "";
|
|
224
|
+
const blocks = [
|
|
225
|
+
s.tripped.length > 0 ? `${lead}\n\n${denominator}` : lead,
|
|
226
|
+
section("Top destinations (victim view)", destinations),
|
|
227
|
+
section("Fan-out — distinct hosts requested per vibe", fanOut),
|
|
228
|
+
section("Transport-error concentration", transport),
|
|
229
|
+
section(`Suspect responses (${s.suspectEvents} flagged)`, suspects),
|
|
230
|
+
`_Thresholds are provisional placeholders, to be recalibrated from measured traffic. This pass proposes; it never blocks a vibe or cools a host._`,
|
|
231
|
+
].filter((b) => b !== undefined);
|
|
232
|
+
return {
|
|
233
|
+
content: s.tripped.length > 0
|
|
234
|
+
? `🚨 Backend egress: ${s.tripped.length} signal${s.tripped.length === 1 ? "" : "s"} in the last ${sinceHours}h`
|
|
235
|
+
: `🛰️ Backend egress: ${s.requests} request${s.requests === 1 ? "" : "s"} in the last ${sinceHours}h`,
|
|
236
|
+
allowed_mentions: { parse: [] },
|
|
237
|
+
embeds: [
|
|
238
|
+
{
|
|
239
|
+
title: `Backend egress (last ${sinceHours}h)`,
|
|
240
|
+
description: truncate(blocks.join("\n\n") + capNote),
|
|
241
|
+
color: s.tripped.length > 0 ? COLOR_TRIPPED : COLOR_QUIET,
|
|
242
|
+
},
|
|
243
|
+
],
|
|
244
|
+
};
|
|
245
|
+
}
|
|
246
|
+
//# sourceMappingURL=egress-abuse-alert-util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"egress-abuse-alert-util.js","sourceRoot":"","sources":["../../jsr/usage-report/egress-abuse-alert-util.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|