From 67d013e40a404ba350e7cf8626f1dd709ab2e57d Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Mon, 10 Mar 2025 00:48:58 +0200 Subject: [PATCH] Use default middleware for parsing request body --- server.js | 6 +- src/endpoints/anthropic.js | 3 +- src/endpoints/assets.js | 9 ++- src/endpoints/avatars.js | 7 +- src/endpoints/azure.js | 5 +- src/endpoints/backends/chat-completions.js | 7 +- src/endpoints/backends/kobold.js | 7 +- src/endpoints/backends/scale-alt.js | 3 +- src/endpoints/backends/text-completions.js | 19 +++--- src/endpoints/backgrounds.js | 9 ++- src/endpoints/caption.js | 3 +- src/endpoints/characters.js | 25 ++++--- src/endpoints/chats.js | 24 ++++--- src/endpoints/classify.js | 5 +- src/endpoints/content-manager.js | 5 +- src/endpoints/extensions.js | 13 ++-- src/endpoints/files.js | 9 ++- src/endpoints/google.js | 5 +- src/endpoints/groups.js | 9 ++- src/endpoints/horde.js | 23 ++++--- src/endpoints/images.js | 5 +- src/endpoints/moving-ui.js | 4 +- src/endpoints/novelai.js | 9 ++- src/endpoints/openai.js | 11 ++-- src/endpoints/openrouter.js | 5 +- src/endpoints/presets.js | 11 ++-- src/endpoints/quick-replies.js | 6 +- src/endpoints/search.js | 15 ++--- src/endpoints/secrets.js | 9 ++- src/endpoints/settings.js | 13 ++-- src/endpoints/speech.js | 5 +- src/endpoints/sprites.js | 9 ++- src/endpoints/stable-diffusion.js | 77 +++++++++++----------- src/endpoints/stats.js | 7 +- src/endpoints/themes.js | 6 +- src/endpoints/thumbnails.js | 3 +- src/endpoints/tokenizers.js | 67 ++++++++++--------- src/endpoints/translate.js | 17 +++-- src/endpoints/users-admin.js | 17 +++-- src/endpoints/users-private.js | 15 ++--- src/endpoints/users-public.js | 8 +-- src/endpoints/vectors.js | 15 ++--- src/endpoints/worldinfo.js | 10 ++- src/express-common.js | 9 +-- 44 files changed, 252 insertions(+), 297 deletions(-) diff --git a/server.js b/server.js index ab06c2cce..d21bb3a2d 100644 --- a/server.js +++ b/server.js @@ -113,6 +113,9 @@ app.use(helmet({ app.use(compression()); app.use(responseTime()); +app.use(bodyParser.json({ limit: '200mb' })); +app.use(bodyParser.urlencoded({ extended: true, limit: '200mb' })); + // CORS Settings // const CORS = cors({ origin: 'null', @@ -135,9 +138,6 @@ if (cliArgs.listen) { } if (cliArgs.enableCorsProxy) { - app.use(bodyParser.json({ - limit: '200mb', - })); app.use('/proxy/:url(*)', corsProxyMiddleware); } else { app.use('/proxy/:url(*)', async (_, res) => { diff --git a/src/endpoints/anthropic.js b/src/endpoints/anthropic.js index f54ca7170..c7d5c75e7 100644 --- a/src/endpoints/anthropic.js +++ b/src/endpoints/anthropic.js @@ -2,11 +2,10 @@ import fetch from 'node-fetch'; import express from 'express'; import { readSecret, SECRET_KEYS } from './secrets.js'; -import { jsonParser } from '../express-common.js'; export const router = express.Router(); -router.post('/caption-image', jsonParser, async (request, response) => { +router.post('/caption-image', async (request, response) => { try { const mimeType = request.body.image.split(';')[0].split(':')[1]; const base64Data = request.body.image.split(',')[1]; diff --git a/src/endpoints/assets.js b/src/endpoints/assets.js index 2b53d8e04..439a62ec5 100644 --- a/src/endpoints/assets.js +++ b/src/endpoints/assets.js @@ -8,7 +8,6 @@ import sanitize from 'sanitize-filename'; import fetch from 'node-fetch'; import { UNSAFE_EXTENSIONS } from '../constants.js'; -import { jsonParser } from '../express-common.js'; import { clientRelativePath } from '../util.js'; const VALID_CATEGORIES = ['bgm', 'ambient', 'blip', 'live2d', 'vrm', 'character', 'temp']; @@ -105,7 +104,7 @@ export const router = express.Router(); * * @returns {void} */ -router.post('/get', jsonParser, async (request, response) => { +router.post('/get', async (request, response) => { const folderPath = path.join(request.user.directories.assets); let output = {}; @@ -189,7 +188,7 @@ router.post('/get', jsonParser, async (request, response) => { * * @returns {void} */ -router.post('/download', jsonParser, async (request, response) => { +router.post('/download', async (request, response) => { const url = request.body.url; const inputCategory = request.body.category; @@ -260,7 +259,7 @@ router.post('/download', jsonParser, async (request, response) => { * * @returns {void} */ -router.post('/delete', jsonParser, async (request, response) => { +router.post('/delete', async (request, response) => { const inputCategory = request.body.category; // Check category @@ -312,7 +311,7 @@ router.post('/delete', jsonParser, async (request, response) => { * * @returns {void} */ -router.post('/character', jsonParser, async (request, response) => { +router.post('/character', async (request, response) => { if (request.query.name === undefined) return response.sendStatus(400); // For backwards compatibility, don't reject invalid character names, just sanitize them diff --git a/src/endpoints/avatars.js b/src/endpoints/avatars.js index f84527670..88373c254 100644 --- a/src/endpoints/avatars.js +++ b/src/endpoints/avatars.js @@ -6,19 +6,18 @@ import sanitize from 'sanitize-filename'; import jimp from 'jimp'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; -import { jsonParser, urlencodedParser } from '../express-common.js'; import { AVATAR_WIDTH, AVATAR_HEIGHT } from '../constants.js'; import { getImages, tryParse } from '../util.js'; import { getFileNameValidationFunction } from '../middleware/validateFileName.js'; export const router = express.Router(); -router.post('/get', jsonParser, function (request, response) { +router.post('/get', function (request, response) { var images = getImages(request.user.directories.avatars); response.send(JSON.stringify(images)); }); -router.post('/delete', jsonParser, getFileNameValidationFunction('avatar'), function (request, response) { +router.post('/delete', getFileNameValidationFunction('avatar'), function (request, response) { if (!request.body) return response.sendStatus(400); if (request.body.avatar !== sanitize(request.body.avatar)) { @@ -36,7 +35,7 @@ router.post('/delete', jsonParser, getFileNameValidationFunction('avatar'), func return response.sendStatus(404); }); -router.post('/upload', urlencodedParser, async (request, response) => { +router.post('/upload', async (request, response) => { if (!request.file) return response.sendStatus(400); try { diff --git a/src/endpoints/azure.js b/src/endpoints/azure.js index ef0c826fb..5eaa7653e 100644 --- a/src/endpoints/azure.js +++ b/src/endpoints/azure.js @@ -2,11 +2,10 @@ import fetch from 'node-fetch'; import { Router } from 'express'; import { readSecret, SECRET_KEYS } from './secrets.js'; -import { jsonParser } from '../express-common.js'; export const router = Router(); -router.post('/list', jsonParser, async (req, res) => { +router.post('/list', async (req, res) => { try { const key = readSecret(req.user.directories, SECRET_KEYS.AZURE_TTS); @@ -44,7 +43,7 @@ router.post('/list', jsonParser, async (req, res) => { } }); -router.post('/generate', jsonParser, async (req, res) => { +router.post('/generate', async (req, res) => { try { const key = readSecret(req.user.directories, SECRET_KEYS.AZURE_TTS); diff --git a/src/endpoints/backends/chat-completions.js b/src/endpoints/backends/chat-completions.js index 710cc9f01..c92b91b9a 100644 --- a/src/endpoints/backends/chat-completions.js +++ b/src/endpoints/backends/chat-completions.js @@ -2,7 +2,6 @@ import process from 'node:process'; import express from 'express'; import fetch from 'node-fetch'; -import { jsonParser } from '../../express-common.js'; import { CHAT_COMPLETION_SOURCES, GEMINI_SAFETY, @@ -821,7 +820,7 @@ async function sendDeepSeekRequest(request, response) { export const router = express.Router(); -router.post('/status', jsonParser, async function (request, response_getstatus_openai) { +router.post('/status', async function (request, response_getstatus_openai) { if (!request.body) return response_getstatus_openai.sendStatus(400); let api_url; @@ -937,7 +936,7 @@ router.post('/status', jsonParser, async function (request, response_getstatus_o } }); -router.post('/bias', jsonParser, async function (request, response) { +router.post('/bias', async function (request, response) { if (!request.body || !Array.isArray(request.body)) return response.sendStatus(400); @@ -1022,7 +1021,7 @@ router.post('/bias', jsonParser, async function (request, response) { }); -router.post('/generate', jsonParser, function (request, response) { +router.post('/generate', function (request, response) { if (!request.body) return response.status(400).send({ error: true }); switch (request.body.chat_completion_source) { diff --git a/src/endpoints/backends/kobold.js b/src/endpoints/backends/kobold.js index 519698ea1..70bd5fac3 100644 --- a/src/endpoints/backends/kobold.js +++ b/src/endpoints/backends/kobold.js @@ -2,14 +2,13 @@ import fs from 'node:fs'; import express from 'express'; import fetch from 'node-fetch'; -import { jsonParser, urlencodedParser } from '../../express-common.js'; import { forwardFetchResponse, delay } from '../../util.js'; import { getOverrideHeaders, setAdditionalHeaders, setAdditionalHeadersByType } from '../../additional-headers.js'; import { TEXTGEN_TYPES } from '../../constants.js'; export const router = express.Router(); -router.post('/generate', jsonParser, async function (request, response_generate) { +router.post('/generate', async function (request, response_generate) { if (!request.body) return response_generate.sendStatus(400); if (request.body.api_server.indexOf('localhost') != -1) { @@ -141,7 +140,7 @@ router.post('/generate', jsonParser, async function (request, response_generate) return response_generate.send({ error: true }); }); -router.post('/status', jsonParser, async function (request, response) { +router.post('/status', async function (request, response) { if (!request.body) return response.sendStatus(400); let api_server = request.body.api_server; if (api_server.indexOf('localhost') != -1) { @@ -188,7 +187,7 @@ router.post('/status', jsonParser, async function (request, response) { response.send(result); }); -router.post('/transcribe-audio', urlencodedParser, async function (request, response) { +router.post('/transcribe-audio', async function (request, response) { try { const server = request.body.server; diff --git a/src/endpoints/backends/scale-alt.js b/src/endpoints/backends/scale-alt.js index b2daddded..bf96e4139 100644 --- a/src/endpoints/backends/scale-alt.js +++ b/src/endpoints/backends/scale-alt.js @@ -1,12 +1,11 @@ import express from 'express'; import fetch from 'node-fetch'; -import { jsonParser } from '../../express-common.js'; import { readSecret, SECRET_KEYS } from '../secrets.js'; export const router = express.Router(); -router.post('/generate', jsonParser, async function (request, response) { +router.post('/generate', async function (request, response) { if (!request.body) return response.sendStatus(400); try { diff --git a/src/endpoints/backends/text-completions.js b/src/endpoints/backends/text-completions.js index f170546da..290142e5e 100644 --- a/src/endpoints/backends/text-completions.js +++ b/src/endpoints/backends/text-completions.js @@ -3,7 +3,6 @@ import fetch from 'node-fetch'; import express from 'express'; import _ from 'lodash'; -import { jsonParser } from '../../express-common.js'; import { TEXTGEN_TYPES, TOGETHERAI_KEYS, @@ -93,7 +92,7 @@ async function abortKoboldCppRequest(url) { } //************** Ooba/OpenAI text completions API -router.post('/status', jsonParser, async function (request, response) { +router.post('/status', async function (request, response) { if (!request.body) return response.sendStatus(400); try { @@ -227,7 +226,7 @@ router.post('/status', jsonParser, async function (request, response) { } }); -router.post('/props', jsonParser, async function (request, response) { +router.post('/props', async function (request, response) { if (!request.body.api_server) return response.sendStatus(400); try { @@ -261,7 +260,7 @@ router.post('/props', jsonParser, async function (request, response) { } }); -router.post('/generate', jsonParser, async function (request, response) { +router.post('/generate', async function (request, response) { if (!request.body) return response.sendStatus(400); try { @@ -432,7 +431,7 @@ router.post('/generate', jsonParser, async function (request, response) { const ollama = express.Router(); -ollama.post('/download', jsonParser, async function (request, response) { +ollama.post('/download', async function (request, response) { try { if (!request.body.name || !request.body.api_server) return response.sendStatus(400); @@ -462,7 +461,7 @@ ollama.post('/download', jsonParser, async function (request, response) { } }); -ollama.post('/caption-image', jsonParser, async function (request, response) { +ollama.post('/caption-image', async function (request, response) { try { if (!request.body.server_url || !request.body.model) { return response.sendStatus(400); @@ -507,7 +506,7 @@ ollama.post('/caption-image', jsonParser, async function (request, response) { const llamacpp = express.Router(); -llamacpp.post('/caption-image', jsonParser, async function (request, response) { +llamacpp.post('/caption-image', async function (request, response) { try { if (!request.body.server_url) { return response.sendStatus(400); @@ -552,7 +551,7 @@ llamacpp.post('/caption-image', jsonParser, async function (request, response) { } }); -llamacpp.post('/props', jsonParser, async function (request, response) { +llamacpp.post('/props', async function (request, response) { try { if (!request.body.server_url) { return response.sendStatus(400); @@ -581,7 +580,7 @@ llamacpp.post('/props', jsonParser, async function (request, response) { } }); -llamacpp.post('/slots', jsonParser, async function (request, response) { +llamacpp.post('/slots', async function (request, response) { try { if (!request.body.server_url) { return response.sendStatus(400); @@ -633,7 +632,7 @@ llamacpp.post('/slots', jsonParser, async function (request, response) { const tabby = express.Router(); -tabby.post('/download', jsonParser, async function (request, response) { +tabby.post('/download', async function (request, response) { try { const baseUrl = String(request.body.api_server).replace(/\/$/, ''); diff --git a/src/endpoints/backgrounds.js b/src/endpoints/backgrounds.js index 4ef726504..0559900eb 100644 --- a/src/endpoints/backgrounds.js +++ b/src/endpoints/backgrounds.js @@ -4,19 +4,18 @@ import path from 'node:path'; import express from 'express'; import sanitize from 'sanitize-filename'; -import { jsonParser, urlencodedParser } from '../express-common.js'; import { invalidateThumbnail } from './thumbnails.js'; import { getImages } from '../util.js'; import { getFileNameValidationFunction } from '../middleware/validateFileName.js'; export const router = express.Router(); -router.post('/all', jsonParser, function (request, response) { +router.post('/all', function (request, response) { var images = getImages(request.user.directories.backgrounds); response.send(JSON.stringify(images)); }); -router.post('/delete', jsonParser, getFileNameValidationFunction('bg'), function (request, response) { +router.post('/delete', getFileNameValidationFunction('bg'), function (request, response) { if (!request.body) return response.sendStatus(400); if (request.body.bg !== sanitize(request.body.bg)) { @@ -36,7 +35,7 @@ router.post('/delete', jsonParser, getFileNameValidationFunction('bg'), function return response.send('ok'); }); -router.post('/rename', jsonParser, function (request, response) { +router.post('/rename', function (request, response) { if (!request.body) return response.sendStatus(400); const oldFileName = path.join(request.user.directories.backgrounds, sanitize(request.body.old_bg)); @@ -58,7 +57,7 @@ router.post('/rename', jsonParser, function (request, response) { return response.send('ok'); }); -router.post('/upload', urlencodedParser, function (request, response) { +router.post('/upload', function (request, response) { if (!request.body || !request.file) return response.sendStatus(400); const img_path = path.join(request.file.destination, request.file.filename); diff --git a/src/endpoints/caption.js b/src/endpoints/caption.js index 8a2aa42d0..0132d001a 100644 --- a/src/endpoints/caption.js +++ b/src/endpoints/caption.js @@ -1,12 +1,11 @@ import express from 'express'; -import { jsonParser } from '../express-common.js'; import { getPipeline, getRawImage } from '../transformers.js'; export const router = express.Router(); const TASK = 'image-to-text'; -router.post('/', jsonParser, async (req, res) => { +router.post('/', async (req, res) => { try { const { image } = req.body; diff --git a/src/endpoints/characters.js b/src/endpoints/characters.js index 7facf052b..9a5775941 100644 --- a/src/endpoints/characters.js +++ b/src/endpoints/characters.js @@ -13,7 +13,6 @@ import mime from 'mime-types'; import jimp from 'jimp'; import { AVATAR_WIDTH, AVATAR_HEIGHT } from '../constants.js'; -import { jsonParser, urlencodedParser } from '../express-common.js'; import { default as validateAvatarUrlMiddleware, getFileNameValidationFunction } from '../middleware/validateFileName.js'; import { deepMerge, humanizedISO8601DateTime, tryParse, extractFileFromZipBuffer, MemoryLimitedMap, getConfigValue } from '../util.js'; import { TavernCardValidator } from '../validator/TavernCardValidator.js'; @@ -768,7 +767,7 @@ async function importFromPng(uploadPath, { request }, preservedFileName) { export const router = express.Router(); -router.post('/create', urlencodedParser, async function (request, response) { +router.post('/create', async function (request, response) { try { if (!request.body) return response.sendStatus(400); @@ -797,7 +796,7 @@ router.post('/create', urlencodedParser, async function (request, response) { } }); -router.post('/rename', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/rename', validateAvatarUrlMiddleware, async function (request, response) { if (!request.body.avatar_url || !request.body.new_name) { return response.sendStatus(400); } @@ -844,7 +843,7 @@ router.post('/rename', jsonParser, validateAvatarUrlMiddleware, async function ( } }); -router.post('/edit', urlencodedParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/edit', validateAvatarUrlMiddleware, async function (request, response) { if (!request.body) { console.warn('Error: no response body detected'); response.status(400).send('Error: no response body detected'); @@ -896,7 +895,7 @@ router.post('/edit', urlencodedParser, validateAvatarUrlMiddleware, async functi * @param {Object} response - The HTTP response object. * @returns {void} */ -router.post('/edit-attribute', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/edit-attribute', validateAvatarUrlMiddleware, async function (request, response) { console.debug(request.body); if (!request.body) { console.warn('Error: no response body detected'); @@ -942,7 +941,7 @@ router.post('/edit-attribute', jsonParser, validateAvatarUrlMiddleware, async fu * * @returns {void} * */ -router.post('/merge-attributes', jsonParser, getFileNameValidationFunction('avatar'), async function (request, response) { +router.post('/merge-attributes', getFileNameValidationFunction('avatar'), async function (request, response) { try { const update = request.body; const avatarPath = path.join(request.user.directories.characters, update.avatar); @@ -973,7 +972,7 @@ router.post('/merge-attributes', jsonParser, getFileNameValidationFunction('avat } }); -router.post('/delete', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/delete', validateAvatarUrlMiddleware, async function (request, response) { if (!request.body || !request.body.avatar_url) { return response.sendStatus(400); } @@ -1023,7 +1022,7 @@ router.post('/delete', jsonParser, validateAvatarUrlMiddleware, async function ( * @param {import("express").Response} response The HTTP response object. * @return {void} */ -router.post('/all', jsonParser, async function (request, response) { +router.post('/all', async function (request, response) { try { const files = fs.readdirSync(request.user.directories.characters); const pngFiles = files.filter(file => file.endsWith('.png')); @@ -1036,7 +1035,7 @@ router.post('/all', jsonParser, async function (request, response) { } }); -router.post('/get', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/get', validateAvatarUrlMiddleware, async function (request, response) { try { if (!request.body) return response.sendStatus(400); const item = request.body.avatar_url; @@ -1055,7 +1054,7 @@ router.post('/get', jsonParser, validateAvatarUrlMiddleware, async function (req } }); -router.post('/chats', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/chats', validateAvatarUrlMiddleware, async function (request, response) { try { if (!request.body) return response.sendStatus(400); @@ -1164,7 +1163,7 @@ function getPreservedName(request) { : undefined; } -router.post('/import', urlencodedParser, async function (request, response) { +router.post('/import', async function (request, response) { if (!request.body || !request.file) return response.sendStatus(400); const uploadPath = path.join(request.file.destination, request.file.filename); @@ -1204,7 +1203,7 @@ router.post('/import', urlencodedParser, async function (request, response) { } }); -router.post('/duplicate', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/duplicate', validateAvatarUrlMiddleware, async function (request, response) { try { if (!request.body.avatar_url) { console.warn('avatar URL not found in request body'); @@ -1250,7 +1249,7 @@ router.post('/duplicate', jsonParser, validateAvatarUrlMiddleware, async functio } }); -router.post('/export', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/export', validateAvatarUrlMiddleware, async function (request, response) { try { if (!request.body.format || !request.body.avatar_url) { return response.sendStatus(400); diff --git a/src/endpoints/chats.js b/src/endpoints/chats.js index a237b3109..8f1e2815d 100644 --- a/src/endpoints/chats.js +++ b/src/endpoints/chats.js @@ -8,7 +8,6 @@ import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; import _ from 'lodash'; -import { jsonParser, urlencodedParser } from '../express-common.js'; import validateAvatarUrlMiddleware from '../middleware/validateFileName.js'; import { getConfigValue, @@ -295,7 +294,7 @@ function importRisuChat(userName, characterName, jsonData) { export const router = express.Router(); -router.post('/save', jsonParser, validateAvatarUrlMiddleware, function (request, response) { +router.post('/save', validateAvatarUrlMiddleware, function (request, response) { try { const directoryName = String(request.body.avatar_url).replace('.png', ''); const chatData = request.body.chat; @@ -311,7 +310,7 @@ router.post('/save', jsonParser, validateAvatarUrlMiddleware, function (request, } }); -router.post('/get', jsonParser, validateAvatarUrlMiddleware, function (request, response) { +router.post('/get', validateAvatarUrlMiddleware, function (request, response) { try { const dirName = String(request.body.avatar_url).replace('.png', ''); const directoryPath = path.join(request.user.directories.chats, dirName); @@ -347,8 +346,7 @@ router.post('/get', jsonParser, validateAvatarUrlMiddleware, function (request, } }); - -router.post('/rename', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/rename', validateAvatarUrlMiddleware, async function (request, response) { if (!request.body || !request.body.original_file || !request.body.renamed_file) { return response.sendStatus(400); } @@ -373,7 +371,7 @@ router.post('/rename', jsonParser, validateAvatarUrlMiddleware, async function ( return response.send({ ok: true, sanitizedFileName }); }); -router.post('/delete', jsonParser, validateAvatarUrlMiddleware, function (request, response) { +router.post('/delete', validateAvatarUrlMiddleware, function (request, response) { const dirName = String(request.body.avatar_url).replace('.png', ''); const fileName = String(request.body.chatfile); const filePath = path.join(request.user.directories.chats, dirName, sanitize(fileName)); @@ -389,7 +387,7 @@ router.post('/delete', jsonParser, validateAvatarUrlMiddleware, function (reques return response.send('ok'); }); -router.post('/export', jsonParser, validateAvatarUrlMiddleware, async function (request, response) { +router.post('/export', validateAvatarUrlMiddleware, async function (request, response) { if (!request.body.file || (!request.body.avatar_url && request.body.is_group === false)) { return response.sendStatus(400); } @@ -458,7 +456,7 @@ router.post('/export', jsonParser, validateAvatarUrlMiddleware, async function ( } }); -router.post('/group/import', urlencodedParser, function (request, response) { +router.post('/group/import', function (request, response) { try { const filedata = request.file; @@ -478,7 +476,7 @@ router.post('/group/import', urlencodedParser, function (request, response) { } }); -router.post('/import', urlencodedParser, validateAvatarUrlMiddleware, function (request, response) { +router.post('/import', validateAvatarUrlMiddleware, function (request, response) { if (!request.body) return response.sendStatus(400); const format = request.body.file_type; @@ -571,7 +569,7 @@ router.post('/import', urlencodedParser, validateAvatarUrlMiddleware, function ( } }); -router.post('/group/get', jsonParser, (request, response) => { +router.post('/group/get', (request, response) => { if (!request.body || !request.body.id) { return response.sendStatus(400); } @@ -591,7 +589,7 @@ router.post('/group/get', jsonParser, (request, response) => { } }); -router.post('/group/delete', jsonParser, (request, response) => { +router.post('/group/delete', (request, response) => { if (!request.body || !request.body.id) { return response.sendStatus(400); } @@ -607,7 +605,7 @@ router.post('/group/delete', jsonParser, (request, response) => { return response.send({ error: true }); }); -router.post('/group/save', jsonParser, (request, response) => { +router.post('/group/save', (request, response) => { if (!request.body || !request.body.id) { return response.sendStatus(400); } @@ -626,7 +624,7 @@ router.post('/group/save', jsonParser, (request, response) => { return response.send({ ok: true }); }); -router.post('/search', jsonParser, validateAvatarUrlMiddleware, function (request, response) { +router.post('/search', validateAvatarUrlMiddleware, function (request, response) { try { const { query, avatar_url, group_id } = request.body; let chatFiles = []; diff --git a/src/endpoints/classify.js b/src/endpoints/classify.js index 996704c49..b65bcdd05 100644 --- a/src/endpoints/classify.js +++ b/src/endpoints/classify.js @@ -1,7 +1,6 @@ import express from 'express'; import { getPipeline } from '../transformers.js'; -import { jsonParser } from '../express-common.js'; const TASK = 'text-classification'; @@ -12,7 +11,7 @@ export const router = express.Router(); */ const cacheObject = new Map(); -router.post('/labels', jsonParser, async (req, res) => { +router.post('/labels', async (req, res) => { try { const pipe = await getPipeline(TASK); const result = Object.keys(pipe.model.config.label2id); @@ -23,7 +22,7 @@ router.post('/labels', jsonParser, async (req, res) => { } }); -router.post('/', jsonParser, async (req, res) => { +router.post('/', async (req, res) => { try { const { text } = req.body; diff --git a/src/endpoints/content-manager.js b/src/endpoints/content-manager.js index efc198aac..898f019ee 100644 --- a/src/endpoints/content-manager.js +++ b/src/endpoints/content-manager.js @@ -9,7 +9,6 @@ import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; import { getConfigValue, color } from '../util.js'; -import { jsonParser } from '../express-common.js'; import { write } from '../character-card-parser.js'; const contentDirectory = path.join(process.cwd(), 'default/content'); @@ -627,7 +626,7 @@ function isHostWhitelisted(host) { export const router = express.Router(); -router.post('/importURL', jsonParser, async (request, response) => { +router.post('/importURL', async (request, response) => { if (!request.body.url) { return response.sendStatus(400); } @@ -713,7 +712,7 @@ router.post('/importURL', jsonParser, async (request, response) => { } }); -router.post('/importUUID', jsonParser, async (request, response) => { +router.post('/importUUID', async (request, response) => { if (!request.body.url) { return response.sendStatus(400); } diff --git a/src/endpoints/extensions.js b/src/endpoints/extensions.js index 542be64ba..2827d8058 100644 --- a/src/endpoints/extensions.js +++ b/src/endpoints/extensions.js @@ -6,7 +6,6 @@ import sanitize from 'sanitize-filename'; import { default as simpleGit } from 'simple-git'; import { PUBLIC_DIRECTORIES } from '../constants.js'; -import { jsonParser } from '../express-common.js'; /** * This function extracts the extension information from the manifest file. @@ -60,7 +59,7 @@ export const router = express.Router(); * * @returns {void} */ -router.post('/install', jsonParser, async (request, response) => { +router.post('/install', async (request, response) => { if (!request.body.url) { return response.status(400).send('Bad Request: URL is required in the request body.'); } @@ -114,7 +113,7 @@ router.post('/install', jsonParser, async (request, response) => { * * @returns {void} */ -router.post('/update', jsonParser, async (request, response) => { +router.post('/update', async (request, response) => { const git = simpleGit(); if (!request.body.extensionName) { return response.status(400).send('Bad Request: extensionName is required in the request body.'); @@ -155,7 +154,7 @@ router.post('/update', jsonParser, async (request, response) => { } }); -router.post('/move', jsonParser, async (request, response) => { +router.post('/move', async (request, response) => { try { const { extensionName, source, destination } = request.body; @@ -209,7 +208,7 @@ router.post('/move', jsonParser, async (request, response) => { * * @returns {void} */ -router.post('/version', jsonParser, async (request, response) => { +router.post('/version', async (request, response) => { const git = simpleGit(); if (!request.body.extensionName) { return response.status(400).send('Bad Request: extensionName is required in the request body.'); @@ -256,7 +255,7 @@ router.post('/version', jsonParser, async (request, response) => { * * @returns {void} */ -router.post('/delete', jsonParser, async (request, response) => { +router.post('/delete', async (request, response) => { if (!request.body.extensionName) { return response.status(400).send('Bad Request: extensionName is required in the request body.'); } @@ -291,7 +290,7 @@ router.post('/delete', jsonParser, async (request, response) => { * Discover the extension folders * If the folder is called third-party, search for subfolders instead */ -router.get('/discover', jsonParser, function (request, response) { +router.get('/discover', function (request, response) { if (!fs.existsSync(path.join(request.user.directories.extensions))) { fs.mkdirSync(path.join(request.user.directories.extensions)); } diff --git a/src/endpoints/files.js b/src/endpoints/files.js index 8ddc8a8f0..4238b5003 100644 --- a/src/endpoints/files.js +++ b/src/endpoints/files.js @@ -6,12 +6,11 @@ import sanitize from 'sanitize-filename'; import { sync as writeFileSyncAtomic } from 'write-file-atomic'; import { validateAssetFileName } from './assets.js'; -import { jsonParser } from '../express-common.js'; import { clientRelativePath } from '../util.js'; export const router = express.Router(); -router.post('/sanitize-filename', jsonParser, async (request, response) => { +router.post('/sanitize-filename', async (request, response) => { try { const fileName = String(request.body.fileName); if (!fileName) { @@ -26,7 +25,7 @@ router.post('/sanitize-filename', jsonParser, async (request, response) => { } }); -router.post('/upload', jsonParser, async (request, response) => { +router.post('/upload', async (request, response) => { try { if (!request.body.name) { return response.status(400).send('No upload name specified'); @@ -52,7 +51,7 @@ router.post('/upload', jsonParser, async (request, response) => { } }); -router.post('/delete', jsonParser, async (request, response) => { +router.post('/delete', async (request, response) => { try { if (!request.body.path) { return response.status(400).send('No path specified'); @@ -76,7 +75,7 @@ router.post('/delete', jsonParser, async (request, response) => { } }); -router.post('/verify', jsonParser, async (request, response) => { +router.post('/verify', async (request, response) => { try { if (!Array.isArray(request.body.urls)) { return response.status(400).send('No URLs specified'); diff --git a/src/endpoints/google.js b/src/endpoints/google.js index 7069701cb..8ef0900a9 100644 --- a/src/endpoints/google.js +++ b/src/endpoints/google.js @@ -4,14 +4,13 @@ import express from 'express'; import { speak, languages } from 'google-translate-api-x'; import { readSecret, SECRET_KEYS } from './secrets.js'; -import { jsonParser } from '../express-common.js'; import { GEMINI_SAFETY } from '../constants.js'; const API_MAKERSUITE = 'https://generativelanguage.googleapis.com'; export const router = express.Router(); -router.post('/caption-image', jsonParser, async (request, response) => { +router.post('/caption-image', async (request, response) => { try { const mimeType = request.body.image.split(';')[0].split(':')[1]; const base64Data = request.body.image.split(',')[1]; @@ -75,7 +74,7 @@ router.post('/list-voices', (_, response) => { return response.json(languages); }); -router.post('/generate-voice', jsonParser, async (request, response) => { +router.post('/generate-voice', async (request, response) => { try { const text = request.body.text; const voice = request.body.voice ?? 'en'; diff --git a/src/endpoints/groups.js b/src/endpoints/groups.js index e700233d8..d6c5bf249 100644 --- a/src/endpoints/groups.js +++ b/src/endpoints/groups.js @@ -5,12 +5,11 @@ import express from 'express'; import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; -import { jsonParser } from '../express-common.js'; import { humanizedISO8601DateTime } from '../util.js'; export const router = express.Router(); -router.post('/all', jsonParser, (request, response) => { +router.post('/all', (request, response) => { const groups = []; if (!fs.existsSync(request.user.directories.groups)) { @@ -54,7 +53,7 @@ router.post('/all', jsonParser, (request, response) => { return response.send(groups); }); -router.post('/create', jsonParser, (request, response) => { +router.post('/create', (request, response) => { if (!request.body) { return response.sendStatus(400); } @@ -88,7 +87,7 @@ router.post('/create', jsonParser, (request, response) => { return response.send(groupMetadata); }); -router.post('/edit', jsonParser, (request, response) => { +router.post('/edit', (request, response) => { if (!request.body || !request.body.id) { return response.sendStatus(400); } @@ -100,7 +99,7 @@ router.post('/edit', jsonParser, (request, response) => { return response.send({ ok: true }); }); -router.post('/delete', jsonParser, async (request, response) => { +router.post('/delete', async (request, response) => { if (!request.body || !request.body.id) { return response.sendStatus(400); } diff --git a/src/endpoints/horde.js b/src/endpoints/horde.js index afc852686..846e98e65 100644 --- a/src/endpoints/horde.js +++ b/src/endpoints/horde.js @@ -3,7 +3,6 @@ import express from 'express'; import { AIHorde, ModelGenerationInputStableSamplers, ModelInterrogationFormTypes, HordeAsyncRequestStates } from '@zeldafan0225/ai_horde'; import { getVersion, delay, Cache } from '../util.js'; import { readSecret, SECRET_KEYS } from './secrets.js'; -import { jsonParser } from '../express-common.js'; const ANONYMOUS_KEY = '0000000000'; const HORDE_TEXT_MODEL_METADATA_URL = 'https://raw.githubusercontent.com/db0/AI-Horde-text-model-reference/main/db.json'; @@ -56,7 +55,7 @@ function sanitizeHordeImagePrompt(prompt) { return prompt; } -router.post('/text-workers', jsonParser, async (request, response) => { +router.post('/text-workers', async (request, response) => { try { const cachedWorkers = cache.get('workers'); @@ -94,7 +93,7 @@ async function mergeModelsAndMetadata(models, metadata) { }); } -router.post('/text-models', jsonParser, async (request, response) => { +router.post('/text-models', async (request, response) => { try { const cachedModels = cache.get('models'); if (cachedModels && !request.body.force) { @@ -127,7 +126,7 @@ router.post('/text-models', jsonParser, async (request, response) => { } }); -router.post('/status', jsonParser, async (_, response) => { +router.post('/status', async (_, response) => { try { const agent = await getClientAgent(); const fetchResult = await fetch('https://aihorde.net/api/v2/status/heartbeat', { @@ -143,7 +142,7 @@ router.post('/status', jsonParser, async (_, response) => { } }); -router.post('/cancel-task', jsonParser, async (request, response) => { +router.post('/cancel-task', async (request, response) => { try { const taskId = request.body.taskId; const agent = await getClientAgent(); @@ -163,7 +162,7 @@ router.post('/cancel-task', jsonParser, async (request, response) => { } }); -router.post('/task-status', jsonParser, async (request, response) => { +router.post('/task-status', async (request, response) => { try { const taskId = request.body.taskId; const agent = await getClientAgent(); @@ -182,7 +181,7 @@ router.post('/task-status', jsonParser, async (request, response) => { } }); -router.post('/generate-text', jsonParser, async (request, response) => { +router.post('/generate-text', async (request, response) => { const apiKey = readSecret(request.user.directories, SECRET_KEYS.HORDE) || ANONYMOUS_KEY; const url = 'https://aihorde.net/api/v2/generate/text/async'; const agent = await getClientAgent(); @@ -213,7 +212,7 @@ router.post('/generate-text', jsonParser, async (request, response) => { } }); -router.post('/sd-samplers', jsonParser, async (_, response) => { +router.post('/sd-samplers', async (_, response) => { try { const samplers = Object.values(ModelGenerationInputStableSamplers); response.send(samplers); @@ -223,7 +222,7 @@ router.post('/sd-samplers', jsonParser, async (_, response) => { } }); -router.post('/sd-models', jsonParser, async (_, response) => { +router.post('/sd-models', async (_, response) => { try { const ai_horde = await getHordeClient(); const models = await ai_horde.getModels(); @@ -234,7 +233,7 @@ router.post('/sd-models', jsonParser, async (_, response) => { } }); -router.post('/caption-image', jsonParser, async (request, response) => { +router.post('/caption-image', async (request, response) => { try { const api_key_horde = readSecret(request.user.directories, SECRET_KEYS.HORDE) || ANONYMOUS_KEY; const ai_horde = await getHordeClient(); @@ -286,7 +285,7 @@ router.post('/caption-image', jsonParser, async (request, response) => { } }); -router.post('/user-info', jsonParser, async (request, response) => { +router.post('/user-info', async (request, response) => { const api_key_horde = readSecret(request.user.directories, SECRET_KEYS.HORDE); if (!api_key_horde) { @@ -303,7 +302,7 @@ router.post('/user-info', jsonParser, async (request, response) => { } }); -router.post('/generate-image', jsonParser, async (request, response) => { +router.post('/generate-image', async (request, response) => { if (!request.body.prompt) { return response.sendStatus(400); } diff --git a/src/endpoints/images.js b/src/endpoints/images.js index cec11e640..fe5bc555f 100644 --- a/src/endpoints/images.js +++ b/src/endpoints/images.js @@ -5,7 +5,6 @@ import { Buffer } from 'node:buffer'; import express from 'express'; import sanitize from 'sanitize-filename'; -import { jsonParser } from '../express-common.js'; import { clientRelativePath, removeFileExtension, getImages } from '../util.js'; /** @@ -36,7 +35,7 @@ export const router = express.Router(); * @param {string} [request.body.ch_name] - Optional character name to determine the sub-directory. * @returns {Object} response - The response object containing the path where the image was saved. */ -router.post('/upload', jsonParser, async (request, response) => { +router.post('/upload', async (request, response) => { // Check for image data if (!request.body || !request.body.image) { return response.status(400).send({ error: 'No image data provided' }); @@ -76,7 +75,7 @@ router.post('/upload', jsonParser, async (request, response) => { } }); -router.post('/list/:folder?', jsonParser, (request, response) => { +router.post('/list/:folder?', (request, response) => { try { if (request.params.folder) { if (request.body.folder) { diff --git a/src/endpoints/moving-ui.js b/src/endpoints/moving-ui.js index 484dfbba8..a79e2a86e 100644 --- a/src/endpoints/moving-ui.js +++ b/src/endpoints/moving-ui.js @@ -3,11 +3,9 @@ import express from 'express'; import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; -import { jsonParser } from '../express-common.js'; - export const router = express.Router(); -router.post('/save', jsonParser, (request, response) => { +router.post('/save', (request, response) => { if (!request.body || !request.body.name) { return response.sendStatus(400); } diff --git a/src/endpoints/novelai.js b/src/endpoints/novelai.js index 43d225751..e007d8e5c 100644 --- a/src/endpoints/novelai.js +++ b/src/endpoints/novelai.js @@ -6,7 +6,6 @@ import express from 'express'; import { readSecret, SECRET_KEYS } from './secrets.js'; import { readAllChunks, extractFileFromZipBuffer, forwardFetchResponse } from '../util.js'; -import { jsonParser } from '../express-common.js'; const API_NOVELAI = 'https://api.novelai.net'; const TEXT_NOVELAI = 'https://text.novelai.net'; @@ -115,7 +114,7 @@ function getRepPenaltyWhitelist(model) { export const router = express.Router(); -router.post('/status', jsonParser, async function (req, res) { +router.post('/status', async function (req, res) { if (!req.body) return res.sendStatus(400); const api_key_novel = readSecret(req.user.directories, SECRET_KEYS.NOVEL); @@ -150,7 +149,7 @@ router.post('/status', jsonParser, async function (req, res) { } }); -router.post('/generate', jsonParser, async function (req, res) { +router.post('/generate', async function (req, res) { if (!req.body) return res.sendStatus(400); const api_key_novel = readSecret(req.user.directories, SECRET_KEYS.NOVEL); @@ -284,7 +283,7 @@ router.post('/generate', jsonParser, async function (req, res) { } }); -router.post('/generate-image', jsonParser, async (request, response) => { +router.post('/generate-image', async (request, response) => { if (!request.body) { return response.sendStatus(400); } @@ -418,7 +417,7 @@ router.post('/generate-image', jsonParser, async (request, response) => { } }); -router.post('/generate-voice', jsonParser, async (request, response) => { +router.post('/generate-voice', async (request, response) => { const token = readSecret(request.user.directories, SECRET_KEYS.NOVEL); if (!token) { diff --git a/src/endpoints/openai.js b/src/endpoints/openai.js index 2952aa21e..14ee69fb8 100644 --- a/src/endpoints/openai.js +++ b/src/endpoints/openai.js @@ -5,7 +5,6 @@ import fetch from 'node-fetch'; import FormData from 'form-data'; import express from 'express'; -import { jsonParser, urlencodedParser } from '../express-common.js'; import { getConfigValue, mergeObjectWithYaml, excludeKeysByYaml, trimV1 } from '../util.js'; import { setAdditionalHeaders } from '../additional-headers.js'; import { readSecret, SECRET_KEYS } from './secrets.js'; @@ -13,7 +12,7 @@ import { OPENROUTER_HEADERS } from '../constants.js'; export const router = express.Router(); -router.post('/caption-image', jsonParser, async (request, response) => { +router.post('/caption-image', async (request, response) => { try { let key = ''; let headers = {}; @@ -189,7 +188,7 @@ router.post('/caption-image', jsonParser, async (request, response) => { } }); -router.post('/transcribe-audio', urlencodedParser, async (request, response) => { +router.post('/transcribe-audio', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.OPENAI); @@ -237,7 +236,7 @@ router.post('/transcribe-audio', urlencodedParser, async (request, response) => } }); -router.post('/generate-voice', jsonParser, async (request, response) => { +router.post('/generate-voice', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.OPENAI); @@ -276,7 +275,7 @@ router.post('/generate-voice', jsonParser, async (request, response) => { } }); -router.post('/generate-image', jsonParser, async (request, response) => { +router.post('/generate-image', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.OPENAI); @@ -312,7 +311,7 @@ router.post('/generate-image', jsonParser, async (request, response) => { const custom = express.Router(); -custom.post('/generate-voice', jsonParser, async (request, response) => { +custom.post('/generate-voice', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.CUSTOM_OPENAI_TTS); const { input, provider_endpoint, response_format, voice, speed, model } = request.body; diff --git a/src/endpoints/openrouter.js b/src/endpoints/openrouter.js index afc26e448..879ca90b5 100644 --- a/src/endpoints/openrouter.js +++ b/src/endpoints/openrouter.js @@ -1,10 +1,9 @@ import express from 'express'; -import { jsonParser } from '../express-common.js'; export const router = express.Router(); const API_OPENROUTER = 'https://openrouter.ai/api/v1'; -router.post('/models/providers', jsonParser, async (req, res) => { +router.post('/models/providers', async (req, res) => { try { const { model } = req.body; const response = await fetch(`${API_OPENROUTER}/models/${model}/endpoints`, { @@ -29,7 +28,7 @@ router.post('/models/providers', jsonParser, async (req, res) => { } }); -router.post('/models/multimodal', jsonParser, async (_req, res) => { +router.post('/models/multimodal', async (_req, res) => { try { // The endpoint is available without authentication const response = await fetch(`${API_OPENROUTER}/models`, { diff --git a/src/endpoints/presets.js b/src/endpoints/presets.js index 55515551f..d742f6289 100644 --- a/src/endpoints/presets.js +++ b/src/endpoints/presets.js @@ -6,7 +6,6 @@ import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; import { getDefaultPresetFile, getDefaultPresets } from './content-manager.js'; -import { jsonParser } from '../express-common.js'; /** * Gets the folder and extension for the preset settings based on the API source ID. @@ -38,7 +37,7 @@ function getPresetSettingsByAPI(apiId, directories) { export const router = express.Router(); -router.post('/save', jsonParser, function (request, response) { +router.post('/save', function (request, response) { const name = sanitize(request.body.name); if (!request.body.preset || !name) { return response.sendStatus(400); @@ -56,7 +55,7 @@ router.post('/save', jsonParser, function (request, response) { return response.send({ name }); }); -router.post('/delete', jsonParser, function (request, response) { +router.post('/delete', function (request, response) { const name = sanitize(request.body.name); if (!name) { return response.sendStatus(400); @@ -79,7 +78,7 @@ router.post('/delete', jsonParser, function (request, response) { } }); -router.post('/restore', jsonParser, function (request, response) { +router.post('/restore', function (request, response) { try { const settings = getPresetSettingsByAPI(request.body.apiId, request.user.directories); const name = sanitize(request.body.name); @@ -102,7 +101,7 @@ router.post('/restore', jsonParser, function (request, response) { }); // TODO: Merge with /api/presets/save -router.post('/save-openai', jsonParser, function (request, response) { +router.post('/save-openai', function (request, response) { if (!request.body || typeof request.query.name !== 'string') return response.sendStatus(400); const name = sanitize(request.query.name); if (!name) return response.sendStatus(400); @@ -114,7 +113,7 @@ router.post('/save-openai', jsonParser, function (request, response) { }); // TODO: Merge with /api/presets/delete -router.post('/delete-openai', jsonParser, function (request, response) { +router.post('/delete-openai', function (request, response) { if (!request.body || !request.body.name) { return response.sendStatus(400); } diff --git a/src/endpoints/quick-replies.js b/src/endpoints/quick-replies.js index f2f05852c..93fcc6b4f 100644 --- a/src/endpoints/quick-replies.js +++ b/src/endpoints/quick-replies.js @@ -5,11 +5,9 @@ import express from 'express'; import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; -import { jsonParser } from '../express-common.js'; - export const router = express.Router(); -router.post('/save', jsonParser, (request, response) => { +router.post('/save', (request, response) => { if (!request.body || !request.body.name) { return response.sendStatus(400); } @@ -20,7 +18,7 @@ router.post('/save', jsonParser, (request, response) => { return response.sendStatus(200); }); -router.post('/delete', jsonParser, (request, response) => { +router.post('/delete', (request, response) => { if (!request.body || !request.body.name) { return response.sendStatus(400); } diff --git a/src/endpoints/search.js b/src/endpoints/search.js index 50c0deee3..91d18d949 100644 --- a/src/endpoints/search.js +++ b/src/endpoints/search.js @@ -3,7 +3,6 @@ import express from 'express'; import { decode } from 'html-entities'; import { readSecret, SECRET_KEYS } from './secrets.js'; -import { jsonParser } from '../express-common.js'; import { trimV1 } from '../util.js'; import { setAdditionalHeaders } from '../additional-headers.js'; @@ -91,7 +90,7 @@ async function extractTranscript(videoPageBody, lang) { return transcriptText; } -router.post('/serpapi', jsonParser, async (request, response) => { +router.post('/serpapi', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.SERPAPI); @@ -124,7 +123,7 @@ router.post('/serpapi', jsonParser, async (request, response) => { * Get the transcript of a YouTube video * @copyright https://github.com/Kakulukian/youtube-transcript (MIT License) */ -router.post('/transcript', jsonParser, async (request, response) => { +router.post('/transcript', async (request, response) => { try { const id = request.body.id; const lang = request.body.lang; @@ -161,7 +160,7 @@ router.post('/transcript', jsonParser, async (request, response) => { } }); -router.post('/searxng', jsonParser, async (request, response) => { +router.post('/searxng', async (request, response) => { try { const { baseUrl, query, preferences, categories } = request.body; @@ -215,7 +214,7 @@ router.post('/searxng', jsonParser, async (request, response) => { } }); -router.post('/tavily', jsonParser, async (request, response) => { +router.post('/tavily', async (request, response) => { try { const apiKey = readSecret(request.user.directories, SECRET_KEYS.TAVILY); @@ -264,7 +263,7 @@ router.post('/tavily', jsonParser, async (request, response) => { } }); -router.post('/koboldcpp', jsonParser, async (request, response) => { +router.post('/koboldcpp', async (request, response) => { try { const { query, url } = request.body; @@ -300,7 +299,7 @@ router.post('/koboldcpp', jsonParser, async (request, response) => { } }); -router.post('/serper', jsonParser, async (request, response) => { +router.post('/serper', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.SERPER); @@ -342,7 +341,7 @@ router.post('/serper', jsonParser, async (request, response) => { } }); -router.post('/visit', jsonParser, async (request, response) => { +router.post('/visit', async (request, response) => { try { const url = request.body.url; const html = Boolean(request.body.html ?? true); diff --git a/src/endpoints/secrets.js b/src/endpoints/secrets.js index 9f2c74769..857a3950f 100644 --- a/src/endpoints/secrets.js +++ b/src/endpoints/secrets.js @@ -4,7 +4,6 @@ import path from 'node:path'; import express from 'express'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; import { getConfigValue } from '../util.js'; -import { jsonParser } from '../express-common.js'; export const SECRETS_FILE = 'secrets.json'; export const SECRET_KEYS = { @@ -164,7 +163,7 @@ export function getAllSecrets(directories) { export const router = express.Router(); -router.post('/write', jsonParser, (request, response) => { +router.post('/write', (request, response) => { const key = request.body.key; const value = request.body.value; @@ -172,7 +171,7 @@ router.post('/write', jsonParser, (request, response) => { return response.send('ok'); }); -router.post('/read', jsonParser, (request, response) => { +router.post('/read', (request, response) => { try { const state = readSecretState(request.user.directories); return response.send(state); @@ -182,7 +181,7 @@ router.post('/read', jsonParser, (request, response) => { } }); -router.post('/view', jsonParser, async (request, response) => { +router.post('/view', async (request, response) => { const allowKeysExposure = getConfigValue('allowKeysExposure', false, 'boolean'); if (!allowKeysExposure) { @@ -204,7 +203,7 @@ router.post('/view', jsonParser, async (request, response) => { } }); -router.post('/find', jsonParser, (request, response) => { +router.post('/find', (request, response) => { const allowKeysExposure = getConfigValue('allowKeysExposure', false, 'boolean'); const key = request.body.key; diff --git a/src/endpoints/settings.js b/src/endpoints/settings.js index 2f31b82f3..3b1209fdc 100644 --- a/src/endpoints/settings.js +++ b/src/endpoints/settings.js @@ -7,7 +7,6 @@ import { sync as writeFileAtomicSync } from 'write-file-atomic'; import { SETTINGS_FILE } from '../constants.js'; import { getConfigValue, generateTimestamp, removeOldBackups } from '../util.js'; -import { jsonParser } from '../express-common.js'; import { getAllUserHandles, getUserDirectories } from '../users.js'; import { getFileNameValidationFunction } from '../middleware/validateFileName.js'; @@ -195,7 +194,7 @@ function getLatestBackup(handle) { export const router = express.Router(); -router.post('/save', jsonParser, function (request, response) { +router.post('/save', function (request, response) { try { const pathToSettings = path.join(request.user.directories.root, SETTINGS_FILE); writeFileAtomicSync(pathToSettings, JSON.stringify(request.body, null, 4), 'utf8'); @@ -208,7 +207,7 @@ router.post('/save', jsonParser, function (request, response) { }); // Wintermute's code -router.post('/get', jsonParser, (request, response) => { +router.post('/get', (request, response) => { let settings; try { const pathToSettings = path.join(request.user.directories.root, SETTINGS_FILE); @@ -279,7 +278,7 @@ router.post('/get', jsonParser, (request, response) => { }); }); -router.post('/get-snapshots', jsonParser, async (request, response) => { +router.post('/get-snapshots', async (request, response) => { try { const snapshots = fs.readdirSync(request.user.directories.backups); const userFilesPattern = getFilePrefix(request.user.profile.handle); @@ -297,7 +296,7 @@ router.post('/get-snapshots', jsonParser, async (request, response) => { } }); -router.post('/load-snapshot', jsonParser, getFileNameValidationFunction('name'), async (request, response) => { +router.post('/load-snapshot', getFileNameValidationFunction('name'), async (request, response) => { try { const userFilesPattern = getFilePrefix(request.user.profile.handle); @@ -321,7 +320,7 @@ router.post('/load-snapshot', jsonParser, getFileNameValidationFunction('name'), } }); -router.post('/make-snapshot', jsonParser, async (request, response) => { +router.post('/make-snapshot', async (request, response) => { try { backupUserSettings(request.user.profile.handle, false); response.sendStatus(204); @@ -331,7 +330,7 @@ router.post('/make-snapshot', jsonParser, async (request, response) => { } }); -router.post('/restore-snapshot', jsonParser, getFileNameValidationFunction('name'), async (request, response) => { +router.post('/restore-snapshot', getFileNameValidationFunction('name'), async (request, response) => { try { const userFilesPattern = getFilePrefix(request.user.profile.handle); diff --git a/src/endpoints/speech.js b/src/endpoints/speech.js index b92dc0b64..0ef5e74fb 100644 --- a/src/endpoints/speech.js +++ b/src/endpoints/speech.js @@ -1,7 +1,6 @@ import { Buffer } from 'node:buffer'; import express from 'express'; import wavefile from 'wavefile'; -import { jsonParser } from '../express-common.js'; import { getPipeline } from '../transformers.js'; export const router = express.Router(); @@ -34,7 +33,7 @@ function getWaveFile(audio) { return audioData; } -router.post('/recognize', jsonParser, async (req, res) => { +router.post('/recognize', async (req, res) => { try { const TASK = 'automatic-speech-recognition'; const { model, audio, lang } = req.body; @@ -53,7 +52,7 @@ router.post('/recognize', jsonParser, async (req, res) => { } }); -router.post('/synthesize', jsonParser, async (req, res) => { +router.post('/synthesize', async (req, res) => { try { const TASK = 'text-to-speech'; const { text, model, speaker } = req.body; diff --git a/src/endpoints/sprites.js b/src/endpoints/sprites.js index 0677ddb32..15a21bff1 100644 --- a/src/endpoints/sprites.js +++ b/src/endpoints/sprites.js @@ -7,7 +7,6 @@ import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; import { getImageBuffers } from '../util.js'; -import { jsonParser, urlencodedParser } from '../express-common.js'; /** * Gets the path to the sprites folder for the provided character name @@ -109,7 +108,7 @@ export function importRisuSprites(directories, data) { export const router = express.Router(); -router.get('/get', jsonParser, function (request, response) { +router.get('/get', function (request, response) { const name = String(request.query.name); const isSubfolder = name.includes('/'); const spritesPath = getSpritesPath(request.user.directories, name, isSubfolder); @@ -144,7 +143,7 @@ router.get('/get', jsonParser, function (request, response) { return response.send(sprites); }); -router.post('/delete', jsonParser, async (request, response) => { +router.post('/delete', async (request, response) => { const label = request.body.label; const name = request.body.name; const spriteName = request.body.spriteName || label; @@ -177,7 +176,7 @@ router.post('/delete', jsonParser, async (request, response) => { } }); -router.post('/upload-zip', urlencodedParser, async (request, response) => { +router.post('/upload-zip', async (request, response) => { const file = request.file; const name = request.body.name; @@ -224,7 +223,7 @@ router.post('/upload-zip', urlencodedParser, async (request, response) => { } }); -router.post('/upload', urlencodedParser, async (request, response) => { +router.post('/upload', async (request, response) => { const file = request.file; const label = request.body.label; const name = request.body.name; diff --git a/src/endpoints/stable-diffusion.js b/src/endpoints/stable-diffusion.js index c5d94e4b6..6401491f3 100644 --- a/src/endpoints/stable-diffusion.js +++ b/src/endpoints/stable-diffusion.js @@ -10,7 +10,6 @@ import urlJoin from 'url-join'; import _ from 'lodash'; import { delay, getBasicAuthHeader, tryParse } from '../util.js'; -import { jsonParser } from '../express-common.js'; import { readSecret, SECRET_KEYS } from './secrets.js'; /** @@ -27,7 +26,7 @@ function getComfyWorkflows(directories) { export const router = express.Router(); -router.post('/ping', jsonParser, async (request, response) => { +router.post('/ping', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/sdapi/v1/options'; @@ -50,7 +49,7 @@ router.post('/ping', jsonParser, async (request, response) => { } }); -router.post('/upscalers', jsonParser, async (request, response) => { +router.post('/upscalers', async (request, response) => { try { async function getUpscalerModels() { const url = new URL(request.body.url); @@ -104,7 +103,7 @@ router.post('/upscalers', jsonParser, async (request, response) => { } }); -router.post('/vaes', jsonParser, async (request, response) => { +router.post('/vaes', async (request, response) => { try { const autoUrl = new URL(request.body.url); autoUrl.pathname = '/sdapi/v1/sd-vae'; @@ -136,7 +135,7 @@ router.post('/vaes', jsonParser, async (request, response) => { } }); -router.post('/samplers', jsonParser, async (request, response) => { +router.post('/samplers', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/sdapi/v1/samplers'; @@ -163,7 +162,7 @@ router.post('/samplers', jsonParser, async (request, response) => { } }); -router.post('/schedulers', jsonParser, async (request, response) => { +router.post('/schedulers', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/sdapi/v1/schedulers'; @@ -189,7 +188,7 @@ router.post('/schedulers', jsonParser, async (request, response) => { } }); -router.post('/models', jsonParser, async (request, response) => { +router.post('/models', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/sdapi/v1/sd-models'; @@ -215,7 +214,7 @@ router.post('/models', jsonParser, async (request, response) => { } }); -router.post('/get-model', jsonParser, async (request, response) => { +router.post('/get-model', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/sdapi/v1/options'; @@ -235,7 +234,7 @@ router.post('/get-model', jsonParser, async (request, response) => { } }); -router.post('/set-model', jsonParser, async (request, response) => { +router.post('/set-model', async (request, response) => { try { async function getProgress() { const url = new URL(request.body.url); @@ -294,7 +293,7 @@ router.post('/set-model', jsonParser, async (request, response) => { } }); -router.post('/generate', jsonParser, async (request, response) => { +router.post('/generate', async (request, response) => { try { try { const optionsUrl = new URL(request.body.url); @@ -349,7 +348,7 @@ router.post('/generate', jsonParser, async (request, response) => { } }); -router.post('/sd-next/upscalers', jsonParser, async (request, response) => { +router.post('/sd-next/upscalers', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/sdapi/v1/upscalers'; @@ -384,7 +383,7 @@ router.post('/sd-next/upscalers', jsonParser, async (request, response) => { const comfy = express.Router(); -comfy.post('/ping', jsonParser, async (request, response) => { +comfy.post('/ping', async (request, response) => { try { const url = new URL(urlJoin(request.body.url, '/system_stats')); @@ -400,7 +399,7 @@ comfy.post('/ping', jsonParser, async (request, response) => { } }); -comfy.post('/samplers', jsonParser, async (request, response) => { +comfy.post('/samplers', async (request, response) => { try { const url = new URL(urlJoin(request.body.url, '/object_info')); @@ -418,7 +417,7 @@ comfy.post('/samplers', jsonParser, async (request, response) => { } }); -comfy.post('/models', jsonParser, async (request, response) => { +comfy.post('/models', async (request, response) => { try { const url = new URL(urlJoin(request.body.url, '/object_info')); @@ -446,7 +445,7 @@ comfy.post('/models', jsonParser, async (request, response) => { } }); -comfy.post('/schedulers', jsonParser, async (request, response) => { +comfy.post('/schedulers', async (request, response) => { try { const url = new URL(urlJoin(request.body.url, '/object_info')); @@ -464,7 +463,7 @@ comfy.post('/schedulers', jsonParser, async (request, response) => { } }); -comfy.post('/vaes', jsonParser, async (request, response) => { +comfy.post('/vaes', async (request, response) => { try { const url = new URL(urlJoin(request.body.url, '/object_info')); @@ -482,7 +481,7 @@ comfy.post('/vaes', jsonParser, async (request, response) => { } }); -comfy.post('/workflows', jsonParser, async (request, response) => { +comfy.post('/workflows', async (request, response) => { try { const data = getComfyWorkflows(request.user.directories); return response.send(data); @@ -492,7 +491,7 @@ comfy.post('/workflows', jsonParser, async (request, response) => { } }); -comfy.post('/workflow', jsonParser, async (request, response) => { +comfy.post('/workflow', async (request, response) => { try { let filePath = path.join(request.user.directories.comfyWorkflows, sanitize(String(request.body.file_name))); if (!fs.existsSync(filePath)) { @@ -506,7 +505,7 @@ comfy.post('/workflow', jsonParser, async (request, response) => { } }); -comfy.post('/save-workflow', jsonParser, async (request, response) => { +comfy.post('/save-workflow', async (request, response) => { try { const filePath = path.join(request.user.directories.comfyWorkflows, sanitize(String(request.body.file_name))); writeFileAtomicSync(filePath, request.body.workflow, 'utf8'); @@ -518,7 +517,7 @@ comfy.post('/save-workflow', jsonParser, async (request, response) => { } }); -comfy.post('/delete-workflow', jsonParser, async (request, response) => { +comfy.post('/delete-workflow', async (request, response) => { try { const filePath = path.join(request.user.directories.comfyWorkflows, sanitize(String(request.body.file_name))); if (fs.existsSync(filePath)) { @@ -531,7 +530,7 @@ comfy.post('/delete-workflow', jsonParser, async (request, response) => { } }); -comfy.post('/generate', jsonParser, async (request, response) => { +comfy.post('/generate', async (request, response) => { try { let item; const url = new URL(urlJoin(request.body.url, '/prompt')); @@ -599,7 +598,7 @@ comfy.post('/generate', jsonParser, async (request, response) => { const together = express.Router(); -together.post('/models', jsonParser, async (request, response) => { +together.post('/models', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.TOGETHERAI); @@ -638,7 +637,7 @@ together.post('/models', jsonParser, async (request, response) => { } }); -together.post('/generate', jsonParser, async (request, response) => { +together.post('/generate', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.TOGETHERAI); @@ -694,7 +693,7 @@ together.post('/generate', jsonParser, async (request, response) => { const drawthings = express.Router(); -drawthings.post('/ping', jsonParser, async (request, response) => { +drawthings.post('/ping', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/'; @@ -714,7 +713,7 @@ drawthings.post('/ping', jsonParser, async (request, response) => { } }); -drawthings.post('/get-model', jsonParser, async (request, response) => { +drawthings.post('/get-model', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/'; @@ -733,7 +732,7 @@ drawthings.post('/get-model', jsonParser, async (request, response) => { } }); -drawthings.post('/get-upscaler', jsonParser, async (request, response) => { +drawthings.post('/get-upscaler', async (request, response) => { try { const url = new URL(request.body.url); url.pathname = '/'; @@ -752,7 +751,7 @@ drawthings.post('/get-upscaler', jsonParser, async (request, response) => { } }); -drawthings.post('/generate', jsonParser, async (request, response) => { +drawthings.post('/generate', async (request, response) => { try { console.debug('SD DrawThings API request:', request.body); @@ -788,7 +787,7 @@ drawthings.post('/generate', jsonParser, async (request, response) => { const pollinations = express.Router(); -pollinations.post('/models', jsonParser, async (_request, response) => { +pollinations.post('/models', async (_request, response) => { try { const modelsUrl = new URL('https://image.pollinations.ai/models'); const result = await fetch(modelsUrl); @@ -813,7 +812,7 @@ pollinations.post('/models', jsonParser, async (_request, response) => { } }); -pollinations.post('/generate', jsonParser, async (request, response) => { +pollinations.post('/generate', async (request, response) => { try { const promptUrl = new URL(`https://image.pollinations.ai/prompt/${encodeURIComponent(request.body.prompt)}`); const params = new URLSearchParams({ @@ -850,7 +849,7 @@ pollinations.post('/generate', jsonParser, async (request, response) => { const stability = express.Router(); -stability.post('/generate', jsonParser, async (request, response) => { +stability.post('/generate', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.STABILITY); @@ -910,7 +909,7 @@ stability.post('/generate', jsonParser, async (request, response) => { const blockentropy = express.Router(); -blockentropy.post('/models', jsonParser, async (request, response) => { +blockentropy.post('/models', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); @@ -946,7 +945,7 @@ blockentropy.post('/models', jsonParser, async (request, response) => { } }); -blockentropy.post('/generate', jsonParser, async (request, response) => { +blockentropy.post('/generate', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.BLOCKENTROPY); @@ -993,7 +992,7 @@ blockentropy.post('/generate', jsonParser, async (request, response) => { const huggingface = express.Router(); -huggingface.post('/generate', jsonParser, async (request, response) => { +huggingface.post('/generate', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.HUGGINGFACE); @@ -1032,7 +1031,7 @@ huggingface.post('/generate', jsonParser, async (request, response) => { const nanogpt = express.Router(); -nanogpt.post('/models', jsonParser, async (request, response) => { +nanogpt.post('/models', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.NANOGPT); @@ -1072,7 +1071,7 @@ nanogpt.post('/models', jsonParser, async (request, response) => { } }); -nanogpt.post('/generate', jsonParser, async (request, response) => { +nanogpt.post('/generate', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.NANOGPT); @@ -1116,7 +1115,7 @@ nanogpt.post('/generate', jsonParser, async (request, response) => { const bfl = express.Router(); -bfl.post('/generate', jsonParser, async (request, response) => { +bfl.post('/generate', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.BFL); @@ -1230,7 +1229,7 @@ bfl.post('/generate', jsonParser, async (request, response) => { const falai = express.Router(); -falai.post('/models', jsonParser, async (_request, response) => { +falai.post('/models', async (_request, response) => { try { const modelsUrl = new URL('https://fal.ai/api/models?categories=text-to-image'); const result = await fetch(modelsUrl); @@ -1260,7 +1259,7 @@ falai.post('/models', jsonParser, async (_request, response) => { } }); -falai.post('/generate', jsonParser, async (request, response) => { +falai.post('/generate', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.FALAI); @@ -1276,7 +1275,7 @@ falai.post('/generate', jsonParser, async (request, response) => { seed: request.body.seed ?? null, guidance_scale: request.body.guidance, enable_safety_checker: false, // Disable general safety checks - safety_tolerance: 6 // Make Flux the least strict + safety_tolerance: 6, // Make Flux the least strict }; console.debug('FAL.AI request:', requestBody); diff --git a/src/endpoints/stats.js b/src/endpoints/stats.js index a2077df78..fa03a438c 100644 --- a/src/endpoints/stats.js +++ b/src/endpoints/stats.js @@ -8,7 +8,6 @@ import writeFileAtomic from 'write-file-atomic'; const readFile = fs.promises.readFile; const readdir = fs.promises.readdir; -import { jsonParser } from '../express-common.js'; import { getAllUserHandles, getUserDirectories } from '../users.js'; const STATS_FILE = 'stats.json'; @@ -440,7 +439,7 @@ export const router = express.Router(); /** * Handle a POST request to get the stats object */ -router.post('/get', jsonParser, function (request, response) { +router.post('/get', function (request, response) { const stats = STATS.get(request.user.profile.handle) || {}; response.send(stats); }); @@ -448,7 +447,7 @@ router.post('/get', jsonParser, function (request, response) { /** * Triggers the recreation of statistics from chat files. */ -router.post('/recreate', jsonParser, async function (request, response) { +router.post('/recreate', async function (request, response) { try { await recreateStats(request.user.profile.handle, request.user.directories.chats, request.user.directories.characters); return response.sendStatus(200); @@ -461,7 +460,7 @@ router.post('/recreate', jsonParser, async function (request, response) { /** * Handle a POST request to update the stats object */ -router.post('/update', jsonParser, function (request, response) { +router.post('/update', function (request, response) { if (!request.body) return response.sendStatus(400); setCharStats(request.user.profile.handle, request.body); return response.sendStatus(200); diff --git a/src/endpoints/themes.js b/src/endpoints/themes.js index 7d8145162..868a769d0 100644 --- a/src/endpoints/themes.js +++ b/src/endpoints/themes.js @@ -5,11 +5,9 @@ import express from 'express'; import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; -import { jsonParser } from '../express-common.js'; - export const router = express.Router(); -router.post('/save', jsonParser, (request, response) => { +router.post('/save', (request, response) => { if (!request.body || !request.body.name) { return response.sendStatus(400); } @@ -20,7 +18,7 @@ router.post('/save', jsonParser, (request, response) => { return response.sendStatus(200); }); -router.post('/delete', jsonParser, function (request, response) { +router.post('/delete', function (request, response) { if (!request.body || !request.body.name) { return response.sendStatus(400); } diff --git a/src/endpoints/thumbnails.js b/src/endpoints/thumbnails.js index 4d1b8b4a2..0eada3236 100644 --- a/src/endpoints/thumbnails.js +++ b/src/endpoints/thumbnails.js @@ -10,7 +10,6 @@ import { sync as writeFileAtomicSync } from 'write-file-atomic'; import { getAllUserHandles, getUserDirectories } from '../users.js'; import { getConfigValue } from '../util.js'; -import { jsonParser } from '../express-common.js'; const thumbnailsEnabled = !!getConfigValue('thumbnails.enabled', true, 'boolean'); const quality = Math.min(100, Math.max(1, parseInt(getConfigValue('thumbnails.quality', 95, 'number')))); @@ -176,7 +175,7 @@ export async function ensureThumbnailCache() { export const router = express.Router(); // Important: This route must be mounted as '/thumbnail'. It is used in the client code and saved to chat files. -router.get('/', jsonParser, async function (request, response) { +router.get('/', async function (request, response) { try{ if (typeof request.query.file !== 'string' || typeof request.query.type !== 'string') { return response.sendStatus(400); diff --git a/src/endpoints/tokenizers.js b/src/endpoints/tokenizers.js index 4eaaf6204..c1468ad36 100644 --- a/src/endpoints/tokenizers.js +++ b/src/endpoints/tokenizers.js @@ -11,7 +11,6 @@ import tiktoken from 'tiktoken'; import { convertClaudePrompt } from '../prompt-converters.js'; import { TEXTGEN_TYPES } from '../constants.js'; -import { jsonParser } from '../express-common.js'; import { setAdditionalHeaders } from '../additional-headers.js'; import { getConfigValue, isValidUrl } from '../util.js'; @@ -689,36 +688,36 @@ function createWebTokenizerDecodingHandler(tokenizer) { export const router = express.Router(); -router.post('/llama/encode', jsonParser, createSentencepieceEncodingHandler(spp_llama)); -router.post('/nerdstash/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd)); -router.post('/nerdstash_v2/encode', jsonParser, createSentencepieceEncodingHandler(spp_nerd_v2)); -router.post('/mistral/encode', jsonParser, createSentencepieceEncodingHandler(spp_mistral)); -router.post('/yi/encode', jsonParser, createSentencepieceEncodingHandler(spp_yi)); -router.post('/gemma/encode', jsonParser, createSentencepieceEncodingHandler(spp_gemma)); -router.post('/jamba/encode', jsonParser, createSentencepieceEncodingHandler(spp_jamba)); -router.post('/gpt2/encode', jsonParser, createTiktokenEncodingHandler('gpt2')); -router.post('/claude/encode', jsonParser, createWebTokenizerEncodingHandler(claude_tokenizer)); -router.post('/llama3/encode', jsonParser, createWebTokenizerEncodingHandler(llama3_tokenizer)); -router.post('/qwen2/encode', jsonParser, createWebTokenizerEncodingHandler(qwen2Tokenizer)); -router.post('/command-r/encode', jsonParser, createWebTokenizerEncodingHandler(commandTokenizer)); -router.post('/nemo/encode', jsonParser, createWebTokenizerEncodingHandler(nemoTokenizer)); -router.post('/deepseek/encode', jsonParser, createWebTokenizerEncodingHandler(deepseekTokenizer)); -router.post('/llama/decode', jsonParser, createSentencepieceDecodingHandler(spp_llama)); -router.post('/nerdstash/decode', jsonParser, createSentencepieceDecodingHandler(spp_nerd)); -router.post('/nerdstash_v2/decode', jsonParser, createSentencepieceDecodingHandler(spp_nerd_v2)); -router.post('/mistral/decode', jsonParser, createSentencepieceDecodingHandler(spp_mistral)); -router.post('/yi/decode', jsonParser, createSentencepieceDecodingHandler(spp_yi)); -router.post('/gemma/decode', jsonParser, createSentencepieceDecodingHandler(spp_gemma)); -router.post('/jamba/decode', jsonParser, createSentencepieceDecodingHandler(spp_jamba)); -router.post('/gpt2/decode', jsonParser, createTiktokenDecodingHandler('gpt2')); -router.post('/claude/decode', jsonParser, createWebTokenizerDecodingHandler(claude_tokenizer)); -router.post('/llama3/decode', jsonParser, createWebTokenizerDecodingHandler(llama3_tokenizer)); -router.post('/qwen2/decode', jsonParser, createWebTokenizerDecodingHandler(qwen2Tokenizer)); -router.post('/command-r/decode', jsonParser, createWebTokenizerDecodingHandler(commandTokenizer)); -router.post('/nemo/decode', jsonParser, createWebTokenizerDecodingHandler(nemoTokenizer)); -router.post('/deepseek/decode', jsonParser, createWebTokenizerDecodingHandler(deepseekTokenizer)); +router.post('/llama/encode', createSentencepieceEncodingHandler(spp_llama)); +router.post('/nerdstash/encode', createSentencepieceEncodingHandler(spp_nerd)); +router.post('/nerdstash_v2/encode', createSentencepieceEncodingHandler(spp_nerd_v2)); +router.post('/mistral/encode', createSentencepieceEncodingHandler(spp_mistral)); +router.post('/yi/encode', createSentencepieceEncodingHandler(spp_yi)); +router.post('/gemma/encode', createSentencepieceEncodingHandler(spp_gemma)); +router.post('/jamba/encode', createSentencepieceEncodingHandler(spp_jamba)); +router.post('/gpt2/encode', createTiktokenEncodingHandler('gpt2')); +router.post('/claude/encode', createWebTokenizerEncodingHandler(claude_tokenizer)); +router.post('/llama3/encode', createWebTokenizerEncodingHandler(llama3_tokenizer)); +router.post('/qwen2/encode', createWebTokenizerEncodingHandler(qwen2Tokenizer)); +router.post('/command-r/encode', createWebTokenizerEncodingHandler(commandTokenizer)); +router.post('/nemo/encode', createWebTokenizerEncodingHandler(nemoTokenizer)); +router.post('/deepseek/encode', createWebTokenizerEncodingHandler(deepseekTokenizer)); +router.post('/llama/decode', createSentencepieceDecodingHandler(spp_llama)); +router.post('/nerdstash/decode', createSentencepieceDecodingHandler(spp_nerd)); +router.post('/nerdstash_v2/decode', createSentencepieceDecodingHandler(spp_nerd_v2)); +router.post('/mistral/decode', createSentencepieceDecodingHandler(spp_mistral)); +router.post('/yi/decode', createSentencepieceDecodingHandler(spp_yi)); +router.post('/gemma/decode', createSentencepieceDecodingHandler(spp_gemma)); +router.post('/jamba/decode', createSentencepieceDecodingHandler(spp_jamba)); +router.post('/gpt2/decode', createTiktokenDecodingHandler('gpt2')); +router.post('/claude/decode', createWebTokenizerDecodingHandler(claude_tokenizer)); +router.post('/llama3/decode', createWebTokenizerDecodingHandler(llama3_tokenizer)); +router.post('/qwen2/decode', createWebTokenizerDecodingHandler(qwen2Tokenizer)); +router.post('/command-r/decode', createWebTokenizerDecodingHandler(commandTokenizer)); +router.post('/nemo/decode', createWebTokenizerDecodingHandler(nemoTokenizer)); +router.post('/deepseek/decode', createWebTokenizerDecodingHandler(deepseekTokenizer)); -router.post('/openai/encode', jsonParser, async function (req, res) { +router.post('/openai/encode', async function (req, res) { try { const queryModel = String(req.query.model || ''); @@ -786,7 +785,7 @@ router.post('/openai/encode', jsonParser, async function (req, res) { } }); -router.post('/openai/decode', jsonParser, async function (req, res) { +router.post('/openai/decode', async function (req, res) { try { const queryModel = String(req.query.model || ''); @@ -854,7 +853,7 @@ router.post('/openai/decode', jsonParser, async function (req, res) { } }); -router.post('/openai/count', jsonParser, async function (req, res) { +router.post('/openai/count', async function (req, res) { try { if (!req.body) return res.sendStatus(400); @@ -968,7 +967,7 @@ router.post('/openai/count', jsonParser, async function (req, res) { } }); -router.post('/remote/kobold/count', jsonParser, async function (request, response) { +router.post('/remote/kobold/count', async function (request, response) { if (!request.body) { return response.sendStatus(400); } @@ -1002,7 +1001,7 @@ router.post('/remote/kobold/count', jsonParser, async function (request, respons } }); -router.post('/remote/textgenerationwebui/encode', jsonParser, async function (request, response) { +router.post('/remote/textgenerationwebui/encode', async function (request, response) { if (!request.body) { return response.sendStatus(400); } diff --git a/src/endpoints/translate.js b/src/endpoints/translate.js index cafd2c676..167b11645 100644 --- a/src/endpoints/translate.js +++ b/src/endpoints/translate.js @@ -8,7 +8,6 @@ import urlJoin from 'url-join'; import { readSecret, SECRET_KEYS } from './secrets.js'; import { getConfigValue, uuidv4 } from '../util.js'; -import { jsonParser } from '../express-common.js'; const DEEPLX_URL_DEFAULT = 'http://127.0.0.1:1188/translate'; const ONERING_URL_DEFAULT = 'http://127.0.0.1:4990/translate'; @@ -40,7 +39,7 @@ function decodeBuffer(buffer) { } } -router.post('/libre', jsonParser, async (request, response) => { +router.post('/libre', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.LIBRE); const url = readSecret(request.user.directories, SECRET_KEYS.LIBRE_URL); @@ -100,7 +99,7 @@ router.post('/libre', jsonParser, async (request, response) => { } }); -router.post('/google', jsonParser, async (request, response) => { +router.post('/google', async (request, response) => { try { const text = request.body.text; const lang = request.body.lang; @@ -133,7 +132,7 @@ router.post('/google', jsonParser, async (request, response) => { } }); -router.post('/yandex', jsonParser, async (request, response) => { +router.post('/yandex', async (request, response) => { try { if (request.body.lang === 'pt-PT') { request.body.lang = 'pt'; @@ -189,7 +188,7 @@ router.post('/yandex', jsonParser, async (request, response) => { } }); -router.post('/lingva', jsonParser, async (request, response) => { +router.post('/lingva', async (request, response) => { try { const secretUrl = readSecret(request.user.directories, SECRET_KEYS.LINGVA_URL); const baseUrl = secretUrl || LINGVA_DEFAULT; @@ -233,7 +232,7 @@ router.post('/lingva', jsonParser, async (request, response) => { } }); -router.post('/deepl', jsonParser, async (request, response) => { +router.post('/deepl', async (request, response) => { try { const key = readSecret(request.user.directories, SECRET_KEYS.DEEPL); @@ -295,7 +294,7 @@ router.post('/deepl', jsonParser, async (request, response) => { } }); -router.post('/onering', jsonParser, async (request, response) => { +router.post('/onering', async (request, response) => { try { const secretUrl = readSecret(request.user.directories, SECRET_KEYS.ONERING_URL); const url = secretUrl || ONERING_URL_DEFAULT; @@ -352,7 +351,7 @@ router.post('/onering', jsonParser, async (request, response) => { } }); -router.post('/deeplx', jsonParser, async (request, response) => { +router.post('/deeplx', async (request, response) => { try { const secretUrl = readSecret(request.user.directories, SECRET_KEYS.DEEPLX_URL); const url = secretUrl || DEEPLX_URL_DEFAULT; @@ -408,7 +407,7 @@ router.post('/deeplx', jsonParser, async (request, response) => { } }); -router.post('/bing', jsonParser, async (request, response) => { +router.post('/bing', async (request, response) => { try { const text = request.body.text; let lang = request.body.lang; diff --git a/src/endpoints/users-admin.js b/src/endpoints/users-admin.js index 33da31729..3a4399495 100644 --- a/src/endpoints/users-admin.js +++ b/src/endpoints/users-admin.js @@ -3,7 +3,6 @@ import { promises as fsPromises } from 'node:fs'; import storage from 'node-persist'; import express from 'express'; import lodash from 'lodash'; -import { jsonParser } from '../express-common.js'; import { checkForNewContent, CONTENT_TYPES } from './content-manager.js'; import { KEY_PREFIX, @@ -20,7 +19,7 @@ import { DEFAULT_USER } from '../constants.js'; export const router = express.Router(); -router.post('/get', requireAdminMiddleware, jsonParser, async (_request, response) => { +router.post('/get', requireAdminMiddleware, async (_request, response) => { try { /** @type {import('../users.js').User[]} */ const users = await storage.values(x => x.key.startsWith(KEY_PREFIX)); @@ -50,7 +49,7 @@ router.post('/get', requireAdminMiddleware, jsonParser, async (_request, respons } }); -router.post('/disable', requireAdminMiddleware, jsonParser, async (request, response) => { +router.post('/disable', requireAdminMiddleware, async (request, response) => { try { if (!request.body.handle) { console.warn('Disable user failed: Missing required fields'); @@ -79,7 +78,7 @@ router.post('/disable', requireAdminMiddleware, jsonParser, async (request, resp } }); -router.post('/enable', requireAdminMiddleware, jsonParser, async (request, response) => { +router.post('/enable', requireAdminMiddleware, async (request, response) => { try { if (!request.body.handle) { console.warn('Enable user failed: Missing required fields'); @@ -103,7 +102,7 @@ router.post('/enable', requireAdminMiddleware, jsonParser, async (request, respo } }); -router.post('/promote', requireAdminMiddleware, jsonParser, async (request, response) => { +router.post('/promote', requireAdminMiddleware, async (request, response) => { try { if (!request.body.handle) { console.warn('Promote user failed: Missing required fields'); @@ -127,7 +126,7 @@ router.post('/promote', requireAdminMiddleware, jsonParser, async (request, resp } }); -router.post('/demote', requireAdminMiddleware, jsonParser, async (request, response) => { +router.post('/demote', requireAdminMiddleware, async (request, response) => { try { if (!request.body.handle) { console.warn('Demote user failed: Missing required fields'); @@ -156,7 +155,7 @@ router.post('/demote', requireAdminMiddleware, jsonParser, async (request, respo } }); -router.post('/create', requireAdminMiddleware, jsonParser, async (request, response) => { +router.post('/create', requireAdminMiddleware, async (request, response) => { try { if (!request.body.handle || !request.body.name) { console.warn('Create user failed: Missing required fields'); @@ -203,7 +202,7 @@ router.post('/create', requireAdminMiddleware, jsonParser, async (request, respo } }); -router.post('/delete', requireAdminMiddleware, jsonParser, async (request, response) => { +router.post('/delete', requireAdminMiddleware, async (request, response) => { try { if (!request.body.handle) { console.warn('Delete user failed: Missing required fields'); @@ -235,7 +234,7 @@ router.post('/delete', requireAdminMiddleware, jsonParser, async (request, respo } }); -router.post('/slugify', requireAdminMiddleware, jsonParser, async (request, response) => { +router.post('/slugify', requireAdminMiddleware, async (request, response) => { try { if (!request.body.text) { console.warn('Slugify failed: Missing required fields'); diff --git a/src/endpoints/users-private.js b/src/endpoints/users-private.js index 5a424a199..7aa3d4349 100644 --- a/src/endpoints/users-private.js +++ b/src/endpoints/users-private.js @@ -5,7 +5,6 @@ import crypto from 'node:crypto'; import storage from 'node-persist'; import express from 'express'; -import { jsonParser } from '../express-common.js'; import { getUserAvatar, toKey, getPasswordHash, getPasswordSalt, createBackupArchive, ensurePublicDirectoriesExist, toAvatarKey } from '../users.js'; import { SETTINGS_FILE } from '../constants.js'; import { checkForNewContent, CONTENT_TYPES } from './content-manager.js'; @@ -55,7 +54,7 @@ router.get('/me', async (request, response) => { } }); -router.post('/change-avatar', jsonParser, async (request, response) => { +router.post('/change-avatar', async (request, response) => { try { if (!request.body.handle) { console.warn('Change avatar failed: Missing required fields'); @@ -90,7 +89,7 @@ router.post('/change-avatar', jsonParser, async (request, response) => { } }); -router.post('/change-password', jsonParser, async (request, response) => { +router.post('/change-password', async (request, response) => { try { if (!request.body.handle) { console.warn('Change password failed: Missing required fields'); @@ -137,7 +136,7 @@ router.post('/change-password', jsonParser, async (request, response) => { } }); -router.post('/backup', jsonParser, async (request, response) => { +router.post('/backup', async (request, response) => { try { const handle = request.body.handle; @@ -158,7 +157,7 @@ router.post('/backup', jsonParser, async (request, response) => { } }); -router.post('/reset-settings', jsonParser, async (request, response) => { +router.post('/reset-settings', async (request, response) => { try { const password = request.body.password; @@ -178,7 +177,7 @@ router.post('/reset-settings', jsonParser, async (request, response) => { } }); -router.post('/change-name', jsonParser, async (request, response) => { +router.post('/change-name', async (request, response) => { try { if (!request.body.name || !request.body.handle) { console.warn('Change name failed: Missing required fields'); @@ -208,7 +207,7 @@ router.post('/change-name', jsonParser, async (request, response) => { } }); -router.post('/reset-step1', jsonParser, async (request, response) => { +router.post('/reset-step1', async (request, response) => { try { const resetCode = String(crypto.randomInt(1000, 9999)); console.log(); @@ -222,7 +221,7 @@ router.post('/reset-step1', jsonParser, async (request, response) => { } }); -router.post('/reset-step2', jsonParser, async (request, response) => { +router.post('/reset-step2', async (request, response) => { try { if (!request.body.code) { console.warn('Recover step 2 failed: Missing required fields'); diff --git a/src/endpoints/users-public.js b/src/endpoints/users-public.js index a117d2a06..ec677d740 100644 --- a/src/endpoints/users-public.js +++ b/src/endpoints/users-public.js @@ -3,7 +3,7 @@ import crypto from 'node:crypto'; import storage from 'node-persist'; import express from 'express'; import { RateLimiterMemory, RateLimiterRes } from 'rate-limiter-flexible'; -import { jsonParser, getIpFromRequest, getRealIpFromHeader } from '../express-common.js'; +import { getIpFromRequest, getRealIpFromHeader } from '../express-common.js'; import { color, Cache, getConfigValue } from '../util.js'; import { KEY_PREFIX, getUserAvatar, toKey, getPasswordHash, getPasswordSalt } from '../users.js'; @@ -56,7 +56,7 @@ router.post('/list', async (_request, response) => { } }); -router.post('/login', jsonParser, async (request, response) => { +router.post('/login', async (request, response) => { try { if (!request.body.handle) { console.warn('Login failed: Missing required fields'); @@ -104,7 +104,7 @@ router.post('/login', jsonParser, async (request, response) => { } }); -router.post('/recover-step1', jsonParser, async (request, response) => { +router.post('/recover-step1', async (request, response) => { try { if (!request.body.handle) { console.warn('Recover step 1 failed: Missing required fields'); @@ -144,7 +144,7 @@ router.post('/recover-step1', jsonParser, async (request, response) => { } }); -router.post('/recover-step2', jsonParser, async (request, response) => { +router.post('/recover-step2', async (request, response) => { try { if (!request.body.handle || !request.body.code) { console.warn('Recover step 2 failed: Missing required fields'); diff --git a/src/endpoints/vectors.js b/src/endpoints/vectors.js index 75ce34e7c..9630ce862 100644 --- a/src/endpoints/vectors.js +++ b/src/endpoints/vectors.js @@ -5,7 +5,6 @@ import vectra from 'vectra'; import express from 'express'; import sanitize from 'sanitize-filename'; -import { jsonParser } from '../express-common.js'; import { getConfigValue } from '../util.js'; import { getNomicAIBatchVector, getNomicAIVector } from '../vectors/nomicai-vectors.js'; @@ -384,7 +383,7 @@ async function regenerateCorruptedIndexErrorHandler(req, res, error) { export const router = express.Router(); -router.post('/query', jsonParser, async (req, res) => { +router.post('/query', async (req, res) => { try { if (!req.body.collectionId || !req.body.searchText) { return res.sendStatus(400); @@ -404,7 +403,7 @@ router.post('/query', jsonParser, async (req, res) => { } }); -router.post('/query-multi', jsonParser, async (req, res) => { +router.post('/query-multi', async (req, res) => { try { if (!Array.isArray(req.body.collectionIds) || !req.body.searchText) { return res.sendStatus(400); @@ -424,7 +423,7 @@ router.post('/query-multi', jsonParser, async (req, res) => { } }); -router.post('/insert', jsonParser, async (req, res) => { +router.post('/insert', async (req, res) => { try { if (!Array.isArray(req.body.items) || !req.body.collectionId) { return res.sendStatus(400); @@ -442,7 +441,7 @@ router.post('/insert', jsonParser, async (req, res) => { } }); -router.post('/list', jsonParser, async (req, res) => { +router.post('/list', async (req, res) => { try { if (!req.body.collectionId) { return res.sendStatus(400); @@ -459,7 +458,7 @@ router.post('/list', jsonParser, async (req, res) => { } }); -router.post('/delete', jsonParser, async (req, res) => { +router.post('/delete', async (req, res) => { try { if (!Array.isArray(req.body.hashes) || !req.body.collectionId) { return res.sendStatus(400); @@ -477,7 +476,7 @@ router.post('/delete', jsonParser, async (req, res) => { } }); -router.post('/purge-all', jsonParser, async (req, res) => { +router.post('/purge-all', async (req, res) => { try { for (const source of SOURCES) { const sourcePath = path.join(req.user.directories.vectors, sanitize(source)); @@ -495,7 +494,7 @@ router.post('/purge-all', jsonParser, async (req, res) => { } }); -router.post('/purge', jsonParser, async (req, res) => { +router.post('/purge', async (req, res) => { try { if (!req.body.collectionId) { return res.sendStatus(400); diff --git a/src/endpoints/worldinfo.js b/src/endpoints/worldinfo.js index aeaa2eb55..0c043ea35 100644 --- a/src/endpoints/worldinfo.js +++ b/src/endpoints/worldinfo.js @@ -5,8 +5,6 @@ import express from 'express'; import sanitize from 'sanitize-filename'; import { sync as writeFileAtomicSync } from 'write-file-atomic'; -import { jsonParser, urlencodedParser } from '../express-common.js'; - /** * Reads a World Info file and returns its contents * @param {import('../users.js').UserDirectoryList} directories User directories @@ -36,7 +34,7 @@ export function readWorldInfoFile(directories, worldInfoName, allowDummy) { export const router = express.Router(); -router.post('/get', jsonParser, (request, response) => { +router.post('/get', (request, response) => { if (!request.body?.name) { return response.sendStatus(400); } @@ -46,7 +44,7 @@ router.post('/get', jsonParser, (request, response) => { return response.send(file); }); -router.post('/delete', jsonParser, (request, response) => { +router.post('/delete', (request, response) => { if (!request.body?.name) { return response.sendStatus(400); } @@ -64,7 +62,7 @@ router.post('/delete', jsonParser, (request, response) => { return response.sendStatus(200); }); -router.post('/import', urlencodedParser, (request, response) => { +router.post('/import', (request, response) => { if (!request.file) return response.sendStatus(400); const filename = `${path.parse(sanitize(request.file.originalname)).name}.json`; @@ -99,7 +97,7 @@ router.post('/import', urlencodedParser, (request, response) => { return response.send({ name: worldName }); }); -router.post('/edit', jsonParser, (request, response) => { +router.post('/edit', (request, response) => { if (!request.body) { return response.sendStatus(400); } diff --git a/src/express-common.js b/src/express-common.js index 9717450a1..7963c3e96 100644 --- a/src/express-common.js +++ b/src/express-common.js @@ -1,9 +1,10 @@ -import express from 'express'; import ipaddr from 'ipaddr.js'; -// Instantiate parser middleware here with application-level size limits -export const jsonParser = express.json({ limit: '200mb' }); -export const urlencodedParser = express.urlencoded({ extended: true, limit: '200mb' }); +const noopMiddleware = (_req, _res, next) => next(); +/** @deprecated Do not use. A global middleware is provided at the application level. */ +export const jsonParser = noopMiddleware; +/** @deprecated Do not use. A global middleware is provided at the application level. */ +export const urlencodedParser = noopMiddleware; /** * Gets the IP address of the client from the request object.