diff --git a/changelog.md b/changelog.md
index a2f8665..4cb504b 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,4 +1,9 @@
-## version 0.5.1 -> 0.5.7
+## versiom 0.5.11
+- Improve docker-compose import support for alternative syntaxes
+- Improve docker service creation when using force secure label (fixes few containers not liking restarting too fast when created)
+- Add toggle for using insecure HTTPS targets (fixes Unifi controller)
+
+## version 0.5.1 -> 0.5.10
- Add Wilcard certificates support
- Auto switch to Mongo 4 if CPU has no ADX
- Improve setup for certificates on new install
diff --git a/client/src/pages/config/routes/routeman.jsx b/client/src/pages/config/routes/routeman.jsx
index f030e79..0a21790 100644
--- a/client/src/pages/config/routes/routeman.jsx
+++ b/client/src/pages/config/routes/routeman.jsx
@@ -46,6 +46,7 @@ const RouteManagement = ({ routeConfig, routeNames, TargetContainer, noControls
Target: routeConfig.Target,
UseHost: routeConfig.UseHost,
Host: routeConfig.Host,
+ AcceptInsecureHTTPSTarget: routeConfig.AcceptInsecureHTTPSTarget === true,
UsePathPrefix: routeConfig.UsePathPrefix,
PathPrefix: routeConfig.PathPrefix,
StripPathPrefix: routeConfig.StripPathPrefix,
@@ -167,6 +168,12 @@ const RouteManagement = ({ routeConfig, routeNames, TargetContainer, noControls
/>
}
+ {formik.values.Target.startsWith('https://') && }
+
diff --git a/client/src/pages/servapps/containers/docker-compose.jsx b/client/src/pages/servapps/containers/docker-compose.jsx
index 3dead81..db6fc31 100644
--- a/client/src/pages/servapps/containers/docker-compose.jsx
+++ b/client/src/pages/servapps/containers/docker-compose.jsx
@@ -1,7 +1,7 @@
// material-ui
import * as React from 'react';
import { Alert, Button, Stack, Typography } from '@mui/material';
-import { WarningOutlined, PlusCircleOutlined, CopyOutlined, ExclamationCircleOutlined , SyncOutlined, UserOutlined, KeyOutlined, ArrowUpOutlined, FileZipOutlined } from '@ant-design/icons';
+import { WarningOutlined, PlusCircleOutlined, CopyOutlined, ExclamationCircleOutlined, SyncOutlined, UserOutlined, KeyOutlined, ArrowUpOutlined, FileZipOutlined } from '@ant-design/icons';
import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
@@ -28,13 +28,13 @@ import NewDockerService from './newService';
import yaml from 'js-yaml';
function checkIsOnline() {
- API.isOnline().then((res) => {
- window.location.reload();
- }).catch((err) => {
- setTimeout(() => {
- checkIsOnline();
- }, 1000);
- });
+ API.isOnline().then((res) => {
+ window.location.reload();
+ }).catch((err) => {
+ setTimeout(() => {
+ checkIsOnline();
+ }, 1000);
+ });
}
const preStyle = {
@@ -63,30 +63,25 @@ const preStyle = {
marginRight: '0',
}
-const DockerComposeImport = ({refresh}) => {
- const [step, setStep] = useState(0);
- const [isLoading, setIsLoading] = useState(false);
- const [openModal, setOpenModal] = useState(false);
- const [dockerCompose, setDockerCompose] = useState('');
- const [service, setService] = useState({});
- const [ymlError, setYmlError] = useState('');
+const DockerComposeImport = ({ refresh }) => {
+ const [step, setStep] = useState(0);
+ const [isLoading, setIsLoading] = useState(false);
+ const [openModal, setOpenModal] = useState(false);
+ const [dockerCompose, setDockerCompose] = useState('');
+ const [service, setService] = useState({});
+ const [ymlError, setYmlError] = useState('');
- useEffect(() => {
- if(dockerCompose === '') {
- return;
- }
+ useEffect(() => {
+ if (dockerCompose === '') {
+ return;
+ }
+
+ setYmlError('');
+ let doc;
+ let newService = {};
+ try {
+ doc = yaml.load(dockerCompose);
- setYmlError('');
- let doc;
- let newService = {};
- try {
- doc = yaml.load(dockerCompose);
- } catch (e) {
- console.log(e);
- setYmlError(e.message);
- return;
- }
-
if (typeof doc === 'object' && doc !== null && Object.keys(doc).length > 0 &&
!doc.services && !doc.networks && !doc.volumes) {
doc = {
@@ -94,52 +89,66 @@ const DockerComposeImport = ({refresh}) => {
}
}
-
+
// convert to the proper format
- if(doc.services) {
+ if (doc.services) {
Object.keys(doc.services).forEach((key) => {
+
// convert volumes
- if(doc.services[key].volumes) {
- let volumes = [];
- doc.services[key].volumes.forEach((volume) => {
- let volumeSplit = volume.split(':');
- let volumeObj = {
- Source: volumeSplit[0],
- Target: volumeSplit[1],
- Type: volume[0] === '/' ? 'bind' : 'volume',
- };
- volumes.push(volumeObj);
- });
- doc.services[key].volumes = volumes;
+ if (doc.services[key].volumes) {
+ if(Array.isArray(doc.services[key].volumes)) {
+ let volumes = [];
+ doc.services[key].volumes.forEach((volume) => {
+ if (typeof volume === 'object') {
+ volumes.push(volume);
+ } else {
+ let volumeSplit = volume.split(':');
+ let volumeObj = {
+ Source: volumeSplit[0],
+ Target: volumeSplit[1],
+ Type: volume[0] === '/' ? 'bind' : 'volume',
+ };
+ volumes.push(volumeObj);
+ }
+ });
+ doc.services[key].volumes = volumes;
+ }
}
// convert expose
- if(doc.services[key].expose) {
+ if (doc.services[key].expose) {
doc.services[key].expose = doc.services[key].expose.map((port) => {
- return ''+port;
+ return '' + port;
})
}
//convert user
- if(doc.services[key].user) {
+ if (doc.services[key].user) {
doc.services[key].user = '' + doc.services[key].user;
}
// convert labels:
- if(doc.services[key].labels) {
- if(Array.isArray(doc.services[key].labels)) {
+ if (doc.services[key].labels) {
+ if (Array.isArray(doc.services[key].labels)) {
let labels = {};
doc.services[key].labels.forEach((label) => {
const [key, value] = label.split('=');
- labels[''+key] = ''+value;
+ labels['' + key] = '' + value;
+ });
+ doc.services[key].labels = labels;
+ }
+ if (typeof doc.services[key].labels == 'object') {
+ let labels = {};
+ Object.keys(doc.services[key].labels).forEach((keylabel) => {
+ labels['' + keylabel] = '' + doc.services[key].labels[keylabel];
});
doc.services[key].labels = labels;
}
}
-
+
// convert environment
- if(doc.services[key].environment) {
- if(!Array.isArray(doc.services[key].environment)) {
+ if (doc.services[key].environment) {
+ if (!Array.isArray(doc.services[key].environment)) {
let environment = [];
Object.keys(doc.services[key].environment).forEach((keyenv) => {
environment.push(keyenv + '=' + doc.services[key].environment[keyenv]);
@@ -149,100 +158,155 @@ const DockerComposeImport = ({refresh}) => {
}
// convert network
- if(doc.services[key].networks) {
- if(Array.isArray(doc.services[key].networks)) {
+ if (doc.services[key].networks) {
+ if (Array.isArray(doc.services[key].networks)) {
let networks = {};
doc.services[key].networks.forEach((network) => {
- networks[''+network] = {};
+ if (typeof network === 'object') {
+ networks['' + network.name] = network;
+ }
+ else
+ networks['' + network] = {};
});
doc.services[key].networks = networks;
}
}
// ensure container_name
- if(!doc.services[key].container_name) {
+ if (!doc.services[key].container_name) {
doc.services[key].container_name = key;
}
});
}
- setService(doc);
- }, [dockerCompose]);
+ // convert networks
+ if (doc.networks) {
+ if (Array.isArray(doc.networks)) {
+ let networks = {};
+ doc.networks.forEach((network) => {
+ if (typeof network === 'object') {
+ networks['' + network.name] = network;
+ }
+ else
+ networks['' + network] = {};
+ });
+ doc.networks = networks;
+ } else {
+ let networks = {};
+ Object.keys(doc.networks).forEach((key) => {
+ networks['' + key] = doc.networks[key] || {};
+ });
+ doc.networks = networks;
+ }
+ }
- return <>
-
+ setService(doc);
+ }, [dockerCompose]);
- setOpenModal(true)}
- variant="outlined"
- startIcon={}
- >
- Import Docker Compose
-
- >;
+ return <>
+
+
+ setOpenModal(true)}
+ variant="outlined"
+ startIcon={}
+ >
+ Import Docker Compose
+
+ >;
};
export default DockerComposeImport;
diff --git a/package-lock.json b/package-lock.json
index 27a9b1f..38d1bfb 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "cosmos-server",
- "version": "0.5.0-unstable",
+ "version": "0.5.10",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "cosmos-server",
- "version": "0.5.0-unstable",
+ "version": "0.5.10",
"dependencies": {
"@ant-design/colors": "^6.0.0",
"@ant-design/icons": "^4.7.0",
diff --git a/package.json b/package.json
index 52e8b0b..69e9293 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "cosmos-server",
- "version": "0.5.10",
+ "version": "0.5.11",
"description": "",
"main": "test-server.js",
"bugs": {
@@ -56,10 +56,10 @@
"client": "vite",
"client-build": "vite build --base=/ui/",
"start": "env COSMOS_HOSTNAME=localhost CONFIG_FILE=./config_dev.json EZ=UTC build/cosmos",
- "build": " sh build.sh",
+ "build": "sh build.sh",
"dev": "npm run build && npm run start",
- "dockerdevbuild": "sh build.sh && npm run client-build && docker build --tag cosmos-dev .",
- "dockerdevrun": "docker stop cosmos-dev; docker rm cosmos-dev; docker run -d -p 80:80 -p 443:443 -e DOCKER_HOST=tcp://host.docker.internal:2375 -e COSMOS_MONGODB=$MONGODB -e COSMOS_LOG_LEVEL=DEBUG --restart=unless-stopped -h cosmos-dev --name cosmos-dev cosmos-dev",
+ "dockerdevbuild": "sh build.sh && docker build --tag cosmos-dev .",
+ "dockerdevrun": "docker stop cosmos-dev; docker rm cosmos-dev; docker run -d -p 80:80 -p 443:443 -e DOCKER_HOST=tcp://host.docker.internal:2375 -e COSMOS_MONGODB=$MONGODB -e COSMOS_LOG_LEVEL=DEBUG -v /:/mnt/host --restart=unless-stopped -h cosmos-dev --name cosmos-dev cosmos-dev",
"dockerdev": "npm run dockerdevbuild && npm run dockerdevrun",
"demo": "vite build --base=/ui/ --mode demo",
"devdemo": "vite --mode demo"
diff --git a/readme.md b/readme.md
index 54e1bae..5183944 100644
--- a/readme.md
+++ b/readme.md
@@ -110,7 +110,7 @@ Authentication is very hard (how do you check the password match? What encryptio
Installation is simple using Docker:
```
-docker run -d -p 80:80 -p 443:443 --name cosmos-server -h cosmos-server --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /var/lib/cosmos:/config azukaar/cosmos-server:latest
+docker run -d -p 80:80 -p 443:443 --name cosmos-server -h cosmos-server --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v /:/mnt/host -v /var/lib/cosmos:/config azukaar/cosmos-server:latest
```
Once installed, simply go to `http://your-server-ip` and follow the instructions of the setup wizard.
diff --git a/src/docker/api_blueprint.go b/src/docker/api_blueprint.go
index 5c7bfc6..e434693 100644
--- a/src/docker/api_blueprint.go
+++ b/src/docker/api_blueprint.go
@@ -22,6 +22,12 @@ import (
"github.com/azukaar/cosmos-server/src/utils"
)
+type ContainerCreateRequestServiceNetwork struct {
+ Aliases []string `json:"aliases,omitempty"`
+ IPV4Address string `json:"ipv4_address,omitempty"`
+ IPV6Address string `json:"ipv6_address,omitempty"`
+}
+
type ContainerCreateRequestContainer struct {
Name string `json:"container_name"`
Image string `json:"image"`
@@ -29,12 +35,8 @@ type ContainerCreateRequestContainer struct {
Labels map[string]string `json:"labels"`
Ports []string `json:"ports"`
Volumes []mount.Mount `json:"volumes"`
- Networks map[string]struct {
- Aliases []string `json:"aliases,omitempty"`
- IPV4Address string `json:"ipv4_address,omitempty"`
- IPV6Address string `json:"ipv6_address,omitempty"`
- } `json:"networks"`
- Routes []utils.ProxyRouteConfig `json:"routes"`
+ Networks map[string]ContainerCreateRequestServiceNetwork `json:"networks"`
+ Routes []utils.ProxyRouteConfig `json:"routes"`
RestartPolicy string `json:"restart,omitempty"`
Devices []string `json:"devices"`
@@ -100,7 +102,7 @@ type ContainerCreateRequestNetwork struct {
type DockerServiceCreateRequest struct {
Services map[string]ContainerCreateRequestContainer `json:"services"`
- Volumes []ContainerCreateRequestVolume `json:"volumes"`
+ Volumes map[string]ContainerCreateRequestVolume `json:"volumes"`
Networks map[string]ContainerCreateRequestNetwork `json:"networks"`
}
@@ -137,6 +139,9 @@ func Rollback(actions []DockerServiceCreateRollback , w http.ResponseWriter, flu
flusher.Flush()
}
case "network":
+ if os.Getenv("HOSTNAME") != "" {
+ DockerClient.NetworkDisconnect(DockerContext, action.Name, os.Getenv("HOSTNAME"), true)
+ }
err := DockerClient.NetworkRemove(DockerContext, action.Name)
if err != nil {
utils.Error("Rollback: Network", err)
@@ -220,6 +225,48 @@ func CreateService(w http.ResponseWriter, req *http.Request, serviceRequest Dock
var rollbackActions []DockerServiceCreateRollback
var err error
+ // check if services have the cosmos-force-network-secured label
+ for serviceName, service := range serviceRequest.Services {
+ utils.Log(fmt.Sprintf("Checking service %s...", serviceName))
+ fmt.Fprintf(w, "Checking service %s...\n", serviceName)
+ flusher.Flush()
+
+ if service.Labels["cosmos-force-network-secured"] == "true" {
+ utils.Log(fmt.Sprintf("Forcing secure %s...", serviceName))
+ fmt.Fprintf(w, "Forcing secure %s...\n", serviceName)
+ flusher.Flush()
+
+ newNetwork, errNC := CreateCosmosNetwork()
+ if errNC != nil {
+ utils.Error("CreateService: Network", err)
+ fmt.Fprintf(w, "[ERROR] Network %s cant be created\n", newNetwork)
+ flusher.Flush()
+ Rollback(rollbackActions, w, flusher)
+ return err
+ }
+
+ service.Labels["cosmos-network-name"] = newNetwork
+
+ AttachNetworkToCosmos(newNetwork)
+
+ if service.Networks == nil {
+ service.Networks = make(map[string]ContainerCreateRequestServiceNetwork)
+ }
+
+ service.Networks[newNetwork] = ContainerCreateRequestServiceNetwork{}
+
+ rollbackActions = append(rollbackActions, DockerServiceCreateRollback{
+ Action: "remove",
+ Type: "network",
+ Name: newNetwork,
+ })
+
+ utils.Log(fmt.Sprintf("Created secure network %s", newNetwork))
+ fmt.Fprintf(w, "Created secure network %s\n", newNetwork)
+ flusher.Flush()
+ }
+ }
+
// Create networks
for networkToCreateName, networkToCreate := range serviceRequest.Networks {
utils.Log(fmt.Sprintf("Creating network %s...", networkToCreateName))
@@ -391,11 +438,32 @@ func CreateService(w http.ResponseWriter, req *http.Request, serviceRequest Dock
// Create missing folders for bind mounts
for _, newmount := range container.Volumes {
if newmount.Type == mount.TypeBind {
- if _, err := os.Stat(newmount.Source); os.IsNotExist(err) {
- err := os.MkdirAll(newmount.Source, 0755)
+ newSource := newmount.Source
+
+ if os.Getenv("HOSTNAME") != "" {
+ if _, err := os.Stat("/mnt/host"); os.IsNotExist(err) {
+ utils.Error("CreateService: Unable to create directory for bind mount in the host directory. Please mount the host / in Cosmos with -v /:/mnt/host to enable folder creations, or create the bind folder yourself", err)
+ fmt.Fprintf(w, "[ERROR] Unable to create directory for bind mount in the host directory. Please mount the host / in Cosmos with -v /:/mnt/host to enable folder creations, or create the bind folder yourself: "+err.Error())
+ flusher.Flush()
+ Rollback(rollbackActions, w, flusher)
+ return err
+ }
+ newSource = "/mnt/host" + newSource
+ }
+
+ utils.Log(fmt.Sprintf("Checking directory %s for bind mount", newSource))
+ fmt.Fprintf(w, "Checking directory %s for bind mount\n", newSource)
+ flusher.Flush()
+
+ if _, err := os.Stat(newSource); os.IsNotExist(err) {
+ utils.Log(fmt.Sprintf("Not found. Creating directory %s for bind mount", newSource))
+ fmt.Fprintf(w, "Not found. Creating directory %s for bind mount\n", newSource)
+ flusher.Flush()
+
+ err := os.MkdirAll(newSource, 0755)
if err != nil {
- utils.Error("CreateService: Unable to create directory for bind mount", err)
- fmt.Fprintf(w, "[ERROR] Unable to create directory for bind mount: "+err.Error())
+ utils.Error("CreateService: Unable to create directory for bind mount. Make sure parent directories exist, and that Cosmos has permissions to create directories in the host directory", err)
+ fmt.Fprintf(w, "[ERROR] Unable to create directory for bind mount. Make sure parent directories exist, and that Cosmos has permissions to create directories in the host directory for bind mount: "+err.Error())
flusher.Flush()
Rollback(rollbackActions, w, flusher)
return err
@@ -411,7 +479,7 @@ func CreateService(w http.ResponseWriter, req *http.Request, serviceRequest Dock
} else {
uid, _ := strconv.Atoi(userInfo.Uid)
gid, _ := strconv.Atoi(userInfo.Gid)
- err = os.Chown(newmount.Source, uid, gid)
+ err = os.Chown(newSource, uid, gid)
if err != nil {
utils.Error("CreateService: Unable to change ownership of directory", err)
fmt.Fprintf(w, "[ERROR] Unable to change ownership of directory: "+err.Error())
diff --git a/src/docker/api_updateContainer.go b/src/docker/api_updateContainer.go
index 33f9a84..5f203a6 100644
--- a/src/docker/api_updateContainer.go
+++ b/src/docker/api_updateContainer.go
@@ -4,8 +4,6 @@ import (
"encoding/json"
"net/http"
"os"
- "os/user"
- "strconv"
"github.com/azukaar/cosmos-server/src/utils"
containerType "github.com/docker/docker/api/types/container"
@@ -86,33 +84,6 @@ func UpdateContainerRoute(w http.ResponseWriter, req *http.Request) {
}
}
if(form.Volumes != nil) {
- // Create missing folders for bind mounts
- for _, newmount := range form.Volumes {
- if newmount.Type == mount.TypeBind {
- if _, err := os.Stat(newmount.Source); os.IsNotExist(err) {
- err := os.MkdirAll(newmount.Source, 0755)
- if err != nil {
- utils.Error("UpdateService: Unable to create directory for bind mount", err)
- utils.HTTPError(w, "Unable to create directory for bind mount: "+err.Error(), http.StatusInternalServerError, "DS004")
- return
- }
-
- // Change the ownership of the directory to the container.User
- userInfo, err := user.Lookup(container.Config.User)
- if err != nil {
- utils.Error("UpdateService: Unable to lookup user", err)
- } else {
- uid, _ := strconv.Atoi(userInfo.Uid)
- gid, _ := strconv.Atoi(userInfo.Gid)
- err = os.Chown(newmount.Source, uid, gid)
- if err != nil {
- utils.Error("UpdateService: Unable to change ownership of directory", err)
- }
- }
- }
- }
- }
-
container.HostConfig.Mounts = form.Volumes
container.HostConfig.Binds = []string{}
}
diff --git a/src/docker/docker.go b/src/docker/docker.go
index 3733428..c80e171 100644
--- a/src/docker/docker.go
+++ b/src/docker/docker.go
@@ -5,12 +5,17 @@ import (
"errors"
"time"
"bufio"
+ "os"
+ "os/user"
+ "fmt"
"strings"
+ "strconv"
"github.com/azukaar/cosmos-server/src/utils"
"github.com/docker/docker/client"
// natting "github.com/docker/go-connections/nat"
"github.com/docker/docker/api/types/container"
+ mountType "github.com/docker/docker/api/types/mount"
"github.com/docker/docker/api/types"
)
@@ -111,6 +116,49 @@ func EditContainer(oldContainerID string, newConfig types.ContainerJSON, noLock
oldContainer := newConfig
if(oldContainerID != "") {
+ // create missing folders
+
+ for _, newmount := range newConfig.HostConfig.Mounts {
+ if newmount.Type == mountType.TypeBind {
+ newSource := newmount.Source
+
+ if os.Getenv("HOSTNAME") != "" {
+ if _, err := os.Stat("/mnt/host"); os.IsNotExist(err) {
+ utils.Error("EditContainer: Unable to create directory for bind mount in the host directory. Please mount the host / in Cosmos with -v /:/mnt/host to enable folder creations, or create the bind folder yourself", err)
+ return "", errors.New("Unable to create directory for bind mount in the host directory. Please mount the host / in Cosmos with -v /:/mnt/host to enable folder creations, or create the bind folder yourself")
+ }
+ newSource = "/mnt/host" + newSource
+ }
+
+ utils.Log(fmt.Sprintf("Checking directory %s for bind mount", newSource))
+
+ if _, err := os.Stat(newSource); os.IsNotExist(err) {
+ utils.Log(fmt.Sprintf("Not found. Creating directory %s for bind mount", newSource))
+
+ err := os.MkdirAll(newSource, 0755)
+ if err != nil {
+ utils.Error("EditContainer: Unable to create directory for bind mount", err)
+ return "", errors.New("Unable to create directory for bind mount. Make sure parent directories exist, and that Cosmos has permissions to create directories in the host directory")
+ }
+
+ if newConfig.Config.User != "" {
+ // Change the ownership of the directory to the container.User
+ userInfo, err := user.Lookup(newConfig.Config.User)
+ if err != nil {
+ utils.Error("EditContainer: Unable to lookup user", err)
+ } else {
+ uid, _ := strconv.Atoi(userInfo.Uid)
+ gid, _ := strconv.Atoi(userInfo.Gid)
+ err = os.Chown(newSource, uid, gid)
+ if err != nil {
+ utils.Error("EditContainer: Unable to change ownership of directory", err)
+ }
+ }
+ }
+ }
+ }
+ }
+
utils.Log("EditContainer - Container updating. Retriveing currently running " + oldContainerID)
var err error
diff --git a/src/proxy/routeTo.go b/src/proxy/routeTo.go
index e12b0b0..f6072ec 100644
--- a/src/proxy/routeTo.go
+++ b/src/proxy/routeTo.go
@@ -4,12 +4,13 @@ import (
"net/http"
"net/http/httputil"
"net/url"
+ "crypto/tls"
spa "github.com/roberthodgen/spa-server"
"github.com/azukaar/cosmos-server/src/utils"
)
// NewProxy takes target host and creates a reverse proxy
-func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
+func NewProxy(targetHost string, AcceptInsecureHTTPSTarget bool) (*httputil.ReverseProxy, error) {
url, err := url.Parse(targetHost)
if err != nil {
return nil, err
@@ -17,6 +18,12 @@ func NewProxy(targetHost string) (*httputil.ReverseProxy, error) {
proxy := httputil.NewSingleHostReverseProxy(url)
+ if AcceptInsecureHTTPSTarget && url.Scheme == "https" {
+ proxy.Transport = &http.Transport{
+ TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
+ }
+ }
+
proxy.ModifyResponse = func(resp *http.Response) error {
utils.Debug("Response from backend: " + resp.Status)
utils.Debug("URL was " + resp.Request.URL.String())
@@ -35,7 +42,7 @@ func RouteTo(route utils.ProxyRouteConfig) http.Handler {
routeType := route.Mode
if(routeType == "SERVAPP" || routeType == "PROXY") {
- proxy, err := NewProxy(destination)
+ proxy, err := NewProxy(destination, route.AcceptInsecureHTTPSTarget)
if err != nil {
utils.Error("Create Route", err)
}
diff --git a/src/utils/types.go b/src/utils/types.go
index 71aff15..1a473ee 100644
--- a/src/utils/types.go
+++ b/src/utils/types.go
@@ -148,6 +148,7 @@ type ProxyRouteConfig struct {
Mode ProxyMode
BlockCommonBots bool
BlockAPIAbuse bool
+ AcceptInsecureHTTPSTarget bool
}
type EmailConfig struct {
diff --git a/vite.config.js b/vite.config.js
index cc8210f..da5d2a2 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -8,7 +8,6 @@ export default defineConfig({
build: {
outDir: '../static',
},
- // base: '/ui',
server: {
proxy: {
'/cosmos/api': {
@@ -16,6 +15,10 @@ export default defineConfig({
secure: false,
ws: true,
}
+ },
+
+ watch: {
+ usePolling: true
}
}
})