فهرست منبع

v0.3.0-unstable11

Yann Stepienik 2 سال پیش
والد
کامیت
868bc6edee

+ 1 - 1
build.sh

@@ -5,7 +5,7 @@ if [ $? -ne 0 ]; then
 fi
 cp -r static build/
 cp -r GeoLite2-Country.mmdb build/
-cp -r Logo.png build/static/
+cp -r Logo.png build/
 mkdir build/images
 cp client/src/assets/images/icons/cosmos_gray.png build/cosmos_gray.png
 cp client/src/assets/images/icons/cosmos_gray.png cosmos_gray.png

+ 10 - 0
client/src/api/config.ts

@@ -33,6 +33,15 @@ function restart() {
   })
 }
 
+function canSendEmail() {
+  return wrap(fetch('/cosmos/api/can-send-email', {
+    method: 'GET',
+    headers: {
+      'Content-Type': 'application/json'
+    },
+  }))
+}
+
 async function rawUpdateRoute(routeName: string, operation: Operation, newRoute?: Route): Promise<void> {
   const payload = {
     routeName,
@@ -82,4 +91,5 @@ export {
   moveRouteDown,
   deleteRoute,
   addRoute,
+  canSendEmail,
 };

+ 14 - 3
client/src/pages/authentication/auth-forms/AuthLogin.jsx

@@ -36,6 +36,7 @@ import { LoadingButton } from '@mui/lab';
 
 const AuthLogin = () => {
     const [checked, setChecked] = React.useState(false);
+    const [showResetPassword, setShowResetPassword] = React.useState(false);
 
     const [showPassword, setShowPassword] = React.useState(false);
     const handleClickShowPassword = () => {
@@ -61,7 +62,14 @@ const AuthLogin = () => {
                 window.location.href = '/ui/newInstall';
             }
         });
-    });       
+
+
+        API.config.canSendEmail().then((resp) => {
+            if(resp.status == 'OK' && resp.data.canSendEmail) {
+                setShowResetPassword(true);
+            }
+        });
+    }, []);       
 
     return (
         <>
@@ -184,9 +192,12 @@ const AuthLogin = () => {
                                         }
                                         label={<Typography variant="h6">Keep me sign in</Typography>}
                                     />*/}
