mirror of
https://github.com/simplex-chat/simplexmq.git
synced 2026-03-30 18:35:59 +00:00
* xftp-server: embed file download widget in XFTP server web page When a URL has a hash fragment (>50 chars), the server page shows the file download UI instead of the server info page. Embeds xftp-web assets (JS, CSS, crypto worker) and protocol overlay with matching website content. Overlay renders below the server navbar. * xftp-server: fix overlay scroll lock, remove extra margin, fix dark SVG * xftp-server: move file transfer widget to standalone /file page * web: collapse all repeated Nothing sections in render section_ only collapsed the first occurrence of a section when content was Nothing, leaving subsequent sections with the same label intact. This caused SMP server pages to show raw <x-xftpConfig> tags. * xftp-server: update bundled css/js * xftp-server: move file.html to xftp-server, rename xftp bundle dir * web: remove unused server-info wrapper div * refactor * fix --------- Co-authored-by: Evgeny <evgeny@poberezkin.com>
68 lines
3.0 KiB
Haskell
68 lines
3.0 KiB
Haskell
{-# LANGUAGE NamedFieldPuns #-}
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
{-# LANGUAGE TemplateHaskell #-}
|
|
|
|
module XFTPWeb
|
|
( xftpGenerateSite,
|
|
xftpServerInformation,
|
|
) where
|
|
|
|
import Control.Monad (forM_)
|
|
import qualified Data.ByteString.Char8 as B
|
|
import Data.ByteString (ByteString)
|
|
import Data.FileEmbed (embedDir, embedFile)
|
|
import Data.Maybe (isJust)
|
|
import Data.String (fromString)
|
|
import Web.Embedded (embeddedContent)
|
|
import Simplex.FileTransfer.Server.Env (XFTPServerConfig (..))
|
|
import Simplex.Messaging.Encoding.String (strEncode)
|
|
import Simplex.Messaging.Server.Expiration (ExpirationConfig (..))
|
|
import Simplex.Messaging.Server.Information (ServerPublicInfo)
|
|
import Simplex.Messaging.Server.Main (simplexmqSource)
|
|
import qualified Simplex.Messaging.Server.Web as Web
|
|
import Simplex.Messaging.Server.Web (render, serverInfoSubsts, timedTTLText)
|
|
import Simplex.Messaging.Transport.Client (TransportHost (..))
|
|
import System.Directory (createDirectoryIfMissing)
|
|
import System.FilePath ((</>))
|
|
|
|
xftpWebContent :: [(FilePath, ByteString)]
|
|
xftpWebContent = $(embedDir "apps/xftp-server/static/xftp-web-bundle/")
|
|
|
|
xftpMediaContent :: [(FilePath, ByteString)]
|
|
xftpMediaContent = $(embedDir "apps/xftp-server/static/media/")
|
|
|
|
xftpFilePageHtml :: ByteString
|
|
xftpFilePageHtml = $(embedFile "apps/xftp-server/static/file.html")
|
|
|
|
xftpGenerateSite :: XFTPServerConfig -> Maybe ServerPublicInfo -> Maybe TransportHost -> FilePath -> IO ()
|
|
xftpGenerateSite cfg info onionHost path = do
|
|
let substs = xftpSubsts cfg info onionHost
|
|
Web.generateSite embeddedContent (render (Web.indexHtml embeddedContent) substs) [] path
|
|
let xftpDir = path </> "xftp-web-bundle"
|
|
mediaDir = path </> "media"
|
|
fileDir = path </> "file"
|
|
filePage xftpDir xftpWebContent
|
|
filePage mediaDir xftpMediaContent
|
|
createDirectoryIfMissing True fileDir
|
|
B.writeFile (fileDir </> "index.html") $ render xftpFilePageHtml substs
|
|
where
|
|
filePage dir content_ = do
|
|
createDirectoryIfMissing True dir
|
|
forM_ content_ $ \(fp, content) -> B.writeFile (dir </> fp) content
|
|
|
|
xftpServerInformation :: XFTPServerConfig -> Maybe ServerPublicInfo -> Maybe TransportHost -> ByteString
|
|
xftpServerInformation cfg info onionHost = render (Web.indexHtml embeddedContent) (xftpSubsts cfg info onionHost)
|
|
|
|
xftpSubsts :: XFTPServerConfig -> Maybe ServerPublicInfo -> Maybe TransportHost -> [(ByteString, Maybe ByteString)]
|
|
xftpSubsts XFTPServerConfig {fileExpiration, logStatsInterval, allowNewFiles, newFileBasicAuth} information onionHost =
|
|
[("smpConfig", Nothing), ("xftpConfig", Just "y")] <> substConfig <> serverInfoSubsts simplexmqSource information <> [("onionHost", strEncode <$> onionHost), ("iniFileName", Just "file-server.ini")]
|
|
where
|
|
substConfig =
|
|
[ ("fileExpiration", Just $ maybe "Never" (fromString . timedTTLText . ttl) fileExpiration),
|
|
("statsEnabled", Just . yesNo $ isJust logStatsInterval),
|
|
("newUploadsAllowed", Just . yesNo $ allowNewFiles),
|
|
("basicAuthEnabled", Just . yesNo $ isJust newFileBasicAuth)
|
|
]
|
|
yesNo True = "Yes"
|
|
yesNo False = "No"
|