79 lines
2.4 KiB
JavaScript
79 lines
2.4 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, 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;
|