@samitouri / QOSami-HFS / commits / aa954856

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