diff --git a/server.js b/server.js index 0103be08f..1635da308 100644 --- a/server.js +++ b/server.js @@ -48,7 +48,7 @@ const { jsonParser, urlencodedParser } = require('./src/express-common.js'); const contentManager = require('./src/endpoints/content-manager'); const statsHelpers = require('./statsHelpers.js'); const { readSecret, migrateSecrets, SECRET_KEYS } = require('./src/endpoints/secrets'); -const { delay, getVersion, getConfigValue, color, uuidv4, humanizedISO8601DateTime, tryParse } = require('./src/util'); +const { delay, getVersion, getConfigValue, color, uuidv4, humanizedISO8601DateTime, tryParse, clientRelativePath } = require('./src/util'); const { invalidateThumbnail, ensureThumbnailCache } = require('./src/endpoints/thumbnails'); const { getTokenizerModel, getTiktokenTokenizer, loadTokenizers, TEXT_COMPLETION_MODELS, getSentencepiceTokenizer, sentencepieceTokenizers } = require('./src/endpoints/tokenizers'); const { convertClaudePrompt } = require('./src/chat-completion'); @@ -1587,10 +1587,7 @@ app.post('/uploadimage', jsonParser, async (request, response) => { ensureDirectoryExistence(pathToNewFile); const imageBuffer = Buffer.from(base64Data, 'base64'); await fs.promises.writeFile(pathToNewFile, imageBuffer); - // send the path to the image, relative to the client folder, which means removing the first folder from the path which is 'public' - // Use forward slashes, even on Windows - pathToNewFile = pathToNewFile.split(path.sep).slice(1).join('/'); - response.send({ path: pathToNewFile }); + response.send({ path: clientRelativePath(pathToNewFile) }); } catch (error) { console.log(error); response.status(500).send({ error: 'Failed to save the image' }); diff --git a/src/endpoints/assets.js b/src/endpoints/assets.js index 64a75011f..99af83957 100644 --- a/src/endpoints/assets.js +++ b/src/endpoints/assets.js @@ -6,6 +6,7 @@ const fetch = require('node-fetch').default; const { finished } = require('stream/promises'); const { DIRECTORIES, UNSAFE_EXTENSIONS } = require('../constants'); const { jsonParser } = require('../express-common'); +const { clientRelativePath } = require('../util'); const VALID_CATEGORIES = ['bgm', 'ambient', 'blip', 'live2d']; @@ -99,10 +100,9 @@ router.post('/get', jsonParser, async (_, response) => { const files = getFiles(live2d_folder); //console.debug("FILE FOUND:",files) for (let file of files) { - file = path.normalize(file.replace('public' + path.sep, '')); if (file.includes('model') && file.endsWith('.json')) { //console.debug("Asset live2d model found:",file) - output[folder].push(path.normalize(file).replace(/\\/g, '/')); + output[folder].push(clientRelativePath(file)); } } continue; @@ -115,7 +115,7 @@ router.post('/get', jsonParser, async (_, response) => { }); output[folder] = []; for (const file of files) { - output[folder].push(path.join('assets', folder, file).replace(/\\/g, '/')); + output[folder].push(`assets/${folder}/${file}`); } } } diff --git a/src/endpoints/files.js b/src/endpoints/files.js index 4e0b106f1..fb8dd4f93 100644 --- a/src/endpoints/files.js +++ b/src/endpoints/files.js @@ -5,6 +5,7 @@ const router = express.Router(); const { validateAssetFileName } = require('./assets'); const { jsonParser } = require('../express-common'); const { DIRECTORIES } = require('../constants'); +const { clientRelativePath } = require('../util'); router.post('/upload', jsonParser, async (request, response) => { try { @@ -23,7 +24,7 @@ router.post('/upload', jsonParser, async (request, response) => { const pathToUpload = path.join(DIRECTORIES.files, request.body.name); writeFileSyncAtomic(pathToUpload, request.body.data, 'base64'); - const url = path.normalize(pathToUpload.replace('public' + path.sep, '').replace(/\\/g, '/')); + const url = clientRelativePath(pathToUpload); return response.send({ path: url }); } catch (error) { console.log(error); diff --git a/src/util.js b/src/util.js index b01bdb615..e9163c692 100644 --- a/src/util.js +++ b/src/util.js @@ -288,6 +288,16 @@ function tryParse(str) { } } +/** + * Takes a path to a client-accessible file in the `public` folder and converts it to a relative URL segment that the + * client can fetch it from. This involves stripping the `public/` prefix and always using `/` as the separator. + * @param {string} inputPath The path to be converted. + * @returns The relative URL path from which the client can access the file. + */ +function clientRelativePath(inputPath) { + return path.normalize(inputPath).split(path.sep).slice(1).join('/'); +} + module.exports = { getConfig, getConfigValue, @@ -302,4 +312,5 @@ module.exports = { uuidv4, humanizedISO8601DateTime, tryParse, + clientRelativePath, };