mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-10 19:14:16 +00:00
189 lines
5.3 KiB
JavaScript
189 lines
5.3 KiB
JavaScript
import EventEmitter from "@foxify/events"
|
|
|
|
import axios from "axios"
|
|
import { io } from "socket.io-client"
|
|
|
|
import remotes from "./remotes"
|
|
|
|
//import request from "./handlers/request"
|
|
import Storage from "./helpers/withStorage"
|
|
|
|
import SessionModel from "./models/session"
|
|
import { createHandlers } from "./models"
|
|
|
|
globalThis.isServerMode = typeof window === "undefined" && typeof global !== "undefined"
|
|
|
|
if (globalThis.isServerMode) {
|
|
const { Buffer } = require("buffer")
|
|
|
|
globalThis.b64Decode = (data) => {
|
|
return Buffer.from(data, "base64").toString("utf-8")
|
|
}
|
|
globalThis.b64Encode = (data) => {
|
|
return Buffer.from(data, "utf-8").toString("base64")
|
|
}
|
|
}
|
|
|
|
export async function createWebsockets() {
|
|
const instances = globalThis.__comty_shared_state.wsInstances
|
|
|
|
for (let [key, instance] of Object.entries(instances)) {
|
|
if (instance.connected) {
|
|
// disconnect first
|
|
instance.disconnect()
|
|
}
|
|
|
|
// remove current listeners
|
|
instance.removeAllListeners()
|
|
|
|
delete globalThis.__comty_shared_state.wsInstances[key]
|
|
}
|
|
|
|
for (let [key, remote] of Object.entries(remotes)) {
|
|
if (!remote.hasWebsocket) {
|
|
continue
|
|
}
|
|
|
|
let opts = {
|
|
transports: ["websocket"],
|
|
autoConnect: remote.autoConnect ?? true,
|
|
...remote.wsParams ?? {},
|
|
}
|
|
|
|
if (remote.noAuth !== true) {
|
|
opts.auth = {
|
|
token: SessionModel.token,
|
|
}
|
|
}
|
|
|
|
globalThis.__comty_shared_state.wsInstances[key] = io(remote.wsOrigin ?? remote.origin, opts)
|
|
}
|
|
|
|
// regsister events
|
|
for (let [key, instance] of Object.entries(instances)) {
|
|
instance.on("connect", () => {
|
|
console.debug(`[WS-API][${key}] Connected`)
|
|
|
|
if (remotes[key].useClassicAuth && remotes[key].noAuth !== true) {
|
|
// try to auth
|
|
instance.emit("authenticate", {
|
|
token: SessionModel.token,
|
|
})
|
|
}
|
|
|
|
globalThis.__comty_shared_state.eventBus.emit(`${key}:connected`)
|
|
})
|
|
|
|
instance.on("disconnect", () => {
|
|
console.debug(`[WS-API][${key}] Disconnected`)
|
|
|
|
globalThis.__comty_shared_state.eventBus.emit(`${key}:disconnected`)
|
|
})
|
|
|
|
instance.on("error", (error) => {
|
|
console.error(`[WS-API][${key}] Error`, error)
|
|
|
|
globalThis.__comty_shared_state.eventBus.emit(`${key}:error`, error)
|
|
})
|
|
|
|
instance.onAny((event, ...args) => {
|
|
console.debug(`[WS-API][${key}] Event (${event})`, ...args)
|
|
|
|
globalThis.__comty_shared_state.eventBus.emit(`${key}:${event}`, ...args)
|
|
})
|
|
}
|
|
}
|
|
|
|
export async function reconnectWebsockets({ force = false } = {}) {
|
|
const instances = globalThis.__comty_shared_state.wsInstances
|
|
|
|
for (let [key, instance] of Object.entries(instances)) {
|
|
if (instance.connected) {
|
|
if (!instance.auth) {
|
|
instance.disconnect()
|
|
|
|
instance.auth = {
|
|
token: SessionModel.token,
|
|
}
|
|
|
|
instance.connect()
|
|
continue
|
|
}
|
|
|
|
if (!force) {
|
|
instance.emit("reauthenticate", {
|
|
token: SessionModel.token,
|
|
})
|
|
|
|
continue
|
|
}
|
|
|
|
// disconnect first
|
|
instance.disconnect()
|
|
}
|
|
|
|
if (remotes[key].noAuth !== true) {
|
|
instance.auth = {
|
|
token: SessionModel.token,
|
|
}
|
|
}
|
|
|
|
instance.connect()
|
|
}
|
|
}
|
|
|
|
export default function createClient({
|
|
accessKey = null,
|
|
privateKey = null,
|
|
enableWs = false,
|
|
} = {}) {
|
|
const sharedState = globalThis.__comty_shared_state = {
|
|
onExpiredExceptionEvent: false,
|
|
excludedExpiredExceptionURL: ["/session/regenerate"],
|
|
eventBus: new EventEmitter(),
|
|
mainOrigin: remotes.default.origin,
|
|
instances: Object(),
|
|
wsInstances: Object(),
|
|
rest: null,
|
|
}
|
|
|
|
if (globalThis.isServerMode) {
|
|
sharedState.rest = createHandlers()
|
|
}
|
|
|
|
if (privateKey && accessKey && globalThis.isServerMode) {
|
|
Storage.engine.set("token", `${accessKey}:${privateKey}`)
|
|
}
|
|
|
|
// create instances for every remote
|
|
for (const [key, remote] of Object.entries(remotes)) {
|
|
sharedState.instances[key] = axios.create({
|
|
baseURL: remote.origin,
|
|
headers: {
|
|
"Content-Type": "application/json",
|
|
}
|
|
})
|
|
|
|
// create a interceptor to attach the token every request
|
|
sharedState.instances[key].interceptors.request.use((config) => {
|
|
// check if current request has no Authorization header, if so, attach the token
|
|
if (!config.headers["Authorization"]) {
|
|
const sessionToken = SessionModel.token
|
|
|
|
if (sessionToken) {
|
|
config.headers["Authorization"] = `${globalThis.isServerMode ? "Server" : "Bearer"} ${sessionToken}`
|
|
} else {
|
|
console.warn("Making a request with no session token")
|
|
}
|
|
}
|
|
|
|
return config
|
|
})
|
|
}
|
|
|
|
if (enableWs) {
|
|
createWebsockets()
|
|
}
|
|
|
|
return sharedState
|
|
} |