Introduce granular role-based permissions with SuperAdmin env override, admin roles UI, and permission-gated API routes. Fix admin user Nostr metadata by batching relay profile fetches, normalizing npub pubkeys to hex, and adding reusable NostrAvatar/useNostrProfile components. Co-authored-by: Cursor <cursoragent@cursor.com>
69 lines
2.0 KiB
TypeScript
69 lines
2.0 KiB
TypeScript
import { Router, Request, Response } from 'express';
|
|
import { prisma } from '../db/prisma';
|
|
import { requireAuth, requires } from '../middleware/auth';
|
|
|
|
const router = Router();
|
|
|
|
router.use(requireAuth, requires('board.manage'));
|
|
|
|
router.get('/', async (_req: Request, res: Response) => {
|
|
try {
|
|
const messages = await prisma.boardMessage.findMany({
|
|
orderBy: { createdAt: 'desc' },
|
|
});
|
|
res.json(messages);
|
|
} catch (err) {
|
|
console.error('Admin list board messages error:', err);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
/** Toggle active <-> hidden */
|
|
router.post('/:id/hide', async (req: Request, res: Response) => {
|
|
try {
|
|
const rawId = req.params.id;
|
|
const id = Array.isArray(rawId) ? rawId[0] : rawId;
|
|
const msg = await prisma.boardMessage.findUnique({ where: { id } });
|
|
if (!msg) {
|
|
res.status(404).json({ error: 'Not found' });
|
|
return;
|
|
}
|
|
if (msg.status === 'deleted') {
|
|
res.status(400).json({ error: 'Message is deleted' });
|
|
return;
|
|
}
|
|
const next = msg.status === 'hidden' ? 'active' : 'hidden';
|
|
const updated = await prisma.boardMessage.update({
|
|
where: { id: msg.id },
|
|
data: { status: next },
|
|
});
|
|
res.json(updated);
|
|
} catch (err) {
|
|
console.error('Admin hide board message error:', err);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
/** Soft-delete */
|
|
router.delete('/:id', async (req: Request, res: Response) => {
|
|
try {
|
|
const rawId = req.params.id;
|
|
const id = Array.isArray(rawId) ? rawId[0] : rawId;
|
|
const msg = await prisma.boardMessage.findUnique({ where: { id } });
|
|
if (!msg) {
|
|
res.status(404).json({ error: 'Not found' });
|
|
return;
|
|
}
|
|
const updated = await prisma.boardMessage.update({
|
|
where: { id: msg.id },
|
|
data: { status: 'deleted' },
|
|
});
|
|
res.json(updated);
|
|
} catch (err) {
|
|
console.error('Admin delete board message error:', err);
|
|
res.status(500).json({ error: 'Internal server error' });
|
|
}
|
|
});
|
|
|
|
export default router;
|