clone

push a directory of html from the terminal and get a four-character url back. a deno cli on cloudflare

main
nzip / worker / test / notify.test.mjs
notify.test.mjs 3.2K
1import assert from "node:assert/strict";2import { createECDH, randomBytes } from "node:crypto";3import { describe, it } from "node:test";4import webPush from "web-push";5import { validateNotifyRequest } from "../src/notify.ts";6import { buildWebPushRequest, validatePushEndpoint } from "../src/web_push.ts";78const env = {9 PUBLIC_BASE: "https://share.demo.dev",10 SITE_DOMAIN: "demo.dev",11 WEB_PUSH_ORIGINS:12 "https://fcm.googleapis.com,https://web.push.apple.com,https://updates.push.services.mozilla.com",13};1415describe("notification validation", () => {16 it("accepts bounded Unicode notification content", () => {17 assert.deepEqual(18 validateNotifyRequest({19 title: "Build ✓",20 body: "Ready 🚀",21 path: "/12af",22 tag: "build-main",23 }),24 {25 title: "Build ✓",26 body: "Ready 🚀",27 path: "/12af",28 tag: "build-main",29 },30 );31 });3233 it("rejects cross-origin, encoded, and unknown notification fields", () => {34 for (35 const value of [36 { body: "x", path: "https://example.com/" },37 { body: "x", path: "//example.com" },38 { body: "x", path: "/%31%32af" },39 { body: "x", extra: true },40 ]41 ) {42 assert.throws(() => validateNotifyRequest(value));43 }44 });4546 it("counts Unicode scalars instead of UTF-16 code units", () => {47 assert.equal(48 validateNotifyRequest({ body: "🚀".repeat(240) }).body.length,49 480,50 );51 assert.throws(() => validateNotifyRequest({ body: "🚀".repeat(241) }));52 });53});5455describe("push endpoint policy", () => {56 it("accepts only configured HTTPS provider origins", () => {57 assert.equal(58 validatePushEndpoint(env, "https://fcm.googleapis.com/fcm/send/abc")59 .hostname,60 "fcm.googleapis.com",61 );62 assert.throws(() => validatePushEndpoint(env, "https://example.com/push"));63 assert.throws(() =>64 validatePushEndpoint(env, "http://fcm.googleapis.com/push")65 );66 });6768 it("builds an RFC 8291 aes128gcm request", () => {69 const vapid = webPush.generateVAPIDKeys();70 const client = createECDH("prime256v1");71 client.generateKeys();72 const request = buildWebPushRequest({73 ...env,74 VAPID_PUBLIC_KEY: vapid.publicKey,75 VAPID_PRIVATE_KEY: vapid.privateKey,76 VAPID_SUBJECT: "https://share.demo.dev",77 }, {78 endpoint: "https://fcm.googleapis.com/fcm/send/test",79 keys: {80 p256dh: client.getPublicKey().toString("base64url"),81 auth: randomBytes(16).toString("base64url"),82 },83 }, {84 eventId: "00000000-0000-4000-8000-000000000000",85 title: "nzip",86 body: "transport fixture ✓",87 });8889 assert.equal(request.headers["Content-Encoding"], "aes128gcm");90 assert.match(request.headers.Authorization, /^vapid /);91 assert.ok(request.body.byteLength > 0);92 });9394 it("rejects own-zone, credentialed, IP-literal, and alternate-port endpoints", () => {95 for (96 const endpoint of [97 "https://share.demo.dev/_notify/reenter",98 "https://user:pass@fcm.googleapis.com/push",99 "https://127.0.0.1/push",100 "https://2130706433/push",101 "https://fcm.googleapis.com:8443/push",102 ]103 ) {104 assert.throws(() => validatePushEndpoint(env, endpoint));105 }106 });107});