diff --git a/src/endpoints/content-manager.js b/src/endpoints/content-manager.js index 6cebf53b7..7102637f5 100644 --- a/src/endpoints/content-manager.js +++ b/src/endpoints/content-manager.js @@ -540,9 +540,21 @@ async function downloadGenericPng(url) { if (result.ok) { const buffer = Buffer.from(await result.arrayBuffer()); - const fileName = sanitize(result.url.split('?')[0].split('/').reverse()[0]); + let fileName = sanitize(result.url.split('?')[0].split('/').reverse()[0]); const contentType = result.headers.get('content-type') || 'image/png'; //yoink it from AICC function lol + // The `importCharacter()` function detects the MIME (content-type) of the file + // using its file extension. The problem is that not all third-party APIs serve + // their cards with a `.png` extension. To support more third-party sites, + // dynamically append the `.png` extension to the filename if it doesn't + // already have a file extension. + if (contentType === 'image/png') { + const ext = fileName.match(/\.(\w+)$/); // Same regex used by `importCharacter()` + if (!ext) { + fileName += '.png'; + } + } + return { buffer: buffer, fileName: fileName, @@ -694,10 +706,12 @@ router.post('/importURL', async (request, response) => { type = 'character'; result = await downloadRisuCharacter(uuid); } else if (isGeneric) { - console.info('Downloading from generic url.'); + console.info('Downloading from generic url:', url); type = 'character'; result = await downloadGenericPng(url); } else { + const receivedURL = new URL(url); + console.error(`Received an import for "${receivedURL.host}", but site is not whitelisted. This domain must be added to the config key "whitelistImportDomains" to allow import from this source.`); return response.sendStatus(404); }