릴리스: v1.2.26 관리자 회원 관리와 셸 UI 개선

This commit is contained in:
2026-03-31 14:17:19 +09:00
parent df46e43da5
commit ba6ad0593a
25 changed files with 1944 additions and 733 deletions

View File

@@ -61,6 +61,14 @@ const upload = multer({
limits: { fileSize: 6 * 1024 * 1024 },
})
const avatarUpload = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => cb(null, path.join(__dirname, '..', '..', 'uploads', 'avatars')),
filename: (req, file, cb) => cb(null, buildUploadFilename(file)),
}),
limits: { fileSize: 3 * 1024 * 1024 },
})
router.post('/games', requireAdmin, async (req, res) => {
const schema = z.object({ id: z.string().min(1), name: z.string().min(1).max(60) })
const parsed = schema.safeParse(req.body)
@@ -494,6 +502,29 @@ router.patch('/users/:userId', requireAdmin, async (req, res) => {
}
})
router.post('/users/:userId/avatar', requireAdmin, avatarUpload.single('avatar'), async (req, res) => {
const schema = z.object({
removeAvatar: z.union([z.literal('1'), z.undefined()]).optional(),
})
const parsed = schema.safeParse(req.body)
if (!parsed.success) return res.status(400).json({ error: 'bad_request' })
const user = await findUserById(req.params.userId)
if (!user) return res.status(404).json({ error: 'not_found' })
const shouldRemoveAvatar = parsed.data.removeAvatar === '1'
const nextAvatarSrc = shouldRemoveAvatar ? '' : req.file ? `/uploads/avatars/${req.file.filename}` : user.avatarSrc || ''
const updated = await adminUpdateUser({
id: user.id,
email: user.email,
nickname: user.nickname || '',
isAdmin: !!user.isAdmin,
avatarSrc: nextAvatarSrc,
})
res.json({ user: updated })
})
router.delete('/users/:userId', requireAdmin, async (req, res) => {
if (req.params.userId === req.session.userId) {
return res.status(400).json({ error: 'cannot_delete_self' })