@vibes.diy/api-svc 13.0.7 → 13.0.9

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.
Files changed (68) hide show
  1. package/index.d.ts +2 -0
  2. package/index.js +2 -0
  3. package/index.js.map +1 -1
  4. package/intern/attempt-backend-fetch.d.ts +4 -0
  5. package/intern/attempt-backend-fetch.js +10 -0
  6. package/intern/attempt-backend-fetch.js.map +1 -1
  7. package/intern/attempt-backend-onchange.d.ts +4 -0
  8. package/intern/attempt-backend-onchange.js +12 -2
  9. package/intern/attempt-backend-onchange.js.map +1 -1
  10. package/intern/attempt-backend-scheduled.d.ts +4 -0
  11. package/intern/attempt-backend-scheduled.js +10 -0
  12. package/intern/attempt-backend-scheduled.js.map +1 -1
  13. package/intern/backend-do-addr.d.ts +5 -0
  14. package/intern/backend-do-addr.js +7 -0
  15. package/intern/backend-do-addr.js.map +1 -1
  16. package/intern/backend-github-callback.d.ts +11 -0
  17. package/intern/backend-github-callback.js +141 -0
  18. package/intern/backend-github-callback.js.map +1 -0
  19. package/intern/backend-github-op.d.ts +1 -0
  20. package/intern/backend-github-op.js +2 -0
  21. package/intern/backend-github-op.js.map +1 -0
  22. package/intern/backend-policy-version.d.ts +1 -1
  23. package/intern/backend-policy-version.js +1 -1
  24. package/intern/egress-platform-list.js +2 -0
  25. package/intern/egress-platform-list.js.map +1 -1
  26. package/intern/github-app-auth.d.ts +40 -0
  27. package/intern/github-app-auth.js +214 -0
  28. package/intern/github-app-auth.js.map +1 -0
  29. package/intern/write-apps.js +2 -2
  30. package/intern/write-apps.js.map +1 -1
  31. package/package.json +12 -11
  32. package/public/app-documents-head-query.d.ts +17 -0
  33. package/public/app-documents-head-query.js +38 -1
  34. package/public/app-documents-head-query.js.map +1 -1
  35. package/public/app-documents-read-eventos.js +7 -2
  36. package/public/app-documents-read-eventos.js.map +1 -1
  37. package/public/convert-image-evt.js +1 -1
  38. package/public/convert-image-evt.js.map +1 -1
  39. package/public/dm-lane.d.ts +0 -1
  40. package/public/dm-lane.js +0 -1
  41. package/public/dm-lane.js.map +1 -1
  42. package/public/dm-read-eventos.d.ts +3 -0
  43. package/public/dm-read-eventos.js +15 -6
  44. package/public/dm-read-eventos.js.map +1 -1
  45. package/public/dm-sync-eventos.js +2 -2
  46. package/public/dm-sync-eventos.js.map +1 -1
  47. package/public/dm-write-eventos.js +2 -13
  48. package/public/dm-write-eventos.js.map +1 -1
  49. package/public/email-unsubscribe.js +6 -2
  50. package/public/email-unsubscribe.js.map +1 -1
  51. package/public/ensure-user-settings.js +4 -2
  52. package/public/ensure-user-settings.js.map +1 -1
  53. package/public/github-setup.d.ts +26 -0
  54. package/public/github-setup.js +339 -0
  55. package/public/github-setup.js.map +1 -0
  56. package/public/github-webhook.d.ts +29 -0
  57. package/public/github-webhook.js +150 -0
  58. package/public/github-webhook.js.map +1 -0
  59. package/public/prompt-chat-section.js +4 -3
  60. package/public/prompt-chat-section.js.map +1 -1
  61. package/usage-report/backfill-geo-country.d.ts +1 -0
  62. package/usage-report/backfill-geo-country.js +168 -0
  63. package/usage-report/backfill-geo-country.js.map +1 -0
  64. package/usage-report/backfill-release-tailwind-util.js +2 -11
  65. package/usage-report/backfill-release-tailwind-util.js.map +1 -1
  66. package/usage-report/geo-country-normalize.d.ts +1 -0
  67. package/usage-report/geo-country-normalize.js +135 -0
  68. package/usage-report/geo-country-normalize.js.map +1 -0
