@middy/http-cors 6.1.6 → 6.2.1

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.
Files changed (3) hide show
  1. package/index.d.ts +15 -15
  2. package/index.js +168 -167
  3. package/package.json +67 -70
package/index.d.ts CHANGED
@@ -1,20 +1,20 @@
1
- import middy from '@middy/core'
1
+ import type middy from "@middy/core";
2
2
 
3
3
  export interface Options {
4
- getOrigin?: (incomingOrigin: string, options: Options) => string
5
- credentials?: boolean | string
6
- disableBeforePreflightResponse?: boolean
7
- headers?: string
8
- methods?: string
9
- origin?: string
10
- origins?: string[]
11
- exposeHeaders?: string
12
- maxAge?: number | string
13
- requestHeaders?: string
14
- requestMethods?: string
15
- cacheControl?: string
4
+ getOrigin?: (incomingOrigin: string, options: Options) => string;
5
+ credentials?: boolean | string;
6
+ disableBeforePreflightResponse?: boolean;
7
+ headers?: string;
8
+ methods?: string;
9
+ origin?: string;
10
+ origins?: string[];
11
+ exposeHeaders?: string;
12
+ maxAge?: number | string;
13
+ requestHeaders?: string;
14
+ requestMethods?: string;
15
+ cacheControl?: string;
16
16
  }
17
17
 
18
- declare function httpCors (options?: Options): middy.MiddlewareObj
18
+ declare function httpCors(options?: Options): middy.MiddlewareObj;
19
19
 
20
- export default httpCors
20
+ export default httpCors;
package/index.js CHANGED
@@ -1,186 +1,187 @@
1
- import { normalizeHttpResponse } from '@middy/util'
1
+ import { normalizeHttpResponse } from "@middy/util";
2
2
 
3
3
  const defaults = {
4
- disableBeforePreflightResponse: true,
5
- getOrigin: undefined, // default inserted below
6
- credentials: undefined,
7
- headers: undefined,
8
- methods: undefined,
9
- origin: undefined,
10
- origins: [],
11
- exposeHeaders: undefined,
12
- maxAge: undefined,
13
- cacheControl: undefined,
14
- vary: undefined
15
- }
4
+ disableBeforePreflightResponse: true,
5
+ getOrigin: undefined, // default inserted below
6
+ credentials: undefined,
7
+ headers: undefined,
8
+ methods: undefined,
9
+ origin: undefined,
10
+ origins: [],
11
+ exposeHeaders: undefined,
12
+ maxAge: undefined,
13
+ cacheControl: undefined,
14
+ vary: undefined,
15
+ };
16
16
 
