Skip to content

Commit 79abd7d

Browse files
committed
Update cors middleware
1 parent 67f9258 commit 79abd7d

File tree

8 files changed

+129
-68
lines changed

8 files changed

+129
-68
lines changed

bun.lock

Lines changed: 19 additions & 23 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rabbit-company/web-monorepo",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"description": "High-performance web framework monorepo",
55
"private": true,
66
"type": "module",
@@ -9,7 +9,8 @@
99
"author": "Rabbit Company <info@rabbit-company.com>",
1010
"license": "MIT",
1111
"workspaces": [
12-
"packages/*"
12+
"packages/core",
13+
"packages/middleware"
1314
],
1415
"scripts": {
1516
"build": "bun run build.ts",
@@ -48,11 +49,12 @@
4849
],
4950
"devDependencies": {
5051
"@types/bun": "latest",
52+
"@types/node": "^25.0.9",
5153
"typescript": "^5.9.3",
5254
"@rabbit-company/logger": "^5.6.0",
5355
"bun-plugin-dts": "^0.3.0",
54-
"hono": "^4.10.4",
55-
"elysia": "^1.4.13"
56+
"hono": "^4.11.4",
57+
"elysia": "^1.4.22"
5658
},
5759
"dependencies": {
5860
"@rabbit-company/rate-limiter": "^3.0.0"

packages/core/jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rabbit-company/web",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"license": "MIT",
55
"exports": "./src/index.ts",
66
"publish": {

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rabbit-company/web",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"description": "High-performance web framework",
55
"main": "./dist/index.js",
66
"types": "./dist/index.d.ts",

packages/middleware/jsr.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rabbit-company/web-middleware",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"license": "MIT",
55
"exports": {
66
"./basic-auth": "./src/basic-auth.ts",

packages/middleware/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@rabbit-company/web-middleware",
3-
"version": "0.16.0",
3+
"version": "0.17.0",
44
"description": "Official middleware collection for Rabbit Company Web Framework",
55
"type": "module",
66
"homepage": "https://github.com/Rabbit-Company/Web-JS",
@@ -83,7 +83,7 @@
8383
"rate-limit"
8484
],
8585
"peerDependencies": {
86-
"@rabbit-company/web": "^0.16.0"
86+
"@rabbit-company/web": "^0.17.0"
8787
},
8888
"dependencies": {
8989
"@rabbit-company/rate-limiter": "^3.0.0",

packages/middleware/src/cors.ts

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -69,18 +69,29 @@ const defaults: CorsOptions = {
6969
* @returns {Middleware<T, B>} - A middleware function for handling CORS headers.
7070
*/
7171
export function cors<T extends Record<string, unknown> = Record<string, unknown>, B extends Record<string, unknown> = Record<string, unknown>>(
72-
options: CorsOptions = {}
72+
options: CorsOptions = {},
7373
): Middleware<T, B> {
7474
const opts = { ...defaults, ...options };
7575

7676
return async (ctx: Context<T, B>, next) => {
77-
const origin = ctx.req.headers.get("Origin") || "";
77+
const requestOrigin = ctx.req.headers.get("Origin");
7878

79-
// Check if origin is allowed
80-
const isAllowed = await checkOrigin(origin, opts.origin);
79+
// Non-CORS request
80+
if (!requestOrigin) {
81+
return next();
82+
}
83+
84+
const isAllowed = await checkOrigin(requestOrigin, opts.origin);
8185

8286
if (isAllowed) {
83-
ctx.header("Access-Control-Allow-Origin", origin || "*");
87+
const isWildcard = opts.origin === "*" && !opts.credentials;
88+
89+
if (isWildcard) {
90+
ctx.header("Access-Control-Allow-Origin", "*");
91+
} else {
92+
ctx.header("Access-Control-Allow-Origin", requestOrigin);
93+
appendVary(ctx, "Origin");
94+
}
8495

8596
if (opts.credentials) {
8697
ctx.header("Access-Control-Allow-Credentials", "true");
@@ -91,7 +102,7 @@ export function cors<T extends Record<string, unknown> = Record<string, unknown>
91102
}
92103
}
93104

94-
// Handle preflight
105+
// Preflight request
95106
if (ctx.req.method === "OPTIONS") {
96107
if (opts.allowMethods?.length) {
97108
ctx.header("Access-Control-Allow-Methods", opts.allowMethods.join(", "));
@@ -101,12 +112,12 @@ export function cors<T extends Record<string, unknown> = Record<string, unknown>
101112
ctx.header("Access-Control-Allow-Headers", opts.allowHeaders.join(", "));
102113
}
103114

104-
if (opts.maxAge) {
105-
ctx.header("Access-Control-Max-Age", opts.maxAge.toString());
115+
if (opts.maxAge !== undefined) {
116+
ctx.header("Access-Control-Max-Age", String(opts.maxAge));
106117
}
107118

108119
if (!opts.preflightContinue) {
109-
return ctx.text("", opts.optionsSuccessStatus || 204);
120+
return ctx.text("", opts.optionsSuccessStatus ?? 204);
110121
}
111122
}
112123

@@ -125,6 +136,20 @@ async function checkOrigin(origin: string, allowed?: string | string[] | ((origi
125136
if (!allowed || allowed === "*") return true;
126137
if (typeof allowed === "string") return origin === allowed;
127138
if (Array.isArray(allowed)) return allowed.includes(origin);
128-
if (typeof allowed === "function") return allowed(origin);
139+
if (typeof allowed === "function") return await allowed(origin);
129140
return false;
130141
}
142+
143+
function appendVary(ctx: Context<any, any>, value: string) {
144+
const existing = ctx.res?.headers.get("Vary");
145+
if (!existing) {
146+
ctx.header("Vary", value);
147+
} else if (
148+
!existing
149+
.split(",")
150+
.map((v) => v.trim())
151+
.includes(value)
152+
) {
153+
ctx.header("Vary", `${existing}, ${value}`);
154+
}
155+
}

0 commit comments

Comments
 (0)