mirror of
https://github.com/mollersuite/monofile.git
synced 2024-11-25 07:06:25 -08:00
Server now runs
This commit is contained in:
parent
549f7de7ac
commit
25afbf493c
|
@ -7,10 +7,12 @@ import Files from "./lib/files.js"
|
||||||
import { getAccount } from "./lib/middleware.js"
|
import { getAccount } from "./lib/middleware.js"
|
||||||
import APIRouter from "./routes/api.js"
|
import APIRouter from "./routes/api.js"
|
||||||
import preview from "./routes/preview.js"
|
import preview from "./routes/preview.js"
|
||||||
|
import {fileURLToPath} from "url"
|
||||||
|
import {dirname} from "path"
|
||||||
|
import pkg from "../../package.json" assert {type:"json"}
|
||||||
|
import config from "../../config.json" assert {type:"json"}
|
||||||
|
|
||||||
const pkg = require(`${process.cwd()}/package.json`)
|
|
||||||
const app = new Hono()
|
const app = new Hono()
|
||||||
let config = require(`${process.cwd()}/config.json`)
|
|
||||||
|
|
||||||
app.get(
|
app.get(
|
||||||
"/static/assets/*",
|
"/static/assets/*",
|
||||||
|
@ -72,6 +74,7 @@ app.get("/server", (ctx) =>
|
||||||
|
|
||||||
// init data
|
// init data
|
||||||
|
|
||||||
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
||||||
if (!fs.existsSync(__dirname + "/../.data/"))
|
if (!fs.existsSync(__dirname + "/../.data/"))
|
||||||
fs.mkdirSync(__dirname + "/../.data/")
|
fs.mkdirSync(__dirname + "/../.data/")
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ export class Client {
|
||||||
}
|
}
|
||||||
|
|
||||||
let capture = Math.min(
|
let capture = Math.min(
|
||||||
(this.config.maxDiscordFileSize - (bytes_sent % this.config.maxDiscordFileSize)) + 1,
|
(this.config.maxDiscordFileSize - (bytes_sent % this.config.maxDiscordFileSize)),
|
||||||
chunk.byteLength-position
|
chunk.byteLength-position
|
||||||
)
|
)
|
||||||
console.log(`Capturing ${capture} bytes, ${chunk.subarray(position, position+capture).byteLength}`)
|
console.log(`Capturing ${capture} bytes, ${chunk.subarray(position, position+capture).byteLength}`)
|
||||||
|
|
|
@ -137,7 +137,7 @@ export class UploadStream extends Writable {
|
||||||
|
|
||||||
while (position < data.byteLength) {
|
while (position < data.byteLength) {
|
||||||
let capture = Math.min(
|
let capture = Math.min(
|
||||||
((this.files.config.maxDiscordFileSize*10) - (this.filled % (this.files.config.maxDiscordFileSize*10))) + 1,
|
((this.files.config.maxDiscordFileSize*10) - (this.filled % (this.files.config.maxDiscordFileSize*10))),
|
||||||
data.byteLength-position
|
data.byteLength-position
|
||||||
)
|
)
|
||||||
console.log(`Capturing ${capture} bytes for megachunk, ${data.subarray(position, position + capture).byteLength}`)
|
console.log(`Capturing ${capture} bytes for megachunk, ${data.subarray(position, position + capture).byteLength}`)
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { createTransport } from "nodemailer"
|
import { createTransport } from "nodemailer"
|
||||||
|
import "dotenv/config"
|
||||||
|
import config from "../../../config.json" assert {type:"json"}
|
||||||
|
|
||||||
// required i guess
|
let mailConfig = config.mail,
|
||||||
require("dotenv").config()
|
|
||||||
|
|
||||||
let mailConfig = require(process.cwd() + "/config.json").mail,
|
|
||||||
transport = createTransport({
|
transport = createTransport({
|
||||||
...mailConfig.transport,
|
...mailConfig.transport,
|
||||||
auth: {
|
auth: {
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
import { Hono } from "hono"
|
import { Hono } from "hono"
|
||||||
import { readFile, readdir } from "fs/promises"
|
import { readFile, readdir } from "fs/promises"
|
||||||
import Files from "../lib/files.js"
|
import Files from "../lib/files.js"
|
||||||
|
import {fileURLToPath} from "url"
|
||||||
|
import {dirname} from "path"
|
||||||
|
|
||||||
const APIDirectory = __dirname + "/api"
|
const APIDirectory = dirname(fileURLToPath(import.meta.url)) + "/api"
|
||||||
|
|
||||||
interface APIMount {
|
interface APIMount {
|
||||||
file: string
|
file: string
|
||||||
|
@ -25,18 +27,21 @@ class APIVersion {
|
||||||
readonly definition: APIDefinition
|
readonly definition: APIDefinition
|
||||||
readonly apiPath: string
|
readonly apiPath: string
|
||||||
readonly root: Hono = new Hono()
|
readonly root: Hono = new Hono()
|
||||||
|
readonly files: Files
|
||||||
|
|
||||||
constructor(definition: APIDefinition, files: Files) {
|
constructor(definition: APIDefinition, files: Files) {
|
||||||
this.definition = definition
|
this.definition = definition
|
||||||
this.apiPath = APIDirectory + "/" + definition.name
|
this.apiPath = APIDirectory + "/" + definition.name
|
||||||
|
this.files = files
|
||||||
|
}
|
||||||
|
|
||||||
for (let _mount of definition.mount) {
|
async load() {
|
||||||
let mount = resolveMount(_mount)
|
for (let _mount of this.definition.mount) {
|
||||||
|
let mount = resolveMount(_mount);
|
||||||
// no idea if there's a better way to do this but this is all i can think of
|
// no idea if there's a better way to do this but this is all i can think of
|
||||||
let route = require(`${this.apiPath}/${mount.file}.js`) as (
|
let { default: route } = await import(`${this.apiPath}/${mount.file}.js`) as { default: (files: Files) => Hono }
|
||||||
files: Files
|
|
||||||
) => Hono
|
this.root.route(mount.to, route(this.files))
|
||||||
this.root.route(mount.to, route(files))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -54,12 +59,15 @@ export default class APIRouter {
|
||||||
* @param definition Definition to mount.
|
* @param definition Definition to mount.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private mount(definition: APIDefinition) {
|
private async mount(definition: APIDefinition) {
|
||||||
console.log(`mounting APIDefinition ${definition.name}`)
|
console.log(`mounting APIDefinition ${definition.name}`)
|
||||||
|
|
||||||
|
let def = new APIVersion(definition, this.files)
|
||||||
|
await def.load()
|
||||||
|
|
||||||
this.root.route(
|
this.root.route(
|
||||||
definition.baseURL,
|
definition.baseURL,
|
||||||
new APIVersion(definition, this.files).root
|
def.root
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +82,7 @@ export default class APIRouter {
|
||||||
)
|
)
|
||||||
).toString()
|
).toString()
|
||||||
) as APIDefinition
|
) as APIDefinition
|
||||||
this.mount(def)
|
await this.mount(def)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,9 +22,7 @@ adminRoutes
|
||||||
.use(requiresAdmin)
|
.use(requiresAdmin)
|
||||||
.use(requiresPermissions("admin"))
|
.use(requiresPermissions("admin"))
|
||||||
|
|
||||||
let config = require(`${process.cwd()}/config.json`)
|
export default function (files: Files) {
|
||||||
|
|
||||||
module.exports = function (files: Files) {
|
|
||||||
adminRoutes.post("/reset", async (ctx) => {
|
adminRoutes.post("/reset", async (ctx) => {
|
||||||
let acc = ctx.get("account") as Accounts.Account
|
let acc = ctx.get("account") as Accounts.Account
|
||||||
const body = await ctx.req.json()
|
const body = await ctx.req.json()
|
||||||
|
|
|
@ -26,12 +26,11 @@ export let authRoutes = new Hono<{
|
||||||
}
|
}
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
let config = require(`${process.cwd()}/config.json`)
|
import config from "../../../../../config.json" assert {type:"json"}
|
||||||
authRoutes.all("*", getAccount)
|
authRoutes.all("*", getAccount)
|
||||||
|
|
||||||
module.exports = function (files: Files) {
|
export default function (files: Files) {
|
||||||
authRoutes.post("/login", async (ctx) => {
|
authRoutes.post("/login", async (ctx) => {
|
||||||
console.log(ctx)
|
|
||||||
const body = await ctx.req.json()
|
const body = await ctx.req.json()
|
||||||
if (
|
if (
|
||||||
typeof body.username != "string" ||
|
typeof body.username != "string" ||
|
||||||
|
|
|
@ -14,7 +14,6 @@ export let fileApiRoutes = new Hono<{
|
||||||
}
|
}
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
let config = require(`${process.cwd()}/config.json`)
|
|
||||||
fileApiRoutes.use("*", getAccount) // :warning: /list somehow crashes Hono with an internal error!
|
fileApiRoutes.use("*", getAccount) // :warning: /list somehow crashes Hono with an internal error!
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
@ -27,7 +26,7 @@ TypeError: Cannot read properties of undefined (reading 'get')
|
||||||
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module.exports = function (files: Files) {
|
export default function (files: Files) {
|
||||||
fileApiRoutes.get(
|
fileApiRoutes.get(
|
||||||
"/list",
|
"/list",
|
||||||
requiresAccount,
|
requiresAccount,
|
||||||
|
|
|
@ -3,36 +3,24 @@ import { Hono } from "hono"
|
||||||
|
|
||||||
import * as Accounts from "../../../lib/accounts.js"
|
import * as Accounts from "../../../lib/accounts.js"
|
||||||
import * as auth from "../../../lib/auth.js"
|
import * as auth from "../../../lib/auth.js"
|
||||||
import axios, { AxiosResponse } from "axios"
|
import RangeParser, { type Range } from "range-parser"
|
||||||
import { type Range } from "range-parser"
|
|
||||||
import multer, { memoryStorage } from "multer"
|
|
||||||
import { Readable } from "stream"
|
|
||||||
import ServeError from "../../../lib/errors.js"
|
import ServeError from "../../../lib/errors.js"
|
||||||
import Files from "../../../lib/files.js"
|
import Files from "../../../lib/files.js"
|
||||||
import { getAccount, requiresPermissions } from "../../../lib/middleware.js"
|
import { getAccount } from "../../../lib/middleware.js"
|
||||||
|
import {Readable} from "node:stream"
|
||||||
let parser = bodyParser.json({
|
|
||||||
type: ["text/plain", "application/json"],
|
|
||||||
})
|
|
||||||
|
|
||||||
export let primaryApi = new Hono<{
|
export let primaryApi = new Hono<{
|
||||||
Variables: {
|
Variables: {
|
||||||
account: Accounts.Account
|
account: Accounts.Account
|
||||||
}
|
}
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const multerSetup = multer({ storage: memoryStorage() })
|
|
||||||
|
|
||||||
let config = require(`${process.cwd()}/config.json`)
|
|
||||||
|
|
||||||
primaryApi.use(getAccount)
|
primaryApi.use(getAccount)
|
||||||
|
|
||||||
module.exports = function (files: Files) {/*
|
export default function (files: Files) {
|
||||||
primaryApi.get(
|
primaryApi.get(
|
||||||
["/file/:fileId", "/cpt/:fileId/*", "/:fileId"],
|
"/file/:fileId",
|
||||||
async (ctx) => {
|
async (ctx): Promise<Response> => {
|
||||||
const fileId = (ctx.req.param() as {fileId: string}).fileId
|
const fileId = (ctx.req.param() as {fileId: string}).fileId
|
||||||
const reqRange
|
|
||||||
|
|
||||||
let acc = ctx.get("account") as Accounts.Account
|
let acc = ctx.get("account") as Accounts.Account
|
||||||
|
|
||||||
|
@ -54,8 +42,7 @@ module.exports = function (files: Files) {/*
|
||||||
.getPermissions(auth.tokenFor(ctx)!)
|
.getPermissions(auth.tokenFor(ctx)!)
|
||||||
?.includes("private")
|
?.includes("private")
|
||||||
) {
|
) {
|
||||||
ServeError(ctx, 403, "insufficient permissions")
|
return ServeError(ctx, 403, "insufficient permissions")
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,29 +52,18 @@ module.exports = function (files: Files) {/*
|
||||||
if (file.sizeInBytes) {
|
if (file.sizeInBytes) {
|
||||||
ctx.header("Content-Length", file.sizeInBytes.toString())
|
ctx.header("Content-Length", file.sizeInBytes.toString())
|
||||||
|
|
||||||
if (file.chunkSize) {
|
if (file.chunkSize && ctx.req.header("Range")) {
|
||||||
let range = ctx.range(file.sizeInBytes)
|
let ranges = RangeParser(file.sizeInBytes, ctx.req.header("Range") || "")
|
||||||
if (range) {
|
|
||||||
// error handling
|
|
||||||
if (typeof range == "number") {
|
|
||||||
return ctx.status(range == -1 ? 416 : 400)
|
|
||||||
}
|
|
||||||
if (range.type != "bytes") {
|
|
||||||
return ctx.status(400)
|
|
||||||
}
|
|
||||||
|
|
||||||
// set ranges var
|
if (ranges) {
|
||||||
let rngs = Array.from(range)
|
if (typeof ranges == "number")
|
||||||
if (rngs.length != 1) {
|
return ServeError(ctx, ranges == -1 ? 416 : 400, ranges == -1 ? "unsatisfiable ranges" : "invalid ranges")
|
||||||
return ctx.status(400)
|
if (ranges.length > 1) return ServeError(ctx, 400, "multiple ranges not supported")
|
||||||
}
|
range = ranges[0]
|
||||||
range = rngs[0]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// supports ranges
|
|
||||||
|
|
||||||
return files
|
return files
|
||||||
.readFileStream(fileId, range)
|
.readFileStream(fileId, range)
|
||||||
.then(async (stream) => {
|
.then(async (stream) => {
|
||||||
|
@ -103,8 +79,8 @@ module.exports = function (files: Files) {/*
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx.stream((stre) => {
|
return ctx.req.method == "HEAD" ? ctx.body(null) : ctx.stream(async (webStream) => {
|
||||||
// Somehow return a stream?
|
webStream.pipe(Readable.toWeb(stream) as ReadableStream)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
|
@ -114,7 +90,7 @@ module.exports = function (files: Files) {/*
|
||||||
return ServeError(ctx, 404, "file not found")
|
return ServeError(ctx, 404, "file not found")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)*/
|
)
|
||||||
|
|
||||||
// primaryApi.head(
|
// primaryApi.head(
|
||||||
// ["/file/:fileId", "/cpt/:fileId/*", "/:fileId"],
|
// ["/file/:fileId", "/cpt/:fileId/*", "/:fileId"],
|
||||||
|
|
|
@ -19,7 +19,7 @@ import {
|
||||||
import ServeError from "../../../lib/errors.js"
|
import ServeError from "../../../lib/errors.js"
|
||||||
import { sendMail } from "../../../lib/mail.js"
|
import { sendMail } from "../../../lib/mail.js"
|
||||||
|
|
||||||
const Configuration = require(`${process.cwd()}/config.json`)
|
import Configuration from "../../../../../config.json" assert {type:"json"}
|
||||||
|
|
||||||
const router = new Hono<{
|
const router = new Hono<{
|
||||||
Variables: {
|
Variables: {
|
||||||
|
@ -29,7 +29,7 @@ const router = new Hono<{
|
||||||
|
|
||||||
router.use(getAccount)
|
router.use(getAccount)
|
||||||
|
|
||||||
module.exports = function (files: Files) {
|
export default function (files: Files) {
|
||||||
router.post("/login", async (ctx, res) => {
|
router.post("/login", async (ctx, res) => {
|
||||||
const body = await ctx.req.json()
|
const body = await ctx.req.json()
|
||||||
if (
|
if (
|
||||||
|
|
|
@ -17,8 +17,6 @@ import {
|
||||||
import ServeError from "../../../lib/errors.js"
|
import ServeError from "../../../lib/errors.js"
|
||||||
import { sendMail } from "../../../lib/mail.js"
|
import { sendMail } from "../../../lib/mail.js"
|
||||||
|
|
||||||
const Configuration = require(`${process.cwd()}/config.json`)
|
|
||||||
|
|
||||||
const router = new Hono<{
|
const router = new Hono<{
|
||||||
Variables: {
|
Variables: {
|
||||||
account?: Accounts.Account
|
account?: Accounts.Account
|
||||||
|
@ -27,7 +25,7 @@ const router = new Hono<{
|
||||||
|
|
||||||
router.use(getAccount, requiresAccount, requiresAdmin)
|
router.use(getAccount, requiresAccount, requiresAdmin)
|
||||||
|
|
||||||
module.exports = function (files: Files) {
|
export default function (files: Files) {
|
||||||
router.patch("/account/:username/password", async (ctx) => {
|
router.patch("/account/:username/password", async (ctx) => {
|
||||||
const Account = ctx.get("account") as Accounts.Account
|
const Account = ctx.get("account") as Accounts.Account
|
||||||
const body = await ctx.req.json()
|
const body = await ctx.req.json()
|
||||||
|
|
|
@ -7,8 +7,7 @@ import {
|
||||||
requiresPermissions,
|
requiresPermissions,
|
||||||
} from "../../../lib/middleware.js"
|
} from "../../../lib/middleware.js"
|
||||||
import ServeError from "../../../lib/errors.js"
|
import ServeError from "../../../lib/errors.js"
|
||||||
|
import Configuration from "../../../../../config.json" assert {type:"json"}
|
||||||
const Configuration = require(`${process.cwd()}/config.json`)
|
|
||||||
|
|
||||||
const router = new Hono<{
|
const router = new Hono<{
|
||||||
Variables: {
|
Variables: {
|
||||||
|
@ -18,7 +17,7 @@ const router = new Hono<{
|
||||||
|
|
||||||
router.use(getAccount)
|
router.use(getAccount)
|
||||||
|
|
||||||
module.exports = function (files: Files) {
|
export default function (files: Files) {
|
||||||
router.put(
|
router.put(
|
||||||
"/css",
|
"/css",
|
||||||
requiresAccount,
|
requiresAccount,
|
||||||
|
|
|
@ -3,6 +3,6 @@ import Files from "../../../lib/files.js";
|
||||||
|
|
||||||
const router = new Hono()
|
const router = new Hono()
|
||||||
|
|
||||||
module.exports = function(files: Files) {
|
export default function(files: Files) {
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,6 @@ import Files from "../../../lib/files.js"
|
||||||
|
|
||||||
const router = new Hono()
|
const router = new Hono()
|
||||||
|
|
||||||
module.exports = function (files: Files) {
|
export default function (files: Files) {
|
||||||
return router
|
return router
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,8 @@ import ServeError from "../lib/errors.js"
|
||||||
import * as Accounts from "../lib/accounts.js"
|
import * as Accounts from "../lib/accounts.js"
|
||||||
import type { Handler } from "hono"
|
import type { Handler } from "hono"
|
||||||
import type Files from "../lib/files.js"
|
import type Files from "../lib/files.js"
|
||||||
const pkg = require(`${process.cwd()}/package.json`)
|
import pkg from "../../../package.json" assert {type:"json"}
|
||||||
|
|
||||||
export default (files: Files): Handler =>
|
export default (files: Files): Handler =>
|
||||||
async (ctx) => {
|
async (ctx) => {
|
||||||
let acc = ctx.get("account") as Accounts.Account
|
let acc = ctx.get("account") as Accounts.Account
|
||||||
|
|
Loading…
Reference in a new issue