fertig-classic-games/server/profile/routes.js

57 lines
1.7 KiB
JavaScript

import fs from 'node:fs';
import path from 'node:path';
import crypto from 'node:crypto';
import { Router } from 'express';
import multer from 'multer';
import config from '../config.js';
import { requireAuth } from '../auth/middleware.js';
import { getProfile, setAvatarPath, updateProfile } from './service.js';
fs.mkdirSync(config.uploads.dir, { recursive: true });
const storage = multer.diskStorage({
destination(_req, _file, cb) {
cb(null, config.uploads.dir);
},
filename(req, file, cb) {
const ext = path.extname(file.originalname).toLowerCase().slice(0, 8) || '';
const random = crypto.randomBytes(8).toString('hex');
cb(null, `u${req.user.id}-${Date.now()}-${random}${ext}`);
},
});
const upload = multer({
storage,
limits: { fileSize: config.uploads.maxSizeMb * 1024 * 1024 },
fileFilter(_req, file, cb) {
if (!config.uploads.allowedMime.includes(file.mimetype)) {
return cb(new Error('Unsupported image type.'));
}
cb(null, true);
},
});
const router = Router();
router.get('/', requireAuth, (req, res) => {
res.json({ profile: getProfile(req.user.id) });
});
router.patch('/', requireAuth, (req, res) => {
const { displayName, bio } = req.body ?? {};
const profile = updateProfile(req.user.id, { displayName, bio });
res.json({ profile });
});
router.post('/avatar', requireAuth, (req, res, next) => {
upload.single('avatar')(req, res, (err) => {
if (err) return res.status(400).json({ error: err.message });
if (!req.file) return res.status(400).json({ error: 'No file uploaded.' });
const publicPath = `/uploads/${path.basename(req.file.path)}`;
const profile = setAvatarPath(req.user.id, publicPath);
res.json({ profile });
});
});
export default router;