improve client config and fix reconnect token bug

This commit is contained in:
hippoz 2022-02-07 16:14:43 +02:00
parent d82f79c095
commit b95af521a3
No known key found for this signature in database
GPG key ID: 7C52899193467641
8 changed files with 74 additions and 23 deletions

41
README.md Normal file
View file

@ -0,0 +1,41 @@
# bridge
bridge is an extensible program that allows bridging various chat applications, providing an API that bridge clients can use. Currently, it only supports bridging Discord to the bridge API.
# Install
`node` and `npm` are required. `yarn` is recommended instead of `npm`. (If using yarn, replace occurrences of `npm` with `yarn`)
```
npm install
```
Before running it, you will probably want to edit the server's `config.js` to match the Discord guilds you'd like to bridge or change other settings.
Then, to run it:
```
DISCORD_TOKEN="your discord token" JWT_SECRET="jwt secret" node index.js
```
# Building the frontend
You may also want to build the frontend web application.
First, install the dependencies:
```
cd frontend
npm install
```
Then, open `src/config.js` in your editor and update the values to match where you're hosting the bridge's http server. You may use a reverse proxy such as NGINX. If you just want to run and use it locally, the defaults are fine.
Once you're done tweaking the configuration, you can build it:
```
npm run build
```
# Notice
This software may break the ToS of certain chat applications that do not allow bridging (either directly or indirectly). It is only for educational purposes and I am not responsible for any damage caused.

View file

@ -1,16 +1,15 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset='utf-8'> <meta charset="utf-8">
<meta name='viewport' content='width=device-width,initial-scale=1'> <meta name="viewport" content="width=device-width,initial-scale=1">
<title>App</title> <title>App</title>
<link rel='icon' type='image/png' href='/favicon.png'> <link rel="stylesheet" href="global.css">
<link rel='stylesheet' href='/global.css'> <link rel="stylesheet" href="build/bundle.css">
<link rel='stylesheet' href='/build/bundle.css'>
<script defer src='/build/bundle.js'></script> <script defer src="build/bundle.js"></script>
</head> </head>
<body> <body>

View file

@ -75,7 +75,7 @@ export default class GatewayClient {
console.log("gateway: closed"); console.log("gateway: closed");
setTimeout(() => { setTimeout(() => {
console.log("gateway: reconnecting"); console.log("gateway: reconnecting");
this.connect(); this.connect(token);
}, 4000); }, 4000);
}); });
} }

View file

@ -1,3 +1,4 @@
import { apiBase, getRuntimeConfigField } from "../config";
import APIClient from "./APIClient"; import APIClient from "./APIClient";
export const apiClient = new APIClient(`${location.origin}/api/v1`, localStorage.getItem("token")); export const apiClient = new APIClient(apiBase, getRuntimeConfigField("token"));

View file

@ -1,6 +1,7 @@
<script> <script>
import { apiClient } from "../api/common"; import { apiClient } from "../api/common";
import GatewayClient from "../api/GatewayClient"; import GatewayClient from "../api/GatewayClient";
import { gatewayBase, getRuntimeConfigField } from "../config";
import { supportsWebsockets } from "../util/browser"; import { supportsWebsockets } from "../util/browser";
import ChatView from "./ChatView.svelte"; import ChatView from "./ChatView.svelte";
import FuzzyView from "./FuzzyView.svelte"; import FuzzyView from "./FuzzyView.svelte";
@ -73,21 +74,20 @@
if (guilds[0].channels.length > 0) if (guilds[0].channels.length > 0)
selectedChannel = guilds[0].channels[0]; selectedChannel = guilds[0].channels[0];
} }
if (supportsWebsockets() && !localStorage.getItem("f_disableWebsockets")) {
console.log("App: browser supports WebSocket, using gateway");
const gatewayConnection = new GatewayClient(`${ location.protocol === "https:" ? "wss://" : "ws://" }${location.host}/gateway`);
gatewayConnection.onEvent = handleEvent;
gatewayConnection.connect(apiClient.token);
} else {
console.warn("App: browser does not support WebSocket, using polling");
const { poll } = apiClient.createPollingListener(null, ({ event }) => {
handleEvent(event);
});
poll();
}
}); });
if (supportsWebsockets() && !getRuntimeConfigField("f_disableWebsockets")) {
console.log("App: browser supports WebSocket, using gateway");
const gatewayConnection = new GatewayClient(gatewayBase);
gatewayConnection.onEvent = handleEvent;
gatewayConnection.connect(apiClient.token);
} else {
console.warn("App: browser does not support WebSocket (or it is disabled), using polling");
const { poll } = apiClient.createPollingListener(null, ({ event }) => {
handleEvent(event);
});
poll();
}
function onTextEntryMessage(event) { function onTextEntryMessage(event) {
const content = event.detail; const content = event.detail;

10
frontend/src/config.js Normal file
View file

@ -0,0 +1,10 @@
export const apiBase = "http://localhost:4050/api/v1";
export const gatewayBase = "ws://localhost:4050/gateway";
export function getRuntimeConfigField(field) {
return localStorage.getItem(field);
}
export function setRuntimeConfigField(field, value) {
return localStorage.setItem(field, value);
}

View file

@ -1,4 +1,4 @@
import App from './components/App.svelte'; import App from "./components/App.svelte";
const app = new App({ const app = new App({
target: document.body, target: document.body,

View file

@ -104,7 +104,7 @@ router.get("/guilds/:guildId", checkAuth(async (req, res) => {
router.get("/users/@self/guilds", checkAuth(async (req, res) => { router.get("/users/@self/guilds", checkAuth(async (req, res) => {
const { guildAccess } = req.user; const { guildAccess } = req.user;
res.status(200).send({ error: false, guilds: guildAccess.map(e => guildMap.get(e)?.guildObject) }); res.status(200).send({ error: false, guilds: guildAccess.map(e => guildMap.get(e)?.guildObject).filter(e => !!e) });
})); }));
router.get("/guilds/:guildId/events/poll", checkAuth(async (req, res) => { router.get("/guilds/:guildId/events/poll", checkAuth(async (req, res) => {