dh_demo

DreamHanks demo project
git clone git://git.lair.cx/dh_demo
Log | Files | Refs | README

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 }