diff --git a/src/auth.ts b/src/auth.ts index 01ca71e..11f9eda 100644 --- a/src/auth.ts +++ b/src/auth.ts @@ -2,21 +2,13 @@ import e, { NextFunction, Request, Response } from "express"; import { sign, verify } from "jsonwebtoken"; import { query } from "./database"; import { errors } from "./errors"; -import serverConfig from "./serverconfig"; +import serverConfig, { jwtSecret } from "./serverconfig"; import { compare } from "bcrypt"; -const jwtSecret = process.env.JWT_SECRET || "[generic token]"; - const tokenTypes = { BEARER: 1 } -if (jwtSecret === "[generic token]") { - console.error("ERROR: No JWT_SECRET environment variable was specified."); - console.error("ERROR: exiting..."); - process.exit(1); -} - export function getUserPermissions(user: User) { return { create_channel: serverConfig.superuserRequirement.createChannel ? user.is_superuser : true diff --git a/src/index.ts b/src/index.ts index 03561a1..7924f15 100644 --- a/src/index.ts +++ b/src/index.ts @@ -4,8 +4,8 @@ import { createServer } from "node:http"; import databaseInit from "./database/init"; import gateway from "./gateway"; import server from "./server"; +import { port } from "./serverconfig"; -const port = process.env.PORT || 3000; const app = express(); server(app); diff --git a/src/serverconfig.ts b/src/serverconfig.ts index d42e6ab..796eb75 100644 --- a/src/serverconfig.ts +++ b/src/serverconfig.ts @@ -1,10 +1,54 @@ +import { hashSync } from "bcrypt"; +import { existsSync, mkdirSync, statSync } from "node:fs"; +import path from "node:path"; + + export default { superuserRequirement: { createChannel: false } }; +export let port = process.env.PORT ?? 3000; +if (typeof port === "string") { + port = parseInt(port); +} +if (isNaN(port) || !isFinite(port) || port <= 0) { + console.error(`provided PORT in process environment is not valid, exiting... (got '${port}')`); + process.exit(1); +} + +export const jwtSecret = process.env.JWT_SECRET ?? ""; +if (!jwtSecret || jwtSecret === "") { + console.error("JWT_SECRET not found in process environment, exiting..."); + process.exit(1); +} + export const maxBufferByteLength = 8388608; // 8MiB export const maxGatewayJsonStringLength = 4500; export const maxGatewayJsonStringByteLength = maxGatewayJsonStringLength * 2; // https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder/encodeInto#buffer_sizing export const maxGatewayPayloadByteLength = maxBufferByteLength + maxGatewayJsonStringByteLength + 4; + +export const superuserKey = process.env.SUPERUSER_KEY ? hashSync(process.env.SUPERUSER_KEY, 10) : null; + +export const disableAccountCreation = (process.env.DISABLE_ACCOUNT_CREATION === "true"); + +export const uploadsMode = 0o600; +export const uploadsDirectoryMode = 0o700; +export const avatarUploadDirectory = path.resolve(process.env.AVATAR_UPLOADS_DIR ?? "./uploads/avatar"); +export const attachmentUploadDirectory = path.resolve(process.env.ATTACHMENT_UPLOADS_DIR ?? "./uploads/attachment"); +const ensureDirectory = (dir: string) => { + const stats = statSync(dir, { throwIfNoEntry: false }); + if (!stats) { + mkdirSync(dir, { mode: uploadsDirectoryMode }); + return; + } + if (!stats.isDirectory()) { + throw new Error(`Expected path ${dir} to point to a directory`); + } +}; +const ensureDirectories = () => { + ensureDirectory(avatarUploadDirectory); + ensureDirectory(attachmentUploadDirectory); +}; +ensureDirectories();