bxo 0.0.5-dev.39 → 0.0.5-dev.40

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/README.md CHANGED
@@ -221,6 +221,13 @@ app.use(cors({
221
221
  }));
222
222
  ```
223
223
 
224
+ **Features:**
225
+ - **Origin Header Support**: Standard CORS origin header handling
226
+ - **Referer Header Fallback**: Automatically falls back to Referer header when Origin is not present
227
+ - **Origin Precedence**: When both Origin and Referer are present, Origin takes precedence
228
+ - **Invalid URL Handling**: Gracefully handles invalid Referer URLs
229
+ - **Flexible Origin Configuration**: Supports string, array, boolean, or wildcard (`*`) origins
230
+
224
231
  #### Logger Plugin
225
232
 
226
233
  ```typescript
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bxo",
3
3
  "module": "index.ts",
4
- "version": "0.0.5-dev.39",
4
+ "version": "0.0.5-dev.40",
5
5
  "description": "A simple and lightweight web framework for Bun",
6
6
  "type": "module",
7
7
  "devDependencies": {
package/plugins/cors.ts CHANGED
@@ -8,6 +8,46 @@ interface CORSOptions {
8
8
  maxAge?: number;
9
9
  }
10
10
 
11
+ // Helper function to extract origin from request headers
12
+ function getRequestOrigin(request: Request): string | null {
13
+ // Try Origin header first (standard for CORS)
14
+ const origin = request.headers.get('origin');
15
+ if (origin) {
16
+ return origin;
17
+ }
18
+
19
+ // Fallback to Referer header
20
+ const referer = request.headers.get('referer');
21
+ if (referer) {
22
+ try {
23
+ const url = new URL(referer);
24
+ return `${url.protocol}//${url.host}`;
25
+ } catch (e) {
26
+ // Invalid referer URL, ignore it
27
+ return null;
28
+ }
29
+ }
30
+
31
+ return null;
32
+ }
33
+
34
+ // Helper function to validate origin against allowed origins
35
+ function validateOrigin(requestOrigin: string | null, allowedOrigins: string | string[] | boolean): string | null {
36
+ if (!requestOrigin) {
37
+ return null;
38
+ }
39
+
40
+ if (typeof allowedOrigins === 'boolean') {
41
+ return allowedOrigins ? requestOrigin : null;
42
+ } else if (typeof allowedOrigins === 'string') {
43
+ return allowedOrigins === '*' || allowedOrigins === requestOrigin ? requestOrigin : null;
44
+ } else if (Array.isArray(allowedOrigins)) {
45
+ return allowedOrigins.includes(requestOrigin) ? requestOrigin : null;
46
+ }
47
+
48
+ return null;
49
+ }
50
+
11
51
  export function cors(options: CORSOptions = {}): any {
12
52
  const {
13
53
  origin = '*',
@@ -24,18 +64,14 @@ export function cors(options: CORSOptions = {}): any {
24
64
  if (ctx.request.method === 'OPTIONS') {
25
65
  const headers: Record<string, string> = {};
26
66
 
27
- // Handle origin
28
- if (typeof origin === 'boolean') {
29
- if (origin) {
30
- headers['Access-Control-Allow-Origin'] = ctx.request.headers.get('origin') || '*';
31
- }
32
- } else if (typeof origin === 'string') {
33
- headers['Access-Control-Allow-Origin'] = origin;
34
- } else if (Array.isArray(origin)) {
35
- const requestOrigin = ctx.request.headers.get('origin');
36
- if (requestOrigin && origin.includes(requestOrigin)) {
37
- headers['Access-Control-Allow-Origin'] = requestOrigin;
38
- }
67
+ // Get and validate origin
68
+ const requestOrigin = getRequestOrigin(ctx.request);
69
+ const validatedOrigin = validateOrigin(requestOrigin, origin);
70
+
71
+ if (validatedOrigin) {
72
+ headers['Access-Control-Allow-Origin'] = validatedOrigin;
73
+ } else if (typeof origin === 'string' && origin === '*') {
74
+ headers['Access-Control-Allow-Origin'] = '*';
39
75
  }
40
76
 
41
77
  headers['Access-Control-Allow-Methods'] = methods.join(', ');
@@ -56,18 +92,14 @@ export function cors(options: CORSOptions = {}): any {
56
92
  onResponse: async (ctx: any, response: any) => {
57
93
  const headers: Record<string, string> = {};
58
94
 
59
- // Handle origin for actual requests
60
- if (typeof origin === 'boolean') {
61
- if (origin) {
62
- headers['Access-Control-Allow-Origin'] = ctx.request.headers.get('origin') || '*';
63
- }
64
- } else if (typeof origin === 'string') {
65
- headers['Access-Control-Allow-Origin'] = origin;
66
- } else if (Array.isArray(origin)) {
67
- const requestOrigin = ctx.request.headers.get('origin');
68
- if (requestOrigin && origin.includes(requestOrigin)) {
69
- headers['Access-Control-Allow-Origin'] = requestOrigin;
70
- }
95
+ // Get and validate origin for actual requests
96
+ const requestOrigin = getRequestOrigin(ctx.request);
97
+ const validatedOrigin = validateOrigin(requestOrigin, origin);
98
+
99
+ if (validatedOrigin) {
100
+ headers['Access-Control-Allow-Origin'] = validatedOrigin;
101
+ } else if (typeof origin === 'string' && origin === '*') {
102
+ headers['Access-Control-Allow-Origin'] = '*';
71
103
  }
72
104
 
73
105
  if (credentials) {