serve customized "unauthorized" page if authentication on protected file fails
Massimo Melina committed
Feb 7, 2024 at 19:18 UTC
aa9548567f57f5b8fc299e7760775d98f8941bc3
2 files changed
+4
-4
src/errorPages.ts
+3
-3
@@ -1,7 +1,7 @@
1
import Koa from 'koa'
2
import { getLangData } from './lang'
3
import { getSection } from './customHtml'
4
-import { HTTP_FORBIDDEN, HTTP_MESSAGES, HTTP_NOT_FOUND, HTTP_TOO_MANY_REQUESTS } from './cross'
4
+import { HTTP_FORBIDDEN, HTTP_MESSAGES, HTTP_NOT_FOUND, HTTP_TOO_MANY_REQUESTS, HTTP_UNAUTHORIZED } from './cross'
5
6
const declaredErrorPages = [HTTP_NOT_FOUND, HTTP_FORBIDDEN, HTTP_TOO_MANY_REQUESTS].map(String)
7
@@ -10,7 +10,7 @@ export function getErrorSections() {
10
}
11
12
// to be used with errors whose recipient is possibly human
13
-export async function sendErrorPage(ctx: Koa.Context, code: number) {
13
+export async function sendErrorPage(ctx: Koa.Context, code=ctx.status) {
14
ctx.type = 'text'
15
ctx.set('content-disposition', '') // reset ctx.attachment
16
ctx.status = code
@@ -20,7 +20,7 @@ export async function sendErrorPage(ctx: Koa.Context, code: number) {
20
if (!lang) return
21
const trans = (Object.values(lang)[0] as any)?.translate
22
ctx.body = trans?.[msg] ?? msg
23
- const errorPage = getSection(String(ctx.status))
23
+ const errorPage = getSection(ctx.status === HTTP_UNAUTHORIZED ? 'unauthorized' : String(ctx.status))
24
if (!errorPage) return
25
if (errorPage.includes('<'))
26
ctx.type = 'html'
src/serveGuiAndSharedFiles.ts
+1
-1
@@ -84,7 +84,7 @@ export const serveGuiAndSharedFiles: Koa.Middleware = async (ctx, next) => {
84
return !node.source ? sendErrorPage(ctx, HTTP_METHOD_NOT_ALLOWED)
85
: !statusCodeForMissingPerm(node, 'can_read', ctx) ? serveFileNode(ctx, node)
86
: ctx.status !== HTTP_UNAUTHORIZED ? null
87
- : !path.endsWith('/') ? ctx.set('WWW-Authenticate', 'Basic') // this is necessary to support standard urls with credentials. Final / means we are dealing with default file...
87
+ : !path.endsWith('/') ? (ctx.set('WWW-Authenticate', 'Basic'), sendErrorPage(ctx)) // this is necessary to support standard urls with credentials. Final / means we are dealing with default file...
88
: (ctx.state.serveApp = true) && serveFrontendFiles(ctx, next) // ...for which we still provide fancy login
89
if (!path.endsWith('/'))
90
return ctx.redirect(ctx.state.revProxyPath + ctx.originalUrl.replace(/(\?|$)/, '/$1')) // keep query-string, if any