@samitouri / QOSami-HFS / commits / 5a848d30

admin/home: detect cloudflare and advice configuration

Massimo Melina committed Sep 19, 2024 at 16:06 UTC 5a848d30fd845d906c4a15cfeea86ac830708a86
3 files changed +12 -6
admin/src/HomePage.ts
+7 -5
@@ -4,7 +4,7 @@ import { createElement as h, ReactNode, useState } from 'react'
4 import { Box, Card, CardContent, LinearProgress, Link } from '@mui/material'
5 import { apiCall, useApiEx, useApiList } from './api'
6 import { dontBotherWithKeys, objSameKeys, onlyTruthy, prefix, REPO_URL, md,
7 - replaceStringToReact, wait, with_ } from './misc'
7 + replaceStringToReact, wait, with_, DAY } from './misc'
8 import { Btn, Flex, InLink, LinkBtn, wikiLink, } from './mui'
9 import { BrowserUpdated as UpdateIcon, CheckCircle, Error, Info, Launch, OpenInNew, Warning } from '@mui/icons-material'
10 import { state, useSnapState } from './state'
@@ -54,15 +54,17 @@ export default function HomePage() {
54 dontBotherWithKeys(status.alerts?.map(x => entry('warning', md(x, { html: false })))),
55 errors.length ? dontBotherWithKeys(errors.map(msg => entry('error', dontBotherWithKeys(msg))))
56 : entry('success', "Server is working"),
57 - !vfs ? h(LinearProgress)
58 - : !vfs.root?.children?.length && !vfs.root?.source ? entry('warning', "You have no files shared", SOLUTION_SEP, fsLink("add some"))
59 - : entry('', md("This is the Admin-panel, where you manage your server. Access your files on "),
60 - h(Link, { target:'frontend', href: '../..' }, "Front-end", h(Launch, { sx: { verticalAlign: 'sub', ml: '.2em' } }))),
57 !href && entry('warning', "Frontend unreachable: ",
58 _.map(serverErrors, (v,k) => k + " " + (v ? "is in error" : "is off")).join(', '),
59 !errors.length && [ SOLUTION_SEP, cfgLink("switch http or https on") ]
60 ),
61 plugins.find(x => x.badApi) && entry('warning', "Some plugins may be incompatible"),
62 + !cfg.data?.split_uploads && (Date.now() - Number(status.cloudflareDetected || 0)) < DAY
63 + && entry('', wikiLink('Reverse-proxy#cloudflare', "Cloudflare detected, read our guide")),
64 + !vfs ? h(LinearProgress)
65 + : !vfs.root?.children?.length && !vfs.root?.source ? entry('warning', "You have no files shared", SOLUTION_SEP, fsLink("add some"))
66 + : entry('', md("This is the Admin-panel, where you manage your server. Access your files on "),
67 + h(Link, { target:'frontend', href: '../..' }, "Front-end", h(Launch, { sx: { verticalAlign: 'sub', ml: '.2em' } }))),
68 !account?.adminActualAccess && entry('', md("On <u>localhost</u> you don't need to login"),
69 SOLUTION_SEP, "to access Admin-panel from another computer ", h(InLink, { to:'accounts' }, md("create an account with *admin* permission")) ),
70 with_(proxyWarning(cfg, status), x => x && entry('warning', x,
src/adminApis.ts
+2 -1
@@ -23,7 +23,7 @@ import { getConnections } from './connections'
23 import { apiAssertTypes, debounceAsync, isLocalHost, makeNetMatcher, typedEntries, waitFor } from './misc'
24 import { accountCanLoginAdmin, accountsConfig } from './perm'
25 import Koa from 'koa'
26 -import { getProxyDetected } from './middlewares'
26 +import { cloudflareDetected, getProxyDetected } from './middlewares'
27 import { writeFile } from 'fs/promises'
28 import { execFile } from 'child_process'
29 import { promisify } from 'util'
@@ -128,6 +128,7 @@ export const adminApis = {
128 autoCheckUpdateResult: autoCheckUpdateResult.get(), // in this form, we get the same type of the serialized json
129 alerts: alerts.get(),
130 proxyDetected: getProxyDetected(),
131 + cloudflareDetected,
132 ram: process.memoryUsage.rss(),
133 frpDetected: localhostAdmin.get() && !getProxyDetected()
134 && getConnections().every(isLocalHost)
src/middlewares.ts
+3
@@ -48,6 +48,7 @@ export const headRequests: Koa.Middleware = async (ctx, next) => {
48 }
49
50 let proxyDetected: undefined | Koa.Context
51 +export let cloudflareDetected: undefined | Date
52 export const someSecurity: Koa.Middleware = (ctx, next) => {
53 ctx.request.ip = normalizeIp(ctx.ip)
54 const ss = ctx.session
@@ -71,6 +72,8 @@ export const someSecurity: Koa.Middleware = (ctx, next) => {
72 proxyDetected = ctx
73 ctx.state.whenProxyDetected = new Date()
74 }
75 + if (ctx.get('cf-ray'))
76 + cloudflareDetected = new Date()
77 }
78 catch {
79 return ctx.status = HTTP_FOOL