@@ -0,0 +1,339 @@
1
+ import { exception2Result, BuildURI, TxtEnDecoderSingleton, URI } from "@adviser/cement";
2
+ import { cfDrizzle, createVibesApiTables, toDBFlavour } from "@vibes.diy/api-sql";
3
+ import { and, eq, ne, or } from "drizzle-orm/sql/expressions";
4
+ import { getInstallationToken, listUserInstallationRepos, nextGithubPageUrl } from "../intern/github-app-auth.js";
5
+ import { timingSafeEqualString } from "./github-webhook.js";
6
+ export const GITHUB_SETUP_STATE_RE = /^[a-z0-9][a-z0-9-]*\/[a-z0-9][a-z0-9-]*$/;
7
+ function htmlPage(title, body, status) {
8
+ return new Response(`<!doctype html><html><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>${title}</title></head>` +
9
+ `<body style="font-family: system-ui, sans-serif; max-width: 32rem; margin: 4rem auto; padding: 0 1rem;"><h1 style="font-size:1.4rem">${title}</h1><p>${body}</p></body></html>`, { status, headers: { "Content-Type": "text/html; charset=utf-8" } });
10
+ }
11
+ function sessionTokenFrom(request) {
12
+ const authorization = request.headers.get("authorization") ?? request.headers.get("Authorization");
13
+ if (authorization !== null && /^Bearer\s+/i.test(authorization)) {
14
+ const bearer = authorization.replace(/^Bearer\s+/i, "").trim();
15
+ if (bearer !== "")
16
+ return bearer;
17
+ }
18
+ const cookie = request.headers.get("cookie") ?? request.headers.get("Cookie") ?? "";
19
+ const match = /(?:^|;\s*)__session=([^;]+)/.exec(cookie);
20
+ if (match === null)
21
+ return undefined;
22
+ const r = exception2Result(() => decodeURIComponent(match[1]));
23
+ return r.isErr() ? undefined : r.Ok();
24
+ }
25
+ export const GITHUB_SETUP_OAUTH_STATE_TTL_MS = 10 * 60 * 1000;
26
+ const GITHUB_OAUTH_AUTHORIZE_URL = "https://github.com/login/oauth/authorize";
27
+ const GITHUB_OAUTH_TOKEN_URL = "https://github.com/login/oauth/access_token";
28
+ const GITHUB_USER_INSTALLATIONS_URL = "https://api.github.com/user/installations?per_page=100";
29
+ const GITHUB_USER_INSTALLATIONS_PATH = "/user/installations";
30
+ const USER_AGENT = "vibes.diy-github-app";
31
+ const MAX_INSTALLATION_PAGES = 20;
32
+ export const GITHUB_SETUP_MAX_REPOS = 200;
33
+ function stateSecret(env) {
34
+ const preferred = env.VIBES_GH_APP_STATE_SECRET ?? "";
35
+ const secret = preferred.length === 0 ? (env.VIBES_GH_APP_WEBHOOK_SECRET ?? "") : preferred;
36
+ return secret.length === 0 ? undefined : secret;
37
+ }
38
+ function b64urlEncode(bytes) {
39
+ let bin = "";
40
+ for (const b of bytes)
41
+ bin += String.fromCharCode(b);
42
+ return btoa(bin).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
43
+ }
44
+ function b64urlDecode(text) {
45
+ const r = exception2Result(() => {
46
+ const padded = text.replace(/-/g, "+").replace(/_/g, "/") + "===".slice((text.length + 3) % 4);
47
+ const bin = atob(padded);
48
+ const bytes = new Uint8Array(bin.length);
49
+ for (let i = 0; i < bin.length; i = i + 1)
50
+ bytes[i] = bin.charCodeAt(i);
51
+ return TxtEnDecoderSingleton().decode(bytes);
52
+ });
53
+ return r.isErr() ? undefined : r.Ok();
54
+ }
55
+ function toHex(bytes) {
56
+ return Array.from(new Uint8Array(bytes))
57
+ .map((b) => b.toString(16).padStart(2, "0"))
58
+ .join("");
59
+ }
60
+ async function hmacHex(secret, message) {
61
+ const key = await crypto.subtle.importKey("raw", TxtEnDecoderSingleton().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
62
+ return toHex(await crypto.subtle.sign("HMAC", key, TxtEnDecoderSingleton().encode(message)));
63
+ }
64
+ export async function signGithubSetupState(secret, state) {
65
+ const blob = b64urlEncode(TxtEnDecoderSingleton().encode(JSON.stringify(state)));
66
+ return `${blob}.${await hmacHex(secret, blob)}`;
67
+ }
68
+ export async function verifyGithubSetupState(secret, signed, nowMs) {
69
+ const dot = signed.lastIndexOf(".");
70
+ if (dot <= 0)
71
+ return undefined;
72
+ const blob = signed.slice(0, dot);
73
+ const provided = signed.slice(dot + 1);
74
+ const expected = await hmacHex(secret, blob);
75
+ if (!timingSafeEqualString(provided, expected))
76
+ return undefined;
77
+ const json = b64urlDecode(blob);
78
+ if (json === undefined)
79
+ return undefined;
80
+ const rParsed = exception2Result(() => JSON.parse(json));
81
+ if (rParsed.isErr())
82
+ return undefined;
83
+ const parsed = rParsed.Ok();
84
+ if (typeof parsed.owner !== "string" || typeof parsed.slug !== "string")
85
+ return undefined;
86
+ if (typeof parsed.installationId !== "string" || parsed.installationId === "")
87
+ return undefined;
88
+ if (typeof parsed.exp !== "number" || nowMs >= parsed.exp)
89
+ return undefined;
90
+ if (!GITHUB_SETUP_STATE_RE.test(`${parsed.owner}/${parsed.slug}`))
91
+ return undefined;
92
+ return { owner: parsed.owner, slug: parsed.slug, installationId: parsed.installationId, exp: parsed.exp };
93
+ }
94
+ async function exchangeOAuthCode(input) {
95
+ const rRes = await exception2Result(() => input.fetchImpl(GITHUB_OAUTH_TOKEN_URL, {
96
+ method: "POST",
97
+ headers: { accept: "application/json", "content-type": "application/json", "user-agent": USER_AGENT },
98
+ body: JSON.stringify({ client_id: input.clientId, client_secret: input.clientSecret, code: input.code }),
99
+ }));
100
+ if (rRes.isErr()) {
101
+ console.error("[github-setup] oauth token request never reached GitHub:", rRes.Err().message);
102
+ return undefined;
103
+ }
104
+ const res = rRes.Ok();
105
+ if (res.ok === false) {
106
+ console.error(`[github-setup] oauth token request refused with HTTP ${res.status}`);
107
+ return undefined;
108
+ }
109
+ const rBody = await exception2Result(() => res.json());
110
+ if (rBody.isErr()) {
111
+ console.error("[github-setup] oauth token response was not JSON:", rBody.Err().message);
112
+ return undefined;
113
+ }
114
+ const body = rBody.Ok();
115
+ if (typeof body.access_token === "string" && body.access_token !== "")
116
+ return body.access_token;
117
+ console.error(`[github-setup] oauth token refused by GitHub: ${body.error ?? "(no error field)"} — ${body.error_description ?? ""}`);
118
+ return undefined;
119
+ }
120
+ async function userInstallationIds(input) {
121
+ const ids = [];
122
+ let url = GITHUB_USER_INSTALLATIONS_URL;
123
+ for (let page = 0; page < MAX_INSTALLATION_PAGES && url !== undefined; page = page + 1) {
124
+ const pageUrl = url;
125
+ const rRes = await exception2Result(() => input.fetchImpl(pageUrl, {
126
+ method: "GET",
127
+ headers: {
128
+ authorization: `Bearer ${input.userToken}`,
129
+ accept: "application/vnd.github+json",
130
+ "user-agent": USER_AGENT,
131
+ },
132
+ }));
133
+ if (rRes.isErr())
134
+ return undefined;
135
+ const res = rRes.Ok();
136
+ if (res.ok === false)
137
+ return undefined;
138
+ const rBody = await exception2Result(() => res.json());
139
+ if (rBody.isErr())
140
+ return undefined;
141
+ for (const inst of rBody.Ok().installations ?? []) {
142
+ if (inst.id !== undefined)
143
+ ids.push(String(inst.id));
144
+ }
145
+ const rNext = nextGithubPageUrl(res.headers.get("link"), GITHUB_USER_INSTALLATIONS_PATH);
146
+ if (rNext.isErr()) {
147
+ console.error(`[github-setup] ${rNext.Err().message}`);
148
+ return undefined;
149
+ }
150
+ url = rNext.Ok();
151
+ }
152
+ return ids;
153
+ }
154
+ function sqlFor(env, deps) {
155
+ return (deps.sql ??
156
+ {
157
+ db: cfDrizzle(env, env.DB).db,
158
+ tables: createVibesApiTables(toDBFlavour(env.DB_FLAVOUR)),
159
+ });
160
+ }
161
+ async function ownsHandle(sql, userId, ownerHandle) {
162
+ const t_hb = sql.tables.handleBinding;
163
+ const row = await sql.db
164
+ .select({ handle: t_hb.handle })
165
+ .from(t_hb)
166
+ .where(and(eq(t_hb.handle, ownerHandle), eq(t_hb.userId, userId)))
167
+ .limit(1)
168
+ .then((rows) => rows[0]);
169
+ return row !== undefined;
170
+ }
171
+ async function appExists(sql, ownerHandle, appSlug) {
172
+ const t_apps = sql.tables.apps;
173
+ const row = await sql.db
174
+ .select({ appSlug: t_apps.appSlug })
175
+ .from(t_apps)
176
+ .where(and(eq(t_apps.ownerHandle, ownerHandle), eq(t_apps.appSlug, appSlug)))
177
+ .limit(1)
178
+ .then((rows) => rows[0]);
179
+ return row !== undefined;
180
+ }
181
+ export async function handleGithubSetup(request, env, deps) {
182
+ const appId = env.VIBES_GH_APP_ID ?? "";
183
+ const privateKeyPem = env.VIBES_GH_APP_PRIVATE_KEY ?? "";
184
+ if (appId.length === 0 || privateKeyPem.length === 0) {
185
+ return htmlPage("Not available", "The GitHub connection is not configured on this environment.", 503);
186
+ }
187
+ const token = sessionTokenFrom(request);
188
+ const userId = token === undefined ? undefined : await deps.verifySessionToken(token);
189
+ if (userId === undefined) {
190
+ return htmlPage("Sign in required", "Sign in to vibes.diy and re-run the install from your vibe's settings.", 401);
191
+ }
192
+ const uri = URI.from(request.url);
193
+ const code = uri.getParam("code") ?? "";
194
+ const nowMs = deps.nowMs ?? Date.now();
195
+ const fetchImpl = deps.fetchImpl ?? fetch.bind(globalThis);
196
+ return code === ""
197
+ ? phaseOneStartOAuth({ env, deps, uri, userId, nowMs })
198
+ : phaseTwoBind({ env, deps, uri, userId, nowMs, fetchImpl, code });
199
+ }
200
+ async function phaseOneStartOAuth(input) {
201
+ const { env, deps, uri, userId, nowMs } = input;
202
+ const installationId = uri.getParam("installation_id") ?? "";
203
+ const state = uri.getParam("state") ?? "";
204
+ if (installationId === "" || !GITHUB_SETUP_STATE_RE.test(state)) {
205
+ return htmlPage("Invalid link", "This install link is malformed. Start the connection again from your vibe's settings.", 400);
206
+ }
207
+ const [ownerHandle] = state.split("/");
208
+ if (!(await ownsHandle(sqlFor(env, deps), userId, ownerHandle))) {
209
+ return htmlPage("Not your vibe", "You can only connect a repository to a vibe you own.", 403);
210
+ }
211
+ const signingKey = stateSecret(env);
212
+ const clientId = env.VIBES_GH_APP_CLIENT_ID ?? "";
213
+ const clientSecret = env.VIBES_GH_APP_CLIENT_SECRET ?? "";
214
+ if (clientId.length === 0 || clientSecret.length === 0 || signingKey === undefined) {
215
+ return htmlPage("Not available", "The GitHub connection is not fully provisioned on this environment: connecting a repository needs a GitHub " +
216
+ "authorization step that is not configured yet, so nothing has been connected.", 503);
217
+ }
218
+ const [owner, slug] = state.split("/");
219
+ const signed = await signGithubSetupState(signingKey, {
220
+ owner,
221
+ slug,
222
+ installationId,
223
+ exp: nowMs + GITHUB_SETUP_OAUTH_STATE_TTL_MS,
224
+ });
225
+ const redirectUri = uri.build().cleanParams().hash("").toString();
226
+ const authorize = BuildURI.from(GITHUB_OAUTH_AUTHORIZE_URL)
227
+ .setParam("client_id", clientId)
228
+ .setParam("redirect_uri", redirectUri)
229
+ .setParam("state", signed)
230
+ .toString();
231
+ return new Response(null, { status: 302, headers: { Location: authorize } });
232
+ }
233
+ async function phaseTwoBind(input) {
234
+ const { env, deps, uri, userId, nowMs, fetchImpl, code } = input;
235
+ const signingKey = stateSecret(env);
236
+ const clientId = env.VIBES_GH_APP_CLIENT_ID ?? "";
237
+ const clientSecret = env.VIBES_GH_APP_CLIENT_SECRET ?? "";
238
+ if (clientId.length === 0 || clientSecret.length === 0 || signingKey === undefined) {
239
+ return htmlPage("Not available", "The GitHub connection is not fully provisioned on this environment: connecting a repository needs a GitHub " +
240
+ "authorization step that is not configured yet, so nothing has been connected.", 503);
241
+ }
242
+ const verified = await verifyGithubSetupState(signingKey, uri.getParam("state") ?? "", nowMs);
243
+ if (verified === undefined) {
244
+ return htmlPage("Link expired", "That authorization link is no longer valid. Start the connection again from your vibe's settings.", 400);
245
+ }
246
+ const { owner: ownerHandle, slug: appSlug, installationId } = verified;
247
+ const userToken = await exchangeOAuthCode({
248
+ clientId,
249
+ clientSecret,
250
+ code,
251
+ fetchImpl,
252
+ });
253
+ if (userToken === undefined) {
254
+ return htmlPage("GitHub said no", "We could not confirm your GitHub account. Try the install again.", 502);
255
+ }
256
+ const installations = await userInstallationIds({ userToken, fetchImpl });
257
+ if (installations === undefined) {
258
+ return htmlPage("GitHub said no", "We could not read your GitHub installations. Try the install again.", 502);
259
+ }
260
+ if (!installations.includes(installationId)) {
261
+ console.error(`[github-setup] installation ${installationId} not held by clerk user ${userId} — refusing to bind`);
262
+ return htmlPage("Not your installation", "That GitHub installation is not one your GitHub account can access.", 403);
263
+ }
264
+ const sql = sqlFor(env, deps);
265
+ if (!(await ownsHandle(sql, userId, ownerHandle))) {
266
+ return htmlPage("Not your vibe", "You can only connect a repository to a vibe you own.", 403);
267
+ }
268
+ if (!(await appExists(sql, ownerHandle, appSlug))) {
269
+ return htmlPage("Vibe not found", "That vibe does not exist. Publish it first, then connect the repository.", 404);
270
+ }
271
+ const rToken = await getInstallationToken({
272
+ installationId,
273
+ appId: env.VIBES_GH_APP_ID,
274
+ privateKeyPem: env.VIBES_GH_APP_PRIVATE_KEY,
275
+ nowMs,
276
+ fetchImpl: deps.fetchImpl,
277
+ });
278
+ if (rToken.isErr()) {
279
+ console.error("[github-setup] installation token failed:", rToken.Err().message);
280
+ return htmlPage("GitHub said no", "We could not read that installation from GitHub. Try the install again.", 502);
281
+ }
282
+ const rRepos = await listUserInstallationRepos({ installationId, userToken, fetchImpl: deps.fetchImpl });
283
+ if (rRepos.isErr()) {
284
+ console.error("[github-setup] repository listing failed:", rRepos.Err().message);
285
+ return htmlPage("GitHub said no", "We could not list that installation's repositories. Try the install again.", 502);
286
+ }
287
+ const repos = rRepos.Ok();
288
+ if (repos.length === 0) {
289
+ return htmlPage("No repositories", "That installation has no repositories your GitHub account can access, so nothing has been connected. Ask an " +
290
+ "organization owner to grant you access, or install the app on a repository you own.", 403);
291
+ }
292
+ if (repos.length > GITHUB_SETUP_MAX_REPOS) {
293
+ return htmlPage("Too many repositories", `That installation covers ${repos.length} repositories, more than the ${GITHUB_SETUP_MAX_REPOS} a single connection ` +
294
+ "can bind, so nothing has been connected. In GitHub, change the app's repository access to select fewer " +
295
+ "repositories and run the connection again.", 400);
296
+ }
297
+ const t = sql.tables.githubRepoRoutes;
298
+ const heldBy = new Map();
299
+ for (const row of await sql.db
300
+ .select({ repoFullName: t.repoFullName, installedByUserId: t.installedByUserId })
301
+ .from(t)
302
+ .where(and(eq(t.installationId, installationId), eq(t.removedAt, "")))) {
303
+ heldBy.set(row.repoFullName, row.installedByUserId);
304
+ }
305
+ const now = new Date().toISOString();
306
+ const bound = [];
307
+ for (const repo of repos) {
308
+ const applied = await sql.db
309
+ .insert(t)
310
+ .values({
311
+ installationId,
312
+ repoFullName: repo.fullName,
313
+ ownerHandle,
314
+ appSlug,
315
+ accountLogin: repo.accountLogin,
316
+ installedByUserId: userId,
317
+ created: now,
318
+ updated: now,
319
+ removedAt: "",
320
+ })
321
+ .onConflictDoUpdate({
322
+ target: [t.installationId, t.repoFullName],
323
+ set: { ownerHandle, appSlug, installedByUserId: userId, updated: now, removedAt: "" },
324
+ setWhere: or(eq(t.installedByUserId, userId), ne(t.removedAt, "")),
325
+ })
326
+ .returning({ repoFullName: t.repoFullName });
327
+ if (applied.length === 0) {
328
+ console.warn(`[github-setup] installation ${installationId} repo ${repo.fullName} is already connected by clerk user ` +
329
+ `${heldBy.get(repo.fullName) ?? "unknown"}; refusing to rebind it for clerk user ${userId}`);
330
+ continue;
331
+ }
332
+ bound.push(repo.fullName);
333
+ }
334
+ if (bound.length === 0) {
335
+ return htmlPage("Already connected", "Those repositories are already connected to another vibe. Whoever connected them has to disconnect them first.", 409);
336
+ }
337
+ return new Response(null, { status: 302, headers: { Location: `/vibe/${ownerHandle}/${appSlug}` } });
338
+ }
339
+ //# sourceMappingURL=github-setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-setup.js","sourceRoot":"","sources":["../../jsr/public/github-setup.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { CFEnv } from "@vibes.diy/api-types";
2
+ import { cfDrizzle, VibesApiTables } from "@vibes.diy/api-sql";
3
+ export interface GithubWebhookSql {
4
+ db: ReturnType<typeof cfDrizzle>["db"];
5
+ tables: VibesApiTables;
6
+ }
7
+ export declare const GITHUB_EVENT_HEADER = "x-github-event";
8
+ export declare const GITHUB_DELIVERY_HEADER = "x-github-delivery";
9
+ export declare const GITHUB_SIGNATURE_HEADER = "x-hub-signature-256";
10
+ export declare const VIBES_GITHUB_EVENT_HEADER = "x-vibes-github-event";
11
+ export declare const VIBES_GITHUB_DELIVERY_HEADER = "x-vibes-github-delivery";
12
+ export declare const VIBES_GITHUB_INSTALLATION_HEADER = "x-vibes-github-installation";
13
+ export declare const VIBES_GITHUB_SIGNATURE_HEADER = "x-vibes-signature-256";
14
+ export declare const VIBES_CONTENT_HEADER = "x-vibes-content";
15
+ export declare const VIBES_CONTENT_UNTRUSTED = "untrusted-external";
16
+ export declare const VIBES_TIMESTAMP_HEADER = "x-vibes-timestamp";
17
+ export declare function timingSafeEqualString(a: string, b: string): boolean;
18
+ export declare function githubSignatureFor(secret: string, rawBody: string): Promise<string>;
19
+ export declare function vibeProvenanceSignature(input: {
20
+ secret: string;
21
+ ownerHandle: string;
22
+ appSlug: string;
23
+ event: string;
24
+ deliveryId: string;
25
+ installationId: string;
26
+ timestampMs: string;
27
+ rawBody: string;
28
+ }): Promise<string>;
29
+ export declare function handleGithubWebhook(request: Request, env: CFEnv, sqlOverride?: GithubWebhookSql): Promise<Response>;
@@ -0,0 +1,150 @@
1
+ import { exception2Result, TxtEnDecoderSingleton } from "@adviser/cement";
2
+ import { cfDrizzle, createVibesApiTables, toDBFlavour } from "@vibes.diy/api-sql";
3
+ import { and, eq, inArray } from "drizzle-orm/sql/expressions";
4
+ import { BACKEND_INTERNAL_AUTH_HEADER, backendDoName, sanitizeBackendApiForwardHeaders } from "../intern/backend-do-addr.js";
5
+ export const GITHUB_EVENT_HEADER = "x-github-event";
6
+ export const GITHUB_DELIVERY_HEADER = "x-github-delivery";
7
+ export const GITHUB_SIGNATURE_HEADER = "x-hub-signature-256";
8
+ export const VIBES_GITHUB_EVENT_HEADER = "x-vibes-github-event";
9
+ export const VIBES_GITHUB_DELIVERY_HEADER = "x-vibes-github-delivery";
10
+ export const VIBES_GITHUB_INSTALLATION_HEADER = "x-vibes-github-installation";
11
+ export const VIBES_GITHUB_SIGNATURE_HEADER = "x-vibes-signature-256";
12
+ export const VIBES_CONTENT_HEADER = "x-vibes-content";
13
+ export const VIBES_CONTENT_UNTRUSTED = "untrusted-external";
14
+ export const VIBES_TIMESTAMP_HEADER = "x-vibes-timestamp";
15
+ function jsonResponse(body, status) {
16
+ return new Response(JSON.stringify(body), { status, headers: { "Content-Type": "application/json" } });
17
+ }
18
+ function toHex(bytes) {
19
+ return Array.from(new Uint8Array(bytes))
20
+ .map((b) => b.toString(16).padStart(2, "0"))
21
+ .join("");
22
+ }
23
+ async function hmacSha256(key, message) {
24
+ const raw = key instanceof Uint8Array ? key.slice().buffer : key;
25
+ const cryptoKey = await crypto.subtle.importKey("raw", raw, { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
26
+ return crypto.subtle.sign("HMAC", cryptoKey, TxtEnDecoderSingleton().encode(message));
27
+ }
28
+ export function timingSafeEqualString(a, b) {
29
+ if (a.length !== b.length)
30
+ return false;
31
+ let diff = 0;
32
+ for (let i = 0; i < a.length; i = i + 1) {
33
+ diff = diff | (a.charCodeAt(i) ^ b.charCodeAt(i));
34
+ }
35
+ return diff === 0;
36
+ }
37
+ export async function githubSignatureFor(secret, rawBody) {
38
+ return `sha256=${toHex(await hmacSha256(TxtEnDecoderSingleton().encode(secret), rawBody))}`;
39
+ }
40
+ export async function vibeProvenanceSignature(input) {
41
+ const perVibeKey = await hmacSha256(TxtEnDecoderSingleton().encode(input.secret), `${input.ownerHandle}/${input.appSlug}`);
42
+ const signingString = ["v1", input.event, input.deliveryId, input.installationId, input.timestampMs, input.rawBody].join("\n");
43
+ return `sha256=${toHex(await hmacSha256(perVibeKey, signingString))}`;
44
+ }
45
+ export async function handleGithubWebhook(request, env, sqlOverride) {
46
+ const secret = env.VIBES_GH_APP_WEBHOOK_SECRET ?? "";
47
+ if (secret.length === 0) {
48
+ return jsonResponse({ type: "error", message: "not configured" }, 503);
49
+ }
50
+ const rawBody = await request.text();
51
+ const provided = request.headers.get(GITHUB_SIGNATURE_HEADER);
52
+ const expected = await githubSignatureFor(secret, rawBody);
53
+ if (provided === null || !timingSafeEqualString(provided, expected)) {
54
+ console.error(`[github-webhook] signature verification failed (${provided === null ? "missing" : "mismatch"})`);
55
+ return jsonResponse({ type: "error", message: "invalid signature" }, 401);
56
+ }
57
+ const rPayload = exception2Result(() => JSON.parse(rawBody));
58
+ const payload = rPayload.isErr() ? {} : rPayload.Ok();
59
+ const event = request.headers.get(GITHUB_EVENT_HEADER) ?? "";
60
+ const installationId = payload.installation?.id === undefined ? undefined : String(payload.installation.id);
61
+ const sql = sqlOverride ??
62
+ {
63
+ db: cfDrizzle(env, env.DB).db,
64
+ tables: createVibesApiTables(toDBFlavour(env.DB_FLAVOUR)),
65
+ };
66
+ const t = sql.tables.githubRepoRoutes;
67
+ const now = new Date().toISOString();
68
+ if (event === "installation" && installationId !== undefined && (payload.action === "deleted" || payload.action === "suspend")) {
69
+ await sql.db.update(t).set({ removedAt: now, updated: now }).where(eq(t.installationId, installationId));
70
+ return jsonResponse({ type: "ok" }, 200);
71
+ }
72
+ if (event === "installation" && installationId !== undefined && payload.action === "unsuspend") {
73
+ await sql.db.update(t).set({ removedAt: "", updated: now }).where(eq(t.installationId, installationId));
74
+ return jsonResponse({ type: "ok" }, 200);
75
+ }
76
+ if (event === "installation_repositories" && installationId !== undefined) {
77
+ const removed = (payload.repositories_removed ?? [])
78
+ .map((r) => r.full_name)
79
+ .filter((n) => typeof n === "string")
80
+ .map((n) => n.toLowerCase());
81
+ if (removed.length > 0) {
82
+ await sql.db
83
+ .update(t)
84
+ .set({ removedAt: now, updated: now })
85
+ .where(and(eq(t.installationId, installationId), inArray(t.repoFullName, removed)));
86
+ return jsonResponse({ type: "ok" }, 200);
87
+ }
88
+ }
89
+ const repoFullName = payload.repository?.full_name?.toLowerCase();
90
+ if (installationId === undefined || repoFullName === undefined) {
91
+ console.warn(`[github-webhook] unroutable ${event}: installation=${installationId ?? "-"} repo=${repoFullName ?? "-"}`);
92
+ return new Response(null, { status: 204 });
93
+ }
94
+ const route = await sql.db
95
+ .select({ ownerHandle: t.ownerHandle, appSlug: t.appSlug })
96
+ .from(t)
97
+ .where(and(eq(t.installationId, installationId), eq(t.repoFullName, repoFullName), eq(t.removedAt, "")))
98
+ .limit(1)
99
+ .then((rows) => rows[0]);
100
+ if (route === undefined) {
101
+ console.warn(`[github-webhook] unroutable ${event}: installation=${installationId} repo=${repoFullName} (no active route)`);
102
+ return new Response(null, { status: 204 });
103
+ }
104
+ const targetUrl = `https://${route.appSlug}--${route.ownerHandle}.${env.VIBES_SVC_HOSTNAME_BASE}/_api/github-webhook`;
105
+ const fwd = new Request(targetUrl, { method: "POST", body: rawBody, headers: new Headers(request.headers) });
106
+ sanitizeBackendApiForwardHeaders(fwd.headers, { ownerHandle: route.ownerHandle, appSlug: route.appSlug });
107
+ const deliveryId = request.headers.get(GITHUB_DELIVERY_HEADER) ?? "";
108
+ const timestampMs = String(Date.now());
109
+ fwd.headers.delete(GITHUB_SIGNATURE_HEADER);
110
+ fwd.headers.delete("x-hub-signature");
111
+ fwd.headers.set("content-type", "application/json");
112
+ fwd.headers.set(VIBES_GITHUB_EVENT_HEADER, event);
113
+ fwd.headers.set(VIBES_GITHUB_DELIVERY_HEADER, deliveryId);
114
+ fwd.headers.set(VIBES_GITHUB_INSTALLATION_HEADER, installationId);
115
+ fwd.headers.set(VIBES_CONTENT_HEADER, VIBES_CONTENT_UNTRUSTED);
116
+ fwd.headers.set(VIBES_TIMESTAMP_HEADER, timestampMs);
117
+ fwd.headers.set(VIBES_GITHUB_SIGNATURE_HEADER, await vibeProvenanceSignature({
118
+ secret,
119
+ ownerHandle: route.ownerHandle,
120
+ appSlug: route.appSlug,
121
+ event,
122
+ deliveryId,
123
+ installationId,
124
+ timestampMs,
125
+ rawBody,
126
+ }));
127
+ const internalSecret = env.BACKEND_INTERNAL_SECRET ?? "";
128
+ if (internalSecret.length > 0) {
129
+ fwd.headers.set(BACKEND_INTERNAL_AUTH_HEADER, internalSecret);
130
+ }
131
+ const rRes = await exception2Result(async () => {
132
+ const doId = env.BACKEND_DO.idFromName(backendDoName(route.ownerHandle, route.appSlug));
133
+ return env.BACKEND_DO.get(doId).fetch(fwd);
134
+ });
135
+ if (rRes.isErr()) {
136
+ console.error(`[github-webhook] vibe ${route.ownerHandle}/${route.appSlug} threw for ${event}:`, rRes.Err());
137
+ return jsonResponse({ type: "error", message: "vibe delivery failed" }, 502);
138
+ }
139
+ const res = rRes.Ok();
140
+ if (res.status >= 400 && res.status < 500) {
141
+ console.warn(`[github-webhook] vibe ${route.ownerHandle}/${route.appSlug} returned ${res.status} for ${event} — terminal, not retried`);
142
+ return new Response(null, { status: 204 });
143
+ }
144
+ if (res.status < 200 || res.status >= 300) {
145
+ console.error(`[github-webhook] vibe ${route.ownerHandle}/${route.appSlug} returned ${res.status} for ${event}`);
146
+ return jsonResponse({ type: "error", message: "vibe delivery failed" }, 502);
147
+ }
148
+ return jsonResponse({ type: "ok" }, 200);
149
+ }
150
+ //# sourceMappingURL=github-webhook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-webhook.js","sourceRoot":"","sources":["../../jsr/public/github-webhook.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { Result, Option, EventoResult, exception2Result } from "@adviser/cement";
2
2
  import { scopey } from "@adviser/scopey";
3
- import { isAccessWizardRequest, isUpgradeBackendRequest, isDiscussRequest, isWorkRequest, isReqCreationPromptChatSection, isReqPromptApplicationChatSection, isReqPromptFSChatSection, isReqPromptImageChatSection, isReqPromptLLMChatSection, reqPromptChatSection, RESEARCH_BLOCK_SEQ, } from "@vibes.diy/api-types";
3
+ import { isAccessWizardRequest, isUpgradeBackendRequest, isDiscussRequest, isWorkRequest, isReqCreationPromptChatSection, isReqPromptApplicationChatSection, isReqPromptFSChatSection, isReqPromptImageChatSection, isReqPromptLLMChatSection, reqPromptChatSection, isBuildNotifyMode, RESEARCH_BLOCK_SEQ, } from "@vibes.diy/api-types";
4
4
  import { type } from "arktype";
5
5
  import { checkAuth } from "../check-auth.js";
6
6
  import { unwrapMsgBase, wrapMsgBase } from "../unwrap-msg-base.js";
@@ -566,6 +566,7 @@ export const promptChatSection = {
566
566
  }));
567
567
  await scopey(async (scope) => {
568
568
  const seq = { val: 0 };
569
+ const notifiesBuild = isBuildNotifyMode(req.mode);
569
570
  let turnErrored = false;
570
571
  scope.onCatch(async (e) => {
571
572
  turnErrored = true;
@@ -602,7 +603,7 @@ export const promptChatSection = {
602
603
  .Any("event", { chatId: req.chatId, promptId, blockSeq: errorSeq })
603
604
  .Msg("prompt-error-persist-failed");
604
605
  }
605
- if (vctx.notifyUser) {
606
+ if (vctx.notifyUser && notifiesBuild) {
606
607
  const userId = req._auth.verifiedAuth.claims.userId;
607
608
  const connId = clientWsSend(ctx).connId;
608
609
  void vctx
@@ -674,7 +675,7 @@ export const promptChatSection = {
674
675
  .Any("event", { chatId: req.chatId, promptId, blockSeq: seq.val })
675
676
  .Msg("prompt-block-end-persist-failed");
676
677
  }
677
- if (vctx.notifyUser && turnErrored === false) {
678
+ if (vctx.notifyUser && notifiesBuild && turnErrored === false) {
678
679
  const userId = req._auth.verifiedAuth.claims.userId;
679
680
  const connId = clientWsSend(ctx).connId;
680
681
  void vctx