diff --git a/deno.json b/deno.json index 7274bba..4c93d8a 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,7 @@ { "tasks": { - "dev": "deno run -A --env-file --unstable-kv src/main.ts" + "dev": "deno run -A --unstable-kv src/main.ts", + "compile-win": "deno compile --unstable-kv --target x86_64-pc-windows-msvc --include ./res/ --include ./src/ -o ./build/GalvanicCorrosionRewritten.exe --allow-net --allow-sys --allow-env -R --allow-write=. --allow-ffi --deny-run src/main.ts" }, "imports": { "@felix/bcrypt": "jsr:@felix/bcrypt@^1.0.5", @@ -9,6 +10,7 @@ "@oneday/http-status": "jsr:@oneday/http-status@^0.2.0", "@proxnet/undead-logging": "jsr:@proxnet/undead-logging@^1.5.0", "@std/assert": "jsr:@std/assert@1", + "@std/dotenv": "jsr:@std/dotenv@^0.225.5", "chalk": "npm:chalk@^5.6.2", "sharp": "npm:sharp@^0.34.3", "zod": "npm:zod@^4.0.5" diff --git a/deno.lock b/deno.lock index 8f9183c..a14f1f0 100644 --- a/deno.lock +++ b/deno.lock @@ -9,6 +9,7 @@ "jsr:@oneday/http-status@0.2": "0.2.0", "jsr:@proxnet/undead-logging@^1.5.0": "1.5.1", "jsr:@std/assert@1": "1.0.14", + "jsr:@std/dotenv@~0.225.5": "0.225.5", "jsr:@std/encoding@1": "1.0.10", "jsr:@std/fmt@1": "1.0.8", "jsr:@std/fs@1": "1.0.19", @@ -63,6 +64,9 @@ "jsr:@std/internal@^1.0.10" ] }, + "@std/dotenv@0.225.5": { + "integrity": "9ce6f9d0ec3311f74a32535aa1b8c62ed88b1ab91b7f0815797d77a6f60c922f" + }, "@std/encoding@1.0.10": { "integrity": "8783c6384a2d13abd5e9e87a7ae0520a30e9f56aeeaa3bdf910a3eaaf5c811a1" }, @@ -334,6 +338,7 @@ "jsr:@oneday/http-status@0.2", "jsr:@proxnet/undead-logging@^1.5.0", "jsr:@std/assert@1", + "jsr:@std/dotenv@~0.225.5", "npm:chalk@^5.6.2", "npm:sharp@~0.34.3", "npm:zod@^4.0.5" diff --git a/src/env.ts b/src/env.ts new file mode 100644 index 0000000..1694b02 --- /dev/null +++ b/src/env.ts @@ -0,0 +1,9 @@ +import * as dotenv from "@std/dotenv"; + +interface EnvironmentVars { + SECRET?: string, + STEAMKEY?: string, + CONSOLESECRET?: string +} + +export const env = dotenv.loadSync() as EnvironmentVars; \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 35d0c4f..6bbcbf0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -15,6 +15,7 @@ import { PlatformType, TokenFormat, TokenType } from "./server/platforms/types.t import { HonoEnv } from "./util/types.ts"; import { Context } from "@hono/hono"; import { compress } from "@hono/hono/compress"; +import { env } from "./env.ts"; LoggingConfiguration.resetTimeFormat = TimeFormat.Unix; LoggingConfiguration.resetLogTiming = LogTiming.Microtask; @@ -101,7 +102,7 @@ const server = Deno.serve({ const splitHeader = authHeader.split(' ')[1]; if (!splitHeader) return unauthRes; - const secret = Deno.env.get('SECRET'); + const secret = env["SECRET"]; if (!secret) { log.w(`No secret set!`); return unauthRes; @@ -128,8 +129,8 @@ const server = Deno.serve({ } } else { const pass = url.searchParams.get('pass'); - if (!pass) return unauthRes; - else if (pass !== Deno.env.get('CONSOLESECRET')) return unauthRes; + if (pass == null) return unauthRes; + else if (pass !== env["CONSOLESECRET"]) return unauthRes; const { response, socket } = Deno.upgradeWebSocket(req); const handler = new SocketConsoleHandler(socket, req, info); diff --git a/src/routes/auth/routes/connect.ts b/src/routes/auth/routes/connect.ts index 440bed1..5a86c54 100644 --- a/src/routes/auth/routes/connect.ts +++ b/src/routes/auth/routes/connect.ts @@ -9,6 +9,7 @@ import { SteamAuthResult } from "../../../util/steam/SteamAuthTypes.ts"; import Server from "../../../server/server.ts"; import Logging from "@proxnet/undead-logging"; import { verify } from "@hono/hono/jwt"; +import { env } from "../../../env.ts"; const log = new Logging("ConnectRouteDebug"); @@ -87,7 +88,7 @@ route.app.post('/token', typedZValidator('form', tokenGrantSchema), async c => { const logins = await Server.Platforms.getCachedLogins(form.platform, form.platform_id, false); if (form.grant_type == 'refresh_token') { - const secret = Deno.env.get('SECRET'); + const secret = env["SECRET"]; if (!secret) { log.w(`Secret not set!`); return error(TokenRequestError.InvalidRequest); diff --git a/src/routes/img/base.ts b/src/routes/img/base.ts index 2428776..f9a44c1 100644 --- a/src/routes/img/base.ts +++ b/src/routes/img/base.ts @@ -2,13 +2,13 @@ import z from "zod"; import Server from "../../server/server.ts"; import { createHonoRoute } from "../../util/import.ts"; import { typedZValidator } from "../../util/validators.ts"; -import sharp from "sharp"; import path from "node:path"; import { RootPath } from "../../util/path.ts"; import Logging from "@proxnet/undead-logging"; import { statusResponse } from "../../util/api.ts"; import { HTTPStatus } from "@oneday/http-status"; import { Buffer } from "node:buffer"; +import sharp from "sharp"; export const route = createHonoRoute('/img'); diff --git a/src/server/platforms/base.ts b/src/server/platforms/base.ts index 2a86b49..9f084b0 100644 --- a/src/server/platforms/base.ts +++ b/src/server/platforms/base.ts @@ -6,6 +6,7 @@ import { sign } from "@hono/hono/jwt"; import { CachedLogin, DbCachedLogin, PlatformMask, PlatformType, TokenFormat, TokenType } from "./types.ts"; import type Profile from "../profiles/profile.ts"; import { getNetConfig } from "../../net.ts"; +import { env } from "../../env.ts"; export const steamAuthTicketSchema = z.object({ Ticket: z.string().min(256), @@ -23,7 +24,7 @@ export class PlatformsManager extends ServerContentBase { } async getToken(prof: Profile, type: TokenType) { - const secret = Deno.env.get('SECRET'); + const secret = env["SECRET"]; if (!secret) throw new Error("No SECRET in env. Did you forget to set it?"); const exp = type == TokenType.Access ? Math.round(Date.now() / 1000) + 21_600 : Math.round(Date.now() / 1000) + 31_556_952; diff --git a/src/util/api.ts b/src/util/api.ts index 3ce527d..0782f76 100644 --- a/src/util/api.ts +++ b/src/util/api.ts @@ -7,6 +7,7 @@ import Server from "../server/server.ts"; import { TokenFormat } from "../server/platforms/types.ts"; import { HTTPStatus, httpStatusText } from "@oneday/http-status"; import { ContentfulStatusCode } from "@hono/hono/utils/http-status"; +import { env } from "../env.ts"; const log = new Logging("APIUtils"); @@ -33,7 +34,7 @@ const authHeaderSchema = z.string().transform((arg, ctx) => { return split[1]; }); export async function authenticate(c: Context, nxt: Next) { - const secret = Deno.env.get('SECRET'); + const secret = env["SECRET"]; if (!secret) return c.json(genericResponse(false, "Internal Server Error"), 500); const authHeader = authHeaderSchema.safeParse(c.req.header('Authorization')); diff --git a/src/util/import.ts b/src/util/import.ts index af25111..c8e4503 100644 --- a/src/util/import.ts +++ b/src/util/import.ts @@ -1,13 +1,16 @@ import Logging from "@proxnet/undead-logging"; import { Hono } from "@hono/hono"; import path from "node:path"; -import process from "node:process"; import { HonoEnv, RouteImport } from "./types.ts"; +import { RootPath } from "./path.ts"; +const log = new Logging("RouteImport"); const debug = false; export async function routeImporter(hono: Hono, prefix: string, paths: string[]) { - const items = await importer('route', prefix, paths); + const p = `${RootPath.replaceAll('\\', '/')}${prefix}`; + if (debug) log.d(`Importing from "${p}"`); + const items = await importer('route', p, paths); for (const route of items) hono.route(route.path, route.app); } @@ -17,7 +20,7 @@ export async function importer(importKey: string, p: string, paths: string[]) for (const pathStr of paths) { - const importPath = path.join(process.cwd(), p, pathStr); + const importPath = `${p}${pathStr}/`; if (debug) log.d(`'${importKey}' found ${importPath}`); for await (const localPath of Deno.readDir(importPath)) { diff --git a/src/util/path.ts b/src/util/path.ts index b265cef..7911460 100644 --- a/src/util/path.ts +++ b/src/util/path.ts @@ -1,3 +1,9 @@ import { platform } from "node:process"; +import Logging, { TimeFormat } from "@proxnet/undead-logging"; -export const RootPath = Deno.mainModule.substring(platform == 'win32' ? 8 : 7, Deno.mainModule.length - 11); \ No newline at end of file +const log = new Logging("Path"); + +export const RootPath = Deno.mainModule.substring(platform == 'win32' ? 8 : 7, Deno.mainModule.length - 11); + +log.timeFormat = TimeFormat.Unix; +log.i(`RootPath: ${RootPath}`); \ No newline at end of file diff --git a/src/util/steam/steam.ts b/src/util/steam/steam.ts index 8b189bf..635e187 100644 --- a/src/util/steam/steam.ts +++ b/src/util/steam/steam.ts @@ -18,10 +18,11 @@ along with this program. If not, see . */ import Logging from "@proxnet/undead-logging"; import { SteamAuth, SteamAuthResult, SteamAuthRes } from "./SteamAuthTypes.ts"; import { SteamPlayer } from "./SteamCommonTypes.ts"; +import { env } from "../../env.ts"; const log = new Logging("Steam"); -const steamkey = Deno.env.get("STEAMKEY"); +const steamkey = env["STEAMKEY"]; function buildSteamUrl(steaminterface: string, endpoint: string) { return `https://api.steampowered.com/${steaminterface}/${endpoint}`;