create-safest-tools 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-safest-tools",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Create customer-owned abuse-reporting infrastructure on Cloudflare",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "safest-resolve-installation",
3
- "version": "0.5.2",
4
- "safestToolsVersion": "0.5.2-resolve",
3
+ "version": "0.5.3",
4
+ "safestToolsVersion": "0.5.3-resolve",
5
5
  "private": true,
6
6
  "license": "Apache-2.0",
7
7
  "type": "module",
@@ -67,7 +67,8 @@ export function reporterEmailConfigured(env: unknown): boolean {
67
67
  export type CaseReplyAudience = "reporter" | "affected_user";
68
68
 
69
69
  const legacyReplyTokenPattern = /^r1\.([a-z0-9_-]{16})\.([0-9a-f]{8})\.([0-9a-f]{24})$/u;
70
- const replyTokenPattern = /^r2([ra])\.([a-z0-9_-]{16})\.([0-9a-f]{8})\.([0-9a-f]{24})$/u;
70
+ const replyTokenPattern = /^r([ra])\.([a-z0-9_-]{16})\.([0-9a-f]{8})\.([0-9a-f]{24})$/u;
71
+ const transitionalReplyTokenPattern = /^r2([ra])\.([a-z0-9_-]{16})\.([0-9a-f]{8})\.([0-9a-f]{24})$/u;
71
72
  const encoder = new TextEncoder();
72
73
 
73
74
  function hex(bytes: Uint8Array): string {
@@ -98,7 +99,7 @@ export async function reporterReplyToken(input: {
98
99
  const expiry = input.expiresAt.toString(16).padStart(8, "0");
99
100
  if (!/^[0-9a-f]{8}$/u.test(expiry)) throw new Error("The reporter reply expiry is outside the supported range.");
100
101
  const audience = input.audience === "affected_user" ? "a" : "r";
101
- const payload = `r2${audience}.${reference}.${expiry}`;
102
+ const payload = `r${audience}.${reference}.${expiry}`;
102
103
  return `${payload}.${hex(await replySignature(input.signingSecret, payload))}`;
103
104
  }
104
105
 
@@ -108,21 +109,23 @@ export async function verifyReporterReplyToken(
108
109
  currentTime = Math.floor(Date.now() / 1_000),
109
110
  ): Promise<{ publicReference: string; expiresAt: number; audience: CaseReplyAudience } | null> {
110
111
  const current = replyTokenPattern.exec(token);
111
- const legacy = current ? null : legacyReplyTokenPattern.exec(token);
112
- if (!current && !legacy) return null;
113
- const reference = current?.[2] ?? legacy?.[1] ?? "";
114
- const expiryHex = current?.[3] ?? legacy?.[2] ?? "";
115
- const signatureHex = current?.[4] ?? legacy?.[3] ?? "";
112
+ const transitional = current ? null : transitionalReplyTokenPattern.exec(token);
113
+ const legacy = current || transitional ? null : legacyReplyTokenPattern.exec(token);
114
+ if (!current && !transitional && !legacy) return null;
115
+ const reference = current?.[2] ?? transitional?.[2] ?? legacy?.[1] ?? "";
116
+ const expiryHex = current?.[3] ?? transitional?.[3] ?? legacy?.[2] ?? "";
117
+ const signatureHex = current?.[4] ?? transitional?.[4] ?? legacy?.[3] ?? "";
116
118
  const expiry = Number.parseInt(expiryHex, 16);
117
119
  const supplied = Uint8Array.from(signatureHex.match(/.{2}/gu) ?? [], (pair) => Number.parseInt(pair, 16));
118
120
  if (!expiry || expiry <= currentTime) return null;
119
- const payload = current ? `r2${current[1]}.${reference}.${expiryHex}` : `r1.${reference}.${expiryHex}`;
121
+ const payload = current ? `r${current[1]}.${reference}.${expiryHex}`
122
+ : transitional ? `r2${transitional[1]}.${reference}.${expiryHex}` : `r1.${reference}.${expiryHex}`;
120
123
  const expected = await replySignature(signingSecret, payload);
121
124
  if (!constantTimeEqual(supplied, expected)) return null;
122
125
  return {
123
126
  publicReference: `RPT-${reference.toUpperCase()}`,
124
127
  expiresAt: expiry,
125
- audience: current?.[1] === "a" ? "affected_user" : "reporter",
128
+ audience: (current?.[1] ?? transitional?.[1]) === "a" ? "affected_user" : "reporter",
126
129
  };
127
130
  }
128
131