Skip to content
29 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)1#!/usr/bin/env node
2// A new VAPID key pair for browser push (services/notify). Stores nothing.
3//
4// node scripts/ops/vapid-keys.mjs
5// prints both halves, base64url, for you to put where they go.
6//
7// node scripts/ops/vapid-keys.mjs --pipe | (cd services/notify && npx wrangler secret put VAPID_PRIVATE_KEY)
8// writes only the private half to stdout, straight into the secret,
9// and the public half to stderr, for VAPID_PUBLIC_KEY in
10// services/notify/wrangler.jsonc. The private half never touches disk.
11//
12// A new pair invalidates every browser subscribed with the old one: they
13// subscribe again the next time the person opens g1t with notifications on.
14import { webcrypto } from "node:crypto";
15
16const b64url = (bytes) => Buffer.from(bytes).toString("base64url");
17
18const pair = await webcrypto.subtle.generateKey({ name: "ECDSA", namedCurve: "P-256" }, true, ["sign", "verify"]);
19const publicKey = b64url(new Uint8Array(await webcrypto.subtle.exportKey("raw", pair.publicKey)));
20const privateKey = (await webcrypto.subtle.exportKey("jwk", pair.privateKey)).d;
21
22if (process.argv.includes("--pipe")) {
23 process.stderr.write(`VAPID_PUBLIC_KEY=${publicKey}\n`);
24 process.stdout.write(privateKey);
25} else {
26 console.log(`VAPID_PUBLIC_KEY=${publicKey}`);
27 console.log(`VAPID_PRIVATE_KEY=${privateKey}`);
28 console.log("\nThe private half is a secret: npx wrangler secret put VAPID_PRIVATE_KEY (in services/notify). Keep it nowhere else.");
29}

This file's history is long; its oldest lines are credited to the oldest commit read.