feat: specify cors options via cli or js

Closes #196, #221
This commit is contained in:
Jonas Gloning 2023-02-14 20:45:31 +01:00
parent ac44657961
commit 05f12cdc56
No known key found for this signature in database
GPG Key ID: 684639B5E59E7614
10 changed files with 280 additions and 83 deletions

View File

@ -85,7 +85,7 @@ If you have your own server, you can attach PeerServer.
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 | `"/"` |
@ -96,8 +96,8 @@ You can provide config object to `PeerServer` function or specify options for `p
| `--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 | |
| `--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` | | | `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.

View File

@ -2,8 +2,9 @@ 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';
@ -30,28 +31,61 @@ async function makeRequest() {
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 promise = new Promise<void>((resolve, reject) => {
resolver = resolve;
rejecter = reject;
});
const ls = spawn('node', [path.join(__dirname, '../', 'dist/bin/peerjs.js'), '--port', PORT]);
ls.stdout.on('data', async (data: string) => {
if (!data.includes('Started')) return;
const ls = await startServer()
try { try {
const resp = await makeRequest(); const resp = await makeRequest();
expect(resp).toEqual(expectedJson); expect(resp).toEqual(expectedJson);
resolver();
} catch (error) {
rejecter(error);
} finally { } finally {
ls.kill('SIGKILL'); ls.kill();
} }
}); });
return promise; it('should reflect the origin header in CORS by default', async () => {
expect.assertions(1);
const ls = await startServer()
const origin = crypto.randomUUID();
try {
const res = await fetch(`http://localhost:${PORT}/peerjs/id`, {
headers: {
Origin: origin
}
})
expect(res.headers.get("access-control-allow-origin")).toBe(origin)
} finally {
ls.kill()
}
});
it('should respect the CORS parameters', async () => {
expect.assertions(3);
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()
}
}); });
}); });

View File

@ -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()
})
})
}

View File

@ -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));
@ -79,12 +80,22 @@ const opts = y
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);
}); });

View File

@ -1,8 +1,12 @@
/** @type {import('jest').Config} */ /** @type {import('jest').Config} */
const config = { const config = {
testEnvironment: "node",
transform: { transform: {
"^.+\\.(t|j)sx?$": "@swc/jest", "^.+\\.(t|j)sx?$": "@swc/jest",
}, },
transformIgnorePatterns: [
// "node_modules"
],
collectCoverageFrom: ["./src/**"] collectCoverageFrom: ["./src/**"]
}; };

165
package-lock.json generated
View File

@ -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",

View File

@ -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"
}, },

View File

@ -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);

View File

@ -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;

View File

@ -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,