@rayselfs/cf-rule-engine 1.6.2 → 1.8.0
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 +29 -3
- package/dist/adapters/lambda-edge.d.cts +1 -1
- package/dist/adapters/lambda-edge.d.ts +1 -1
- package/dist/behaviors/index.cjs +3 -3
- package/dist/behaviors/index.js +2 -2
- package/dist/behaviors/set-cors-headers.cjs +6 -2
- package/dist/behaviors/set-cors-headers.d.cts +39 -38
- package/dist/behaviors/set-cors-headers.d.ts +39 -38
- package/dist/behaviors/set-cors-headers.js +5 -1
- package/dist/behaviors/set-security-headers.cjs +2 -2
- package/dist/behaviors/set-security-headers.d.cts +35 -19
- package/dist/behaviors/set-security-headers.d.ts +35 -19
- package/dist/behaviors/set-security-headers.js +1 -1
- package/dist/chunk-3UXNXJ6N.cjs +21 -0
- package/dist/{chunk-H2LO6MQG.js → chunk-3VYYXEER.js} +20 -10
- package/dist/{chunk-63WIEBQB.cjs → chunk-45SNLNLR.cjs} +20 -10
- package/dist/chunk-O4SOSGAP.js +21 -0
- package/dist/{chunk-SOBTD7AD.js → chunk-SRA2DFKG.js} +21 -10
- package/dist/chunk-WAKA4OJD.cjs +50 -0
- package/dist/criteria/header-equals.d.cts +2 -2
- package/dist/criteria/header-equals.d.ts +2 -2
- package/dist/criteria/index.cjs +12 -12
- package/dist/criteria/index.js +12 -12
- package/dist/helpers/index.cjs +8 -7
- package/dist/helpers/index.js +7 -6
- package/dist/helpers/preflight-request.cjs +3 -2
- package/dist/helpers/preflight-request.d.cts +5 -4
- package/dist/helpers/preflight-request.d.ts +5 -4
- package/dist/helpers/preflight-request.js +2 -1
- package/dist/helpers/whitelist.cjs +3 -3
- package/dist/helpers/whitelist.js +2 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/{lambda-edge-9xiONGmR.d.cts → lambda-edge-D1NHYwvA.d.cts} +1 -1
- package/dist/{lambda-edge-BK3-bFx8.d.ts → lambda-edge-DnIvWFGe.d.ts} +1 -1
- package/package.json +1 -1
- package/dist/chunk-GK5JX7OM.cjs +0 -39
- package/dist/chunk-UI6LKDJI.cjs +0 -19
- package/dist/chunk-VQCRSBWL.js +0 -19
- package/dist/{chunk-RL7ZETZR.js → chunk-ER2YEZZO.js} +3 -3
- package/dist/{chunk-T5EXFHVA.cjs → chunk-MO7HW25R.cjs} +3 -3
package/README.md
CHANGED
|
@@ -29,12 +29,12 @@ export default defineViewerRequest([
|
|
|
29
29
|
**viewer-response** — security and CORS headers:
|
|
30
30
|
|
|
31
31
|
```typescript
|
|
32
|
-
import { setSecurityHeaders, setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors/index'
|
|
32
|
+
import { setSecurityHeaders, setCorsHeaders, ORIGIN_WILDCARD } from '@rayselfs/cf-rule-engine/behaviors/index'
|
|
33
33
|
import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/viewer-response'
|
|
34
34
|
|
|
35
35
|
export default defineViewerResponse([
|
|
36
36
|
setSecurityHeaders(),
|
|
37
|
-
setCorsHeaders({ allowedOrigins:
|
|
37
|
+
setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
|
|
38
38
|
])
|
|
39
39
|
```
|
|
40
40
|
|
|
@@ -113,6 +113,31 @@ Use `chain()` when one behavior must see the request mutations (URI rewrite, hea
|
|
|
113
113
|
| `imageOptimize(options)` | ✅ | ✅ |
|
|
114
114
|
| `verifyToken(options)` | ❌ | ✅ |
|
|
115
115
|
|
|
116
|
+
### setCorsHeaders — OriginPolicy
|
|
117
|
+
|
|
118
|
+
`allowedOrigins` accepts an `OriginPolicy` that controls how `Access-Control-Allow-Origin` is set:
|
|
119
|
+
|
|
120
|
+
| Value | Behavior |
|
|
121
|
+
|---|---|
|
|
122
|
+
| `ORIGIN_WILDCARD` (`'*'`) | Static `Access-Control-Allow-Origin: *` — for fully public APIs |
|
|
123
|
+
| `Origin[]` | Compare request `Origin` against the list; echo if matched, skip if not. Supports wildcard subdomains (`https://*.example.com`). |
|
|
124
|
+
| `ORIGIN_ECHO` (`'echo'`) | Echo any request `Origin` if present, skip if none — use with `allowCredentials: true` |
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
import { setCorsHeaders, ORIGIN_WILDCARD, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors/index'
|
|
128
|
+
|
|
129
|
+
// Public API
|
|
130
|
+
setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD })
|
|
131
|
+
|
|
132
|
+
// Restricted — echo only listed origins
|
|
133
|
+
setCorsHeaders({ allowedOrigins: ['https://*.viverse.com', 'https://sdk-api.viverse.com'] })
|
|
134
|
+
|
|
135
|
+
// Echo any origin (required when allowCredentials: true)
|
|
136
|
+
setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true })
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`allowedMethods` and `allowedHeaders` are optional — omit to exclude those headers from the response.
|
|
140
|
+
|
|
116
141
|
## Helpers (`@rayselfs/cf-rule-engine/helpers/index`)
|
|
117
142
|
|
|
118
143
|
Helpers are pre-configured rule factories that combine multiple criteria and behaviors for common use cases.
|
|
@@ -134,9 +159,10 @@ Adds `x-cf-distribution: staging` to the response when the request carries `aws-
|
|
|
134
159
|
|
|
135
160
|
```typescript
|
|
136
161
|
import { stagingIndicator } from '@rayselfs/cf-rule-engine/helpers/index'
|
|
162
|
+
import { setCorsHeaders, ORIGIN_WILDCARD } from '@rayselfs/cf-rule-engine/behaviors/index'
|
|
137
163
|
|
|
138
164
|
defineViewerResponse([
|
|
139
|
-
setCorsHeaders({ allowedOrigins:
|
|
165
|
+
setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
|
|
140
166
|
stagingIndicator(),
|
|
141
167
|
])
|
|
142
168
|
```
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '../core/types.cjs';
|
|
2
|
-
export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-
|
|
2
|
+
export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-D1NHYwvA.cjs';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import '../core/types.js';
|
|
2
|
-
export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-
|
|
2
|
+
export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-DnIvWFGe.js';
|
package/dist/behaviors/index.cjs
CHANGED
|
@@ -6,7 +6,7 @@ var _chunkPPUHEL4Hcjs = require('../chunk-PPUHEL4H.cjs');
|
|
|
6
6
|
var _chunkB4WEJSEZcjs = require('../chunk-B4WEJSEZ.cjs');
|
|
7
7
|
|
|
8
8
|
|
|
9
|
-
var
|
|
9
|
+
var _chunk3UXNXJ6Ncjs = require('../chunk-3UXNXJ6N.cjs');
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
var _chunkMSES76XKcjs = require('../chunk-MSES76XK.cjs');
|
|
@@ -27,7 +27,7 @@ var _chunkMRPTC74Icjs = require('../chunk-MRPTC74I.cjs');
|
|
|
27
27
|
var _chunkCV234DQTcjs = require('../chunk-CV234DQT.cjs');
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
var
|
|
30
|
+
var _chunkWAKA4OJDcjs = require('../chunk-WAKA4OJD.cjs');
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
var _chunkZXS23HXAcjs = require('../chunk-ZXS23HXA.cjs');
|
|
@@ -123,4 +123,4 @@ function verifyToken(options) {
|
|
|
123
123
|
|
|
124
124
|
|
|
125
125
|
|
|
126
|
-
exports.constructResponse = _chunkOSGZTNTScjs.constructResponse; exports.copyHeader = _chunkJU5WX5RUcjs.copyHeader; exports.directoryIndex = _chunkLTLBEBKLcjs.directoryIndex; exports.imageOptimize = _chunkKXC6ES3Bcjs.imageOptimize; exports.redirect = _chunkWWSRNCUPcjs.redirect; exports.removeResponseHeaders = _chunkSGEBNQR2cjs.removeResponseHeaders; exports.rewriteUri = _chunkMRPTC74Icjs.rewriteUri; exports.setCacheControl = _chunkCV234DQTcjs.setCacheControl; exports.setCorsHeaders =
|
|
126
|
+
exports.constructResponse = _chunkOSGZTNTScjs.constructResponse; exports.copyHeader = _chunkJU5WX5RUcjs.copyHeader; exports.directoryIndex = _chunkLTLBEBKLcjs.directoryIndex; exports.imageOptimize = _chunkKXC6ES3Bcjs.imageOptimize; exports.redirect = _chunkWWSRNCUPcjs.redirect; exports.removeResponseHeaders = _chunkSGEBNQR2cjs.removeResponseHeaders; exports.rewriteUri = _chunkMRPTC74Icjs.rewriteUri; exports.setCacheControl = _chunkCV234DQTcjs.setCacheControl; exports.setCorsHeaders = _chunkWAKA4OJDcjs.setCorsHeaders; exports.setCsp = _chunkZXS23HXAcjs.setCsp; exports.setRequestHeader = _chunkPPUHEL4Hcjs.setRequestHeader; exports.setResponseHeader = _chunkB4WEJSEZcjs.setResponseHeader; exports.setSecurityHeaders = _chunk3UXNXJ6Ncjs.setSecurityHeaders; exports.stripQueryParams = _chunkMSES76XKcjs.stripQueryParams; exports.verifyToken = verifyToken;
|
package/dist/behaviors/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
} from "../chunk-RBBKFG5J.js";
|
|
7
7
|
import {
|
|
8
8
|
setSecurityHeaders
|
|
9
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-O4SOSGAP.js";
|
|
10
10
|
import {
|
|
11
11
|
stripQueryParams
|
|
12
12
|
} from "../chunk-XPQG5IML.js";
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from "../chunk-ZTMSH34E.js";
|
|
28
28
|
import {
|
|
29
29
|
setCorsHeaders
|
|
30
|
-
} from "../chunk-
|
|
30
|
+
} from "../chunk-SRA2DFKG.js";
|
|
31
31
|
import {
|
|
32
32
|
setCsp
|
|
33
33
|
} from "../chunk-XUI4Y22M.js";
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var _chunkWAKA4OJDcjs = require('../chunk-WAKA4OJD.cjs');
|
|
4
6
|
require('../chunk-75ZPJI57.cjs');
|
|
5
7
|
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
exports.ORIGIN_ECHO = _chunkWAKA4OJDcjs.ORIGIN_ECHO; exports.ORIGIN_WILDCARD = _chunkWAKA4OJDcjs.ORIGIN_WILDCARD; exports.setCorsHeaders = _chunkWAKA4OJDcjs.setCorsHeaders;
|
|
@@ -1,38 +1,42 @@
|
|
|
1
1
|
import { ResponseBehaviorFn } from '../core/types.cjs';
|
|
2
2
|
|
|
3
|
+
declare const ORIGIN_WILDCARD: "*";
|
|
4
|
+
type OriginWildcard = typeof ORIGIN_WILDCARD;
|
|
5
|
+
declare const ORIGIN_ECHO: "echo";
|
|
6
|
+
type OriginEcho = typeof ORIGIN_ECHO;
|
|
3
7
|
/**
|
|
4
|
-
*
|
|
8
|
+
* A valid HTTP origin — must start with `https://` or `http://`.
|
|
9
|
+
* Supports wildcard subdomains (e.g. `https://*.viverse.com`).
|
|
10
|
+
*/
|
|
11
|
+
type Origin = `https://${string}` | `http://${string}`;
|
|
12
|
+
/**
|
|
13
|
+
* Controls how `Access-Control-Allow-Origin` is set:
|
|
14
|
+
* - `ORIGIN_WILDCARD` (`'*'`) — static `*`, allows all origins without inspection
|
|
15
|
+
* - `Origin[]` — compare request `Origin` header against the list; echo if matched, skip if not
|
|
16
|
+
* - `ORIGIN_ECHO` (`'echo'`) — echo any request `Origin` if present, skip if none
|
|
17
|
+
*/
|
|
18
|
+
type OriginPolicy = OriginWildcard | Origin[] | OriginEcho;
|
|
19
|
+
/**
|
|
20
|
+
* CORS configuration options for `setCorsHeaders` and `preflightRequest`.
|
|
5
21
|
*/
|
|
6
22
|
interface CorsOptions {
|
|
7
23
|
/**
|
|
8
|
-
*
|
|
9
|
-
* (e.g. `'https://*.example.com'`). Use `['*']` to allow all origins.
|
|
10
|
-
* Default: `['*']`
|
|
24
|
+
* Origin policy. See `OriginPolicy` for details.
|
|
11
25
|
*/
|
|
12
|
-
allowedOrigins
|
|
13
|
-
/**
|
|
14
|
-
* When `true`, reflects the incoming `Origin` request header as the
|
|
15
|
-
* `Access-Control-Allow-Origin` response value, provided it matches one of
|
|
16
|
-
* `allowedOrigins`. Required when `allowCredentials` is `true` (browsers reject
|
|
17
|
-
* `Access-Control-Allow-Origin: *` with credentials).
|
|
18
|
-
* Default: `false`
|
|
19
|
-
*/
|
|
20
|
-
allowOriginEcho?: boolean;
|
|
26
|
+
allowedOrigins: OriginPolicy;
|
|
21
27
|
/**
|
|
22
28
|
* Value for the `Access-Control-Allow-Methods` header.
|
|
23
|
-
*
|
|
29
|
+
* Omit to exclude the header.
|
|
24
30
|
*/
|
|
25
31
|
allowedMethods?: string;
|
|
26
32
|
/**
|
|
27
33
|
* Value for the `Access-Control-Allow-Headers` header.
|
|
28
|
-
*
|
|
34
|
+
* Omit to exclude the header.
|
|
29
35
|
*/
|
|
30
36
|
allowedHeaders?: string;
|
|
31
37
|
/**
|
|
32
38
|
* When `true`, sets `Access-Control-Allow-Credentials: true`.
|
|
33
|
-
*
|
|
34
|
-
* wildcard origins when credentials are present.
|
|
35
|
-
* Default: `false`
|
|
39
|
+
* Use with `ORIGIN_ECHO` or `Origin[]` — browsers reject `*` with credentials.
|
|
36
40
|
*/
|
|
37
41
|
allowCredentials?: boolean;
|
|
38
42
|
/**
|
|
@@ -42,35 +46,32 @@ interface CorsOptions {
|
|
|
42
46
|
maxAge?: number;
|
|
43
47
|
}
|
|
44
48
|
/**
|
|
45
|
-
* Sets CORS response headers with configurable origin
|
|
46
|
-
* credentials, and preflight cache duration.
|
|
47
|
-
*
|
|
48
|
-
* Akamai equivalent: typically implemented via `modifyOutgoingResponseHeader` rules
|
|
49
|
-
* for each CORS header individually.
|
|
49
|
+
* Sets CORS response headers with configurable origin policy.
|
|
50
50
|
*
|
|
51
|
-
* @param options - CORS configuration.
|
|
51
|
+
* @param options - CORS configuration. `allowedOrigins` is required.
|
|
52
52
|
* @returns A `ResponseBehaviorFn` to use directly in `defineViewerResponse` or wrapped in a `ResponseRule`.
|
|
53
53
|
*
|
|
54
54
|
* @example
|
|
55
55
|
* ```ts
|
|
56
|
-
* import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
|
|
57
|
-
* import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/
|
|
56
|
+
* import { setCorsHeaders, ORIGIN_WILDCARD, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors/set-cors-headers'
|
|
57
|
+
* import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/viewer-response'
|
|
58
58
|
*
|
|
59
|
-
* //
|
|
60
|
-
* export default defineViewerResponse([
|
|
59
|
+
* // Public API — static Access-Control-Allow-Origin: *
|
|
60
|
+
* export default defineViewerResponse([
|
|
61
|
+
* setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
|
|
62
|
+
* ])
|
|
63
|
+
*
|
|
64
|
+
* // Restricted — echo only listed origins (supports wildcard subdomains)
|
|
65
|
+
* export default defineViewerResponse([
|
|
66
|
+
* setCorsHeaders({ allowedOrigins: ['https://*.viverse.com', 'https://sdk-api.viverse.com'] }),
|
|
67
|
+
* ])
|
|
61
68
|
*
|
|
62
|
-
* // Echo origin
|
|
69
|
+
* // Echo any origin (e.g. for credentialed requests)
|
|
63
70
|
* export default defineViewerResponse([
|
|
64
|
-
* setCorsHeaders({
|
|
65
|
-
* allowedOrigins: ['https://www.example.com', 'https://*.example.com'],
|
|
66
|
-
* allowOriginEcho: true,
|
|
67
|
-
* allowCredentials: true,
|
|
68
|
-
* allowedMethods: 'GET, POST, PUT, DELETE, OPTIONS',
|
|
69
|
-
* maxAge: 86400,
|
|
70
|
-
* }),
|
|
71
|
+
* setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true }),
|
|
71
72
|
* ])
|
|
72
73
|
* ```
|
|
73
74
|
*/
|
|
74
|
-
declare function setCorsHeaders(options
|
|
75
|
+
declare function setCorsHeaders(options: CorsOptions): ResponseBehaviorFn;
|
|
75
76
|
|
|
76
|
-
export { type CorsOptions, setCorsHeaders };
|
|
77
|
+
export { type CorsOptions, ORIGIN_ECHO, ORIGIN_WILDCARD, type Origin, type OriginEcho, type OriginPolicy, type OriginWildcard, setCorsHeaders };
|
|
@@ -1,38 +1,42 @@
|
|
|
1
1
|
import { ResponseBehaviorFn } from '../core/types.js';
|
|
2
2
|
|
|
3
|
+
declare const ORIGIN_WILDCARD: "*";
|
|
4
|
+
type OriginWildcard = typeof ORIGIN_WILDCARD;
|
|
5
|
+
declare const ORIGIN_ECHO: "echo";
|
|
6
|
+
type OriginEcho = typeof ORIGIN_ECHO;
|
|
3
7
|
/**
|
|
4
|
-
*
|
|
8
|
+
* A valid HTTP origin — must start with `https://` or `http://`.
|
|
9
|
+
* Supports wildcard subdomains (e.g. `https://*.viverse.com`).
|
|
10
|
+
*/
|
|
11
|
+
type Origin = `https://${string}` | `http://${string}`;
|
|
12
|
+
/**
|
|
13
|
+
* Controls how `Access-Control-Allow-Origin` is set:
|
|
14
|
+
* - `ORIGIN_WILDCARD` (`'*'`) — static `*`, allows all origins without inspection
|
|
15
|
+
* - `Origin[]` — compare request `Origin` header against the list; echo if matched, skip if not
|
|
16
|
+
* - `ORIGIN_ECHO` (`'echo'`) — echo any request `Origin` if present, skip if none
|
|
17
|
+
*/
|
|
18
|
+
type OriginPolicy = OriginWildcard | Origin[] | OriginEcho;
|
|
19
|
+
/**
|
|
20
|
+
* CORS configuration options for `setCorsHeaders` and `preflightRequest`.
|
|
5
21
|
*/
|
|
6
22
|
interface CorsOptions {
|
|
7
23
|
/**
|
|
8
|
-
*
|
|
9
|
-
* (e.g. `'https://*.example.com'`). Use `['*']` to allow all origins.
|
|
10
|
-
* Default: `['*']`
|
|
24
|
+
* Origin policy. See `OriginPolicy` for details.
|
|
11
25
|
*/
|
|
12
|
-
allowedOrigins
|
|
13
|
-
/**
|
|
14
|
-
* When `true`, reflects the incoming `Origin` request header as the
|
|
15
|
-
* `Access-Control-Allow-Origin` response value, provided it matches one of
|
|
16
|
-
* `allowedOrigins`. Required when `allowCredentials` is `true` (browsers reject
|
|
17
|
-
* `Access-Control-Allow-Origin: *` with credentials).
|
|
18
|
-
* Default: `false`
|
|
19
|
-
*/
|
|
20
|
-
allowOriginEcho?: boolean;
|
|
26
|
+
allowedOrigins: OriginPolicy;
|
|
21
27
|
/**
|
|
22
28
|
* Value for the `Access-Control-Allow-Methods` header.
|
|
23
|
-
*
|
|
29
|
+
* Omit to exclude the header.
|
|
24
30
|
*/
|
|
25
31
|
allowedMethods?: string;
|
|
26
32
|
/**
|
|
27
33
|
* Value for the `Access-Control-Allow-Headers` header.
|
|
28
|
-
*
|
|
34
|
+
* Omit to exclude the header.
|
|
29
35
|
*/
|
|
30
36
|
allowedHeaders?: string;
|
|
31
37
|
/**
|
|
32
38
|
* When `true`, sets `Access-Control-Allow-Credentials: true`.
|
|
33
|
-
*
|
|
34
|
-
* wildcard origins when credentials are present.
|
|
35
|
-
* Default: `false`
|
|
39
|
+
* Use with `ORIGIN_ECHO` or `Origin[]` — browsers reject `*` with credentials.
|
|
36
40
|
*/
|
|
37
41
|
allowCredentials?: boolean;
|
|
38
42
|
/**
|
|
@@ -42,35 +46,32 @@ interface CorsOptions {
|
|
|
42
46
|
maxAge?: number;
|
|
43
47
|
}
|
|
44
48
|
/**
|
|
45
|
-
* Sets CORS response headers with configurable origin
|
|
46
|
-
* credentials, and preflight cache duration.
|
|
47
|
-
*
|
|
48
|
-
* Akamai equivalent: typically implemented via `modifyOutgoingResponseHeader` rules
|
|
49
|
-
* for each CORS header individually.
|
|
49
|
+
* Sets CORS response headers with configurable origin policy.
|
|
50
50
|
*
|
|
51
|
-
* @param options - CORS configuration.
|
|
51
|
+
* @param options - CORS configuration. `allowedOrigins` is required.
|
|
52
52
|
* @returns A `ResponseBehaviorFn` to use directly in `defineViewerResponse` or wrapped in a `ResponseRule`.
|
|
53
53
|
*
|
|
54
54
|
* @example
|
|
55
55
|
* ```ts
|
|
56
|
-
* import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
|
|
57
|
-
* import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/
|
|
56
|
+
* import { setCorsHeaders, ORIGIN_WILDCARD, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors/set-cors-headers'
|
|
57
|
+
* import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/viewer-response'
|
|
58
58
|
*
|
|
59
|
-
* //
|
|
60
|
-
* export default defineViewerResponse([
|
|
59
|
+
* // Public API — static Access-Control-Allow-Origin: *
|
|
60
|
+
* export default defineViewerResponse([
|
|
61
|
+
* setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
|
|
62
|
+
* ])
|
|
63
|
+
*
|
|
64
|
+
* // Restricted — echo only listed origins (supports wildcard subdomains)
|
|
65
|
+
* export default defineViewerResponse([
|
|
66
|
+
* setCorsHeaders({ allowedOrigins: ['https://*.viverse.com', 'https://sdk-api.viverse.com'] }),
|
|
67
|
+
* ])
|
|
61
68
|
*
|
|
62
|
-
* // Echo origin
|
|
69
|
+
* // Echo any origin (e.g. for credentialed requests)
|
|
63
70
|
* export default defineViewerResponse([
|
|
64
|
-
* setCorsHeaders({
|
|
65
|
-
* allowedOrigins: ['https://www.example.com', 'https://*.example.com'],
|
|
66
|
-
* allowOriginEcho: true,
|
|
67
|
-
* allowCredentials: true,
|
|
68
|
-
* allowedMethods: 'GET, POST, PUT, DELETE, OPTIONS',
|
|
69
|
-
* maxAge: 86400,
|
|
70
|
-
* }),
|
|
71
|
+
* setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true }),
|
|
71
72
|
* ])
|
|
72
73
|
* ```
|
|
73
74
|
*/
|
|
74
|
-
declare function setCorsHeaders(options
|
|
75
|
+
declare function setCorsHeaders(options: CorsOptions): ResponseBehaviorFn;
|
|
75
76
|
|
|
76
|
-
export { type CorsOptions, setCorsHeaders };
|
|
77
|
+
export { type CorsOptions, ORIGIN_ECHO, ORIGIN_WILDCARD, type Origin, type OriginEcho, type OriginPolicy, type OriginWildcard, setCorsHeaders };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var _chunk3UXNXJ6Ncjs = require('../chunk-3UXNXJ6N.cjs');
|
|
4
4
|
require('../chunk-75ZPJI57.cjs');
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
exports.setSecurityHeaders =
|
|
7
|
+
exports.setSecurityHeaders = _chunk3UXNXJ6Ncjs.setSecurityHeaders;
|
|
@@ -1,55 +1,71 @@
|
|
|
1
1
|
import { ResponseBehaviorFn } from '../core/types.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Options for
|
|
5
|
-
*
|
|
4
|
+
* Options for individual security header values.
|
|
5
|
+
*
|
|
6
|
+
* Only headers with a provided value are emitted — omitted fields are **not** added to the
|
|
7
|
+
* response. There are no built-in defaults; every emitted header value is explicit.
|
|
8
|
+
*
|
|
9
|
+
* Pass at least one field.
|
|
6
10
|
*/
|
|
7
11
|
interface SecurityHeadersOptions {
|
|
8
12
|
/**
|
|
9
13
|
* Value for the `Strict-Transport-Security` header.
|
|
10
|
-
*
|
|
14
|
+
* Example: `'max-age=31536000; includeSubDomains'`
|
|
11
15
|
*/
|
|
12
16
|
hsts?: string;
|
|
13
17
|
/**
|
|
14
18
|
* Value for the `X-Frame-Options` header. Controls whether the page can be
|
|
15
19
|
* embedded in an iframe. Common values: `'DENY'`, `'SAMEORIGIN'`.
|
|
16
|
-
* Default: `'SAMEORIGIN'`
|
|
17
20
|
*/
|
|
18
21
|
xFrameOptions?: string;
|
|
19
22
|
/**
|
|
20
23
|
* Value for the `X-Content-Type-Options` header. Set to `'nosniff'` to
|
|
21
24
|
* prevent browsers from MIME-sniffing the response content type.
|
|
22
|
-
* Default: `'nosniff'`
|
|
23
25
|
*/
|
|
24
26
|
xContentTypeOptions?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Value for the `X-XSS-Protection` header.
|
|
29
|
+
* Example: `'1; mode=block'`
|
|
30
|
+
*
|
|
31
|
+
* Note: deprecated in modern browsers but still used for legacy compatibility.
|
|
32
|
+
*/
|
|
33
|
+
xXssProtection?: string;
|
|
25
34
|
}
|
|
26
35
|
/**
|
|
27
|
-
* Sets
|
|
36
|
+
* Sets security headers on the outgoing response.
|
|
37
|
+
*
|
|
38
|
+
* Only headers explicitly provided in `options` are emitted — there are **no built-in
|
|
39
|
+
* defaults**. This avoids silently overriding headers set elsewhere in the pipeline and
|
|
40
|
+
* lets Akamai-migrated properties carry their original values verbatim.
|
|
28
41
|
*
|
|
29
|
-
*
|
|
30
|
-
* - `Strict-Transport-Security
|
|
31
|
-
* - `X-Frame-Options
|
|
32
|
-
* - `X-Content-Type-Options
|
|
42
|
+
* Supported headers:
|
|
43
|
+
* - `Strict-Transport-Security` (`hsts`)
|
|
44
|
+
* - `X-Frame-Options` (`xFrameOptions`)
|
|
45
|
+
* - `X-Content-Type-Options` (`xContentTypeOptions`)
|
|
46
|
+
* - `X-XSS-Protection` (`xXssProtection`)
|
|
33
47
|
*
|
|
34
|
-
* Akamai
|
|
48
|
+
* Akamai equivalents: `httpStrictTransportSecurity` (HSTS), `modifyOutgoingResponseHeader`
|
|
49
|
+
* (frame options, content-type options, XSS protection).
|
|
35
50
|
*
|
|
36
|
-
* @param options -
|
|
37
|
-
* @returns A `ResponseBehaviorFn` to use
|
|
51
|
+
* @param options - Security header values to set. Pass at least one field.
|
|
52
|
+
* @returns A `ResponseBehaviorFn` to use in `defineViewerResponse` or a `ResponseRule`.
|
|
38
53
|
*
|
|
39
54
|
* @example
|
|
40
55
|
* ```ts
|
|
41
56
|
* import { setSecurityHeaders } from '@rayselfs/cf-rule-engine/behaviors'
|
|
42
57
|
* import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/cf-function'
|
|
43
58
|
*
|
|
44
|
-
* // Apply defaults
|
|
45
|
-
* export default defineViewerResponse([setSecurityHeaders()])
|
|
46
|
-
*
|
|
47
|
-
* // Override HSTS and frame options
|
|
48
59
|
* export default defineViewerResponse([
|
|
49
|
-
* setSecurityHeaders({
|
|
60
|
+
* setSecurityHeaders({
|
|
61
|
+
* hsts: 'max-age=31536000; includeSubDomains',
|
|
62
|
+
* xFrameOptions: 'SAMEORIGIN',
|
|
63
|
+
* xContentTypeOptions: 'nosniff',
|
|
64
|
+
* xXssProtection: '1; mode=block',
|
|
65
|
+
* }),
|
|
50
66
|
* ])
|
|
51
67
|
* ```
|
|
52
68
|
*/
|
|
53
|
-
declare function setSecurityHeaders(options
|
|
69
|
+
declare function setSecurityHeaders(options: SecurityHeadersOptions): ResponseBehaviorFn;
|
|
54
70
|
|
|
55
71
|
export { type SecurityHeadersOptions, setSecurityHeaders };
|
|
@@ -1,55 +1,71 @@
|
|
|
1
1
|
import { ResponseBehaviorFn } from '../core/types.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
* Options for
|
|
5
|
-
*
|
|
4
|
+
* Options for individual security header values.
|
|
5
|
+
*
|
|
6
|
+
* Only headers with a provided value are emitted — omitted fields are **not** added to the
|
|
7
|
+
* response. There are no built-in defaults; every emitted header value is explicit.
|
|
8
|
+
*
|
|
9
|
+
* Pass at least one field.
|
|
6
10
|
*/
|
|
7
11
|
interface SecurityHeadersOptions {
|
|
8
12
|
/**
|
|
9
13
|
* Value for the `Strict-Transport-Security` header.
|
|
10
|
-
*
|
|
14
|
+
* Example: `'max-age=31536000; includeSubDomains'`
|
|
11
15
|
*/
|
|
12
16
|
hsts?: string;
|
|
13
17
|
/**
|
|
14
18
|
* Value for the `X-Frame-Options` header. Controls whether the page can be
|
|
15
19
|
* embedded in an iframe. Common values: `'DENY'`, `'SAMEORIGIN'`.
|
|
16
|
-
* Default: `'SAMEORIGIN'`
|
|
17
20
|
*/
|
|
18
21
|
xFrameOptions?: string;
|
|
19
22
|
/**
|
|
20
23
|
* Value for the `X-Content-Type-Options` header. Set to `'nosniff'` to
|
|
21
24
|
* prevent browsers from MIME-sniffing the response content type.
|
|
22
|
-
* Default: `'nosniff'`
|
|
23
25
|
*/
|
|
24
26
|
xContentTypeOptions?: string;
|
|
27
|
+
/**
|
|
28
|
+
* Value for the `X-XSS-Protection` header.
|
|
29
|
+
* Example: `'1; mode=block'`
|
|
30
|
+
*
|
|
31
|
+
* Note: deprecated in modern browsers but still used for legacy compatibility.
|
|
32
|
+
*/
|
|
33
|
+
xXssProtection?: string;
|
|
25
34
|
}
|
|
26
35
|
/**
|
|
27
|
-
* Sets
|
|
36
|
+
* Sets security headers on the outgoing response.
|
|
37
|
+
*
|
|
38
|
+
* Only headers explicitly provided in `options` are emitted — there are **no built-in
|
|
39
|
+
* defaults**. This avoids silently overriding headers set elsewhere in the pipeline and
|
|
40
|
+
* lets Akamai-migrated properties carry their original values verbatim.
|
|
28
41
|
*
|
|
29
|
-
*
|
|
30
|
-
* - `Strict-Transport-Security
|
|
31
|
-
* - `X-Frame-Options
|
|
32
|
-
* - `X-Content-Type-Options
|
|
42
|
+
* Supported headers:
|
|
43
|
+
* - `Strict-Transport-Security` (`hsts`)
|
|
44
|
+
* - `X-Frame-Options` (`xFrameOptions`)
|
|
45
|
+
* - `X-Content-Type-Options` (`xContentTypeOptions`)
|
|
46
|
+
* - `X-XSS-Protection` (`xXssProtection`)
|
|
33
47
|
*
|
|
34
|
-
* Akamai
|
|
48
|
+
* Akamai equivalents: `httpStrictTransportSecurity` (HSTS), `modifyOutgoingResponseHeader`
|
|
49
|
+
* (frame options, content-type options, XSS protection).
|
|
35
50
|
*
|
|
36
|
-
* @param options -
|
|
37
|
-
* @returns A `ResponseBehaviorFn` to use
|
|
51
|
+
* @param options - Security header values to set. Pass at least one field.
|
|
52
|
+
* @returns A `ResponseBehaviorFn` to use in `defineViewerResponse` or a `ResponseRule`.
|
|
38
53
|
*
|
|
39
54
|
* @example
|
|
40
55
|
* ```ts
|
|
41
56
|
* import { setSecurityHeaders } from '@rayselfs/cf-rule-engine/behaviors'
|
|
42
57
|
* import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/cf-function'
|
|
43
58
|
*
|
|
44
|
-
* // Apply defaults
|
|
45
|
-
* export default defineViewerResponse([setSecurityHeaders()])
|
|
46
|
-
*
|
|
47
|
-
* // Override HSTS and frame options
|
|
48
59
|
* export default defineViewerResponse([
|
|
49
|
-
* setSecurityHeaders({
|
|
60
|
+
* setSecurityHeaders({
|
|
61
|
+
* hsts: 'max-age=31536000; includeSubDomains',
|
|
62
|
+
* xFrameOptions: 'SAMEORIGIN',
|
|
63
|
+
* xContentTypeOptions: 'nosniff',
|
|
64
|
+
* xXssProtection: '1; mode=block',
|
|
65
|
+
* }),
|
|
50
66
|
* ])
|
|
51
67
|
* ```
|
|
52
68
|
*/
|
|
53
|
-
declare function setSecurityHeaders(options
|
|
69
|
+
declare function setSecurityHeaders(options: SecurityHeadersOptions): ResponseBehaviorFn;
|
|
54
70
|
|
|
55
71
|
export { type SecurityHeadersOptions, setSecurityHeaders };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});// src/behaviors/set-security-headers.ts
|
|
2
|
+
function setSecurityHeaders(options) {
|
|
3
|
+
return (_request, response) => {
|
|
4
|
+
const extra = {};
|
|
5
|
+
if (options.hsts !== void 0)
|
|
6
|
+
extra["strict-transport-security"] = { value: options.hsts };
|
|
7
|
+
if (options.xFrameOptions !== void 0)
|
|
8
|
+
extra["x-frame-options"] = { value: options.xFrameOptions };
|
|
9
|
+
if (options.xContentTypeOptions !== void 0)
|
|
10
|
+
extra["x-content-type-options"] = { value: options.xContentTypeOptions };
|
|
11
|
+
if (options.xXssProtection !== void 0)
|
|
12
|
+
extra["x-xss-protection"] = { value: options.xXssProtection };
|
|
13
|
+
return Object.assign({}, response, {
|
|
14
|
+
headers: Object.assign({}, response.headers, extra)
|
|
15
|
+
});
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
exports.setSecurityHeaders = setSecurityHeaders;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
methodIs
|
|
3
3
|
} from "./chunk-PY3JMRDG.js";
|
|
4
|
+
import {
|
|
5
|
+
ORIGIN_ECHO,
|
|
6
|
+
ORIGIN_WILDCARD
|
|
7
|
+
} from "./chunk-SRA2DFKG.js";
|
|
4
8
|
|
|
5
9
|
// src/helpers/preflight-request.ts
|
|
6
10
|
function matchesOriginPattern(origin, pattern) {
|
|
@@ -10,27 +14,33 @@ function matchesOriginPattern(origin, pattern) {
|
|
|
10
14
|
return new RegExp(`^${escaped}$`).test(origin);
|
|
11
15
|
}
|
|
12
16
|
function preflightRequest(options) {
|
|
13
|
-
const allowedOrigins = options
|
|
14
|
-
const allowedMethods = options
|
|
15
|
-
const allowedHeaders = options
|
|
16
|
-
const allowCredentials = options
|
|
17
|
-
const maxAge = options
|
|
17
|
+
const { allowedOrigins } = options;
|
|
18
|
+
const allowedMethods = options.allowedMethods ?? "GET, POST, OPTIONS";
|
|
19
|
+
const allowedHeaders = options.allowedHeaders ?? "Content-Type, Cache-Control, Pragma, Range";
|
|
20
|
+
const allowCredentials = options.allowCredentials ?? false;
|
|
21
|
+
const maxAge = options.maxAge;
|
|
18
22
|
return {
|
|
19
23
|
criteria: methodIs(["OPTIONS"]),
|
|
20
24
|
behavior: (request) => {
|
|
21
25
|
let allowOrigin;
|
|
22
|
-
if (
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
if (allowedOrigins === ORIGIN_WILDCARD) {
|
|
27
|
+
allowOrigin = "*";
|
|
28
|
+
} else if (allowedOrigins === ORIGIN_ECHO) {
|
|
29
|
+
allowOrigin = request.headers["origin"]?.value;
|
|
25
30
|
} else {
|
|
26
|
-
|
|
31
|
+
const originHeader = request.headers["origin"]?.value;
|
|
32
|
+
if (originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p))) {
|
|
33
|
+
allowOrigin = originHeader;
|
|
34
|
+
}
|
|
27
35
|
}
|
|
28
36
|
const headers = {
|
|
29
37
|
"cache-control": { value: "no-store" },
|
|
30
|
-
"access-control-allow-origin": { value: allowOrigin },
|
|
31
38
|
"access-control-allow-methods": { value: allowedMethods },
|
|
32
39
|
"access-control-allow-headers": { value: allowedHeaders }
|
|
33
40
|
};
|
|
41
|
+
if (allowOrigin !== void 0) {
|
|
42
|
+
headers["access-control-allow-origin"] = { value: allowOrigin };
|
|
43
|
+
}
|
|
34
44
|
if (allowCredentials) {
|
|
35
45
|
headers["access-control-allow-credentials"] = { value: "true" };
|
|
36
46
|
}
|