| import path from 'node:path'; |
| import fs from 'node:fs'; |
|
|
| import express from 'express'; |
| import sanitize from 'sanitize-filename'; |
| import { Jimp } from '../jimp.js'; |
| import { sync as writeFileAtomicSync } from 'write-file-atomic'; |
|
|
| import { getImages, tryParse } from '../util.js'; |
| import { getFileNameValidationFunction } from '../middleware/validateFileName.js'; |
| import { applyAvatarCropResize } from './characters.js'; |
| import { invalidateThumbnail } from './thumbnails.js'; |
| import cacheBuster from '../middleware/cacheBuster.js'; |
|
|
| export const router = express.Router(); |
|
|
| router.post('/get', function (request, response) { |
| const images = getImages(request.user.directories.avatars); |
| response.send(images); |
| }); |
|
|
| router.post('/delete', getFileNameValidationFunction('avatar'), function (request, response) { |
| if (!request.body) return response.sendStatus(400); |
|
|
| if (request.body.avatar !== sanitize(request.body.avatar)) { |
| console.error('Malicious avatar name prevented'); |
| return response.sendStatus(403); |
| } |
|
|
| const fileName = path.join(request.user.directories.avatars, sanitize(request.body.avatar)); |
|
|
| if (fs.existsSync(fileName)) { |
| fs.unlinkSync(fileName); |
| invalidateThumbnail(request.user.directories, 'persona', sanitize(request.body.avatar)); |
| return response.send({ result: 'ok' }); |
| } |
|
|
| return response.sendStatus(404); |
| }); |
|
|
| router.post('/upload', getFileNameValidationFunction('overwrite_name'), async (request, response) => { |
| if (!request.file) return response.sendStatus(400); |
|
|
| try { |
| const pathToUpload = path.join(request.file.destination, request.file.filename); |
| const crop = tryParse(request.query.crop); |
| const rawImg = await Jimp.read(pathToUpload); |
| const image = await applyAvatarCropResize(rawImg, crop); |
|
|
| |
| if (request.body.overwrite_name) { |
| invalidateThumbnail(request.user.directories, 'persona', sanitize(request.body.overwrite_name)); |
| cacheBuster.bust(request, response); |
| } |
|
|
| const filename = sanitize(request.body.overwrite_name || `${Date.now()}.png`); |
| const pathToNewFile = path.join(request.user.directories.avatars, filename); |
| writeFileAtomicSync(pathToNewFile, image); |
| fs.unlinkSync(pathToUpload); |
| return response.send({ path: filename }); |
| } catch (err) { |
| console.error('Error uploading user avatar:', err); |
| return response.status(400).send('Is not a valid image'); |
| } |
| }); |
|
|