Merge commit from fork

232cf6d8255e772a55f64d965c6beb85cfbe931d

Cohee <18619528+Cohee1207@users.noreply.github.com>

Signed
2 files changed, +35 -23Ignore whitespace
src/endpoints/assets.js+33 -21
@@ -8,7 +8,8 @@ import sanitize from 'sanitize-filename';
8import fetch from 'node-fetch';8import fetch from 'node-fetch';
99
10import { UNSAFE_EXTENSIONS } from '../constants.js';10import { UNSAFE_EXTENSIONS } from '../constants.js';
11import { clientRelativePath } from '../util.js';11import { clientRelativePath, isValidUrl } from '../util.js';
12import { getHostFromUrl, isHostWhitelisted } from './content-manager.js';
1213
13const VALID_CATEGORIES = ['bgm', 'ambient', 'blip', 'live2d', 'vrm', 'character', 'temp'];14const VALID_CATEGORIES = ['bgm', 'ambient', 'blip', 'live2d', 'vrm', 'character', 'temp'];
1415
@@ -189,31 +190,42 @@ router.post('/get', async (request, response) => {
189 * @returns {void}190 * @returns {void}
190 */191 */
191router.post('/download', async (request, response) => {192router.post('/download', async (request, response) => {
192 const url = request.body.url;193 try {
193 const inputCategory = request.body.category;194 if (!isValidUrl(request.body.url)) {
195 console.warn('Asset download failed: Must be a valid URL');
196 return response.sendStatus(400);
197 }
194198
195 // Check category199 const url = String(request.body.url);
196 let category = null;200 const inputCategory = request.body.category;
197 for (let i of VALID_CATEGORIES)
198 if (i == inputCategory)
199 category = i;
200201
201 if (category === null) {202 const host = getHostFromUrl(url);
202 console.error('Bad request: unsupported asset category.');203 if (!isHostWhitelisted(host)) {
203 return response.sendStatus(400);204 console.error(`Received an import for "${host}", but site is not whitelisted. This domain must be added to the config key "whitelistImportDomains" to allow import from this source.`);
204 }205 return response.sendStatus(404);
206 }
205207
206 // Validate filename208 // Check category
207 ensureFoldersExist(request.user.directories);209 let category = null;
208 const validation = validateAssetFileName(request.body.filename);210 for (let i of VALID_CATEGORIES)
209 if (validation.error)211 if (i == inputCategory)
210 return response.status(400).send(validation.message);212 category = i;
211213
212 const temp_path = path.join(request.user.directories.assets, 'temp', request.body.filename);214 if (category === null) {
213 const file_path = path.join(request.user.directories.assets, category, request.body.filename);215 console.error('Bad request: unsupported asset category.');
214 console.info('Request received to download', url, 'to', file_path);216 return response.sendStatus(400);
217 }
218
219 // Validate filename
220 ensureFoldersExist(request.user.directories);
221 const validation = validateAssetFileName(request.body.filename);
222 if (validation.error)
223 return response.status(400).send(validation.message);
224
225 const temp_path = path.join(request.user.directories.assets, 'temp', request.body.filename);
226 const file_path = path.join(request.user.directories.assets, category, request.body.filename);
227 console.info('Request received to download', url, 'to', file_path);
215228
216 try {
217 // Download to temp229 // Download to temp
218 const res = await fetch(url);230 const res = await fetch(url);
219 if (!res.ok || res.body === null) {231 if (!res.ok || res.body === null) {
src/endpoints/content-manager.js+2 -2
@@ -872,7 +872,7 @@ function getUuidFromUrl(url) {
872 * @param {String} url URL to strip872 * @param {String} url URL to strip
873 * @returns {String} Domain name873 * @returns {String} Domain name
874 */874 */
875function getHostFromUrl(url) {875export function getHostFromUrl(url) {
876 try {876 try {
877 const urlObj = new URL(url);877 const urlObj = new URL(url);
878 return urlObj.hostname;878 return urlObj.hostname;
@@ -886,7 +886,7 @@ function getHostFromUrl(url) {
886 * @param {String} host Host to check886 * @param {String} host Host to check
887 * @returns {boolean} If the host is on the whitelist.887 * @returns {boolean} If the host is on the whitelist.
888 */888 */
889function isHostWhitelisted(host) {889export function isHostWhitelisted(host) {
890 return WHITELIST_GENERIC_URL_DOWNLOAD_SOURCES.includes(host);890 return WHITELIST_GENERIC_URL_DOWNLOAD_SOURCES.includes(host);
891}891}
892892