two-stroke 8.0.16 → 8.0.18
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 +2 -2
- package/src/index.ts +41 -44
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "two-stroke",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.18",
|
|
4
4
|
"description": "Simple Cloudflare Worker framework.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"zod": "^4.4.3"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@cloudflare/vitest-pool-workers": "^0.18.
|
|
33
|
+
"@cloudflare/vitest-pool-workers": "^0.18.6",
|
|
34
34
|
"knip": "^6.27.0",
|
|
35
35
|
"oxfmt": "^0.59.0",
|
|
36
36
|
"oxlint": "^1.74.0",
|
package/src/index.ts
CHANGED
|
@@ -40,6 +40,7 @@ export function twoStroke<T>(
|
|
|
40
40
|
context: ExecutionContext,
|
|
41
41
|
): Promise<Response> {
|
|
42
42
|
const defaultHeaders = {
|
|
43
|
+
Very: "Origin",
|
|
43
44
|
"Access-Control-Allow-Origin": origin
|
|
44
45
|
? (env.SENTRY_ENVIRONMENT === "staging" || env.SENTRY_ENVIRONMENT === "dev") &&
|
|
45
46
|
req.headers.get("Origin")?.split(":")[1]?.endsWith("localhost")
|
|
@@ -101,9 +102,9 @@ export function twoStroke<T>(
|
|
|
101
102
|
rawBody = route.input
|
|
102
103
|
? req.headers.get("Content-Type") === "application/x-www-form-urlencoded"
|
|
103
104
|
? // oxlint-disable-next-line no-await-in-loop
|
|
104
|
-
|
|
105
|
+
Object.fromEntries(new URLSearchParams(await req.text()))
|
|
105
106
|
: // oxlint-disable-next-line no-await-in-loop
|
|
106
|
-
|
|
107
|
+
await req.json()
|
|
107
108
|
: undefined;
|
|
108
109
|
} catch (error) {
|
|
109
110
|
console.error({
|
|
@@ -124,10 +125,10 @@ export function twoStroke<T>(
|
|
|
124
125
|
const body = route.input
|
|
125
126
|
? route.input.safeParse(rawBody)
|
|
126
127
|
: {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
success: true,
|
|
129
|
+
data: undefined,
|
|
130
|
+
error: undefined,
|
|
131
|
+
};
|
|
131
132
|
if (body.success)
|
|
132
133
|
// oxlint-disable-next-line no-await-in-loop
|
|
133
134
|
response = await route.handler({
|
|
@@ -297,41 +298,41 @@ export function twoStroke<T>(
|
|
|
297
298
|
noAuth,
|
|
298
299
|
pbkdf:
|
|
299
300
|
(k: keyof T, customHeaderName = "Authorization") =>
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
301
|
+
async ({ req, env }: { req: Request; env: T }) => {
|
|
302
|
+
const [scheme, token] = (req.headers.get(customHeaderName) ?? " ").split(" ");
|
|
303
|
+
if (
|
|
304
|
+
(scheme === "token" || scheme === "Bearer") &&
|
|
305
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
|
|
306
|
+
(await pbkdfVerify(env[k] as string, token ?? ""))
|
|
307
|
+
)
|
|
308
|
+
return;
|
|
309
|
+
throw new Error("Invalid");
|
|
310
|
+
},
|
|
310
311
|
jwt:
|
|
311
312
|
<J>(k: keyof T, ak: keyof T) =>
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
313
|
+
async ({ req, env }: { req: Request; env: T }) => {
|
|
314
|
+
const [scheme, token] = (req.headers.get("Authorization") ?? " ").split(" ");
|
|
315
|
+
if (scheme === "Bearer") {
|
|
316
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
|
|
317
|
+
const rawIssuer = env[k] as string;
|
|
318
|
+
// oxlint-disable-next-line typescript/no-unsafe-type-assertion
|
|
319
|
+
const rawAudience = env[ak] as string;
|
|
320
|
+
const issuer = rawIssuer.startsWith("{")
|
|
321
|
+
? // oxlint-disable-next-line typescript/no-unsafe-type-assertion
|
|
321
322
|
(JSON.parse(rawIssuer) as Record<string, JSONWebKeySet | true>)
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
: { [rawIssuer]: true as const };
|
|
324
|
+
const audience = rawAudience.startsWith("[")
|
|
325
|
+
? // oxlint-disable-next-line typescript/no-unsafe-type-assertion
|
|
325
326
|
(JSON.parse(rawAudience) as string[])
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
327
|
+
: [rawAudience];
|
|
328
|
+
const claims = await jwkVerifyMulti<J>(token ?? "", issuer, audience);
|
|
329
|
+
if (!claims) {
|
|
330
|
+
throw new Error("Invalid");
|
|
331
|
+
}
|
|
332
|
+
return claims;
|
|
330
333
|
}
|
|
331
|
-
|
|
332
|
-
}
|
|
333
|
-
throw new Error("Invalid");
|
|
334
|
-
},
|
|
334
|
+
throw new Error("Invalid");
|
|
335
|
+
},
|
|
335
336
|
queueHandler<I extends ZodType>(
|
|
336
337
|
input: I,
|
|
337
338
|
handler: (c: {
|
|
@@ -374,8 +375,7 @@ export function twoStroke<T>(
|
|
|
374
375
|
method: "PUT",
|
|
375
376
|
path,
|
|
376
377
|
matcher: new RegExp(
|
|
377
|
-
|
|
378
|
-
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, "/(?<${seg}>[^\\/]*)")}$`,
|
|
378
|
+
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, String.raw`/(?<$<seg>>[^\/]*)`)}$`,
|
|
379
379
|
),
|
|
380
380
|
input,
|
|
381
381
|
output,
|
|
@@ -397,8 +397,7 @@ export function twoStroke<T>(
|
|
|
397
397
|
method: "POST",
|
|
398
398
|
path,
|
|
399
399
|
matcher: new RegExp(
|
|
400
|
-
|
|
401
|
-
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, "/(?<${seg}>[^\\/]*)")}$`,
|
|
400
|
+
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, String.raw`/(?<$<seg>>[^\/]*)`)}$`,
|
|
402
401
|
),
|
|
403
402
|
input,
|
|
404
403
|
output,
|
|
@@ -419,8 +418,7 @@ export function twoStroke<T>(
|
|
|
419
418
|
method: "GET",
|
|
420
419
|
path,
|
|
421
420
|
matcher: new RegExp(
|
|
422
|
-
|
|
423
|
-
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, "/(?<${seg}>[^\\/]*)")}$`,
|
|
421
|
+
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, String.raw`/(?<$<seg>>[^\/]*)`)}$`,
|
|
424
422
|
),
|
|
425
423
|
output,
|
|
426
424
|
handler,
|
|
@@ -439,8 +437,7 @@ export function twoStroke<T>(
|
|
|
439
437
|
method: "DELETE",
|
|
440
438
|
path,
|
|
441
439
|
matcher: new RegExp(
|
|
442
|
-
|
|
443
|
-
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, "/(?<${seg}>[^\\/]*)")}$`,
|
|
440
|
+
`^${escapeRegex(path).replaceAll(/\/{(?<seg>[^}]*)}/g, String.raw`/(?<$<seg>>[^\/]*)`)}$`,
|
|
444
441
|
),
|
|
445
442
|
output,
|
|
446
443
|
handler,
|