diff --git a/bun.lockb b/bun.lockb index 8591e2f..8cc0a35 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index c7b9ee8..d30b56f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "build": "bun build . --compile --outfile=build/garf-api" }, "devDependencies": { - "@types/bun": "latest" + "@types/bun": "latest", + "@types/node": "^20.11.29" }, "peerDependencies": { "typescript": "^5.0.0" diff --git a/src/env.d.ts b/src/env.d.ts index 936aef7..8992988 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -2,5 +2,7 @@ declare module "bun" { interface Env { DISCORD_CLIENT_ID: string; DISCORD_CLIENT_SECRET: string; + ENCRYPTION_KEY: string; + ENCRYPTION_SALT: string; } } diff --git a/src/index.ts b/src/index.ts index 7769f99..5c1b9dd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,6 @@ import token from "./routes/token"; import config from "./routes/config"; +import negotiate from "./routes/negotiate"; Bun.serve({ port: 3000, @@ -10,8 +11,15 @@ Bun.serve({ if (url.pathname === "/") return await config(req); if (url.pathname === "/token") return await token(req); + if (url.pathname === "/negotiate") return await negotiate(req); return new Response("garf dont know what want..."); }, + websocket: { + message(ws, message) {}, + open(ws) {}, + close(ws, code, message) {}, + drain(ws) {}, + }, }); console.log("Listening on 0.0.0.0:3000"); diff --git a/src/lib/encryption.ts b/src/lib/encryption.ts new file mode 100644 index 0000000..6fc2428 --- /dev/null +++ b/src/lib/encryption.ts @@ -0,0 +1,37 @@ +import { createCipheriv, createDecipheriv, scrypt, randomBytes } from "node:crypto"; + +const KEY = ((await scryptAsync(process.env.ENCRYPTION_KEY, 32)) as Buffer).toString("hex"); + +function scryptAsync(password: string, length: number) { + return new Promise((resolve, reject) => { + const pwBuf = Buffer.from(password); + scrypt(pwBuf, process.env.ENCRYPTION_SALT, length, (err, key) => { + if (err) return reject(err); + resolve(key); + }); + }); +} + +export async function encrypt(data: string) { + const iv = randomBytes(16); + const cipher = createCipheriv("aes-256-ccm", KEY, iv); + + let encrypted = cipher.update(data, "utf8", "base64url"); + encrypted += cipher.final("base64url"); + + return { encrypted, iv: iv.toString("hex") }; +} + +export async function decrypt(data: string, iv: string) { + const ivBuf = Buffer.from(iv, "hex"); + const decipher = createDecipheriv("aes-256-ccm", KEY, ivBuf); + + let decrypted = decipher.update(data, "base64url", "utf-8"); + try { + decrypted += decipher.final("utf8"); + } catch { + return false; + } + + return { decrypted }; +} diff --git a/src/routes/negotiate.ts b/src/routes/negotiate.ts new file mode 100644 index 0000000..c180ceb --- /dev/null +++ b/src/routes/negotiate.ts @@ -0,0 +1,3 @@ +export default async function (req: Request): Promise { + return new Response(); +} diff --git a/src/routes/token.ts b/src/routes/token.ts index 692bd6e..ddba3c5 100644 --- a/src/routes/token.ts +++ b/src/routes/token.ts @@ -30,6 +30,11 @@ export default async function (req: Request): Promise { }); const { access_token } = (await response.json()) as TokenResponse; + const userResponse = await fetch("https://discord/api/v10/user/@me", { + headers: { Authorization: "Bearer " + access_token }, + }); + + console.log(await userResponse.json()); return new Response(JSON.stringify({ access_token }), { headers: {