admin/config: favicon

Massimo Melina committed Feb 7, 2023 at 00:30 UTC ecbfd4311c6c244036ea585c3086bf325b3814ed
5 files changed +10 -4
README.md
+1
@@ -158,6 +158,7 @@ an *env* called `HFS_CONFIG`. Any relative path provided is relative to the *cwd
158 - `localhost_admin` should Admin be accessed without credentials when on localhost. Default is true.
159 - `proxies` number of proxies between server and clients to be trusted about providing clients' IP addresses. Default is 0.
160 - `keep_unfinished_uploads` should unfinished uploads be deleted immediately when interrupted. Default is true.
161 +- `favicon` path to file to be used as favicon. Default is none.
162
163 #### Virtual File System (VFS)
164
admin/src/ConfigPage.ts
+4 -2
@@ -122,9 +122,11 @@ export default function ConfigPage() {
122 helperText: "Leave empty to never delete" },
123 { k: 'min_available_mb', comp: NumberField, sm: 6, md: 3, min : 0, unit: "MBytes", placeholder: "None",
124 label: "Min. available disk space", helperText: "Reject uploads that don't comply" },
125 - { k: 'zip_calculate_size_for_seconds', comp: NumberField, sm: 12, md: 6, label: "Calculate ZIP size for", unit: "seconds",
125 + { k: 'zip_calculate_size_for_seconds', comp: NumberField, sm: 6, label: "Calculate ZIP size for", unit: "seconds",
126 helperText: "If time is not enough, the browser will not show download percentage" },
127 - { k: 'custom_header', multiline: true, sm: 12, sx: { '& textarea': { fontFamily: 'monospace' } },
127 + { k: 'favicon', comp: FileField, sm: 6, md: 6, fileMask: '*.png|*.ico|*.jpg|*.jpeg|*.gif|*.svg',
128 + helperText: "The icon associated to your website" },
129 + { k: 'custom_header', multiline: true, sm: 12, md: 6, sx: { '& textarea': { fontFamily: 'monospace' } },
130 helperText: "Any HTML code here will be displayed on top of the Frontend"
131 },
132 { k: 'mime', comp: StringStringField,
src/adminApis.ts
+1
@@ -152,6 +152,7 @@ for (const [k, was] of Object.entries(adminApis))
152 }
153
154 export const localhostAdmin = defineConfig('localhost_admin', true)
155 +export const favicon = defineConfig<string>('favicon')
156
157 export function ctxAdminAccess(ctx: Koa.Context) {
158 return !ctx.state.proxiedFor // we consider localhost_admin only if no proxy is detected
src/middlewares.ts
+4 -1
@@ -14,7 +14,7 @@ import { FRONTEND_URI } from './const'
14 import { cantReadStatusCode, hasPermission, nodeIsDirectory, urlToNode, vfs } from './vfs'
15 import { dirTraversal, objSameKeys, stream2string, tryJson } from './misc'
16 import { zipStreamFromFolder } from './zip'
17 -import { serveFileNode } from './serveFile'
17 +import { serveFile, serveFileNode } from './serveFile'
18 import { serveGuiFiles } from './serveGuiFiles'
19 import mount from 'koa-mount'
20 import { once, Readable } from 'stream'
@@ -28,6 +28,7 @@ import { basename, dirname } from 'path'
28 import { pipeline } from 'stream/promises'
29 import formidable from 'formidable'
30 import { uploadWriter } from './upload'
31 +import { favicon } from './adminApis'
32
33 export const gzipper = compress({
34 threshold: 2048,
@@ -99,6 +100,8 @@ export const serveGuiAndSharedFiles: Koa.Middleware = async (ctx, next) => {
100 }
101 return
102 }
103 + if (ctx.originalUrl === '/favicon.ico' && favicon.get()) // originalUrl to not be subject to changes (vhosting plugin)
104 + return serveFile(favicon.get())(ctx,next)
105 const node = await urlToNode(path, ctx)
106 if (!node)
107 return ctx.status = HTTP_NOT_FOUND
todo.md
-1
@@ -1,5 +1,4 @@
1 # To do
2 -- config: favicon https://github.com/rejetto/hfs/discussions/94
2 - admin/fs: check if source exists when set
3 - plugins: after installing, switch to installed (and perhaps highlight new one)
4 - plugins' log, accessible in admin