diff --git a/client/src/pages/home/index.jsx b/client/src/pages/home/index.jsx index 18ff950..c8cdf70 100644 --- a/client/src/pages/home/index.jsx +++ b/client/src/pages/home/index.jsx @@ -2,7 +2,7 @@ import { useParams } from "react-router"; import Back from "../../components/back"; import { Alert, Box, CircularProgress, Grid, Stack, useTheme } from "@mui/material"; import { useEffect, useState } from "react"; -import * as API from "../../api"; +import * as API from "../../api"; import wallpaper from '../../assets/images/wallpaper.jpg'; import Grid2 from "@mui/material/Unstable_Grid2/Grid2"; import { getFaviconURL } from "../../utils/routes"; @@ -14,14 +14,14 @@ import IsLoggedIn from "../../isLoggedIn"; const HomeBackground = () => { const theme = useTheme(); return ( - - Cosmos + + Cosmos ); }; const blockStyle = { - margin: 0, + margin: 0, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis', @@ -30,35 +30,40 @@ const blockStyle = { } const HomePage = () => { - const { routeName } = useParams(); - const [config, setConfig] = useState(null); - const [coStatus, setCoStatus] = useState(null); + const { routeName } = useParams(); + const [serveApps, setServeApps] = useState([]); + const [config, setConfig] = useState(null); + const [coStatus, setCoStatus] = useState(null); + const [containers, setContainers] = useState(null); - const refreshStatus = () => { - API.getStatus().then((res) => { - setCoStatus(res.data); - }); - } + const refreshStatus = () => { + API.getStatus().then((res) => { + setCoStatus(res.data); + }); + } - const refreshConfig = () => { - API.config.get().then((res) => { - setConfig(res.data); - }); - }; - - let routes = config && (config.HTTPConfig.ProxyConfig.Routes || []); + const refreshConfig = () => { + API.docker.list().then((res) => { + setServeApps(res.data); + }); + API.config.get().then((res) => { + setConfig(res.data); + }); + }; - useEffect(() => { - refreshConfig(); - refreshStatus(); - }, []); - + let routes = config && (config.HTTPConfig.ProxyConfig.Routes || []); - return - - - - - {coStatus && !coStatus.database && ( - - No Database is setup for Cosmos! User Management and Authentication will not work.
- You can either setup the database, or disable user management in the configuration panel.
-
- )} + + + {coStatus && !coStatus.database && ( + + No Database is setup for Cosmos! User Management and Authentication will not work.
+ You can either setup the database, or disable user management in the configuration panel.
+
+ )} - {coStatus && coStatus.letsencrypt && ( - - You have enabled Let's Encrypt for automatic HTTPS Certificate. You need to provide the configuration with an email address to use for Let's Encrypt in the configs. - - )} + {coStatus && coStatus.letsencrypt && ( + + You have enabled Let's Encrypt for automatic HTTPS Certificate. You need to provide the configuration with an email address to use for Let's Encrypt in the configs. + + )} - {coStatus && coStatus.newVersionAvailable && ( - - A new version of Cosmos is available! Please update to the latest version to get the latest features and bug fixes. - - )} + {coStatus && coStatus.newVersionAvailable && ( + + A new version of Cosmos is available! Please update to the latest version to get the latest features and bug fixes. + + )} - {coStatus && coStatus.needsRestart && ( - - You have made changes to the configuration that require a restart to take effect. Please restart Cosmos to apply the changes. - - )} + {coStatus && coStatus.needsRestart && ( + + You have made changes to the configuration that require a restart to take effect. Please restart Cosmos to apply the changes. + + )} - {coStatus && coStatus.domain && ( - - You are using localhost or 0.0.0.0 as a hostname in the configuration. It is recommended that you use a domain name instead. - - )} + {coStatus && coStatus.domain && ( + + You are using localhost or 0.0.0.0 as a hostname in the configuration. It is recommended that you use a domain name instead. + + )} - {coStatus && !coStatus.docker && ( - - Docker is not connected! Please check your docker connection.
- Did you forget to add
-v /var/run/docker.sock:/var/run/docker.sock
to your docker run command?
- if your docker daemon is running somewhere else, please add
-e DOCKER_HOST=...
to your docker run command. -
- )} -
- - - {config && config.HTTPConfig.ProxyConfig.Routes.map((route) => { - return - - + {coStatus && !coStatus.docker && ( + + Docker is not connected! Please check your docker connection.
+ Did you forget to add
-v /var/run/docker.sock:/var/run/docker.sock
to your docker run command?
+ if your docker daemon is running somewhere else, please add
-e DOCKER_HOST=...
to your docker run command. +
+ )} +
+ + + {config && serveApps && config.HTTPConfig.ProxyConfig.Routes.map((route) => { + let skip = false; + if(route.Mode == "SERVAPP") { + const containerName = route.Target.split(':')[1].slice(2); + console.log('try ' + containerName) + const container = serveApps.find((c) => c.Names.includes('/' + containerName)); + console.log('found ' + container) + if(container && container.State != "running") { + skip = true + } + } + return !skip && + + + + + +
+

{route.Name}

+

{route.Description}

+

{route.Target}

+
+
+ +
+
+ })} + + {config && config.HTTPConfig.ProxyConfig.Routes.length === 0 && ( + + - - -
-

{route.Name}

-

{route.Description}

-

{route.Target}

+
+

No Apps

+

You have no apps configured. Please add some apps in the configuration panel.

- - - - })} - - {config && config.HTTPConfig.ProxyConfig.Routes.length === 0 && ( - - - -
-

No Apps

-

You have no apps configured. Please add some apps in the configuration panel.

-
-
-
-
- )} - - + + + )} + + } export default HomePage; \ No newline at end of file diff --git a/package.json b/package.json index ddc9dce..87e19fa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cosmos-server", - "version": "0.5.0-unstable19", + "version": "0.5.0-unstable20", "description": "", "main": "test-server.js", "bugs": { diff --git a/src/icons.go b/src/icons.go index f5248d8..357e600 100644 --- a/src/icons.go +++ b/src/icons.go @@ -8,6 +8,7 @@ import ( "os" "io/ioutil" "regexp" + "path" "encoding/json" "github.com/azukaar/cosmos-server/src/utils" @@ -21,22 +22,67 @@ type CachedImage struct { var cache = make(map[string]CachedImage) -func ExtractFaviconMetaTag(html string) string { +func ExtractFaviconMetaTag(filename string) string { + // Read the contents of the file + htmlBytes, err := ioutil.ReadFile(filename) + if err != nil { + return "/favicon.ico" + } + html := string(htmlBytes) + // Regular expression pattern to match the favicon metatag - pattern := `]*rel="icon"[^>]*href="([^"]+)"[^>]*>` + pattern := `]*rel="icon"[^>]*(?:sizes="([^"]+)")?[^>]*href="([^"]+)"[^>]*>|]*name="msapplication-TileImage"[^>]*content="([^"]+)"[^>]*>` // Compile the regular expression pattern regex := regexp.MustCompile(pattern) - // Find the first match in the HTML string - match := regex.FindStringSubmatch(html) + // Find all matches in the HTML string + matches := regex.FindAllStringSubmatch(html, -1) - if len(match) > 1 { - // Extract the URL from the matched metatag - faviconURL := match[1] + var faviconURL string + + // Iterate over the matches to find the appropriate favicon + for _, match := range matches { + sizes := match[1] + href := match[2] + msAppTileImage := match[3] + + // Check if the meta tag specifies msapplication-TileImage + if msAppTileImage != "" { + faviconURL = msAppTileImage + break + } + + // Check if the sizes attribute contains 96x96 + if strings.Contains(sizes, "96x96") { + faviconURL = href + break + } + + // Check if the sizes attribute contains 64x64 + if strings.Contains(sizes, "64x64") { + faviconURL = href + continue + } + + // Check if the sizes attribute contains 32x32 + if strings.Contains(sizes, "32x32") { + faviconURL = href + continue + } + + // If no sizes specified, set faviconURL to the first match without sizes + if faviconURL == "" && sizes == "" { + faviconURL = href + } + } + + // If a favicon URL is found, return it + if faviconURL != "" { return faviconURL } + // Return an error if no favicon URL is found return "/favicon.ico" } @@ -119,10 +165,23 @@ func GetFavicon(w http.ResponseWriter, req *http.Request) { sendFallback(w) return } - if !strings.HasPrefix(faviconURL, "/") { - faviconURL = "/" + faviconURL + + if strings.HasPrefix(faviconURL, ".") { + // Relative URL starting with "." + // Resolve the relative URL based on the base URL + baseURL := u.Scheme + "://" + u.Host + faviconURL = baseURL + faviconURL[1:] + } else if strings.HasPrefix(faviconURL, "/") { + // Relative URL starting with "/" + // Append the relative URL to the base URL + faviconURL = u.Scheme + "://" + u.Host + faviconURL + } else { + // Relative URL without starting dot or slash + // Construct the absolute URL based on the current page's URL path + baseURL := u.Scheme + "://" + u.Host + baseURLPath := path.Dir(u.Path) + faviconURL = baseURL + baseURLPath + "/" + faviconURL } - faviconURL = u.Scheme + "://" + u.Host + faviconURL } utils.Log("Favicon: " + faviconURL)