Skip to content
Source
Sign inSign up
Open History to see the last commit

apnsDeliveryJobs.test.ts

60 lines1.7 KB

1import * as NodeCryptoLayer from "@effect/platform-node/NodeCrypto";
2import { describe, expect, it } from "@effect/vitest";
3import * as Effect from "effect/Effect";
4import * as Redacted from "effect/Redacted";
5​
6import {
7 makeApnsDeliveryJobPayload,
8 signApnsDeliveryJob,
9 verifySignedApnsDeliveryJob,
10} from "./apnsDeliveryJobs.ts";
11​
12const secret = Redacted.make("queue-signing-secret");
13​
14describe("apnsDeliveryJobs", () => {
15 it.effect("rejects tampered signed queue jobs", () =>
16 Effect.gen(function* () {
17 const payload = makeApnsDeliveryJobPayload({
18 kind: "live_activity_end",
19 userId: "user-1",
20 deviceId: "device-1",
21 token: "token-1",
22 aggregate: null,
23 createdAt: "2026-05-25T00:00:00.000Z",
24 expiresAt: "2026-05-25T00:05:00.000Z",
25 jobId: "job-1",
26 });
27 const signed = yield* signApnsDeliveryJob({ secret, payload });
28 expect(yield* verifySignedApnsDeliveryJob({ secret, job: signed, nowMs: 0 })).toEqual(
29 payload,
30 );
31 const tampered = {
32 ...signed,
33 payload: {
34 ...signed.payload,
35 target: {
36 ...signed.payload.target,
37 token: "attacker-token",
38 },
39 },
40 };
41​
42 const result = yield* Effect.flip(
43 verifySignedApnsDeliveryJob({
44 secret,
45 job: tampered,
46 nowMs: 0,
47 }),
48 );
49​
50 expect(result).toMatchObject({
51 _tag: "ApnsDeliveryJobSignatureInvalid",
52 jobId: "job-1",
53 kind: "live_activity_end",
54 userId: "user-1",
55 deviceId: "device-1",
56 message: "Invalid signature for APNs delivery job job-1.",
57 });
58 }).pipe(Effect.provide(NodeCryptoLayer.layerMac)),
59 );
60});