17
17
  const httpCorsMiddleware = (opts = {}) => {
18
- const getOrigin = (incomingOrigin, options = {}) => {
19
- if (options.origins.length > 0) {
20
- if (originStatic[incomingOrigin]) {
21
- return incomingOrigin
22
- }
23
- if (originAny) {
24
- if (options.credentials) {
25
- return incomingOrigin
26
- } else {
27
- return '*'
28
- }
29
- }
30
- if (originDynamic.some((regExp) => regExp.test(incomingOrigin))) {
31
- return incomingOrigin
32
- }
33
- // TODO deprecate `else` in v6
34
- } else {
35
- if (incomingOrigin && options.credentials && options.origin === '*') {
36
- return incomingOrigin
37
- }
38
- return options.origin
39
- }
40
- return null
41
- }
42
- const options = {
43
- ...defaults,
44
- getOrigin,
45
- ...opts
46
- }
18
+ const getOrigin = (incomingOrigin, options = {}) => {
19
+ if (options.origins.length > 0) {
20
+ if (originStatic[incomingOrigin]) {
21
+ return incomingOrigin;
22
+ }
23
+ if (originAny) {
24
+ if (options.credentials) {
25
+ return incomingOrigin;
26
+ }
27
+ return "*";
28
+ }
29
+ if (originDynamic.some((regExp) => regExp.test(incomingOrigin))) {
30
+ return incomingOrigin;
31
+ }
32
+ // TODO deprecate `else` in v6
33
+ } else {
34
+ if (incomingOrigin && options.credentials && options.origin === "*") {
35
+ return incomingOrigin;
36
+ }
37
+ return options.origin;
38
+ }
39
+ return null;
40
+ };
41
+ const options = {
42
+ ...defaults,
43
+ getOrigin,
44
+ ...opts,
45
+ };
47
46
 
48
- let originAny = false
49
- let originMany = options.origins.length > 1
50
- const originStatic = {}
51
- const originDynamic = []
47
+ let originAny = false;
48
+ let originMany = options.origins.length > 1;
49
+ const originStatic = {};
50
+ const originDynamic = [];
52
51
 
53
- for (const origin of [options.origin, ...options.origins]) {
54
- if (!origin) {
55
- continue
56
- }
57
- // All
58
- if (origin === '*') {
59
- originAny = true
60
- continue
61
- }
62
- // Static
63
- if (!origin.includes('*')) {
64
- originStatic[origin] = true
65
- continue
66
- }
67
- originMany = true
68
- // Dynamic
69
- // TODO: IDN -> puncycode not handled, add in if requested
70
- const regExpStr = origin.replaceAll('.', '\\.').replaceAll('*', '[^.]*')
71
- originDynamic.push(new RegExp(`^${regExpStr}$`))
72
- }
52
+ for (const origin of [options.origin, ...options.origins]) {
53
+ if (!origin) {
54
+ continue;
55
+ }
56
+ // All
57
+ if (origin === "*") {
58
+ originAny = true;
59
+ continue;
60
+ }
61
+ // Static
62
+ if (!origin.includes("*")) {
63
+ originStatic[origin] = true;
64
+ continue;
65
+ }
66
+ originMany = true;
67
+ // Dynamic
68
+ // TODO: IDN -> puncycode not handled, add in if requested
69
+ const regExpStr = origin.replaceAll(".", "\\.").replaceAll("*", "[^.]*");
70
+ // SAST Skipped: Not accessible by users
71
+ // nosemgrep: javascript.lang.security.audit.detect-non-literal-regexp.detect-non-literal-regexp
72
+ originDynamic.push(new RegExp(`^${regExpStr}$`));
73
+ }
73
74
 
74
- const modifyHeaders = (headers, options, request) => {
75
- const existingHeaders = Object.keys(headers)
76
- if (existingHeaders.includes('Access-Control-Allow-Credentials')) {
77
- options.credentials =
78
- headers['Access-Control-Allow-Credentials'] === 'true'
79
- }
80
- if (options.credentials) {
81
- headers['Access-Control-Allow-Credentials'] = String(options.credentials)
82
- }
83
- if (
84
- options.headers &&
85
- !existingHeaders.includes('Access-Control-Allow-Headers')
86
- ) {
87
- headers['Access-Control-Allow-Headers'] = options.headers
88
- }
89
- if (
90
- options.methods &&
91
- !existingHeaders.includes('Access-Control-Allow-Methods')
92
- ) {
93
- headers['Access-Control-Allow-Methods'] = options.methods
94
- }
75
+ const modifyHeaders = (headers, options, request) => {
76
+ const existingHeaders = Object.keys(headers);
77
+ if (existingHeaders.includes("Access-Control-Allow-Credentials")) {
78
+ options.credentials =
79
+ headers["Access-Control-Allow-Credentials"] === "true";
80
+ }
81
+ if (options.credentials) {
82
+ headers["Access-Control-Allow-Credentials"] = String(options.credentials);
83
+ }
84
+ if (
85
+ options.headers &&
86
+ !existingHeaders.includes("Access-Control-Allow-Headers")
87
+ ) {
88
+ headers["Access-Control-Allow-Headers"] = options.headers;
89
+ }
90
+ if (
91
+ options.methods &&
92
+ !existingHeaders.includes("Access-Control-Allow-Methods")
93
+ ) {
94
+ headers["Access-Control-Allow-Methods"] = options.methods;
95
+ }
95
96
 
96
- let newOrigin
97
- if (!existingHeaders.includes('Access-Control-Allow-Origin')) {
98
- const eventHeaders = request.event.headers ?? {}
99
- const incomingOrigin = eventHeaders.Origin ?? eventHeaders.origin
100
- newOrigin = options.getOrigin(incomingOrigin, options)
101
- if (newOrigin) {
102
- headers['Access-Control-Allow-Origin'] = newOrigin
103
- }
104
- }
97
+ let newOrigin;
98
+ if (!existingHeaders.includes("Access-Control-Allow-Origin")) {
99
+ const eventHeaders = request.event.headers ?? {};
100
+ const incomingOrigin = eventHeaders.Origin ?? eventHeaders.origin;
101
+ newOrigin = options.getOrigin(incomingOrigin, options);
102
+ if (newOrigin) {
103
+ headers["Access-Control-Allow-Origin"] = newOrigin;
104
+ }
105
+ }
105
106
 
106
- if (!headers.Vary) {
107
- addHeaderPart(headers, 'Vary', options.vary)
108
- }
107
+ if (!headers.Vary) {
108
+ addHeaderPart(headers, "Vary", options.vary);
109
+ }
109
110
 
110
- if (
111
- originMany ||
112
- (originAny && newOrigin !== '*') ||
113
- (newOrigin === '*' && options.credentials)
114
- ) {
115
- addHeaderPart(headers, 'Vary', 'Origin')
116
- }
111
+ if (
112
+ originMany ||
113
+ (originAny && newOrigin !== "*") ||
114
+ (newOrigin === "*" && options.credentials)
115
+ ) {
116
+ addHeaderPart(headers, "Vary", "Origin");
117
+ }
117
118
 
118
- if (
119
- options.exposeHeaders &&
120
- !existingHeaders.includes('Access-Control-Expose-Headers')
121
- ) {
122
- headers['Access-Control-Expose-Headers'] = options.exposeHeaders
123
- }
124
- if (options.maxAge && !existingHeaders.includes('Access-Control-Max-Age')) {
125
- headers['Access-Control-Max-Age'] = String(options.maxAge)
126
- }
127
- const httpMethod = getVersionHttpMethod[request.event.version ?? '1.0']?.(
128
- request.event
129
- )
130
- if (
131
- httpMethod === 'OPTIONS' &&
132
- options.cacheControl &&
133
- !existingHeaders.includes('Cache-Control')
134
- ) {
135
- headers['Cache-Control'] = options.cacheControl
136
- }
137
- }
119
+ if (
120
+ options.exposeHeaders &&
121
+ !existingHeaders.includes("Access-Control-Expose-Headers")
122
+ ) {
123
+ headers["Access-Control-Expose-Headers"] = options.exposeHeaders;
124
+ }
125
+ if (options.maxAge && !existingHeaders.includes("Access-Control-Max-Age")) {
126
+ headers["Access-Control-Max-Age"] = String(options.maxAge);
127
+ }
128
+ const httpMethod = getVersionHttpMethod[request.event.version ?? "1.0"]?.(
129
+ request.event,
130
+ );
131
+ if (
132
+ httpMethod === "OPTIONS" &&
133
+ options.cacheControl &&
134
+ !existingHeaders.includes("Cache-Control")
135
+ ) {
136
+ headers["Cache-Control"] = options.cacheControl;
137
+ }
138
+ };
138
139
 
139
- const httpCorsMiddlewareBefore = async (request) => {
140
- if (options.disableBeforePreflightResponse) return
140
+ const httpCorsMiddlewareBefore = async (request) => {
141
+ if (options.disableBeforePreflightResponse) return;
141
142
 
142
- const method = getVersionHttpMethod[request.event.version ?? '1.0']?.(
143
- request.event
144
- )
145
- if (method === 'OPTIONS') {
146
- normalizeHttpResponse(request)
147
- const headers = {}
148
- modifyHeaders(headers, options, request)
149
- request.response.headers = headers
150
- request.response.statusCode = 204
151
- return request.response
152
- }
153
- }
143
+ const method = getVersionHttpMethod[request.event.version ?? "1.0"]?.(
144
+ request.event,
145
+ );
146
+ if (method === "OPTIONS") {
147
+ normalizeHttpResponse(request);
148
+ const headers = {};
149
+ modifyHeaders(headers, options, request);
150
+ request.response.headers = headers;
151
+ request.response.statusCode = 204;
152
+ return request.response;
153
+ }
154
+ };
154
155
 
155
- const httpCorsMiddlewareAfter = async (request) => {
156
- normalizeHttpResponse(request)
157
- const headers = structuredClone(request.response.headers)
158
- modifyHeaders(headers, options, request)
159
- request.response.headers = headers
160
- }
161
- const httpCorsMiddlewareOnError = async (request) => {
162
- if (request.response === undefined) return
163
- await httpCorsMiddlewareAfter(request)
164
- }
165
- return {
166
- before: httpCorsMiddlewareBefore,
167
- after: httpCorsMiddlewareAfter,
168
- onError: httpCorsMiddlewareOnError
169
- }
170
- }
156
+ const httpCorsMiddlewareAfter = async (request) => {
157
+ normalizeHttpResponse(request);
158
+ const headers = structuredClone(request.response.headers);
159
+ modifyHeaders(headers, options, request);
160
+ request.response.headers = headers;
161
+ };
162
+ const httpCorsMiddlewareOnError = async (request) => {
163
+ if (request.response === undefined) return;
164
+ await httpCorsMiddlewareAfter(request);
165
+ };
166
+ return {
167
+ before: httpCorsMiddlewareBefore,
168
+ after: httpCorsMiddlewareAfter,
169
+ onError: httpCorsMiddlewareOnError,
170
+ };
171
+ };
171
172
  const getVersionHttpMethod = {
172
- '1.0': (event) => event.httpMethod,
173
- '2.0': (event) => event.requestContext.http.method
174
- }
173
+ "1.0": (event) => event.httpMethod,
174
+ "2.0": (event) => event.requestContext.http.method,
175
+ };
175
176
 
