The underlying Engine.IO server now supports a 'cors' option, which
will be forwarded to the cors module.
Breaking change: the 'origins' option is removed
Before:
```js
new Server(3000, {
origins: ["https://example.com"]
});
```
The 'origins' option was used in the allowRequest method, in order to
determine whether the request should pass or not. And the Engine.IO
server would implicitly add the necessary Access-Control-Allow-xxx
headers.
After:
```js
new Server(3000, {
cors: {
origin: "https://example.com",
methods: ["GET", "POST"],
allowedHeaders: ["content-type"]
}
});
```
The already existing 'allowRequest' option can be used for validation:
```js
new Server(3000, {
allowRequest: (req, callback) => {
callback(null, req.headers.referer.startsWith("https://example.com"));
}
});
```
Both CommonJS and ES6 import are now supported:
- with `{ "type": "commonjs" }` in the package.json file
```js
const io = require("socket.io")(8080);
// or
const { Server } = require("socket.io");
const io = new Server(8080);
```
- with `{ "type": "module" }`
```js
import { Server } from "socket.io";
const io = new Server(8080);
```
Related: https://nodejs.org/api/packages.html#packages_dual_commonjs_es_module_packages
In previous versions, the Socket#id attribute was equal (or derived,
for a non-default namespace) to the underlying Engine.IO id, which is
used as a mean to authenticate the user throughout the Engine.IO
session and thus is sensitive information that should be kept secret.
The problem with reusing the Engine.IO id is that users could be
tempted to transmit this id to other clients, in order to implement
private messaging for example.
So we'll now generate a new random id for each new socket.
Please note that this id will now be different from the one found in
the query parameters of the HTTP requests.
In previous versions, a client was always connected to the default
namespace, even if it requested access to another namespace.
This meant that the middlewares registered for the default namespace
were triggered in any case, which is a surprising behavior for end
users.
This also meant that the query option of the Socket on the client-side
was not sent in the Socket.IO CONNECT packet for the default namespace:
```js
// default namespace: query sent in the query params
const socket = io({
query: {
abc: "def"
}
});
// another namespace: query sent in the query params + the CONNECT packet
const socket = io("/admin", {
query: {
abc: "def"
}
});
```
The client will now send a CONNECT packet in any case, and the query
option of the Socket is renamed to "auth", in order to make a clear
distinction with the query option of the Manager (included in the query
parameters of the HTTP requests).
```js
// server-side
io.use((socket, next) => {
// not triggered anymore
});
io.of("/admin").use((socket, next => {
// triggered
console.log(socket.handshake.query.abc); // "def"
console.log(socket.handshake.auth.abc); // "123"
});
// client-side
const socket = io("/admin", {
query: {
abc: "def"
},
auth: {
abc: "123"
}
});
```
This event was added in 41956806a7
But it does not convey the information that the Socket is actually
sending a CONNECT packet to the server. It should maybe be moved to the
Socket#onopen() method, but let's remove it for now as it is not
documented anywhere.
These events cannot be used by the end users, because they are part of
the Socket.IO public API, so using them will now throw an error
explicitly.
Related: f7ed81e5d2
Previously, most of the events emitted by the Manager were also emitted
by the Socket instances, but it was somehow misleading for the end
users because they don't have the same meaning:
- Manager: the state of the low-level connection (with connection and reconnection events)
- Socket: the state of the connection to the Namespace (only 'connect', 'disconnect' and 'error')
For example, the `reconnect` event:
```js
socket.on("reconnect", () => {
console.log(socket.connected); // might be false, which is a bit surprising
});
```
Breaking change: the Socket instance will no longer forward the events
of its Manager
Those events can still be accessed on the Manager instance though:
```js
socket.io.on("reconnect", () => {
// ...
});
```
It was included by the previous commit, but the test code is not
currently transpiled to ES5 so it breaks IE in the CI.
Let's use a plain function for now.