feat(binding-http): Make Access-Control-Allow-Origin header configurable#1500
feat(binding-http): Make Access-Control-Allow-Origin header configurable#1500jona42-ui wants to merge 1 commit intoeclipse-thingweb:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a configurable allowedOrigins option to the HttpServer to allow users to customize the Access-Control-Allow-Origin CORS header. Previously, this value was hardcoded to "*" for unsecured (nosec) things. The new option defaults to "*" for full backward compatibility.
Changes:
- Added
allowedOriginsoptional field to theHttpConfiginterface with documentation - Updated HttpServer to store and expose the
allowedOriginsconfiguration - Modified all route handlers to use the configured value instead of hardcoded
"*" - Added comprehensive test suite to verify the new configuration works correctly while maintaining backward compatibility
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/binding-http/src/http.ts | Added optional allowedOrigins field to HttpConfig interface with JSDoc |
| packages/binding-http/src/http-server.ts | Added allowedOrigins property and getAllowedOrigins() public method |
| packages/binding-http/src/routes/things.ts | Updated to use getAllowedOrigins() instead of hardcoded "*" |
| packages/binding-http/src/routes/thing-description.ts | Updated to use getAllowedOrigins() instead of hardcoded "*" |
| packages/binding-http/src/routes/common.ts | Added allowedOrigins parameter to utility functions setCorsForThing and respondUnallowedMethod |
| packages/binding-http/src/routes/property.ts | Updated to pass getAllowedOrigins() to CORS utility functions |
| packages/binding-http/src/routes/property-observe.ts | Updated to pass getAllowedOrigins() to CORS utility functions |
| packages/binding-http/src/routes/properties.ts | Updated to pass getAllowedOrigins() to CORS utility functions |
| packages/binding-http/src/routes/event.ts | Updated to pass getAllowedOrigins() to CORS utility functions |
| packages/binding-http/src/routes/action.ts | Updated to pass getAllowedOrigins() to CORS utility functions |
| packages/binding-http/test/http-server-cors-test.ts | Added comprehensive test suite for the new configuration option |
| } finally { | ||
| await httpServer.stop(); | ||
| } | ||
| } |
There was a problem hiding this comment.
The test suite provides good coverage for properties, thing listing, thing description, and CORS preflight scenarios. However, it's missing test cases for actions and events with the custom allowedOrigins configuration. Consider adding tests similar to the existing "should handle CORS for invoke action (POST)" test in the HttpServerCorsTest suite, but with a configured allowedOrigins value to ensure actions and events also respect the configuration.
| } | |
| } | |
| @test async "should use configured allowedOrigins for invoke action (POST) on nosec thing"() { | |
| const servient = new Servient(); | |
| const httpServer = new HttpServer({ port: 0, allowedOrigins: "http://my-app.example.com" }); | |
| await httpServer.start(servient); | |
| try { | |
| const thing = new ExposedThing(servient, { | |
| title: "TestOriginAction", | |
| actions: { | |
| invoke: { | |
| output: { | |
| type: "string", | |
| }, | |
| forms: [], | |
| }, | |
| }, | |
| }); | |
| thing.setActionHandler("invoke", () => Promise.resolve("ok")); | |
| await httpServer.expose(thing); | |
| const uri = `http://localhost:${httpServer.getPort()}/testoriginaction/actions/invoke`; | |
| const response = await fetch(uri, { | |
| method: "POST", | |
| headers: { | |
| Origin: "http://other.example.com", | |
| "Content-Type": "application/json", | |
| }, | |
| body: JSON.stringify({}), | |
| }); | |
| expect(response.status).to.equal(200); | |
| expect(response.headers.get("Access-Control-Allow-Origin")).to.equal("http://my-app.example.com"); | |
| } finally { | |
| await httpServer.stop(); | |
| } | |
| } | |
| @test async "should use configured allowedOrigins for subscribe event (GET) on nosec thing"() { | |
| const servient = new Servient(); | |
| const httpServer = new HttpServer({ port: 0, allowedOrigins: "http://my-app.example.com" }); | |
| await httpServer.start(servient); | |
| try { | |
| const thing = new ExposedThing(servient, { | |
| title: "TestOriginEvent", | |
| events: { | |
| tick: { | |
| data: { | |
| type: "string", | |
| }, | |
| forms: [], | |
| }, | |
| }, | |
| }); | |
| await httpServer.expose(thing); | |
| const uri = `http://localhost:${httpServer.getPort()}/testoriginevent/events/tick`; | |
| const response = await fetch(uri, { | |
| method: "GET", | |
| headers: { | |
| Origin: "http://other.example.com", | |
| }, | |
| }); | |
| expect(response.status).to.equal(200); | |
| expect(response.headers.get("Access-Control-Allow-Origin")).to.equal("http://my-app.example.com"); | |
| } finally { | |
| await httpServer.stop(); | |
| } | |
| } |
| * Configures the Access-Control-Allow-Origin header. | ||
| * Default is "*" (any origin allowed). |
There was a problem hiding this comment.
The new allowedOrigins configuration option should be documented in the README.md file. Consider adding documentation in the HttpServer Configuration section (around line 271-280) to show users how to configure this option. Example:
new HttpServer({
port: 8080,
allowedOrigins: "https://my-app.example.com" // Restrict CORS to specific origin (default: "*")
})This would help users understand how to use this feature and what the default behavior is.
| * Configures the Access-Control-Allow-Origin header. | |
| * Default is "*" (any origin allowed). | |
| * Configures the Access-Control-Allow-Origin header used for CORS. | |
| * | |
| * Default: "*" (any origin allowed). | |
| * | |
| * Example: | |
| * ```ts | |
| * new HttpServer({ | |
| * port: 8080, | |
| * allowedOrigins: "https://my-app.example.com" // restrict CORS to specific origin | |
| * }); | |
| * ``` |
|
@relu91 I suppose these reviews from copilot make sense |
Add allowedOrigins option to HttpConfig interface to let users configure the Access-Control-Allow-Origin header value. Defaults to '*' for backward compatibility. Secured things still echo the request origin with credentials regardless of this setting. Fixes eclipse-thingweb#941 Signed-off-by: jona42-ui <jonathanthembo123@gmail.com>
b0c3768 to
93392e6
Compare
|
Looking good, I'm a little bit concerned about the new tests structure... there's a lot of duplicated code for just two different setup configurations 🤔 . @danielpeintner what do you think? |
|
@relu91 I see well your point, can we separate each configuration in a test suite or we can look at parameterizing |
Added allowedOrigins option to HttpConfig interface to let users configure the Access-Control-Allow-Origin header value. Defaults to '*' for backward compatibility.
Since allowedOrigins is an optional field, this is fully backward compatible .
Fixes #941