252 lines · 7.1 KB · TypeScript
RawDownload
import { describe, expect, it } from "@effect/vitest";import { EnvironmentId, ThreadId } from "@t3tools/contracts";import type { RelayAgentActivityAggregateState } from "@t3tools/contracts/relay";import * as Redacted from "effect/Redacted"; import {  makeApnsDeliveryJobPayload,  signApnsDeliveryJob,  verifySignedApnsDeliveryJob,} from "./apnsDeliveryJobs.ts"; const secret = Redacted.make("queue-signing-secret");const aggregate: RelayAgentActivityAggregateState = {  title: "T3 Code",  subtitle: "Agent work in progress",  activeCount: 1,  updatedAt: "2026-05-25T00:00:00.000Z",  activities: [    {      environmentId: EnvironmentId.make("env"),      threadId: ThreadId.make("thread"),      projectTitle: "Project",      threadTitle: "Thread",      modelTitle: "gpt-5.4",      phase: "running",      status: "Working",      updatedAt: "2026-05-25T00:00:00.000Z",      deepLink: "/threads/env/thread",    },  ],}; const notification = {  title: "Thread",  body: "Input: Project",  environmentId: "env",  threadId: "thread",  deepLink: "/threads/env/thread",}; describe("apnsDeliveryJobs", () => {  it("rejects tampered signed queue jobs", () => {    const payload = makeApnsDeliveryJobPayload({      kind: "live_activity_end",      userId: "user-1",      deviceId: "device-1",      token: "token-1",      aggregate: null,      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-25T00:05:00.000Z",      jobId: "job-1",    });    const signed = signApnsDeliveryJob({ secret, payload });    const tampered = {      ...signed,      payload: {        ...signed.payload,        target: {          ...signed.payload.target,          token: "attacker-token",        },      },    };     const result = verifySignedApnsDeliveryJob({      secret,      job: tampered,      nowMs: 0,    });     expect(result).toMatchObject({      _tag: "ApnsDeliveryJobSignatureInvalid",      jobId: "job-1",      kind: "live_activity_end",      userId: "user-1",      deviceId: "device-1",      message: "Invalid signature for APNs delivery job job-1.",    });  });   it("rejects Live Activity start jobs without aggregate state", () => {    const payload = makeApnsDeliveryJobPayload({      kind: "live_activity_start",      userId: "user-1",      deviceId: "device-1",      token: "token-1",      aggregate: null,      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-25T00:05:00.000Z",      jobId: "job-start-invalid",    });    const signed = signApnsDeliveryJob({ secret, payload });     const result = verifySignedApnsDeliveryJob({      secret,      job: signed,      nowMs: 0,    });     expect(result).toMatchObject({      _tag: "ApnsDeliveryJobLiveActivityAggregateMissing",      jobId: "job-start-invalid",      kind: "live_activity_start",      userId: "user-1",      deviceId: "device-1",      message: "APNs live activity start job job-start-invalid requires an aggregate.",    });  });   it("rejects push notification jobs carrying aggregate state", () => {    const payload = makeApnsDeliveryJobPayload({      kind: "push_notification",      userId: "user-1",      deviceId: "device-1",      token: "token-1",      aggregate,      notification,      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-25T00:05:00.000Z",      jobId: "job-push-invalid",    });    const signed = signApnsDeliveryJob({ secret, payload });     const result = verifySignedApnsDeliveryJob({      secret,      job: signed,      nowMs: 0,    });     expect(result).toMatchObject({      _tag: "ApnsDeliveryJobPushNotificationAggregateUnexpected",      jobId: "job-push-invalid",      userId: "user-1",      deviceId: "device-1",      message: "APNs push notification job job-push-invalid must not carry aggregate state.",    });  });   it("accepts minimal kind-specific signed queue jobs", () => {    const pushPayload = makeApnsDeliveryJobPayload({      kind: "push_notification",      userId: "user-1",      deviceId: "device-1",      token: "token-1",      aggregate: null,      notification,      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-25T00:05:00.000Z",      jobId: "job-push-valid",    });    const liveActivityPayload = makeApnsDeliveryJobPayload({      kind: "live_activity_update",      userId: "user-1",      deviceId: "device-1",      token: "token-1",      aggregate,      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-25T00:05:00.000Z",      jobId: "job-live-valid",    });     expect(      verifySignedApnsDeliveryJob({        secret,        job: signApnsDeliveryJob({ secret, payload: pushPayload }),        nowMs: 0,      }),    ).toEqual(pushPayload);    expect(      verifySignedApnsDeliveryJob({        secret,        job: signApnsDeliveryJob({ secret, payload: liveActivityPayload }),        nowMs: 0,      }),    ).toEqual(liveActivityPayload);  });   it("rejects jobs with invalid or overlong time windows", () => {    const basePayload = makeApnsDeliveryJobPayload({      kind: "live_activity_end",      userId: "user-1",      deviceId: "device-1",      token: "token-1",      aggregate: null,      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-25T00:10:00.000Z",      jobId: "job-window",    });    const invalidCreatedAt = {      ...basePayload,      createdAt: "not-a-date",    };    const invertedWindow = {      ...basePayload,      expiresAt: "2026-05-24T23:59:59.000Z",    };    const overlongWindow = {      ...basePayload,      expiresAt: "2026-05-25T00:10:01.000Z",    };     expect(      verifySignedApnsDeliveryJob({        secret,        job: signApnsDeliveryJob({ secret, payload: invalidCreatedAt }),        nowMs: 0,      }),    ).toMatchObject({      _tag: "ApnsDeliveryJobCreatedAtInvalid",      jobId: "job-window",      kind: "live_activity_end",      userId: "user-1",      deviceId: "device-1",      createdAt: "not-a-date",      message: "APNs delivery job job-window has invalid creation time not-a-date.",    });    expect(      verifySignedApnsDeliveryJob({        secret,        job: signApnsDeliveryJob({ secret, payload: invertedWindow }),        nowMs: 0,      }),    ).toMatchObject({      _tag: "ApnsDeliveryJobTimeWindowInvalid",      jobId: "job-window",      kind: "live_activity_end",      userId: "user-1",      deviceId: "device-1",      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-24T23:59:59.000Z",      message:        "APNs delivery job job-window has invalid time window 2026-05-25T00:00:00.000Z to 2026-05-24T23:59:59.000Z.",    });    expect(      verifySignedApnsDeliveryJob({        secret,        job: signApnsDeliveryJob({ secret, payload: overlongWindow }),        nowMs: 0,      }),    ).toMatchObject({      _tag: "ApnsDeliveryJobTimeWindowTooLong",      jobId: "job-window",      kind: "live_activity_end",      userId: "user-1",      deviceId: "device-1",      createdAt: "2026-05-25T00:00:00.000Z",      expiresAt: "2026-05-25T00:10:01.000Z",      message:        "APNs delivery job job-window time window 2026-05-25T00:00:00.000Z to 2026-05-25T00:10:01.000Z is too long.",    });  });});