Something went wrong. Try again.
Monorepo for Aesthetic.Computer aesthetic.computer
Something went wrong. Try again.
JavaScript
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586// push.test, 26.06.11// Validates shared/push.mjs Web Push encryption against the RFC 8291// Appendix A test vector, byte-for-byte, plus VAPID JWT shape.// Run: node shared/push.test.mjs
import crypto from "node:crypto";import { encryptWebPush } from "./push.mjs";
let failures = 0;function check(name, actual, expected) { const ok = actual === expected; console.log(`${ok ? "✅" : "❌"} ${name}`); if (!ok) { failures++; console.log(" expected:", expected); console.log(" actual: ", actual); }}
// — RFC 8291 Appendix A —const uaPublic = "BCVxsr7N_eNgVRqvHtD0zTZsEc6-VV-JvLexhqUzORcxaOzi6-AYWXvTBHm4bjyPjs7Vd8pZGH6SRpkNtoIAiw4";const authSecret = "BTBZMqHH6r4Tts7J_aSIgg";const plaintext = "When I grow up, I want to be a watermelon";const asPublicRaw = Buffer.from( "BP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A8", "base64url",);const asJwk = { kty: "EC", crv: "P-256", x: asPublicRaw.subarray(1, 33).toString("base64url"), y: asPublicRaw.subarray(33, 65).toString("base64url"), d: "yfWPiYE-n46HLnH0KqZOF1fJJU3MYrct3AELtAQ-oRw",};const salt = Buffer.from("DGv6ra1nlYgDCS1FRnbzlw", "base64url");const expectedBody = "DGv6ra1nlYgDCS1FRnbzlwAAEABBBP4z9KsN6nGRTbVYI_c7VJSPQTBtkgcy27mlmlMoZIIgDll6e3vCYLocInmYWAmS6TlzAC8wEqKK6PBru3jl7A_yl95bQpu6cVPTpK4Mqgkf1CXztLVBSt2Ks3oZwbuwXPXLWyouBWLVWGNWQexSgSxsj_Qulcy4a-fN";
const body = encryptWebPush(plaintext, uaPublic, authSecret, { asJwk, salt });check("RFC 8291 aes128gcm test vector", body.toString("base64url"), expectedBody);
// — VAPID JWT shape (signature verifies against the public key) —// Ephemeral test keypair, never a real one: production keys live only in the// vault env files.const testPair = crypto.generateKeyPairSync("ec", { namedCurve: "prime256v1" });const testJwk = testPair.privateKey.export({ format: "jwk" });process.env.VAPID_PUBLIC_KEY = Buffer.concat([ Buffer.from([4]), Buffer.from(testJwk.x, "base64url"), Buffer.from(testJwk.y, "base64url"),]).toString("base64url");process.env.VAPID_PRIVATE_KEY = testJwk.d;
// vapidJWT isn't exported; verify indirectly by reconstructing one the same way.const pub = Buffer.from(process.env.VAPID_PUBLIC_KEY, "base64url");const privateKey = crypto.createPrivateKey({ key: { kty: "EC", crv: "P-256", x: pub.subarray(1, 33).toString("base64url"), y: pub.subarray(33, 65).toString("base64url"), d: process.env.VAPID_PRIVATE_KEY, }, format: "jwk",});const header = Buffer.from(JSON.stringify({ typ: "JWT", alg: "ES256" })).toString("base64url");const claims = Buffer.from( JSON.stringify({ aud: "https://fcm.googleapis.com", exp: 0, sub: "mailto:t@t" }),).toString("base64url");const unsigned = `${header}.${claims}`;const sig = crypto.sign("sha256", Buffer.from(unsigned), { key: privateKey, dsaEncoding: "ieee-p1363",});const publicKey = crypto.createPublicKey(privateKey);const verified = crypto.verify( "sha256", Buffer.from(unsigned), { key: publicKey, dsaEncoding: "ieee-p1363" }, sig,);check("VAPID ES256 keypair signs + verifies", verified, true);
process.exit(failures ? 1 : 0);