-                                    <Link variant="h6" component={RouterLink} to="/ui/forgot-password" color="primary">
+                                    {showResetPassword && <Link variant="h6" component={RouterLink} to="/ui/forgot-password" color="primary">
                                         Forgot Your Password?
-                                    </Link>
+                                    </Link>}
+                                    {!showResetPassword &&  <Typography variant="h6">
+                                        This server does not allow password reset.
+                                    </Typography>}
                                 </Stack>
                             </Grid>
                             {errors.submit && (

+ 2 - 2
client/src/pages/config/routes/routeSecurity.jsx

@@ -173,7 +173,7 @@ const RouteSecurity = ({ routeConfig }) => {
 
                     <CosmosInputText
                       name="Timeout"
-                      label="Timeout in milliseconds (0 for no timeout, at least 30000 or less recommended)"
+                      label="Timeout in milliseconds (0 for no timeout, at least 60000 or less recommended)"
                       placeholder="Timeout"
                       type="number"
                       formik={formik}
@@ -189,7 +189,7 @@ const RouteSecurity = ({ routeConfig }) => {
 
                     <CosmosInputText
                       name="ThrottlePerMinute"
-                      label="Maximum number of requests Per Minute (0 for no limit, at least 100 or less recommended)"
+                      label="Maximum number of requests Per Minute (0 for no limit, at least 2000 or less recommended)"
                       placeholder="Throttle Per Minute"
                       type="number"
                       formik={formik}

+ 8 - 0
client/src/routes/MainRoutes.jsx

@@ -9,6 +9,8 @@ import ProxyManagement from '../pages/config/users/proxyman';
 import ServeApps from '../pages/servapps/servapps';
 import { Navigate } from 'react-router';
 import RouteConfigPage from '../pages/config/routeConfigPage';
+import logo from '../assets/images/icons/cosmos.png';
+
 
 // render - dashboard
 const DashboardDefault = Loadable(lazy(() => import('../pages/dashboard')));
@@ -22,6 +24,7 @@ const Color = Loadable(lazy(() => import('../pages/components-overview/Color')))
 const Shadow = Loadable(lazy(() => import('../pages/components-overview/Shadow')));
 const AntIcons = Loadable(lazy(() => import('../pages/components-overview/AntIcons')));
 
+
 // ==============================|| MAIN ROUTING ||============================== //
 
 const MainRoutes = {
@@ -33,6 +36,11 @@ const MainRoutes = {
             // redirect to /ui
             element: <Navigate to="/ui" />
         },
+        {
+            path: '/ui/logo',
+            // redirect to /ui
+            element: <Navigate to={logo} />
+        },
         {
             path: '/ui',
             element: <DashboardDefault />

+ 1 - 0
dockerfile

@@ -12,6 +12,7 @@ WORKDIR /app
 
 COPY build/cosmos .
 COPY build/cosmos_gray.png .
+COPY build/Logo.png .
 COPY build/GeoLite2-Country.mmdb .
 COPY build/meta.json .
 COPY static ./static

+ 1 - 0
dockerfile.arm64

@@ -12,6 +12,7 @@ WORKDIR /app
 
 COPY build/cosmos .
 COPY build/cosmos_gray.png .
+COPY build/Logo.png .
 COPY build/GeoLite2-Country.mmdb .
 COPY build/meta.json .
 COPY static ./static

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "cosmos-server",
-  "version": "0.3.0-unstable10",
+  "version": "0.3.0-unstable11",
   "description": "",
   "main": "test-server.js",
   "bugs": {

+ 2 - 0
src/httpServer.go

@@ -185,6 +185,7 @@ func StartServer() {
 	}
 
 	router := mux.NewRouter().StrictSlash(true)
+	router.HandleFunc("/logo", SendLogo)
 
 	// need rewrite bc it catches too many things and prevent
 	// client to be notified of the error
@@ -199,6 +200,7 @@ func StartServer() {
 	srapi := router.PathPrefix("/cosmos").Subrouter()
 
 	srapi.HandleFunc("/api/status", StatusRoute)
+	srapi.HandleFunc("/api/can-send-email", CanSendEmail)
 	srapi.HandleFunc("/api/favicon", GetFavicon)
 	srapi.HandleFunc("/api/ping", PingURL)
 	srapi.HandleFunc("/api/newInstall", NewInstallRoute)

+ 15 - 0
src/icons.go

@@ -197,4 +197,19 @@ func PingURL(w http.ResponseWriter, req *http.Request) {
 		utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
 		return
 	}
+}
+
+func SendLogo(w http.ResponseWriter, req *http.Request) {
+	pwd,_ := os.Getwd()
+	imgsrc := "Logo.png"
+	Logo, err := ioutil.ReadFile(pwd + "/" + imgsrc)
+	if err != nil {
+		utils.Error("Logo", err)
+		utils.HTTPError(w, "Favicon", http.StatusInternalServerError, "FA003")
+		return
+	}
+	w.Header().Set("Content-Type", "image/png")
+	w.Header().Set("Cache-Control", "max-age=5")
+	w.WriteHeader(http.StatusOK)
+	w.Write(Logo)
 }

+ 2 - 1
src/proxy/shield.go

@@ -266,7 +266,8 @@ func SmartShieldMiddleware(policy utils.SmartShieldPolicy) func(http.Handler) ht
 			userConsumed := shield.GetUserUsedBudgets(clientID)
 
 			if !isPrivileged(r, policy) && !shield.isAllowedToReqest(policy, userConsumed) {
-				utils.Log("SmartShield: User is blocked due to abuse")
+				utils.Log("SmartShield: User is blocked due to abuse: " + fmt.Sprintf("%+v", userConsumed))
+
 				http.Error(w, "Too many requests", http.StatusTooManyRequests)
 				return
 			} else {

+ 16 - 1
src/status.go

@@ -51,4 +51,19 @@ func StatusRoute(w http.ResponseWriter, req *http.Request) {
 		utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
 		return
 	}
-}
+}
+
+func CanSendEmail(w http.ResponseWriter, req *http.Request) {
+	if(req.Method == "GET") {
+		json.NewEncoder(w).Encode(map[string]interface{}{
+			"status": "OK",
+			"data": map[string]interface{}{
+				"canSendEmail": utils.GetMainConfig().EmailConfig.Enabled,
+			},
+		})
+	} else {
+		utils.Error("UserList: Method not allowed" + req.Method, nil)
+		utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
+		return
+	}
+}

+ 1 - 1
src/utils/emails.go

@@ -93,7 +93,7 @@ func SendEmail(recipients []string, subject string, body string) error {
 	}
 
 	ServerURL := GetServerURL()
-	LogoURL := ServerURL + "/ui/assets/Logo.png"
+	LogoURL := ServerURL + "logo"
 
 	send := func(addr string, a smtp.Auth, from string, to []string, msg []byte) error {
 		c, err := smtp.Dial(addr)

+ 1 - 1
src/utils/middleware.go

@@ -165,4 +165,4 @@ func BlockPostWithoutReferer(next http.Handler) http.Handler {
 		// If it's not a POST request or the POST request has a Referer header, pass the request to the next handler
 		next.ServeHTTP(w, r)
 	})
-}
+}

+ 38 - 1
src/utils/utils.go

@@ -5,9 +5,13 @@ import (
 	"math/rand"
 	"regexp"
 	"net/http"
+	"encoding/base64"
 	"os"
 	"strconv"
 	"strings"
+	"io/ioutil"
+	"fmt"
+	"path/filepath"
 
 	"github.com/shirou/gopsutil/v3/mem"
 )
@@ -359,4 +363,37 @@ func GetServerURL() string {
 	}
 
 	return ServerURL + "/"
-}
+}
+
+func ImageToBase64(path string) (string, error) {
+	imageFile, err := os.Open(path)
+	if err != nil {
+		return "", err
+	}
+	defer imageFile.Close()
+
+	imageData, err := ioutil.ReadAll(imageFile)
+	if err != nil {
+		return "", err
+	}
+
+	encodedData := base64.StdEncoding.EncodeToString(imageData)
+
+	fileExt := strings.ToLower(filepath.Ext(path))
+	var mimeType string
+	switch fileExt {
+	case ".jpg", ".jpeg":
+		mimeType = "image/jpeg"
+	case ".png":
+		mimeType = "image/png"
+	case ".gif":
+		mimeType = "image/gif"
+	case ".bmp":
+		mimeType = "image/bmp"
+	default:
+		return "", fmt.Errorf("unsupported file format: %s", fileExt)
+	}
+
+	dataURI := fmt.Sprintf("data:%s;base64,%s", mimeType, encodedData)
+	return dataURI, nil
+}