index.ts (2615B)
1 import { ApiError, ERR_INTERNAL, ERR_INVALID_ACL, ERR_METHOD_NOT_ALLOWED, ERR_NOT_FOUND } from '@/lib/apierror' 2 import { withConnection } from '@/lib/model_helpers' 3 import { getWiki, getWikiViaSlug, updateWiki, WikiInfo } from '@/lib/models/wiki_info' 4 import { ACL_ACTION_MANAGE, ACL_ACTION_READ, resolveACL, validateACL } from '@/lib/security/acl' 5 import { authenticationFromCookies } from '@/lib/security/token' 6 import { getSlugAndPath } from '@/lib/utils/wiki' 7 import { NextApiRequest, NextApiResponse } from 'next' 8 9 interface PatchWikiBody { 10 title: string 11 description: string 12 acl: string 13 } 14 15 export default async function handler (req: NextApiRequest, res: NextApiResponse) { 16 switch (req.method) { 17 case 'GET': 18 await handleGet(req, res) 19 break 20 21 case 'PATCH': 22 await handlePatch(req, res) 23 break 24 25 default: 26 res.status(405).json(ERR_METHOD_NOT_ALLOWED) 27 break 28 } 29 } 30 31 export async function handleGet ( 32 req: NextApiRequest, 33 res: NextApiResponse<ApiError | { wiki: WikiInfo }>, 34 ) { 35 const [slug] = getSlugAndPath(req) 36 if (slug == null) { 37 res.status(404).json(ERR_NOT_FOUND) 38 return 39 } 40 41 const token = authenticationFromCookies(req.cookies) 42 43 const wiki = await getWikiViaSlug([slug]) 44 if (wiki == null) { 45 res.status(404).json(ERR_NOT_FOUND) 46 return 47 } 48 49 if (!resolveACL(token, wiki.acl, ACL_ACTION_READ)) { 50 res.status(404).json(ERR_NOT_FOUND) 51 return 52 } 53 54 res.status(200).json({ 55 wiki: wiki, 56 }) 57 } 58 59 export async function handlePatch ( 60 req: NextApiRequest, 61 res: NextApiResponse<ApiError | { wiki: WikiInfo }>, 62 ) { 63 const [slug] = getSlugAndPath(req) 64 if (slug == null) { 65 res.status(404).json(ERR_NOT_FOUND) 66 return 67 } 68 69 const token = authenticationFromCookies(req.cookies) 70 71 await withConnection(async (conn) => { 72 const wiki = await getWikiViaSlug(conn, [slug]) 73 if (wiki == null) { 74 res.status(404).json(ERR_NOT_FOUND) 75 return 76 } 77 78 if (!resolveACL(token, wiki.acl, ACL_ACTION_MANAGE)) { 79 res.status(404).json(ERR_NOT_FOUND) 80 return 81 } 82 83 const {title, description, acl} = req.body as PatchWikiBody 84 85 let aclData; 86 try { 87 aclData = JSON.parse(acl) 88 } catch (e) { 89 res.status(400).json(ERR_INVALID_ACL) 90 return 91 } 92 93 if (!validateACL(aclData)) { 94 res.status(400).json(ERR_INVALID_ACL) 95 return 96 } 97 98 try { 99 await updateWiki(conn, [title, description, acl, wiki.id]) 100 } catch (e) { 101 console.error(e) 102 res.status(500).json(ERR_INTERNAL) 103 return 104 } 105 106 res.status(200).json({ 107 wiki: wiki, 108 }) 109 }) 110 }