[...path].ts (2222B)
1 import { 2 ApiError, 3 ERR_FORBIDDEN, 4 ERR_INVALID_REQUEST, 5 ERR_METHOD_NOT_ALLOWED, 6 ERR_NOT_FOUND, 7 ERR_UNAUTHORIZED, 8 } from '@/lib/apierror' 9 import { withConnection } from '@/lib/model_helpers' 10 import { createThreadComment } from '@/lib/models/thread' 11 import { getWikiAndPageACLViaPath } from '@/lib/models/wiki_acl' 12 import { createWikiTalk } from '@/lib/models/wiki_talk' 13 import { ACL_ACTION_CREATE_THREAD, resolveACL } from '@/lib/security/acl' 14 import { authenticationFromCookies } from '@/lib/security/token' 15 import { NextApiRequest, NextApiResponse } from 'next' 16 17 export interface CreateTalkRequest { 18 title?: string 19 content?: string 20 } 21 22 export interface CreateTalkResponse { 23 thread: number 24 } 25 26 export default function handler ( 27 req: NextApiRequest, 28 res: NextApiResponse, 29 ) { 30 switch (req.method) { 31 case 'POST': 32 return handlePost(req, res) 33 default: 34 res.status(405).json(ERR_METHOD_NOT_ALLOWED) 35 } 36 } 37 38 async function handlePost ( 39 req: NextApiRequest, 40 res: NextApiResponse<CreateTalkResponse | ApiError>, 41 ) { 42 const token = await authenticationFromCookies(req.cookies) 43 const uid = token?.uid 44 if (uid == null) { 45 res.status(401).json(ERR_UNAUTHORIZED) 46 return 47 } 48 49 const { slug, path: paths } = req.query 50 if (typeof slug !== 'string' || !Array.isArray(paths)) { 51 res.status(400).json(ERR_INVALID_REQUEST) 52 return 53 } 54 55 const path = paths.join('/') 56 57 const { title, content } = req.body as CreateTalkRequest 58 if (typeof title !== 'string' || typeof content !== 'string') { 59 res.status(400).json(ERR_INVALID_REQUEST) 60 return 61 } 62 63 await withConnection(async conn => { 64 // ACL Check 65 const aclInfo = await getWikiAndPageACLViaPath(conn, [slug, path]) 66 if (aclInfo == null || aclInfo.pageId == null) { 67 res.status(404).json(ERR_NOT_FOUND) 68 return 69 } 70 71 if (!resolveACL(token, [aclInfo.wiki, aclInfo.page], ACL_ACTION_CREATE_THREAD)) { 72 res.status(403).json(ERR_FORBIDDEN) 73 return 74 } 75 76 // 새 토론과 첫 댓글 만듦 77 const threadId = await createWikiTalk(conn, [aclInfo.pageId, uid, title]) 78 await createThreadComment(conn, [threadId, uid, content]) 79 80 res.status(200).json({ thread: threadId }) 81 }) 82 }