chore: Format code again.
This commit is contained in:
parent
5f1df9ca88
commit
3143800c92
5 changed files with 255 additions and 171 deletions
|
@ -4,6 +4,6 @@ import { PassyFireBackendProvider } from "./passyfire-reimpl/index.js";
|
|||
import { SSHBackendProvider } from "./ssh.js";
|
||||
|
||||
export const backendProviders: Record<string, typeof BackendBaseClass> = {
|
||||
"ssh": SSHBackendProvider,
|
||||
"passyfire": PassyFireBackendProvider
|
||||
};
|
||||
ssh: SSHBackendProvider,
|
||||
passyfire: PassyFireBackendProvider,
|
||||
};
|
||||
|
|
|
@ -3,40 +3,45 @@ import fastifyWebsocket from "@fastify/websocket";
|
|||
import type { FastifyInstance } from "fastify";
|
||||
import Fastify from "fastify";
|
||||
|
||||
import type { ForwardRule, ConnectedClient, ParameterReturnedValue, BackendBaseClass } from "../base.js";
|
||||
import type {
|
||||
ForwardRule,
|
||||
ConnectedClient,
|
||||
ParameterReturnedValue,
|
||||
BackendBaseClass,
|
||||
} from "../base.js";
|
||||
import { generateRandomData } from "../../libs/generateRandom.js";
|
||||
import { requestHandler } from "./socket.js";
|
||||
import { route } from "./routes.js";
|
||||
|
||||
type BackendProviderUser = {
|
||||
username: string,
|
||||
password: string
|
||||
}
|
||||
username: string;
|
||||
password: string;
|
||||
};
|
||||
|
||||
export type ForwardRuleExt = ForwardRule & {
|
||||
protocol: "tcp" | "udp",
|
||||
userConfig: Record<string, string>
|
||||
protocol: "tcp" | "udp";
|
||||
userConfig: Record<string, string>;
|
||||
};
|
||||
|
||||
export type ConnectedClientExt = ConnectedClient & {
|
||||
connectionDetails: ForwardRuleExt;
|
||||
username: string;
|
||||
username: string;
|
||||
};
|
||||
|
||||
// Fight me (for better naming)
|
||||
type BackendParsedProviderString = {
|
||||
ip: string,
|
||||
port: number,
|
||||
publicPort?: number,
|
||||
isProxied?: boolean,
|
||||
ip: string;
|
||||
port: number;
|
||||
publicPort?: number;
|
||||
isProxied?: boolean;
|
||||
|
||||
users: BackendProviderUser[]
|
||||
}
|
||||
users: BackendProviderUser[];
|
||||
};
|
||||
|
||||
type LoggedInUser = {
|
||||
username: string,
|
||||
token: string
|
||||
}
|
||||
username: string;
|
||||
token: string;
|
||||
};
|
||||
|
||||
function parseBackendProviderString(data: string): BackendParsedProviderString {
|
||||
try {
|
||||
|
@ -47,19 +52,30 @@ function parseBackendProviderString(data: string): BackendParsedProviderString {
|
|||
|
||||
const jsonData = JSON.parse(data);
|
||||
|
||||
if (typeof jsonData.ip != "string") throw new Error("IP field is not a string");
|
||||
if (typeof jsonData.ip != "string")
|
||||
throw new Error("IP field is not a string");
|
||||
if (typeof jsonData.port != "number") throw new Error("Port is not a number");
|
||||
|
||||
if (typeof jsonData.publicPort != "undefined" && typeof jsonData.publicPort != "number") throw new Error("(optional field) Proxied port is not a number");
|
||||
if (typeof jsonData.isProxied != "undefined" && typeof jsonData.isProxied != "boolean") throw new Error("(optional field) 'Is proxied' is not a boolean");
|
||||
if (
|
||||
typeof jsonData.publicPort != "undefined" &&
|
||||
typeof jsonData.publicPort != "number"
|
||||
)
|
||||
throw new Error("(optional field) Proxied port is not a number");
|
||||
if (
|
||||
typeof jsonData.isProxied != "undefined" &&
|
||||
typeof jsonData.isProxied != "boolean"
|
||||
)
|
||||
throw new Error("(optional field) 'Is proxied' is not a boolean");
|
||||
|
||||
if (!Array.isArray(jsonData.users)) throw new Error("Users is not an array");
|
||||
|
||||
for (const userIndex in jsonData.users) {
|
||||
const user = jsonData.users[userIndex];
|
||||
|
||||
if (typeof user.username != "string") throw new Error("Username is not a string, in users array");
|
||||
if (typeof user.password != "string") throw new Error("Password is not a string, in users array");
|
||||
|
||||
if (typeof user.username != "string")
|
||||
throw new Error("Username is not a string, in users array");
|
||||
if (typeof user.password != "string")
|
||||
throw new Error("Password is not a string, in users array");
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -69,8 +85,8 @@ function parseBackendProviderString(data: string): BackendParsedProviderString {
|
|||
publicPort: jsonData.publicPort,
|
||||
isProxied: jsonData.isProxied,
|
||||
|
||||
users: jsonData.users
|
||||
}
|
||||
users: jsonData.users,
|
||||
};
|
||||
}
|
||||
|
||||
export class PassyFireBackendProvider implements BackendBaseClass {
|
||||
|
@ -87,8 +103,8 @@ export class PassyFireBackendProvider implements BackendBaseClass {
|
|||
constructor(parameters: string) {
|
||||
this.logs = [];
|
||||
this.clients = [];
|
||||
this.proxies = [];
|
||||
|
||||
this.proxies = [];
|
||||
|
||||
this.state = "stopped";
|
||||
this.options = parseBackendProviderString(parameters);
|
||||
|
||||
|
@ -100,17 +116,19 @@ export class PassyFireBackendProvider implements BackendBaseClass {
|
|||
|
||||
this.fastify = Fastify({
|
||||
logger: true,
|
||||
trustProxy: this.options.isProxied
|
||||
trustProxy: this.options.isProxied,
|
||||
});
|
||||
|
||||
await this.fastify.register(fastifyWebsocket);
|
||||
route(this);
|
||||
|
||||
this.fastify.get("/", { websocket: true }, (ws, req) => requestHandler(this, ws, req));
|
||||
this.fastify.get("/", { websocket: true }, (ws, req) =>
|
||||
requestHandler(this, ws, req),
|
||||
);
|
||||
|
||||
await this.fastify.listen({
|
||||
port: this.options.port,
|
||||
host: this.options.ip
|
||||
host: this.options.ip,
|
||||
});
|
||||
|
||||
this.state = "started";
|
||||
|
@ -124,18 +142,23 @@ export class PassyFireBackendProvider implements BackendBaseClass {
|
|||
this.users.splice(0, this.users.length);
|
||||
this.proxies.splice(0, this.proxies.length);
|
||||
this.clients.splice(0, this.clients.length);
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
addConnection(sourceIP: string, sourcePort: number, destPort: number, protocol: "tcp" | "udp"): void {
|
||||
return true;
|
||||
}
|
||||
|
||||
addConnection(
|
||||
sourceIP: string,
|
||||
sourcePort: number,
|
||||
destPort: number,
|
||||
protocol: "tcp" | "udp",
|
||||
): void {
|
||||
const proxy: ForwardRuleExt = {
|
||||
sourceIP,
|
||||
sourcePort,
|
||||
destPort,
|
||||
protocol,
|
||||
|
||||
userConfig: {}
|
||||
userConfig: {},
|
||||
};
|
||||
|
||||
for (const user of this.options.users) {
|
||||
|
@ -143,29 +166,49 @@ export class PassyFireBackendProvider implements BackendBaseClass {
|
|||
}
|
||||
|
||||
this.proxies.push(proxy);
|
||||
};
|
||||
}
|
||||
|
||||
removeConnection(sourceIP: string, sourcePort: number, destPort: number, protocol: "tcp" | "udp"): void {
|
||||
const connectionCheck = PassyFireBackendProvider.checkParametersConnection(sourceIP, sourcePort, destPort, protocol);
|
||||
removeConnection(
|
||||
sourceIP: string,
|
||||
sourcePort: number,
|
||||
destPort: number,
|
||||
protocol: "tcp" | "udp",
|
||||
): void {
|
||||
const connectionCheck = PassyFireBackendProvider.checkParametersConnection(
|
||||
sourceIP,
|
||||
sourcePort,
|
||||
destPort,
|
||||
protocol,
|
||||
);
|
||||
if (!connectionCheck.success) throw new Error(connectionCheck.message);
|
||||
|
||||
const foundProxyEntry = this.proxies.find((i) => i.sourceIP == sourceIP && i.sourcePort == sourcePort && i.destPort == destPort);
|
||||
const foundProxyEntry = this.proxies.find(
|
||||
i =>
|
||||
i.sourceIP == sourceIP &&
|
||||
i.sourcePort == sourcePort &&
|
||||
i.destPort == destPort,
|
||||
);
|
||||
if (!foundProxyEntry) return;
|
||||
|
||||
this.proxies.splice(this.proxies.indexOf(foundProxyEntry), 1);
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
getAllConnections(): ConnectedClient[] {
|
||||
if (this.clients == null) return [];
|
||||
return this.clients;
|
||||
};
|
||||
}
|
||||
|
||||
static checkParametersConnection(sourceIP: string, sourcePort: number, destPort: number, protocol: "tcp" | "udp"): ParameterReturnedValue {
|
||||
static checkParametersConnection(
|
||||
sourceIP: string,
|
||||
sourcePort: number,
|
||||
destPort: number,
|
||||
protocol: "tcp" | "udp",
|
||||
): ParameterReturnedValue {
|
||||
return {
|
||||
success: true
|
||||
}
|
||||
};
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
|
||||
static checkParametersBackendInstance(data: string): ParameterReturnedValue {
|
||||
try {
|
||||
|
@ -174,12 +217,12 @@ export class PassyFireBackendProvider implements BackendBaseClass {
|
|||
} catch (e: Error) {
|
||||
return {
|
||||
success: false,
|
||||
message: e.toString()
|
||||
}
|
||||
message: e.toString(),
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
success: true
|
||||
}
|
||||
};
|
||||
}
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@ import type { PassyFireBackendProvider } from "./index.js";
|
|||
|
||||
export function route(instance: PassyFireBackendProvider) {
|
||||
const { fastify } = instance;
|
||||
|
||||
|
||||
const proxiedPort: number = instance.options.publicPort ?? 443;
|
||||
|
||||
const unsupportedSpoofedRoutes: string[] = [
|
||||
|
@ -16,7 +16,7 @@ export function route(instance: PassyFireBackendProvider) {
|
|||
"/api/v1/tunnels/stop",
|
||||
|
||||
// Same scenario for this API.
|
||||
"/api/v1/users",
|
||||
"/api/v1/users",
|
||||
"/api/v1/users/add",
|
||||
"/api/v1/users/remove",
|
||||
"/api/v1/users/enable",
|
||||
|
@ -31,7 +31,7 @@ export function route(instance: PassyFireBackendProvider) {
|
|||
add: true,
|
||||
remove: true,
|
||||
get: true,
|
||||
getPasswords: true
|
||||
getPasswords: true,
|
||||
},
|
||||
routes: {
|
||||
add: true,
|
||||
|
@ -39,125 +39,140 @@ export function route(instance: PassyFireBackendProvider) {
|
|||
start: true,
|
||||
stop: true,
|
||||
get: true,
|
||||
getPasswords: true
|
||||
}
|
||||
}
|
||||
}
|
||||
getPasswords: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
for (const spoofedRoute of unsupportedSpoofedRoutes) {
|
||||
fastify.post(spoofedRoute, (req, res) => {
|
||||
if (typeof req.body != "string") return res.status(400).send({
|
||||
error: "Invalid token"
|
||||
});
|
||||
if (typeof req.body != "string")
|
||||
return res.status(400).send({
|
||||
error: "Invalid token",
|
||||
});
|
||||
|
||||
try {
|
||||
JSON.parse(req.body);
|
||||
} catch (e) {
|
||||
return res.status(400).send({
|
||||
error: "Invalid token"
|
||||
})
|
||||
error: "Invalid token",
|
||||
});
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
if (!req.body.token) return res.status(400).send({
|
||||
error: "Invalid token"
|
||||
});
|
||||
if (!req.body.token)
|
||||
return res.status(400).send({
|
||||
error: "Invalid token",
|
||||
});
|
||||
|
||||
return res.status(403).send({
|
||||
error: "Invalid scope(s)"
|
||||
error: "Invalid scope(s)",
|
||||
});
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
fastify.post("/api/v1/users/login", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["username", "password"],
|
||||
fastify.post(
|
||||
"/api/v1/users/login",
|
||||
{
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["username", "password"],
|
||||
|
||||
properties: {
|
||||
username: { type: "string" },
|
||||
password: { type: "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}, (req, res) => {
|
||||
// @ts-ignore
|
||||
const body: {
|
||||
username: string,
|
||||
password: string
|
||||
} = req.body;
|
||||
|
||||
if (!instance.options.users.find((i) => i.username == body.username && i.password == body.password)) {
|
||||
return res.status(403).send({
|
||||
error: "Invalid username/password."
|
||||
});
|
||||
};
|
||||
|
||||
const token = generateRandomData();
|
||||
|
||||
instance.users.push({
|
||||
username: body.username,
|
||||
token
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
token
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fastify.post("/api/v1/tunnels", {
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["token"],
|
||||
properties: {
|
||||
token: { type: "string" },
|
||||
properties: {
|
||||
username: { type: "string" },
|
||||
password: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}, async (req, res) => {
|
||||
// @ts-ignore
|
||||
const body: {
|
||||
token: string
|
||||
} = req.body;
|
||||
(req, res) => {
|
||||
// @ts-ignore
|
||||
const body: {
|
||||
username: string;
|
||||
password: string;
|
||||
} = req.body;
|
||||
|
||||
const userData = instance.users.find(user => user.token == body.token);
|
||||
if (
|
||||
!instance.options.users.find(
|
||||
i => i.username == body.username && i.password == body.password,
|
||||
)
|
||||
) {
|
||||
return res.status(403).send({
|
||||
error: "Invalid username/password.",
|
||||
});
|
||||
}
|
||||
|
||||
if (!userData) return res.status(403).send({
|
||||
error: "Invalid token"
|
||||
});
|
||||
const token = generateRandomData();
|
||||
|
||||
// const host = req.hostname.substring(0, req.hostname.indexOf(":"));
|
||||
const unparsedPort = req.hostname.substring(req.hostname.indexOf(":") + 1);
|
||||
|
||||
// @ts-ignore
|
||||
// parseInt(...) can take a number just fine, at least in Node.JS
|
||||
const port = parseInt(unparsedPort == "" ? proxiedPort : unparsedPort);
|
||||
instance.users.push({
|
||||
username: body.username,
|
||||
token,
|
||||
});
|
||||
|
||||
// This protocol is so confusing. I'm sorry.
|
||||
res.send({
|
||||
success: true,
|
||||
data: instance.proxies.map((proxy) => ({
|
||||
proxyUrlSettings: {
|
||||
host: "sameAs", // Makes pfC work (this is by design apparently)
|
||||
port,
|
||||
protocol: proxy.protocol.toUpperCase()
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
token,
|
||||
},
|
||||
|
||||
dest: `${proxy.sourceIP}:${proxy.destPort}`,
|
||||
name: `${proxy.protocol.toUpperCase()} on ::${proxy.sourcePort} -> ::${proxy.destPort}`,
|
||||
|
||||
passwords: [
|
||||
proxy.userConfig[userData.username]
|
||||
],
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
running: true
|
||||
}))
|
||||
});
|
||||
});
|
||||
}
|
||||
fastify.post(
|
||||
"/api/v1/tunnels",
|
||||
{
|
||||
schema: {
|
||||
body: {
|
||||
type: "object",
|
||||
required: ["token"],
|
||||
properties: {
|
||||
token: { type: "string" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
async (req, res) => {
|
||||
// @ts-ignore
|
||||
const body: {
|
||||
token: string;
|
||||
} = req.body;
|
||||
|
||||
const userData = instance.users.find(user => user.token == body.token);
|
||||
|
||||
if (!userData)
|
||||
return res.status(403).send({
|
||||
error: "Invalid token",
|
||||
});
|
||||
|
||||
// const host = req.hostname.substring(0, req.hostname.indexOf(":"));
|
||||
const unparsedPort = req.hostname.substring(
|
||||
req.hostname.indexOf(":") + 1,
|
||||
);
|
||||
|
||||
// @ts-ignore
|
||||
// parseInt(...) can take a number just fine, at least in Node.JS
|
||||
const port = parseInt(unparsedPort == "" ? proxiedPort : unparsedPort);
|
||||
|
||||
// This protocol is so confusing. I'm sorry.
|
||||
res.send({
|
||||
success: true,
|
||||
data: instance.proxies.map(proxy => ({
|
||||
proxyUrlSettings: {
|
||||
host: "sameAs", // Makes pfC work (this is by design apparently)
|
||||
port,
|
||||
protocol: proxy.protocol.toUpperCase(),
|
||||
},
|
||||
|
||||
dest: `${proxy.sourceIP}:${proxy.destPort}`,
|
||||
name: `${proxy.protocol.toUpperCase()} on ::${proxy.sourcePort} -> ::${proxy.destPort}`,
|
||||
|
||||
passwords: [proxy.userConfig[userData.username]],
|
||||
|
||||
running: true,
|
||||
})),
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
|
|
@ -9,7 +9,12 @@ import type { ConnectedClientExt, PassyFireBackendProvider } from "./index.js";
|
|||
// This code sucks because this protocol sucks BUUUT it works, and I don't wanna reinvent
|
||||
// the gosh darn wheel for (almost) no reason
|
||||
|
||||
function authenticateSocket(instance: PassyFireBackendProvider, ws: WebSocket, message: string, state: ConnectedClientExt): Boolean {
|
||||
function authenticateSocket(
|
||||
instance: PassyFireBackendProvider,
|
||||
ws: WebSocket,
|
||||
message: string,
|
||||
state: ConnectedClientExt,
|
||||
): Boolean {
|
||||
if (!message.startsWith("Accept: ")) {
|
||||
ws.send("400 Bad Request");
|
||||
return false;
|
||||
|
@ -25,13 +30,13 @@ function authenticateSocket(instance: PassyFireBackendProvider, ws: WebSocket, m
|
|||
for (const proxy of instance.proxies) {
|
||||
for (const username of Object.keys(proxy.userConfig)) {
|
||||
const currentToken = proxy.userConfig[username];
|
||||
|
||||
|
||||
if (token == currentToken) {
|
||||
state.connectionDetails = proxy;
|
||||
state.username = username;
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (state.connectionDetails && state.username) {
|
||||
ws.send("AcceptResponse Bearer: true");
|
||||
|
@ -44,7 +49,11 @@ function authenticateSocket(instance: PassyFireBackendProvider, ws: WebSocket, m
|
|||
return false;
|
||||
}
|
||||
|
||||
export function requestHandler(instance: PassyFireBackendProvider, ws: WebSocket, req: FastifyRequest) {
|
||||
export function requestHandler(
|
||||
instance: PassyFireBackendProvider,
|
||||
ws: WebSocket,
|
||||
req: FastifyRequest,
|
||||
) {
|
||||
let state: "authentication" | "data" = "authentication";
|
||||
let socket: dgram.Socket | net.Socket | undefined;
|
||||
|
||||
|
@ -52,25 +61,31 @@ export function requestHandler(instance: PassyFireBackendProvider, ws: WebSocket
|
|||
let connectedClient: ConnectedClientExt = {};
|
||||
|
||||
ws.on("close", () => {
|
||||
instance.clients.splice(instance.clients.indexOf(connectedClient as ConnectedClientExt), 1);
|
||||
instance.clients.splice(
|
||||
instance.clients.indexOf(connectedClient as ConnectedClientExt),
|
||||
1,
|
||||
);
|
||||
});
|
||||
|
||||
ws.on("message", (rawData: ArrayBuffer) => {
|
||||
if (state == "authentication") {
|
||||
const data = rawData.toString();
|
||||
|
||||
|
||||
if (authenticateSocket(instance, ws, data, connectedClient)) {
|
||||
ws.send("AcceptResponse Bearer: true");
|
||||
|
||||
connectedClient.ip = req.ip;
|
||||
connectedClient.port = req.socket.remotePort ?? -1;
|
||||
|
||||
|
||||
instance.clients.push(connectedClient);
|
||||
|
||||
|
||||
if (connectedClient.connectionDetails.protocol == "tcp") {
|
||||
socket = new net.Socket();
|
||||
|
||||
socket.connect(connectedClient.connectionDetails.sourcePort, connectedClient.connectionDetails.sourceIP);
|
||||
socket.connect(
|
||||
connectedClient.connectionDetails.sourcePort,
|
||||
connectedClient.connectionDetails.sourceIP,
|
||||
);
|
||||
|
||||
socket.on("connect", () => {
|
||||
state = "data";
|
||||
|
@ -79,7 +94,7 @@ export function requestHandler(instance: PassyFireBackendProvider, ws: WebSocket
|
|||
ws.send("InitProxy: Connected");
|
||||
});
|
||||
|
||||
socket.on("data", (data) => {
|
||||
socket.on("data", data => {
|
||||
ws.send(data);
|
||||
});
|
||||
} else if (connectedClient.connectionDetails.protocol == "udp") {
|
||||
|
@ -90,7 +105,11 @@ export function requestHandler(instance: PassyFireBackendProvider, ws: WebSocket
|
|||
ws.send("InitProxy: Connected");
|
||||
|
||||
socket.on("message", (data, rinfo) => {
|
||||
if (rinfo.address != connectedClient.connectionDetails.sourceIP || rinfo.port != connectedClient.connectionDetails.sourcePort) return;
|
||||
if (
|
||||
rinfo.address != connectedClient.connectionDetails.sourceIP ||
|
||||
rinfo.port != connectedClient.connectionDetails.sourcePort
|
||||
)
|
||||
return;
|
||||
ws.send(data);
|
||||
});
|
||||
}
|
||||
|
@ -98,17 +117,24 @@ export function requestHandler(instance: PassyFireBackendProvider, ws: WebSocket
|
|||
} else if (state == "data") {
|
||||
if (socket instanceof dgram.Socket) {
|
||||
const array = new Uint8Array(rawData);
|
||||
|
||||
socket.send(array, connectedClient.connectionDetails.sourcePort, connectedClient.connectionDetails.sourceIP, (err) => {
|
||||
if (err) throw err;
|
||||
});
|
||||
|
||||
socket.send(
|
||||
array,
|
||||
connectedClient.connectionDetails.sourcePort,
|
||||
connectedClient.connectionDetails.sourceIP,
|
||||
err => {
|
||||
if (err) throw err;
|
||||
},
|
||||
);
|
||||
} else if (socket instanceof net.Socket) {
|
||||
const array = new Uint8Array(rawData);
|
||||
|
||||
socket.write(array);
|
||||
}
|
||||
} else {
|
||||
throw new Error(`Whooops, our WebSocket reached an unsupported state: '${state}'`);
|
||||
throw new Error(
|
||||
`Whooops, our WebSocket reached an unsupported state: '${state}'`,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,7 +55,7 @@ const backends: Record<number, BackendBaseClass> = {};
|
|||
|
||||
const fastify = Fastify({
|
||||
logger: true,
|
||||
trustProxy: Boolean(process.env.IS_BEHIND_PROXY)
|
||||
trustProxy: Boolean(process.env.IS_BEHIND_PROXY),
|
||||
});
|
||||
|
||||
const routeOptions: RouteOptions = {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue