@samitouri / QOSami-HFS / commits / 1e2a21b4

better code

Massimo Melina committed May 4, 2024 at 23:59 UTC 1e2a21b46741adb6d501a88595d053c3d60706af
7 files changed +26 -33
admin/src/index.ts
-4
@@ -5,10 +5,6 @@ import { createRoot } from 'react-dom/client'
5 import './index.scss'
6 import '@hfs/shared/min-crypto-polyfill'
7 import App from './App'
8 -import { disableConsoleDebug } from '@hfs/shared'
9 -
10 -//@ts-ignore
11 -if (import.meta.env.PROD) disableConsoleDebug()
8
9 createRoot(document.getElementById('root')!)
10 .render( h(StrictMode, {}, h(App)) )
frontend/src/index.ts
-4
@@ -6,10 +6,6 @@ import './index.scss'
6 import '@hfs/shared/min-crypto-polyfill'
7 import '@hfs/shared/polyfills'
8 import App from './App'
9 -import { disableConsoleDebug } from '@hfs/shared'
10 -
11 -//@ts-ignore
12 -if (import.meta.env.PROD) disableConsoleDebug()
9
10 createRoot(document.getElementById('root')!)
11 .render( h(StrictMode, {}, h(App)) )
shared/index.ts
+6 -5
@@ -29,6 +29,12 @@ Object.assign(HFS, {
29 cpuSpeedIndex,
30 })
31
32 +//@ts-ignore
33 +if (import.meta.env.PROD) {
34 + const was = console.debug
35 + console.debug = (...args) => (window as any).DEV && was(...args)
36 +}
37 +
38 function getScriptAttr(k: string) {
39 return document.currentScript?.getAttribute(k)
40 || console.error("this function must be called at the very top of your file")
@@ -114,11 +120,6 @@ export function focusSelector(selector: string, root: HTMLElement | Document=doc
120 }
121 }
122
117 -export function disableConsoleDebug() {
118 - const was = console.debug
119 - console.debug = (...args) => (window as any).DEV && was(...args)
120 -}
121 -
123 export function loadScript(url: string, more={}) {
124 const el = document.createElement('script')
125 el.type = 'text/javascript'
src/api.auth.ts
+2 -2
@@ -28,7 +28,7 @@ export const loginSrp1: ApiHandler = async ({ username }, ctx) => {
28 const sid = Math.random()
29 ongoingLogins[sid] = step1
30 setTimeout(()=> delete ongoingLogins[sid], 60_000)
31 - ctx.session.loggingIn = { username, sid }
31 + ctx.session.loggingIn = { username, sid } // temporarily store until process is complete
32 return rest
33 }
34 catch (code: any) {
@@ -42,13 +42,13 @@ export const loginSrp2: ApiHandler = async ({ pubKey, proof }, ctx) => {
42 if (!ctx.session.loggingIn)
43 return new ApiError(HTTP_CONFLICT)
44 const { username, sid } = ctx.session.loggingIn
45 + delete ctx.session.loggingIn
46 const step1 = ongoingLogins[sid]
47 if (!step1)
48 return new ApiError(HTTP_NOT_FOUND)
49 try {
50 const M2 = await step1.step2(BigInt(pubKey), BigInt(proof))
51 await setLoggedIn(ctx, username)
51 - delete ctx.session.loggingIn
52 return {
53 proof: String(M2),
54 redirect: ctx.state.account?.redirect,
src/plugins.ts
+3 -3
@@ -217,12 +217,12 @@ export class Plugin implements CommonPluginInterface {
217 }
218 }
219
220 -const SERVER_CODE_ID = '.'
220 +export const SERVER_CODE_ID = '.' // a name that will surely be not found among plugin folders
221 const serverCode = defineConfig('server_code', '', async (script, { k }) => {
222 const res: any = {}
223 try {
224 new Function('exports', script)(res) // parse
225 - return new Plugin(SERVER_CODE_ID, '', await initPlugin(res), _.noop) // '.' is a name that will surely be not found among plugin folders
225 + return new Plugin(SERVER_CODE_ID, '', await initPlugin(res), _.noop)
226 }
227 catch (e: any) {
228 return console.error(k + ':', e.message || String(e))
@@ -246,7 +246,7 @@ type PluginMiddleware = (ctx:Koa.Context) => Promisable<void | Stop | CallMeAfte
246 type Stop = true
247 type CallMeAfter = ()=>any
248
249 -export type Repo = string | { web?: string, main: string, zip?: string, zipRoot?: string }
249 +export type Repo = string | { web?: string, main: string, zip?: string, zipRoot?: string } // string is github, object is custom
250 type Depend = { repo: string, version?: number }[]
251 export interface CommonPluginInterface {
252 id: string
src/serveGuiFiles.ts
+5 -5
@@ -73,7 +73,7 @@ async function treatIndex(ctx: Koa.Context, filesUri: string, body: string) {
73 ctx.set('Cache-Control', 'no-store, no-cache, must-revalidate')
74 ctx.type = 'html'
75
76 - const isFrontend = filesUri === FRONTEND_URI
76 + const isFrontend = filesUri === FRONTEND_URI ? ' ' : '' // as a string will allow neater code later
77
78 const pub = ctx.state.revProxyPath + PLUGINS_PUB_URI
79
@@ -96,7 +96,7 @@ async function treatIndex(ctx: Koa.Context, filesUri: string, body: string) {
96 const isOpen = !isClose
97 if (isHead && isOpen)
98 return all + `
99 - ${!isFrontend ? '' : `
99 + ${isFrontend && `
100 <title>${title.get()}</title>
101 <link rel="shortcut icon" href="/favicon.ico?${timestamp}" />
102 ` + getSection('htmlHead')}
@@ -120,14 +120,14 @@ async function treatIndex(ctx: Koa.Context, filesUri: string, body: string) {
120 `
121 if (isBody && isOpen)
122 return all + `
123 - ${!isFrontend ? '' : getSection('top')}
123 + ${isFrontend && getSection('top')}
124 <style>
125 :root {
126 - ${_.map(plugins, (configs, pluginName) =>
126 + ${_.map(plugins, (configs, pluginName) => // make plugin configs accessible via css
127 _.map(configs, (v,k) => `--${pluginName}-${k}: ${serializeCss(v)};`).join('\n')).join('')}
128 }
129 </style>
130 - ${!isFrontend ? '' : mapPlugins((plug,id) =>
130 + ${isFrontend && mapPlugins((plug,id) =>
131 plug.frontend_css?.map(f =>
132 `<link rel='stylesheet' type='text/css' href='${f.includes('//') ? f : pub + id + '/' + f}' plugin=${JSON.stringify(id)}/>`))
133 .flat().filter(Boolean).join('\n')}
src/throttler.ts
+10 -10
@@ -17,13 +17,17 @@ defineConfig('max_kbps', Infinity).sub(v =>
17 const ip2group: Record<string, {
18 count: number
19 group: ThrottleGroup
20 - destroy: () => void
20 }> = {}
21
22 const SymThrStr = Symbol('stream')
23 const SymTimeout = Symbol('timeout')
24
25 const maxKbpsPerIp = defineConfig('max_kbps_per_ip', Infinity)
26 +maxKbpsPerIp.sub(v => {
27 + for (const [ip, {group}] of Object.entries(ip2group))
28 + if (ip) // empty-string = unlimited group
29 + group.updateLimit(v)
30 +})
31
32 export const throttler: Koa.Middleware = async (ctx, next) => {
33 await next()
@@ -34,14 +38,11 @@ export const throttler: Koa.Middleware = async (ctx, next) => {
38 if (!body || !(body instanceof Readable))
39 return
40 // we wrap the stream also for unlimited connections to get speed and other features
37 - const ipGroup = getOrSet(ip2group, ctx.ip, ()=> {
38 - const doLimit = ctx.state.account?.ignore_limits || isLocalHost(ctx) ? undefined : true
39 - const group = new ThrottleGroup(Infinity, doLimit && mainThrottleGroup)
40 -
41 - const unsub = doLimit && maxKbpsPerIp.sub(v =>
42 - group.updateLimit(v))
43 - return { group, count:0, destroy: unsub }
44 - })
41 + const noLimit = ctx.state.account?.ignore_limits || isLocalHost(ctx)
42 + const ipGroup = getOrSet(ip2group, noLimit ? '' : ctx.ip, () => ({
43 + count:0,
44 + group: new ThrottleGroup(noLimit ? Infinity : maxKbpsPerIp.get(), noLimit ? undefined : mainThrottleGroup),
45 + }))
46 const conn = getConnection(ctx)
47 if (!conn) throw 'assert throttler connection'
48
@@ -72,7 +73,6 @@ export const throttler: Koa.Middleware = async (ctx, next) => {
73 update.flush()
74 closed = true
75 if (--ipGroup.count) return // any left?
75 - ipGroup.destroy?.()
76 delete ip2group[ctx.ip]
77 })
78