main
ts 43 lines 1.55 KB
Raw
1 import Koa from 'koa'
2 import { getLangData } from './lang'
3 import { getSection } from './customHtml'
4 import {
5 HTTP_FORBIDDEN, HTTP_MESSAGES, HTTP_NOT_FOUND, HTTP_TOO_MANY_REQUESTS, HTTP_UNAUTHORIZED, replace
6 } from './cross'
7
8 const declaredErrorPages = [HTTP_NOT_FOUND, HTTP_FORBIDDEN, HTTP_TOO_MANY_REQUESTS].map(String)
9
10 export function getErrorSections() {
11 return declaredErrorPages
12 }
13
14 // to be used with errors whose recipient is possibly human
15 export async function sendErrorPage(ctx: Koa.Context, code=ctx.status) {
16 ctx.type = 'text'
17 ctx.set('content-disposition', '') // reset ctx.attachment (or forceDownload)
18 ctx.status = code
19 let msg = HTTP_MESSAGES[ctx.status] || ''
20 if (!msg) return
21 const lang = await getLangData(ctx)
22 const trans = lang ? (Object.values(lang)[0] as any)?.translate : undefined
23 msg = trans?.[msg] ?? msg
24 const page = getSection(ctx.status === HTTP_UNAUTHORIZED ? 'unauthorized' : String(ctx.status))
25 || SIMPLE_PAGE || ''
26 if (page.includes('<'))
27 ctx.type = 'html'
28 ctx.body = replace(page, { MESSAGE: msg, HOME: trans?.home ?? 'home', URL: ctx.state.revProxyPath || '/' }, '$')
29 }
30
31 const SIMPLE_PAGE = `<!DOCTYPE html>
32 <html><head>
33 <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
34 <title>$MESSAGE</title>
35 <style>
36 body{margin-top:30vh; text-align:center; font-family:sans-serif;}
37 a{color:#68a}
38 @media (prefers-color-scheme:dark){body{background:#111; color:#999;}}
39 </style>
40 </head><body>
41 <h1>$MESSAGE</h1>
42 <h2><a href="$URL">$HOME</a></h2>
43 </body></html>`