diff --git a/.gitignore b/.gitignore index 3d83514..a8a88ca 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ od-spell-caster +/node_modules diff --git a/Dockerfile b/Dockerfile index 7225367..8c4c0ad 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,7 @@ -FROM golang AS build -WORKDIR /app -COPY . . -RUN CGO_ENABLED=0 GOOS=linux go build -o /od-spell-caster . +FROM oven/bun:slim AS build -FROM scratch -COPY --from=build /od-spell-caster /od-spell-caster +COPY main.ts main.ts +COPY util.ts util.ts +COPY consts.ts consts.ts -# bandaid fix -# we'll have to fix this later... -# COPY ./fullchain.pem fullchain.pem -# COPY ./privkey.pem privkey.pem -# COPY ./ash.yaml ./ash.yaml -CMD ["/od-spell-caster"] +ENTRYPOINT ["bun", "run", "main.ts"] diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..8fde704 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,24 @@ +pipeline { + agent any + + stages { + + stage('Docker Build') { + steps { + sh 'docker compose build' + } + } + + stage('Docker Kill') { + steps { + sh 'docker compose down --rmi \'all\'' + } + } + + stage('Docker Run') { + steps { + sh 'docker compose up -d' + } + } + } +} diff --git a/bun.lock b/bun.lock new file mode 100644 index 0000000..504fd10 --- /dev/null +++ b/bun.lock @@ -0,0 +1,29 @@ +{ + "lockfileVersion": 1, + "workspaces": { + "": { + "name": "od-spell-caster", + "devDependencies": { + "@types/bun": "latest", + }, + "peerDependencies": { + "typescript": "^5", + }, + }, + }, + "packages": { + "@types/bun": ["@types/bun@1.3.1", "", { "dependencies": { "bun-types": "1.3.1" } }, "sha512-4jNMk2/K9YJtfqwoAa28c8wK+T7nvJFOjxI4h/7sORWcypRNxBpr+TPNaCfVWq70tLCJsqoFwcf0oI0JU/fvMQ=="], + + "@types/node": ["@types/node@24.9.1", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg=="], + + "@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="], + + "bun-types": ["bun-types@1.3.1", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-NMrcy7smratanWJ2mMXdpatalovtxVggkj11bScuWuiOoXTiKIu2eVS1/7qbyI/4yHedtsn175n4Sm4JcdHLXw=="], + + "csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="], + + "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], + + "undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="], + } +} diff --git a/compose.yaml b/compose.yaml index 9116c62..c78f9b4 100644 --- a/compose.yaml +++ b/compose.yaml @@ -1,14 +1,6 @@ services: - od-ash_tray: + od-spell-caster: build: . ports: - - "0.0.0.0:4242:4242" - # environment: - # - ASH_TRAY_ID - # - ASH_TRAY_DIRECTORY=/cdn - # - ASH_TRAY_KEY - # - ASH_TRAY_PORT=7377 - # volumes: - # - /cdn:/cdn:rw - # - /etc/letsencrypt/live/onlinedi.vision:/certs:r + - "0.0.0.0:6666:6666" diff --git a/consts.ts b/consts.ts new file mode 100644 index 0000000..ea0a2c0 --- /dev/null +++ b/consts.ts @@ -0,0 +1,9 @@ +const spell_cast_api = 'https://onlinedi.vision/api/spell/cast'; +const get_user_servers_api = 'https://onlinedi.vision/api/get_user_servers' +const port = 6666; + +module.exports = { + spell_cast_api, + get_user_servers_api, + port +}; diff --git a/main.js b/main.ts similarity index 56% rename from main.js rename to main.ts index 1f65ba3..746c440 100644 --- a/main.js +++ b/main.ts @@ -1,62 +1,48 @@ -const spell_cast_api = 'https://onlinedi.vision/api/spell/cast'; +const consts = require('./consts.ts'); +const util = require('./util.ts'); let spell_key = ''; let all_ws = {'1313': []}; let connected_ws = []; let secrets = []; -async function addSecretToScylla(username) { - let payload = await fetch( - spell_cast_api, - { - method: 'POST', - body: { - 'username': username - } - } - ); - - if(!payload.ok) { - console.log("[FAILED FETCH] [addSecretToScylla]" + username) - return - } - - let secret = JSON.parse(await payload.json()); - return [ secret['key'], secret['spell'] ]; -} - -async function includeAllServers(username) {} - -async function registerSpellKey() {} +console.log("Starting Websockets Server on port: " + consts.port); Bun.serve({ + port: consts.port, fetch(req, server) { + + console.log('[LOG] [Bun.serve] Upgrading ' + req); + server.upgrade(req,{ data: { username: new URL(req.url).searchParams.get('username') } - })); + }); return new Response("Upgrade failed", { status: 500 }); }, websocket: { - data, async message(ws, message) { - console.log(all_ws); - + console.log('[LOG] [message]'); + if(!connected_ws.includes(ws) && secrets.includes(message)) { connected_ws.push(ws); - console.log(connected_ws); - - let payload = await includeAllServers(data['username']); if(payload.ok) { ws.send("CONNECTED"); - return } else { ws.send("ERROR"); } + return; } + + if(message.startsWith("TOKEN:")) { + let token = await util.includeAllServers(data.username, message.split(":")[1]); + + ws.send(token); + return; + } Object.keys(all_ws).forEach((key) => { if(all_ws[key].includes(ws)) { @@ -69,7 +55,7 @@ Bun.serve({ }, async open(ws) { - let res = await addSecretToScylla(data['username']); + let res = await util.addSecretToScylla(data['username']); let [ key, spell ] = res; secrets.push(spell); ws.send(key); diff --git a/package.json b/package.json new file mode 100644 index 0000000..2ff5a6f --- /dev/null +++ b/package.json @@ -0,0 +1,10 @@ +{ + "name": "od-spell-caster", + "private": true, + "devDependencies": { + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5" + } +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..2d19ff8 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + // Environment setup & latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "Preserve", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": false, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "noImplicitOverride": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/util.ts b/util.ts new file mode 100644 index 0000000..add0bdf --- /dev/null +++ b/util.ts @@ -0,0 +1,49 @@ +const consts = require('./consts.ts'); + +async function addSecretToScylla(username) { + let payload = await fetch( + consts.spell_cast_api, + { + method: 'POST', + body: { + 'username': username + } + } + ); + + if(!payload.ok) { + console.log("[FAILED FETCH] [addSecretToScylla]" + username) + return + } + + let secret = JSON.parse(await payload.json()); + return [ secret['key'], secret['spell'] ]; +} + +async function includeAllServers(username, token) { + let get_user_servers_payload = await fetch( + consts.get_user_servers_api, + { + method: 'POST', + body: { + 'username': username, + 'token': token + } + } + ).json(); + + for (let sid in get_user_servers_paylod['s_list']) { + if(!all_ws.has(sid)) { + all_ws.set(sid, []); + } + all_ws.get(sid).push(sid); + } + + return token; +} + +module.exports = { + addSecretToScylla, + includeAllServers +}; +