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, getChipsBalance, adjustChipsBalance, resetChipsBalance } 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 }); }); }); router.get('/chips', requireAuth, (req, res) => { res.json({ chips: getChipsBalance(req.user.id) }); }); router.post('/chips/adjust', requireAuth, (req, res) => { const { delta } = req.body ?? {}; if (typeof delta !== 'number' || !Number.isInteger(delta)) { return res.status(400).json({ error: 'delta must be an integer.' }); } const chips = adjustChipsBalance(req.user.id, delta); res.json({ chips }); }); router.post('/chips/reset', requireAuth, (req, res) => { try { const chips = resetChipsBalance(req.user.id); res.json({ chips }); } catch (err) { res.status(err.status ?? 500).json({ error: err.message }); } }); export default router;