version exposed to frontend js+css

Massimo Melina committed Feb 26, 2023 at 15:26 UTC bafb99196f8b345c6d349cdc8acf54708d2cdbd8
3 files changed +38 -27
admin/index.html
+3 -5
@@ -2,16 +2,14 @@
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8" />
5 - <link rel="icon" type="image/svg+xml" href="/hfs-logo-icon.svg" />
5 <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6 <script async src='https://unpkg.com/node-forge@1.3.1/dist/forge.min.js'></script>
8 - <script>HFS = {
9 - session: _HFS_SESSION_
10 - }</script>
7 <title>HFS Admin</title>
8 + <script type="module" src="/src/index.ts"></script>
9 + <HFS/>
10 + <link rel="icon" type="image/svg+xml" href="/hfs-logo-icon.svg" />
11 </head>
12 <body>
13 <div id="root"></div>
15 - <script type="module" src="/src/index.ts"></script>
14 </body>
15 </html>
frontend/index.html
+2 -7
@@ -4,16 +4,11 @@
4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=0" />
6 <link href="/fontello.css" rel="stylesheet" />
7 - <link rel="icon"/>
8 - <script>HFS = {
9 - session: _HFS_SESSION_
10 - }</script>
11 - <title>_HFS_TITLE_</title>
7 + <script type="module" src="/src/index.ts"></script>
8 + <HFS/>
9 </head>
10 <body>
11 <noscript>You need to enable JavaScript to run this app.</noscript>
15 - <script type="module" src="/src/index.ts"></script>
12 <div id="root"></div>
17 - <div hidden>_HFS_PLUGINS_</div>
13 </body>
14 </html>
src/serveGuiFiles.ts
+33 -15
@@ -2,7 +2,15 @@
2
3 import Koa from 'koa'
4 import fs from 'fs/promises'
5 -import { HTTP_METHOD_NOT_ALLOWED, HTTP_NO_CONTENT, HTTP_NOT_FOUND, PLUGINS_PUB_URI } from './const'
5 +import {
6 + API_VERSION,
7 + FRONTEND_URI,
8 + HTTP_METHOD_NOT_ALLOWED,
9 + HTTP_NO_CONTENT,
10 + HTTP_NOT_FOUND,
11 + PLUGINS_PUB_URI,
12 + VERSION
13 +} from './const'
14 import { serveFile } from './serveFile'
15 import { mapPlugins } from './plugins'
16 import { refresh_session } from './api.auth'
@@ -56,13 +64,32 @@ function adjustBundlerLinks(path: string, uri: string, data: string | Buffer) {
64 async function treatIndex(ctx: Koa.Context, body: string, filesUri: string) {
65 const session = await refresh_session({}, ctx)
66 ctx.set('etag', '')
67 +
68 + const isFrontend = filesUri === FRONTEND_URI
69 +
70 + const css = mapPlugins((plug,k) =>
71 + (isFrontend ? plug.frontend_css : null)?.map(f => PLUGINS_PUB_URI + k + '/' + f)).flat().filter(Boolean)
72 + const js = mapPlugins((plug,k) =>
73 + (isFrontend ? plug.frontend_js : null)?.map(f => PLUGINS_PUB_URI + k + '/' + f)).flat().filter(Boolean)
74 +
75 return body
76 .replace(/((?:src|href) *= *['"])\/?(?![a-z]+:\/\/)/g, '$1' + filesUri)
61 - .replace('<link rel="icon"/>', `<link rel="icon" href="${favicon.get() ? '/favicon.ico' : 'data:;'}" />`)
62 - .replace('_HFS_TITLE_', title.get())
63 - .replace('_HFS_SESSION_', session instanceof ApiError ? 'null' : JSON.stringify(session))
64 - // replacing this text allow us to avoid injecting in frontends that don't support plugins. Don't use a <--comment--> or it will be removed by webpack
65 - .replace('_HFS_PLUGINS_', pluginsInjection)
77 + .replace('<HFS/>', () => `
78 + ${!isFrontend ? '' : `
79 + <title>${title.get()}</title>
80 + <link rel="icon" href="${favicon.get() ? '/favicon.ico' : 'data:;'}" />
81 + `}
82 + <script>
83 + HFS = ${JSON.stringify({
84 + VERSION,
85 + API_VERSION,
86 + session: session instanceof ApiError ? null : session,
87 + }, null, 4)}
88 + document.documentElement.setAttribute('ver', '${VERSION.split('-')[0] /*for style selectors*/}')
89 + </script>
90 + ${css.map(uri => `<link rel='stylesheet' type='text/css' href='${uri}'/>`).join('\n')}
91 + ${js.map(uri => `<script defer src='${uri}'></script>`).join('\n')}
92 + `)
93 }
94
95 function serveProxied(port: string | undefined, uri: string) { // used for development only
@@ -84,15 +111,6 @@ function serveProxied(port: string | undefined, uri: string) { // used for devel
111 }
112 }
113
87 -function pluginsInjection() {
88 - const css = mapPlugins((plug,k) =>
89 - plug.frontend_css?.map(f => PLUGINS_PUB_URI + k + '/' + f)).flat().filter(Boolean)
90 - const js = mapPlugins((plug,k) =>
91 - plug.frontend_js?.map(f => PLUGINS_PUB_URI + k + '/' + f)).flat().filter(Boolean)
92 - return css.map(uri => `\n<link rel='stylesheet' type='text/css' href='${uri}'/>`).join('')
93 - + js.map(uri => `\n<script defer src='${uri}'></script>`).join('')
94 -}
95 -
114 export function serveGuiFiles(proxyPort:string | undefined, uri:string) {
115 return serveProxied(proxyPort, uri) || serveStatic(uri)
116 }