@jsenv/server 17.1.0 → 17.1.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.
@@ -8005,17 +8005,32 @@ const generateAccessControlHeaders = ({
8005
8005
  } = {}) => {
8006
8006
  const vary = [];
8007
8007
 
8008
- const allowedOriginArray = [...accessControlAllowedOrigins];
8009
- if (accessControlAllowRequestOrigin) {
8010
- if ("origin" in headers && headers.origin !== "null") {
8011
- allowedOriginArray.push(headers.origin);
8008
+ // Access-Control-Allow-Origin must be a single value (not a list).
8009
+ // We reflect back the request's origin if it is in the allowed list.
8010
+ // If no origin matches we fall back to "*" (only when not using credentials).
8011
+ let allowOrigin = null;
8012
+
8013
+ const requestOrigin =
8014
+ "origin" in headers && headers.origin !== "null"
8015
+ ? headers.origin
8016
+ : "referer" in headers
8017
+ ? new URL(headers.referer).origin
8018
+ : null;
8019
+
8020
+ if (requestOrigin) {
8021
+ if (accessControlAllowedOrigins.includes(requestOrigin)) {
8022
+ allowOrigin = requestOrigin;
8023
+ vary.push("origin");
8024
+ } else if (accessControlAllowRequestOrigin) {
8025
+ allowOrigin = requestOrigin;
8012
8026
  vary.push("origin");
8013
- } else if ("referer" in headers) {
8014
- allowedOriginArray.push(new URL(headers.referer).origin);
8015
- vary.push("referer");
8016
- } else {
8017
- allowedOriginArray.push("*");
8018
8027
  }
8028
+ } else if (accessControlAllowRequestOrigin) {
8029
+ allowOrigin = "*";
8030
+ }
8031
+
8032
+ if (allowOrigin === null) {
8033
+ allowOrigin = accessControlAllowedOrigins[0] ?? "*";
8019
8034
  }
8020
8035
 
8021
8036
  const allowedMethodArray = [...accessControlAllowedMethods];
@@ -8049,16 +8064,14 @@ const generateAccessControlHeaders = ({
8049
8064
  }
8050
8065
 
8051
8066
  return {
8052
- "access-control-allow-origin": allowedOriginArray.join(", "),
8067
+ "access-control-allow-origin": allowOrigin,
8053
8068
  "access-control-allow-methods": allowedMethodArray.join(", "),
8054
8069
  "access-control-allow-headers": allowedHeaderArray.join(", "),
8055
8070
  ...(accessControlAllowCredentials
8056
8071
  ? { "access-control-allow-credentials": true }
8057
8072
  : {}),
8058
8073
  "access-control-max-age": accessControlMaxAge,
8059
- ...(timingAllowOrigin
8060
- ? { "timing-allow-origin": allowedOriginArray.join(", ") }
8061
- : {}),
8074
+ ...(timingAllowOrigin ? { "timing-allow-origin": allowOrigin } : {}),
8062
8075
  ...(vary.length ? { vary: vary.join(", ") } : {}),
8063
8076
  };
8064
8077
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/server",
3
- "version": "17.1.0",
3
+ "version": "17.1.1",
4
4
  "description": "A modern Node.js HTTP server with declarative routing, content negotiation, and WebSocket support",
5
5
  "repository": {
6
6
  "type": "git",
@@ -75,17 +75,32 @@ const generateAccessControlHeaders = ({
75
75
  } = {}) => {
76
76
  const vary = [];
77
77
 
78
- const allowedOriginArray = [...accessControlAllowedOrigins];
79
- if (accessControlAllowRequestOrigin) {
80
- if ("origin" in headers && headers.origin !== "null") {
81
- allowedOriginArray.push(headers.origin);
78
+ // Access-Control-Allow-Origin must be a single value (not a list).
79
+ // We reflect back the request's origin if it is in the allowed list.
80
+ // If no origin matches we fall back to "*" (only when not using credentials).
81
+ let allowOrigin = null;
82
+
83
+ const requestOrigin =
84
+ "origin" in headers && headers.origin !== "null"
85
+ ? headers.origin
86
+ : "referer" in headers
87
+ ? new URL(headers.referer).origin
88
+ : null;
89
+
90
+ if (requestOrigin) {
91
+ if (accessControlAllowedOrigins.includes(requestOrigin)) {
92
+ allowOrigin = requestOrigin;
93
+ vary.push("origin");
94
+ } else if (accessControlAllowRequestOrigin) {
95
+ allowOrigin = requestOrigin;
82
96
  vary.push("origin");
83
- } else if ("referer" in headers) {
84
- allowedOriginArray.push(new URL(headers.referer).origin);
85
- vary.push("referer");
86
- } else {
87
- allowedOriginArray.push("*");
88
97
  }
98
+ } else if (accessControlAllowRequestOrigin) {
99
+ allowOrigin = "*";
100
+ }
101
+
102
+ if (allowOrigin === null) {
103
+ allowOrigin = accessControlAllowedOrigins[0] ?? "*";
89
104
  }
90
105
 
91
106
  const allowedMethodArray = [...accessControlAllowedMethods];
@@ -119,16 +134,14 @@ const generateAccessControlHeaders = ({
119
134
  }
120
135
 
121
136
  return {
122
- "access-control-allow-origin": allowedOriginArray.join(", "),
137
+ "access-control-allow-origin": allowOrigin,
123
138
  "access-control-allow-methods": allowedMethodArray.join(", "),
124
139
  "access-control-allow-headers": allowedHeaderArray.join(", "),
125
140
  ...(accessControlAllowCredentials
126
141
  ? { "access-control-allow-credentials": true }
127
142
  : {}),
128
143
  "access-control-max-age": accessControlMaxAge,
129
- ...(timingAllowOrigin
130
- ? { "timing-allow-origin": allowedOriginArray.join(", ") }
131
- : {}),
144
+ ...(timingAllowOrigin ? { "timing-allow-origin": allowOrigin } : {}),
132
145
  ...(vary.length ? { vary: vary.join(", ") } : {}),
133
146
  };
134
147
  };