parent
ac44657961
commit
05f12cdc56
28
README.md
28
README.md
@ -84,20 +84,20 @@ If you have your own server, you can attach PeerServer.
|
|||||||
## Config / CLI options
|
## Config / CLI options
|
||||||
You can provide config object to `PeerServer` function or specify options for `peerjs` CLI.
|
You can provide config object to `PeerServer` function or specify options for `peerjs` CLI.
|
||||||
|
|
||||||
| CLI option | JS option | Description | Required | Default |
|
| CLI option | JS option | Description | Required | Default |
|
||||||
| -------- | ------- | ------------- | :------: | :---------: |
|
|--------------------------|--------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:|:----------:|
|
||||||
| `--port, -p` | `port` | Port to listen (number) | **Yes** | |
|
| `--port, -p` | `port` | Port to listen (number) | **Yes** | |
|
||||||
| `--key, -k` | `key` | Connection key (string). Client must provide it to call API methods | No | `"peerjs"` |
|
| `--key, -k` | `key` | Connection key (string). Client must provide it to call API methods | No | `"peerjs"` |
|
||||||
| `--path` | `path` | Path (string). The server responds for requests to the root URL + path. **E.g.** Set the `path` to `/myapp` and run server on 9000 port via `peerjs --port 9000 --path /myapp` Then open http://127.0.0.1:9000/myapp - you should see a JSON reponse. | No | `"/"` |
|
| `--path` | `path` | Path (string). The server responds for requests to the root URL + path. **E.g.** Set the `path` to `/myapp` and run server on 9000 port via `peerjs --port 9000 --path /myapp` Then open http://127.0.0.1:9000/myapp - you should see a JSON reponse. | No | `"/"` |
|
||||||
| `--proxied` | `proxied` | Set `true` if PeerServer stays behind a reverse proxy (boolean) | No | `false` |
|
| `--proxied` | `proxied` | Set `true` if PeerServer stays behind a reverse proxy (boolean) | No | `false` |
|
||||||
| `--expire_timeout, -t` | `expire_timeout` | The amount of time after which a message sent will expire, the sender will then receive a `EXPIRE` message (milliseconds). | No | `5000` |
|
| `--expire_timeout, -t` | `expire_timeout` | The amount of time after which a message sent will expire, the sender will then receive a `EXPIRE` message (milliseconds). | No | `5000` |
|
||||||
| `--alive_timeout` | `alive_timeout` | Timeout for broken connection (milliseconds). If the server doesn't receive any data from client (includes `pong` messages), the client's connection will be destroyed. | No | `60000` |
|
| `--alive_timeout` | `alive_timeout` | Timeout for broken connection (milliseconds). If the server doesn't receive any data from client (includes `pong` messages), the client's connection will be destroyed. | No | `60000` |
|
||||||
| `--concurrent_limit, -c` | `concurrent_limit` | Maximum number of clients' connections to WebSocket server (number) | No | `5000` |
|
| `--concurrent_limit, -c` | `concurrent_limit` | Maximum number of clients' connections to WebSocket server (number) | No | `5000` |
|
||||||
| `--sslkey` | `sslkey` | Path to SSL key (string) | No | |
|
| `--sslkey` | `sslkey` | Path to SSL key (string) | No | |
|
||||||
| `--sslcert` | `sslcert` | Path to SSL certificate (string) | No | |
|
| `--sslcert` | `sslcert` | Path to SSL certificate (string) | No | |
|
||||||
| `--allow_discovery` | `allow_discovery` | Allow to use GET `/peers` http API method to get an array of ids of all connected clients (boolean) | No | |
|
| `--allow_discovery` | `allow_discovery` | Allow to use GET `/peers` http API method to get an array of ids of all connected clients (boolean) | No | |
|
||||||
| | `generateClientId` | A function which generate random client IDs when calling `/id` API method (`() => string`) | No | `uuid/v4` |
|
| `--cors` | `corsOptions` | The CORS origins that can access this server |
|
||||||
|
| | `generateClientId` | A function which generate random client IDs when calling `/id` API method (`() => string`) | No | `uuid/v4` |
|
||||||
## Using HTTPS
|
## Using HTTPS
|
||||||
Simply pass in PEM-encoded certificate and key.
|
Simply pass in PEM-encoded certificate and key.
|
||||||
|
|
||||||
|
@ -1,57 +1,91 @@
|
|||||||
import { describe, expect, it } from "@jest/globals";
|
import {describe, expect, it} from "@jest/globals";
|
||||||
|
|
||||||
import http from 'http';
|
import http from 'http';
|
||||||
import expectedJson from '../app.json';
|
import expectedJson from '../app.json';
|
||||||
import { spawn } from 'child_process';
|
import fetch from "node-fetch";
|
||||||
import path from 'path';
|
import * as crypto from "crypto";
|
||||||
|
import {startServer} from "./utils";
|
||||||
|
|
||||||
const PORT = '9000';
|
const PORT = '9000';
|
||||||
|
|
||||||
async function makeRequest() {
|
async function makeRequest() {
|
||||||
return new Promise<object>((resolve, reject) => {
|
return new Promise<object>((resolve, reject) => {
|
||||||
http.get(`http://localhost:${PORT}/`, resp => {
|
http.get(`http://localhost:${PORT}/`, resp => {
|
||||||
let data = '';
|
let data = '';
|
||||||
|
|
||||||
resp.on('data', chunk => {
|
resp.on('data', chunk => {
|
||||||
data += chunk;
|
data += chunk;
|
||||||
});
|
});
|
||||||
|
|
||||||
resp.on('end', () => {
|
resp.on('end', () => {
|
||||||
resolve(JSON.parse(data));
|
resolve(JSON.parse(data));
|
||||||
});
|
});
|
||||||
|
|
||||||
}).on("error", err => {
|
}).on("error", err => {
|
||||||
console.log("Error: " + err.message);
|
console.log("Error: " + err.message);
|
||||||
reject(err);
|
reject(err);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
describe('Check bin/peerjs', () => {
|
describe('Check bin/peerjs', () => {
|
||||||
it('should return content of app.json file', async () => {
|
it('should return content of app.json file', async () => {
|
||||||
expect.assertions(1);
|
expect.assertions(1);
|
||||||
let resolver: () => void;
|
|
||||||
let rejecter: (err: unknown) => void;
|
const ls = await startServer()
|
||||||
const promise = new Promise<void>((resolve, reject) => {
|
try {
|
||||||
resolver = resolve;
|
const resp = await makeRequest();
|
||||||
rejecter = reject;
|
expect(resp).toEqual(expectedJson);
|
||||||
|
} finally {
|
||||||
|
ls.kill();
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const ls = spawn('node', [path.join(__dirname, '../', 'dist/bin/peerjs.js'), '--port', PORT]);
|
it('should reflect the origin header in CORS by default', async () => {
|
||||||
ls.stdout.on('data', async (data: string) => {
|
expect.assertions(1);
|
||||||
if (!data.includes('Started')) return;
|
|
||||||
|
|
||||||
try {
|
const ls = await startServer()
|
||||||
const resp = await makeRequest();
|
const origin = crypto.randomUUID();
|
||||||
expect(resp).toEqual(expectedJson);
|
try {
|
||||||
resolver();
|
const res = await fetch(`http://localhost:${PORT}/peerjs/id`, {
|
||||||
} catch (error) {
|
headers: {
|
||||||
rejecter(error);
|
Origin: origin
|
||||||
} finally {
|
}
|
||||||
ls.kill('SIGKILL');
|
})
|
||||||
}
|
expect(res.headers.get("access-control-allow-origin")).toBe(origin)
|
||||||
|
} finally {
|
||||||
|
ls.kill()
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
it('should respect the CORS parameters', async () => {
|
||||||
|
expect.assertions(3);
|
||||||
|
|
||||||
return promise;
|
const origin1 = crypto.randomUUID();
|
||||||
});
|
const origin2 = crypto.randomUUID();
|
||||||
|
const origin3 = crypto.randomUUID();
|
||||||
|
const ls = await startServer(["--cors", origin1, "--cors", origin2])
|
||||||
|
try {
|
||||||
|
const res1 = await fetch(`http://localhost:${PORT}/peerjs/id`, {
|
||||||
|
headers: {
|
||||||
|
Origin: origin1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(res1.headers.get("access-control-allow-origin")).toBe(origin1)
|
||||||
|
const res2 = await fetch(`http://localhost:${PORT}/peerjs/id`, {
|
||||||
|
headers: {
|
||||||
|
Origin: origin2
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(res2.headers.get("access-control-allow-origin")).toBe(origin2)
|
||||||
|
const res3 = await fetch(`http://localhost:${PORT}/peerjs/id`, {
|
||||||
|
headers: {
|
||||||
|
Origin: origin3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
expect(res3.headers.get("access-control-allow-origin")).toBe(null)
|
||||||
|
} finally {
|
||||||
|
ls.kill()
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -1 +1,15 @@
|
|||||||
|
import {ChildProcessWithoutNullStreams, spawn} from "child_process";
|
||||||
|
import path from "path";
|
||||||
|
|
||||||
export const wait = (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms));
|
export const wait = (ms: number): Promise<void> => new Promise(resolve => setTimeout(resolve, ms));
|
||||||
|
|
||||||
|
export const startServer = (params: string[] = []) => {
|
||||||
|
return new Promise<ChildProcessWithoutNullStreams>((resolve, reject)=> {
|
||||||
|
const ls = spawn('node', [path.join(__dirname, '../', 'dist/bin/peerjs.js'), '--port', "9000", ...params]);
|
||||||
|
ls.stdout.once("data", ()=> resolve(ls))
|
||||||
|
ls.stderr.once("data", ()=>{
|
||||||
|
ls.kill()
|
||||||
|
reject()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@ -8,6 +8,7 @@ import yargs from "yargs";
|
|||||||
import { hideBin } from 'yargs/helpers'
|
import { hideBin } from 'yargs/helpers'
|
||||||
import { PeerServer} from "../src";
|
import { PeerServer} from "../src";
|
||||||
import type { AddressInfo } from "node:net";
|
import type { AddressInfo } from "node:net";
|
||||||
|
import type {CorsOptions} from "cors";
|
||||||
|
|
||||||
const y = yargs(hideBin(process.argv));
|
const y = yargs(hideBin(process.argv));
|
||||||
|
|
||||||
@ -73,18 +74,28 @@ const opts = y
|
|||||||
demandOption: false,
|
demandOption: false,
|
||||||
describe: "allow discovery of peers",
|
describe: "allow discovery of peers",
|
||||||
},
|
},
|
||||||
proxied: {
|
proxied: {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
demandOption: false,
|
demandOption: false,
|
||||||
describe: "Set true if PeerServer stays behind a reverse proxy",
|
describe: "Set true if PeerServer stays behind a reverse proxy",
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
cors: {
|
||||||
|
type: "string",
|
||||||
|
array: true,
|
||||||
|
describe: "Set the list of CORS origins",
|
||||||
|
},
|
||||||
})
|
})
|
||||||
.boolean("allow_discovery").parseSync();
|
.boolean("allow_discovery").parseSync();
|
||||||
|
|
||||||
if(!opts.port){
|
if(!opts.port){
|
||||||
opts.port= parseInt(process.env["PORT"] as string)
|
opts.port= parseInt(process.env["PORT"] as string)
|
||||||
}
|
}
|
||||||
|
if(opts.cors){
|
||||||
|
opts["corsOptions"] = {
|
||||||
|
origin: opts.cors
|
||||||
|
} satisfies CorsOptions;
|
||||||
|
}
|
||||||
process.on("uncaughtException", function (e) {
|
process.on("uncaughtException", function (e) {
|
||||||
console.error("Error: " + e);
|
console.error("Error: " + e);
|
||||||
});
|
});
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
/** @type {import('jest').Config} */
|
/** @type {import('jest').Config} */
|
||||||
const config = {
|
const config = {
|
||||||
transform: {
|
testEnvironment: "node",
|
||||||
"^.+\\.(t|j)sx?$": "@swc/jest",
|
transform: {
|
||||||
},
|
"^.+\\.(t|j)sx?$": "@swc/jest",
|
||||||
collectCoverageFrom: ["./src/**"]
|
},
|
||||||
|
transformIgnorePatterns: [
|
||||||
|
// "node_modules"
|
||||||
|
],
|
||||||
|
collectCoverageFrom: ["./src/**"]
|
||||||
};
|
};
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
165
package-lock.json
generated
165
package-lock.json
generated
@ -13,6 +13,7 @@
|
|||||||
"@types/ws": "^7.2.3 || ^8.0.0",
|
"@types/ws": "^7.2.3 || ^8.0.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"node-fetch": "^3.3.0",
|
||||||
"ws": "^7.2.3 || ^8.0.0",
|
"ws": "^7.2.3 || ^8.0.0",
|
||||||
"yargs": "^17.6.2"
|
"yargs": "^17.6.2"
|
||||||
},
|
},
|
||||||
@ -1799,6 +1800,26 @@
|
|||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@octokit/request/node_modules/node-fetch": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "4.x || >=6.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"encoding": "^0.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"encoding": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@octokit/rest": {
|
"node_modules/@octokit/rest": {
|
||||||
"version": "19.0.7",
|
"version": "19.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-19.0.7.tgz",
|
||||||
@ -5028,6 +5049,14 @@
|
|||||||
"node": ">=8.0.0"
|
"node": ">=8.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/data-uri-to-buffer": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 12"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/dateformat": {
|
"node_modules/dateformat": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
||||||
@ -5949,6 +5978,28 @@
|
|||||||
"bser": "2.1.1"
|
"bser": "2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/fetch-blob": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jimmywarting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "paypal",
|
||||||
|
"url": "https://paypal.me/jimmywarting"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dependencies": {
|
||||||
|
"node-domexception": "^1.0.0",
|
||||||
|
"web-streams-polyfill": "^3.0.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^12.20 || >= 14.13"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/figures": {
|
"node_modules/figures": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz",
|
||||||
@ -6093,6 +6144,17 @@
|
|||||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/formdata-polyfill": {
|
||||||
|
"version": "4.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||||
|
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||||
|
"dependencies": {
|
||||||
|
"fetch-blob": "^3.1.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.20.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/forwarded": {
|
"node_modules/forwarded": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
@ -8758,6 +8820,24 @@
|
|||||||
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
|
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/node-domexception": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/jimmywarting"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://paypal.me/jimmywarting"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.5.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/node-emoji": {
|
"node_modules/node-emoji": {
|
||||||
"version": "1.11.0",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
|
||||||
@ -8768,23 +8848,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-fetch": {
|
"node_modules/node-fetch": {
|
||||||
"version": "2.6.9",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
|
||||||
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
|
"integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
|
||||||
"dev": true,
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"whatwg-url": "^5.0.0"
|
"data-uri-to-buffer": "^4.0.0",
|
||||||
|
"fetch-blob": "^3.1.4",
|
||||||
|
"formdata-polyfill": "^4.0.10"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "4.x || >=6.0.0"
|
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"funding": {
|
||||||
"encoding": "^0.1.0"
|
"type": "opencollective",
|
||||||
},
|
"url": "https://opencollective.com/node-fetch"
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"encoding": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/node-gyp-build": {
|
"node_modules/node-gyp-build": {
|
||||||
@ -13980,6 +14057,14 @@
|
|||||||
"integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==",
|
"integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/web-streams-polyfill": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 8"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/webidl-conversions": {
|
"node_modules/webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
@ -15496,6 +15581,17 @@
|
|||||||
"is-plain-object": "^5.0.0",
|
"is-plain-object": "^5.0.0",
|
||||||
"node-fetch": "^2.6.7",
|
"node-fetch": "^2.6.7",
|
||||||
"universal-user-agent": "^6.0.0"
|
"universal-user-agent": "^6.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"node-fetch": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"whatwg-url": "^5.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@octokit/request-error": {
|
"@octokit/request-error": {
|
||||||
@ -17778,6 +17874,11 @@
|
|||||||
"css-tree": "^1.1.2"
|
"css-tree": "^1.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"data-uri-to-buffer": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
|
||||||
|
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A=="
|
||||||
|
},
|
||||||
"dateformat": {
|
"dateformat": {
|
||||||
"version": "3.0.3",
|
"version": "3.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz",
|
||||||
@ -18460,6 +18561,15 @@
|
|||||||
"bser": "2.1.1"
|
"bser": "2.1.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"fetch-blob": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
|
||||||
|
"requires": {
|
||||||
|
"node-domexception": "^1.0.0",
|
||||||
|
"web-streams-polyfill": "^3.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
"figures": {
|
"figures": {
|
||||||
"version": "5.0.0",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz",
|
||||||
@ -18566,6 +18676,14 @@
|
|||||||
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"formdata-polyfill": {
|
||||||
|
"version": "4.0.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
|
||||||
|
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
|
||||||
|
"requires": {
|
||||||
|
"fetch-blob": "^3.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
"forwarded": {
|
"forwarded": {
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
|
||||||
@ -20527,6 +20645,11 @@
|
|||||||
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
|
"integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node-domexception": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="
|
||||||
|
},
|
||||||
"node-emoji": {
|
"node-emoji": {
|
||||||
"version": "1.11.0",
|
"version": "1.11.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
|
"resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.11.0.tgz",
|
||||||
@ -20537,12 +20660,13 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-fetch": {
|
"node-fetch": {
|
||||||
"version": "2.6.9",
|
"version": "3.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz",
|
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.0.tgz",
|
||||||
"integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==",
|
"integrity": "sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"whatwg-url": "^5.0.0"
|
"data-uri-to-buffer": "^4.0.0",
|
||||||
|
"fetch-blob": "^3.1.4",
|
||||||
|
"formdata-polyfill": "^4.0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node-gyp-build": {
|
"node-gyp-build": {
|
||||||
@ -24254,6 +24378,11 @@
|
|||||||
"integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==",
|
"integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"web-streams-polyfill": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q=="
|
||||||
|
},
|
||||||
"webidl-conversions": {
|
"webidl-conversions": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
"@types/ws": "^7.2.3 || ^8.0.0",
|
"@types/ws": "^7.2.3 || ^8.0.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"express": "^4.17.1",
|
"express": "^4.17.1",
|
||||||
|
"node-fetch": "^3.3.0",
|
||||||
"ws": "^7.2.3 || ^8.0.0",
|
"ws": "^7.2.3 || ^8.0.0",
|
||||||
"yargs": "^17.6.2"
|
"yargs": "^17.6.2"
|
||||||
},
|
},
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
import cors from "cors";
|
import cors, {CorsOptions} from "cors";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
import publicContent from "../../app.json";
|
import publicContent from "../../app.json";
|
||||||
import PublicApi from "./v1/public";
|
import PublicApi from "./v1/public";
|
||||||
import type {IConfig} from "../config";
|
import type {IConfig} from "../config";
|
||||||
import type {IRealm} from "../models/realm";
|
import type {IRealm} from "../models/realm";
|
||||||
|
|
||||||
export const Api = ({ config, realm }: {
|
export const Api = ({ config, realm, corsOptions }: {
|
||||||
config: IConfig;
|
config: IConfig;
|
||||||
realm: IRealm;
|
realm: IRealm;
|
||||||
|
corsOptions: CorsOptions;
|
||||||
}): express.Router => {
|
}): express.Router => {
|
||||||
const app = express.Router();
|
const app = express.Router();
|
||||||
|
|
||||||
app.use(cors());
|
app.use(cors(corsOptions));
|
||||||
|
|
||||||
app.get("/", (_, res) => {
|
app.get("/", (_, res) => {
|
||||||
res.send(publicContent);
|
res.send(publicContent);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import type {WebSocketServer, ServerOptions} from 'ws';
|
import type {WebSocketServer, ServerOptions} from 'ws';
|
||||||
|
import type {CorsOptions} from "cors";
|
||||||
|
|
||||||
export interface IConfig {
|
export interface IConfig {
|
||||||
readonly host: string;
|
readonly host: string;
|
||||||
@ -17,6 +18,7 @@ export interface IConfig {
|
|||||||
};
|
};
|
||||||
readonly generateClientId?: () => string;
|
readonly generateClientId?: () => string;
|
||||||
readonly createWebSocketServer?: (options: ServerOptions) => WebSocketServer;
|
readonly createWebSocketServer?: (options: ServerOptions) => WebSocketServer;
|
||||||
|
readonly corsOptions : CorsOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultConfig: IConfig = {
|
const defaultConfig: IConfig = {
|
||||||
@ -30,6 +32,7 @@ const defaultConfig: IConfig = {
|
|||||||
allow_discovery: false,
|
allow_discovery: false,
|
||||||
proxied: false,
|
proxied: false,
|
||||||
cleanup_out_msgs: 1000,
|
cleanup_out_msgs: 1000,
|
||||||
|
corsOptions: {origin: true},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defaultConfig;
|
export default defaultConfig;
|
||||||
|
@ -31,7 +31,7 @@ export const createInstance = ({ app, server, options }: {
|
|||||||
const realm: IRealm = new Realm();
|
const realm: IRealm = new Realm();
|
||||||
const messageHandler = new MessageHandler(realm);
|
const messageHandler = new MessageHandler(realm);
|
||||||
|
|
||||||
const api = Api({ config, realm });
|
const api = Api({ config, realm , corsOptions: options.corsOptions });
|
||||||
const messagesExpire: IMessagesExpire = new MessagesExpire({ realm, config, messageHandler });
|
const messagesExpire: IMessagesExpire = new MessagesExpire({ realm, config, messageHandler });
|
||||||
const checkBrokenConnections = new CheckBrokenConnections({
|
const checkBrokenConnections = new CheckBrokenConnections({
|
||||||
realm,
|
realm,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user