176
177
  // header in offical name, lowercase varient handeled
177
178
  const addHeaderPart = (headers, header, value) => {
178
- if (!value) return
179
- const headerLower = header.toLowerCase()
180
- header = headers[headerLower] ? headerLower : header
181
- headers[header] ??= ''
182
- headers[header] &&= headers[header] + ', '
183
- headers[header] += value
184
- }
179
+ if (!value) return;
180
+ const headerLower = header.toLowerCase();
181
+ const sanitizedHeader = headers[headerLower] ? headerLower : header;
182
+ headers[sanitizedHeader] ??= "";
183
+ headers[sanitizedHeader] &&= `${headers[sanitizedHeader]}, `;
184
+ headers[sanitizedHeader] += value;
185
+ };
185
186
 
186
- export default httpCorsMiddleware
187
+ export default httpCorsMiddleware;
package/package.json CHANGED
@@ -1,72 +1,69 @@
1
1
  {
2
- "name": "@middy/http-cors",
3
- "version": "6.1.6",
4
- "description": "CORS (Cross-Origin Resource Sharing) middleware for the middy framework",
5
- "type": "module",
6
- "engines": {
7
- "node": ">=20"
8
- },
9
- "engineStrict": true,
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "module": "./index.js",
14
- "exports": {
15
- ".": {
16
- "import": {
17
- "types": "./index.d.ts",
18
- "default": "./index.js"
19
- },
20
- "require": {
21
- "default": "./index.js"
22
- }
23
- }
24
- },
25
- "types": "index.d.ts",
26
- "files": [
27
- "index.js",
28
- "index.d.ts"
29
- ],
30
- "scripts": {
31
- "test": "npm run test:unit && npm run test:fuzz",
32
- "test:unit": "node --test __tests__/index.js",
33
- "test:fuzz": "node --test __tests__/fuzz.js",
34
- "test:benchmark": "node __benchmarks__/index.js"
35
- },
36
- "license": "MIT",
37
- "keywords": [
38
- "Lambda",
39
- "Middleware",
40
- "Serverless",
41
- "Framework",
42
- "AWS",
43
- "AWS Lambda",
44
- "Middy",
45
- "CORS",
46
- "Cross-Origin Resource Sharing"
47
- ],
48
- "author": {
49
- "name": "Middy contributors",
50
- "url": "https://github.com/middyjs/middy/graphs/contributors"
51
- },
52
- "repository": {
53
- "type": "git",
54
- "url": "git+https://github.com/middyjs/middy.git",
55
- "directory": "packages/http-cors"
56
- },
57
- "bugs": {
58
- "url": "https://github.com/middyjs/middy/issues"
59
- },
60
- "homepage": "https://middy.js.org",
61
- "funding": {
62
- "type": "github",
63
- "url": "https://github.com/sponsors/willfarrell"
64
- },
65
- "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431",
66
- "dependencies": {
67
- "@middy/util": "6.1.6"
68
- },
69
- "devDependencies": {
70
- "@middy/core": "6.1.6"
71
- }
2
+ "name": "@middy/http-cors",
3
+ "version": "6.2.1",
4
+ "description": "CORS (Cross-Origin Resource Sharing) middleware for the middy framework",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=20"
8
+ },
9
+ "engineStrict": true,
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "module": "./index.js",
14
+ "exports": {
15
+ ".": {
16
+ "import": {
17
+ "types": "./index.d.ts",
18
+ "default": "./index.js"
19
+ },
20
+ "require": {
21
+ "default": "./index.js"
22
+ }
23
+ }
24
+ },
25
+ "types": "index.d.ts",
26
+ "files": ["index.js", "index.d.ts"],
27
+ "scripts": {
28
+ "test": "npm run test:unit && npm run test:fuzz",
29
+ "test:unit": "node --test",
30
+ "test:fuzz": "node --test index.fuzz.js",
31
+ "test:perf": "node --test index.perf.js"
32
+ },
33
+ "license": "MIT",
34
+ "keywords": [
35
+ "Lambda",
36
+ "Middleware",
37
+ "Serverless",
38
+ "Framework",
39
+ "AWS",
40
+ "AWS Lambda",
41
+ "Middy",
42
+ "CORS",
43
+ "Cross-Origin Resource Sharing"
44
+ ],
45
+ "author": {
46
+ "name": "Middy contributors",
47
+ "url": "https://github.com/middyjs/middy/graphs/contributors"
48
+ },
49
+ "repository": {
50
+ "type": "git",
51
+ "url": "git+https://github.com/middyjs/middy.git",
52
+ "directory": "packages/http-cors"
53
+ },
54
+ "bugs": {
55
+ "url": "https://github.com/middyjs/middy/issues"
56
+ },
57
+ "homepage": "https://middy.js.org",
58
+ "funding": {
59
+ "type": "github",
60
+ "url": "https://github.com/sponsors/willfarrell"
61
+ },
62
+ "gitHead": "7a6c0fbb8ab71d6a2171e678697de9f237568431",
63
+ "dependencies": {
64
+ "@middy/util": "6.2.1"
65
+ },
66
+ "devDependencies": {
67
+ "@middy/core": "6.2.1"
68
+ }
72
69
  }