mirror of
https://github.com/tobychui/zoraxy.git
synced 2025-06-27 01:41:44 +02:00
Fixed #267
- Added csrf middleware to management portal mux - Added csrf token to all html templates - Added csrf validation to all endpoints - Optimized some old endpoints implementation
This commit is contained in:
32
src/api.go
32
src/api.go
@ -22,11 +22,11 @@ import (
|
|||||||
|
|
||||||
var requireAuth = true
|
var requireAuth = true
|
||||||
|
|
||||||
func initAPIs() {
|
func initAPIs(targetMux *http.ServeMux) {
|
||||||
|
|
||||||
authRouter := auth.NewManagedHTTPRouter(auth.RouterOption{
|
authRouter := auth.NewManagedHTTPRouter(auth.RouterOption{
|
||||||
AuthAgent: authAgent,
|
AuthAgent: authAgent,
|
||||||
RequireAuth: requireAuth,
|
RequireAuth: requireAuth,
|
||||||
|
TargetMux: targetMux,
|
||||||
DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
|
DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
http.Error(w, "401 - Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "401 - Unauthorized", http.StatusUnauthorized)
|
||||||
},
|
},
|
||||||
@ -37,12 +37,12 @@ func initAPIs() {
|
|||||||
if development {
|
if development {
|
||||||
fs = http.FileServer(http.Dir("web/"))
|
fs = http.FileServer(http.Dir("web/"))
|
||||||
}
|
}
|
||||||
//Add a layer of middleware for advance control
|
//Add a layer of middleware for advance control
|
||||||
advHandler := FSHandler(fs)
|
advHandler := FSHandler(fs)
|
||||||
http.Handle("/", advHandler)
|
targetMux.Handle("/", advHandler)
|
||||||
|
|
||||||
//Authentication APIs
|
//Authentication APIs
|
||||||
registerAuthAPIs(requireAuth)
|
registerAuthAPIs(requireAuth, targetMux)
|
||||||
|
|
||||||
//Reverse proxy
|
//Reverse proxy
|
||||||
authRouter.HandleFunc("/api/proxy/enable", ReverseProxyHandleOnOff)
|
authRouter.HandleFunc("/api/proxy/enable", ReverseProxyHandleOnOff)
|
||||||
@ -187,8 +187,8 @@ func initAPIs() {
|
|||||||
authRouter.HandleFunc("/api/tools/fwdproxy/port", forwardProxy.HandlePort)
|
authRouter.HandleFunc("/api/tools/fwdproxy/port", forwardProxy.HandlePort)
|
||||||
|
|
||||||
//Account Reset
|
//Account Reset
|
||||||
http.HandleFunc("/api/account/reset", HandleAdminAccountResetEmail)
|
targetMux.HandleFunc("/api/account/reset", HandleAdminAccountResetEmail)
|
||||||
http.HandleFunc("/api/account/new", HandleNewPasswordSetup)
|
targetMux.HandleFunc("/api/account/new", HandleNewPasswordSetup)
|
||||||
|
|
||||||
//ACME & Auto Renewer
|
//ACME & Auto Renewer
|
||||||
authRouter.HandleFunc("/api/acme/listExpiredDomains", acmeHandler.HandleGetExpiredDomains)
|
authRouter.HandleFunc("/api/acme/listExpiredDomains", acmeHandler.HandleGetExpiredDomains)
|
||||||
@ -228,7 +228,7 @@ func initAPIs() {
|
|||||||
authRouter.HandleFunc("/api/docker/containers", DockerUXOptimizer.HandleDockerContainersList)
|
authRouter.HandleFunc("/api/docker/containers", DockerUXOptimizer.HandleDockerContainersList)
|
||||||
|
|
||||||
//Others
|
//Others
|
||||||
http.HandleFunc("/api/info/x", HandleZoraxyInfo)
|
targetMux.HandleFunc("/api/info/x", HandleZoraxyInfo)
|
||||||
authRouter.HandleFunc("/api/info/geoip", HandleGeoIpLookup)
|
authRouter.HandleFunc("/api/info/geoip", HandleGeoIpLookup)
|
||||||
authRouter.HandleFunc("/api/conf/export", ExportConfigAsZip)
|
authRouter.HandleFunc("/api/conf/export", ExportConfigAsZip)
|
||||||
authRouter.HandleFunc("/api/conf/import", ImportConfigFromZip)
|
authRouter.HandleFunc("/api/conf/import", ImportConfigFromZip)
|
||||||
@ -243,18 +243,18 @@ func initAPIs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Function to renders Auth related APIs
|
// Function to renders Auth related APIs
|
||||||
func registerAuthAPIs(requireAuth bool) {
|
func registerAuthAPIs(requireAuth bool, targetMux *http.ServeMux) {
|
||||||
//Auth APIs
|
//Auth APIs
|
||||||
http.HandleFunc("/api/auth/login", authAgent.HandleLogin)
|
targetMux.HandleFunc("/api/auth/login", authAgent.HandleLogin)
|
||||||
http.HandleFunc("/api/auth/logout", authAgent.HandleLogout)
|
targetMux.HandleFunc("/api/auth/logout", authAgent.HandleLogout)
|
||||||
http.HandleFunc("/api/auth/checkLogin", func(w http.ResponseWriter, r *http.Request) {
|
targetMux.HandleFunc("/api/auth/checkLogin", func(w http.ResponseWriter, r *http.Request) {
|
||||||
if requireAuth {
|
if requireAuth {
|
||||||
authAgent.CheckLogin(w, r)
|
authAgent.CheckLogin(w, r)
|
||||||
} else {
|
} else {
|
||||||
utils.SendJSONResponse(w, "true")
|
utils.SendJSONResponse(w, "true")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
http.HandleFunc("/api/auth/username", func(w http.ResponseWriter, r *http.Request) {
|
targetMux.HandleFunc("/api/auth/username", func(w http.ResponseWriter, r *http.Request) {
|
||||||
username, err := authAgent.GetUserName(w, r)
|
username, err := authAgent.GetUserName(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)
|
||||||
@ -264,12 +264,12 @@ func registerAuthAPIs(requireAuth bool) {
|
|||||||
js, _ := json.Marshal(username)
|
js, _ := json.Marshal(username)
|
||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
})
|
})
|
||||||
http.HandleFunc("/api/auth/userCount", func(w http.ResponseWriter, r *http.Request) {
|
targetMux.HandleFunc("/api/auth/userCount", func(w http.ResponseWriter, r *http.Request) {
|
||||||
uc := authAgent.GetUserCounts()
|
uc := authAgent.GetUserCounts()
|
||||||
js, _ := json.Marshal(uc)
|
js, _ := json.Marshal(uc)
|
||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
})
|
})
|
||||||
http.HandleFunc("/api/auth/register", func(w http.ResponseWriter, r *http.Request) {
|
targetMux.HandleFunc("/api/auth/register", func(w http.ResponseWriter, r *http.Request) {
|
||||||
if authAgent.GetUserCounts() == 0 {
|
if authAgent.GetUserCounts() == 0 {
|
||||||
//Allow register root admin
|
//Allow register root admin
|
||||||
authAgent.HandleRegisterWithoutEmail(w, r, func(username, reserved string) {
|
authAgent.HandleRegisterWithoutEmail(w, r, func(username, reserved string) {
|
||||||
@ -280,7 +280,7 @@ func registerAuthAPIs(requireAuth bool) {
|
|||||||
utils.SendErrorResponse(w, "Root management account already exists")
|
utils.SendErrorResponse(w, "Root management account already exists")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
http.HandleFunc("/api/auth/changePassword", func(w http.ResponseWriter, r *http.Request) {
|
targetMux.HandleFunc("/api/auth/changePassword", func(w http.ResponseWriter, r *http.Request) {
|
||||||
username, err := authAgent.GetUserName(w, r)
|
username, err := authAgent.GetUserName(w, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
http.Error(w, "401 - Unauthorized", http.StatusUnauthorized)
|
http.Error(w, "401 - Unauthorized", http.StatusUnauthorized)
|
||||||
|
23
src/cert.go
23
src/cert.go
@ -182,27 +182,28 @@ func handleToggleTLSProxy(w http.ResponseWriter, r *http.Request) {
|
|||||||
sysdb.Read("settings", "usetls", ¤tTlsSetting)
|
sysdb.Read("settings", "usetls", ¤tTlsSetting)
|
||||||
}
|
}
|
||||||
|
|
||||||
newState, err := utils.PostPara(r, "set")
|
if r.Method == http.MethodGet {
|
||||||
if err != nil {
|
//Get the current status
|
||||||
//No setting. Get the current status
|
|
||||||
js, _ := json.Marshal(currentTlsSetting)
|
js, _ := json.Marshal(currentTlsSetting)
|
||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
} else {
|
} else if r.Method == http.MethodPost {
|
||||||
if newState == "true" {
|
newState, err := utils.PostBool(r, "set")
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, "new state not set or invalid")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if newState {
|
||||||
sysdb.Write("settings", "usetls", true)
|
sysdb.Write("settings", "usetls", true)
|
||||||
SystemWideLogger.Println("Enabling TLS mode on reverse proxy")
|
SystemWideLogger.Println("Enabling TLS mode on reverse proxy")
|
||||||
dynamicProxyRouter.UpdateTLSSetting(true)
|
dynamicProxyRouter.UpdateTLSSetting(true)
|
||||||
} else if newState == "false" {
|
} else {
|
||||||
sysdb.Write("settings", "usetls", false)
|
sysdb.Write("settings", "usetls", false)
|
||||||
SystemWideLogger.Println("Disabling TLS mode on reverse proxy")
|
SystemWideLogger.Println("Disabling TLS mode on reverse proxy")
|
||||||
dynamicProxyRouter.UpdateTLSSetting(false)
|
dynamicProxyRouter.UpdateTLSSetting(false)
|
||||||
} else {
|
|
||||||
utils.SendErrorResponse(w, "invalid state given. Only support true or false")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.SendOK(w)
|
utils.SendOK(w)
|
||||||
|
} else {
|
||||||
|
http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,7 @@ require (
|
|||||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
|
||||||
github.com/googleapis/gax-go/v2 v2.12.2 // indirect
|
github.com/googleapis/gax-go/v2 v2.12.2 // indirect
|
||||||
github.com/gophercloud/gophercloud v1.0.0 // indirect
|
github.com/gophercloud/gophercloud v1.0.0 // indirect
|
||||||
|
github.com/gorilla/csrf v1.7.2 // indirect
|
||||||
github.com/gorilla/css v1.0.1 // indirect
|
github.com/gorilla/css v1.0.1 // indirect
|
||||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||||
|
@ -317,6 +317,8 @@ github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7
|
|||||||
github.com/gophercloud/gophercloud v1.0.0 h1:9nTGx0jizmHxDobe4mck89FyQHVyA3CaXLIUSGJjP9k=
|
github.com/gophercloud/gophercloud v1.0.0 h1:9nTGx0jizmHxDobe4mck89FyQHVyA3CaXLIUSGJjP9k=
|
||||||
github.com/gophercloud/gophercloud v1.0.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c=
|
github.com/gophercloud/gophercloud v1.0.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c=
|
||||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||||
|
github.com/gorilla/csrf v1.7.2 h1:oTUjx0vyf2T+wkrx09Trsev1TE+/EbDAeHtSTbtC2eI=
|
||||||
|
github.com/gorilla/csrf v1.7.2/go.mod h1:F1Fj3KG23WYHE6gozCmBAezKookxbIvUJT+121wTuLk=
|
||||||
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
github.com/gorilla/css v1.0.1 h1:ntNaBIghp6JmvWnxbZKANoLyuXTPZ4cAMlo6RyhlbO8=
|
||||||
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
github.com/gorilla/css v1.0.1/go.mod h1:BvnYkspnSzMmwRK+b8/xgNPLiIuNZr6vbZBTPQ2A3b0=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
|
21
src/main.go
21
src/main.go
@ -12,6 +12,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
|
"github.com/gorilla/csrf"
|
||||||
"imuslab.com/zoraxy/mod/access"
|
"imuslab.com/zoraxy/mod/access"
|
||||||
"imuslab.com/zoraxy/mod/acme"
|
"imuslab.com/zoraxy/mod/acme"
|
||||||
"imuslab.com/zoraxy/mod/auth"
|
"imuslab.com/zoraxy/mod/auth"
|
||||||
@ -60,7 +61,7 @@ var (
|
|||||||
name = "Zoraxy"
|
name = "Zoraxy"
|
||||||
version = "3.1.0"
|
version = "3.1.0"
|
||||||
nodeUUID = "generic" //System uuid, in uuidv4 format
|
nodeUUID = "generic" //System uuid, in uuidv4 format
|
||||||
development = true //Set this to false to use embedded web fs
|
development = false //Set this to false to use embedded web fs
|
||||||
bootTime = time.Now().Unix()
|
bootTime = time.Now().Unix()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -72,10 +73,12 @@ var (
|
|||||||
/*
|
/*
|
||||||
Handler Modules
|
Handler Modules
|
||||||
*/
|
*/
|
||||||
sysdb *database.Database //System database
|
sysdb *database.Database //System database
|
||||||
authAgent *auth.AuthAgent //Authentication agent
|
authAgent *auth.AuthAgent //Authentication agent
|
||||||
tlsCertManager *tlscert.Manager //TLS / SSL management
|
tlsCertManager *tlscert.Manager //TLS / SSL management
|
||||||
redirectTable *redirection.RuleTable //Handle special redirection rule sets
|
redirectTable *redirection.RuleTable //Handle special redirection rule sets
|
||||||
|
webminPanelMux *http.ServeMux //Server mux for handling webmin panel APIs
|
||||||
|
csrfMiddleware func(http.Handler) http.Handler //CSRF protection middleware
|
||||||
|
|
||||||
pathRuleHandler *pathrule.Handler //Handle specific path blocking or custom headers
|
pathRuleHandler *pathrule.Handler //Handle specific path blocking or custom headers
|
||||||
geodbStore *geodb.Store //GeoIP database, for resolving IP into country code
|
geodbStore *geodb.Store //GeoIP database, for resolving IP into country code
|
||||||
@ -176,12 +179,16 @@ func main() {
|
|||||||
}
|
}
|
||||||
nodeUUID = string(uuidBytes)
|
nodeUUID = string(uuidBytes)
|
||||||
|
|
||||||
|
//Create a new webmin mux and csrf middleware layer
|
||||||
|
webminPanelMux := http.NewServeMux()
|
||||||
|
csrfMiddleware := csrf.Protect([]byte(nodeUUID))
|
||||||
|
|
||||||
//Startup all modules
|
//Startup all modules
|
||||||
startupSequence()
|
startupSequence()
|
||||||
|
|
||||||
//Initiate management interface APIs
|
//Initiate management interface APIs
|
||||||
requireAuth = !(*noauth)
|
requireAuth = !(*noauth)
|
||||||
initAPIs()
|
initAPIs(webminPanelMux)
|
||||||
|
|
||||||
//Start the reverse proxy server in go routine
|
//Start the reverse proxy server in go routine
|
||||||
go func() {
|
go func() {
|
||||||
@ -194,7 +201,7 @@ func main() {
|
|||||||
finalSequence()
|
finalSequence()
|
||||||
|
|
||||||
SystemWideLogger.Println("Zoraxy started. Visit control panel at http://localhost" + *webUIPort)
|
SystemWideLogger.Println("Zoraxy started. Visit control panel at http://localhost" + *webUIPort)
|
||||||
err = http.ListenAndServe(*webUIPort, nil)
|
err = http.ListenAndServe(*webUIPort, csrfMiddleware(webminPanelMux))
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
|
@ -140,7 +140,7 @@ func (a *AutoRenewer) StopAutoRenewTicker() {
|
|||||||
// opr = setSelected -> Enter a list of file names (or matching rules) for auto renew
|
// opr = setSelected -> Enter a list of file names (or matching rules) for auto renew
|
||||||
// opr = setAuto -> Set to use auto detect certificates and renew
|
// opr = setAuto -> Set to use auto detect certificates and renew
|
||||||
func (a *AutoRenewer) HandleSetAutoRenewDomains(w http.ResponseWriter, r *http.Request) {
|
func (a *AutoRenewer) HandleSetAutoRenewDomains(w http.ResponseWriter, r *http.Request) {
|
||||||
opr, err := utils.GetPara(r, "opr")
|
opr, err := utils.PostPara(r, "opr")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "Operation not set")
|
utils.SendErrorResponse(w, "Operation not set")
|
||||||
return
|
return
|
||||||
@ -170,6 +170,8 @@ func (a *AutoRenewer) HandleSetAutoRenewDomains(w http.ResponseWriter, r *http.R
|
|||||||
a.RenewerConfig.RenewAll = true
|
a.RenewerConfig.RenewAll = true
|
||||||
a.saveRenewConfigToFile()
|
a.saveRenewConfigToFile()
|
||||||
utils.SendOK(w)
|
utils.SendOK(w)
|
||||||
|
} else {
|
||||||
|
utils.SendErrorResponse(w, "invalid operation given")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -213,19 +215,22 @@ func (a *AutoRenewer) HandleRenewNow(w http.ResponseWriter, r *http.Request) {
|
|||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HandleAutoRenewEnable get and set the auto renew enable state
|
||||||
func (a *AutoRenewer) HandleAutoRenewEnable(w http.ResponseWriter, r *http.Request) {
|
func (a *AutoRenewer) HandleAutoRenewEnable(w http.ResponseWriter, r *http.Request) {
|
||||||
val, err := utils.PostPara(r, "enable")
|
if r.Method == http.MethodGet {
|
||||||
if err != nil {
|
|
||||||
js, _ := json.Marshal(a.RenewerConfig.Enabled)
|
js, _ := json.Marshal(a.RenewerConfig.Enabled)
|
||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
} else {
|
} else if r.Method == http.MethodPost {
|
||||||
if val == "true" {
|
val, err := utils.PostBool(r, "enable")
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, "invalid or empty enable state")
|
||||||
|
}
|
||||||
|
if val {
|
||||||
//Check if the email is not empty
|
//Check if the email is not empty
|
||||||
if a.RenewerConfig.Email == "" {
|
if a.RenewerConfig.Email == "" {
|
||||||
utils.SendErrorResponse(w, "Email is not set")
|
utils.SendErrorResponse(w, "Email is not set")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
a.RenewerConfig.Enabled = true
|
a.RenewerConfig.Enabled = true
|
||||||
a.saveRenewConfigToFile()
|
a.saveRenewConfigToFile()
|
||||||
log.Println("[ACME] ACME auto renew enabled")
|
log.Println("[ACME] ACME auto renew enabled")
|
||||||
@ -236,7 +241,10 @@ func (a *AutoRenewer) HandleAutoRenewEnable(w http.ResponseWriter, r *http.Reque
|
|||||||
log.Println("[ACME] ACME auto renew disabled")
|
log.Println("[ACME] ACME auto renew disabled")
|
||||||
a.StopAutoRenewTicker()
|
a.StopAutoRenewTicker()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AutoRenewer) HandleACMEEmail(w http.ResponseWriter, r *http.Request) {
|
func (a *AutoRenewer) HandleACMEEmail(w http.ResponseWriter, r *http.Request) {
|
||||||
|
@ -10,7 +10,7 @@ type RouterOption struct {
|
|||||||
AuthAgent *AuthAgent
|
AuthAgent *AuthAgent
|
||||||
RequireAuth bool //This router require authentication
|
RequireAuth bool //This router require authentication
|
||||||
DeniedHandler func(http.ResponseWriter, *http.Request) //Things to do when request is rejected
|
DeniedHandler func(http.ResponseWriter, *http.Request) //Things to do when request is rejected
|
||||||
|
TargetMux *http.ServeMux
|
||||||
}
|
}
|
||||||
|
|
||||||
type RouterDef struct {
|
type RouterDef struct {
|
||||||
@ -35,17 +35,31 @@ func (router *RouterDef) HandleFunc(endpoint string, handler func(http.ResponseW
|
|||||||
authAgent := router.option.AuthAgent
|
authAgent := router.option.AuthAgent
|
||||||
|
|
||||||
//OK. Register handler
|
//OK. Register handler
|
||||||
http.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
|
if router.option.TargetMux == nil {
|
||||||
//Check authentication of the user
|
http.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
|
||||||
if router.option.RequireAuth {
|
//Check authentication of the user
|
||||||
authAgent.HandleCheckAuth(w, r, func(w http.ResponseWriter, r *http.Request) {
|
if router.option.RequireAuth {
|
||||||
|
authAgent.HandleCheckAuth(w, r, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
handler(w, r)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
handler(w, r)
|
handler(w, r)
|
||||||
})
|
}
|
||||||
} else {
|
|
||||||
handler(w, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
} else {
|
||||||
|
router.option.TargetMux.HandleFunc(endpoint, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
//Check authentication of the user
|
||||||
|
if router.option.RequireAuth {
|
||||||
|
authAgent.HandleCheckAuth(w, r, func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
handler(w, r)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
handler(w, r)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
router.endpoints[endpoint] = handler
|
router.endpoints[endpoint] = handler
|
||||||
|
|
||||||
|
@ -3,8 +3,6 @@
|
|||||||
|
|
||||||
package dockerux
|
package dockerux
|
||||||
|
|
||||||
/* Windows docker optimizer*/
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
@ -16,7 +14,6 @@ import (
|
|||||||
"imuslab.com/zoraxy/mod/utils"
|
"imuslab.com/zoraxy/mod/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Windows build not support docker
|
|
||||||
func (d *UXOptimizer) HandleDockerAvailable(w http.ResponseWriter, r *http.Request) {
|
func (d *UXOptimizer) HandleDockerAvailable(w http.ResponseWriter, r *http.Request) {
|
||||||
js, _ := json.Marshal(d.RunninInDocker)
|
js, _ := json.Marshal(d.RunninInDocker)
|
||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
|
@ -173,7 +173,7 @@ func (fm *FileManager) HandleDownload(w http.ResponseWriter, r *http.Request) {
|
|||||||
// HandleNewFolder creates a new folder in the specified directory
|
// HandleNewFolder creates a new folder in the specified directory
|
||||||
func (fm *FileManager) HandleNewFolder(w http.ResponseWriter, r *http.Request) {
|
func (fm *FileManager) HandleNewFolder(w http.ResponseWriter, r *http.Request) {
|
||||||
// Parse the directory name from the request
|
// Parse the directory name from the request
|
||||||
dirName, err := utils.GetPara(r, "path")
|
dirName, err := utils.PostPara(r, "path")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "invalid directory name")
|
utils.SendErrorResponse(w, "invalid directory name")
|
||||||
return
|
return
|
||||||
@ -268,13 +268,13 @@ func (fm *FileManager) HandleFileCopy(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
func (fm *FileManager) HandleFileMove(w http.ResponseWriter, r *http.Request) {
|
func (fm *FileManager) HandleFileMove(w http.ResponseWriter, r *http.Request) {
|
||||||
// Parse the source and destination paths from the request
|
// Parse the source and destination paths from the request
|
||||||
srcPath, err := utils.GetPara(r, "srcpath")
|
srcPath, err := utils.PostPara(r, "srcpath")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "invalid source path")
|
utils.SendErrorResponse(w, "invalid source path")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
destPath, err := utils.GetPara(r, "destpath")
|
destPath, err := utils.PostPara(r, "destpath")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "invalid destination path")
|
utils.SendErrorResponse(w, "invalid destination path")
|
||||||
return
|
return
|
||||||
|
@ -572,7 +572,7 @@ func ReverseProxyHandleAlias(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func DeleteProxyEndpoint(w http.ResponseWriter, r *http.Request) {
|
func DeleteProxyEndpoint(w http.ResponseWriter, r *http.Request) {
|
||||||
ep, err := utils.GetPara(r, "ep")
|
ep, err := utils.PostPara(r, "ep")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "Invalid ep given")
|
utils.SendErrorResponse(w, "Invalid ep given")
|
||||||
return
|
return
|
||||||
@ -941,18 +941,22 @@ func ReverseProxyList(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// Handle port 80 incoming traffics
|
// Handle port 80 incoming traffics
|
||||||
func HandleUpdatePort80Listener(w http.ResponseWriter, r *http.Request) {
|
func HandleUpdatePort80Listener(w http.ResponseWriter, r *http.Request) {
|
||||||
enabled, err := utils.GetPara(r, "enable")
|
if r.Method == http.MethodGet {
|
||||||
if err != nil {
|
|
||||||
//Load the current status
|
//Load the current status
|
||||||
currentEnabled := false
|
currentEnabled := false
|
||||||
err = sysdb.Read("settings", "listenP80", ¤tEnabled)
|
err := sysdb.Read("settings", "listenP80", ¤tEnabled)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, err.Error())
|
utils.SendErrorResponse(w, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
js, _ := json.Marshal(currentEnabled)
|
js, _ := json.Marshal(currentEnabled)
|
||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
} else {
|
} else if r.Method == http.MethodPost {
|
||||||
|
enabled, err := utils.PostPara(r, "enable")
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, "enable state not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
if enabled == "true" {
|
if enabled == "true" {
|
||||||
sysdb.Write("settings", "listenP80", true)
|
sysdb.Write("settings", "listenP80", true)
|
||||||
SystemWideLogger.Println("Enabling port 80 listener")
|
SystemWideLogger.Println("Enabling port 80 listener")
|
||||||
@ -965,38 +969,48 @@ func HandleUpdatePort80Listener(w http.ResponseWriter, r *http.Request) {
|
|||||||
utils.SendErrorResponse(w, "invalid mode given: "+enabled)
|
utils.SendErrorResponse(w, "invalid mode given: "+enabled)
|
||||||
}
|
}
|
||||||
utils.SendOK(w)
|
utils.SendOK(w)
|
||||||
|
} else {
|
||||||
|
http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle https redirect
|
// Handle https redirect
|
||||||
func HandleUpdateHttpsRedirect(w http.ResponseWriter, r *http.Request) {
|
func HandleUpdateHttpsRedirect(w http.ResponseWriter, r *http.Request) {
|
||||||
useRedirect, err := utils.GetPara(r, "set")
|
if r.Method == http.MethodGet {
|
||||||
if err != nil {
|
|
||||||
currentRedirectToHttps := false
|
currentRedirectToHttps := false
|
||||||
//Load the current status
|
//Load the current status
|
||||||
err = sysdb.Read("settings", "redirect", ¤tRedirectToHttps)
|
err := sysdb.Read("settings", "redirect", ¤tRedirectToHttps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, err.Error())
|
utils.SendErrorResponse(w, err.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
js, _ := json.Marshal(currentRedirectToHttps)
|
js, _ := json.Marshal(currentRedirectToHttps)
|
||||||
utils.SendJSONResponse(w, string(js))
|
utils.SendJSONResponse(w, string(js))
|
||||||
} else {
|
} else if r.Method == http.MethodPost {
|
||||||
|
useRedirect, err := utils.PostBool(r, "set")
|
||||||
|
if err != nil {
|
||||||
|
utils.SendErrorResponse(w, "status not set")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if dynamicProxyRouter.Option.Port == 80 {
|
if dynamicProxyRouter.Option.Port == 80 {
|
||||||
utils.SendErrorResponse(w, "This option is not available when listening on port 80")
|
utils.SendErrorResponse(w, "This option is not available when listening on port 80")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if useRedirect == "true" {
|
if useRedirect {
|
||||||
sysdb.Write("settings", "redirect", true)
|
sysdb.Write("settings", "redirect", true)
|
||||||
SystemWideLogger.Println("Updating force HTTPS redirection to true")
|
SystemWideLogger.Println("Updating force HTTPS redirection to true")
|
||||||
dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(true)
|
dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(true)
|
||||||
} else if useRedirect == "false" {
|
} else {
|
||||||
sysdb.Write("settings", "redirect", false)
|
sysdb.Write("settings", "redirect", false)
|
||||||
SystemWideLogger.Println("Updating force HTTPS redirection to false")
|
SystemWideLogger.Println("Updating force HTTPS redirection to false")
|
||||||
dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(false)
|
dynamicProxyRouter.UpdateHttpToHttpsRedirectSetting(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
utils.SendOK(w)
|
utils.SendOK(w)
|
||||||
|
} else {
|
||||||
|
http.Error(w, "405 - Method not allowed", http.StatusMethodNotAllowed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1086,13 +1100,13 @@ func HandleIncomingPortSet(w http.ResponseWriter, r *http.Request) {
|
|||||||
//List all the custom header defined in this proxy rule
|
//List all the custom header defined in this proxy rule
|
||||||
|
|
||||||
func HandleCustomHeaderList(w http.ResponseWriter, r *http.Request) {
|
func HandleCustomHeaderList(w http.ResponseWriter, r *http.Request) {
|
||||||
epType, err := utils.PostPara(r, "type")
|
epType, err := utils.GetPara(r, "type")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "endpoint type not defined")
|
utils.SendErrorResponse(w, "endpoint type not defined")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
domain, err := utils.PostPara(r, "domain")
|
domain, err := utils.GetPara(r, "domain")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "domain or matching rule not defined")
|
utils.SendErrorResponse(w, "domain or matching rule not defined")
|
||||||
return
|
return
|
||||||
|
@ -4,9 +4,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gorilla/csrf"
|
||||||
"imuslab.com/zoraxy/mod/sshprox"
|
"imuslab.com/zoraxy/mod/sshprox"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -42,11 +44,15 @@ func FSHandler(handler http.Handler) http.Handler {
|
|||||||
|
|
||||||
// Allow access to /script/*, /img/pubic/* and /login.html without authentication
|
// Allow access to /script/*, /img/pubic/* and /login.html without authentication
|
||||||
if strings.HasPrefix(r.URL.Path, ppf("/script/")) || strings.HasPrefix(r.URL.Path, ppf("/img/public/")) || r.URL.Path == ppf("/login.html") || r.URL.Path == ppf("/reset.html") || r.URL.Path == ppf("/favicon.png") {
|
if strings.HasPrefix(r.URL.Path, ppf("/script/")) || strings.HasPrefix(r.URL.Path, ppf("/img/public/")) || r.URL.Path == ppf("/login.html") || r.URL.Path == ppf("/reset.html") || r.URL.Path == ppf("/favicon.png") {
|
||||||
|
if isHTMLFilePath(r.URL.Path) {
|
||||||
|
handleInjectHTML(w, r, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
handler.ServeHTTP(w, r)
|
handler.ServeHTTP(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// check authentication
|
// Check authentication
|
||||||
if !authAgent.CheckAuth(r) && requireAuth {
|
if !authAgent.CheckAuth(r) && requireAuth {
|
||||||
http.Redirect(w, r, ppf("/login.html"), http.StatusTemporaryRedirect)
|
http.Redirect(w, r, ppf("/login.html"), http.StatusTemporaryRedirect)
|
||||||
return
|
return
|
||||||
@ -77,6 +83,10 @@ func FSHandler(handler http.Handler) http.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Authenticated
|
//Authenticated
|
||||||
|
if isHTMLFilePath(r.URL.Path) {
|
||||||
|
handleInjectHTML(w, r, r.URL.Path)
|
||||||
|
return
|
||||||
|
}
|
||||||
handler.ServeHTTP(w, r)
|
handler.ServeHTTP(w, r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -88,3 +98,53 @@ func ppf(relativeFilepath string) string {
|
|||||||
}
|
}
|
||||||
return relativeFilepath
|
return relativeFilepath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isHTMLFilePath(requestURI string) bool {
|
||||||
|
return strings.HasSuffix(requestURI, ".html") || strings.HasSuffix(requestURI, "/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Serve the html file with template token injected
|
||||||
|
func handleInjectHTML(w http.ResponseWriter, r *http.Request, relativeFilepath string) {
|
||||||
|
// Read the HTML file
|
||||||
|
var content []byte
|
||||||
|
var err error
|
||||||
|
if len(relativeFilepath) > 0 && relativeFilepath[len(relativeFilepath)-1:] == "/" {
|
||||||
|
relativeFilepath = relativeFilepath + "index.html"
|
||||||
|
}
|
||||||
|
if development {
|
||||||
|
//Load from disk
|
||||||
|
targetFilePath := strings.ReplaceAll(filepath.Join("web/", relativeFilepath), "\\", "/")
|
||||||
|
content, err = os.ReadFile(targetFilePath)
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Load from embedded fs, require trimming off the prefix slash for relative path
|
||||||
|
relativeFilepath = strings.TrimPrefix(relativeFilepath, "/")
|
||||||
|
content, err = webres.ReadFile(relativeFilepath)
|
||||||
|
if err != nil {
|
||||||
|
SystemWideLogger.Println("load embedded web file failed: ", err)
|
||||||
|
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert the file content to a string
|
||||||
|
htmlContent := string(content)
|
||||||
|
|
||||||
|
//Defeine the system template for this request
|
||||||
|
templateStrings := map[string]string{
|
||||||
|
".csrfToken": csrf.Token(r),
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replace template tokens in the HTML content
|
||||||
|
for key, value := range templateStrings {
|
||||||
|
placeholder := "{{" + key + "}}"
|
||||||
|
htmlContent = strings.ReplaceAll(htmlContent, placeholder, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the modified HTML content to the response
|
||||||
|
w.Header().Set("Content-Type", "text/html")
|
||||||
|
w.Write([]byte(htmlContent))
|
||||||
|
}
|
||||||
|
@ -292,7 +292,7 @@ func startupSequence() {
|
|||||||
|
|
||||||
/* Docker UX Optimizer */
|
/* Docker UX Optimizer */
|
||||||
if runtime.GOOS == "windows" && *runningInDocker {
|
if runtime.GOOS == "windows" && *runningInDocker {
|
||||||
SystemWideLogger.PrintAndLog("WARNING", "Invalid start flag combination: docker=true && runtime.GOOS == windows. Running in docker UX development mode.", nil)
|
SystemWideLogger.PrintAndLog("warning", "Invalid start flag combination: docker=true && runtime.GOOS == windows. Running in docker UX development mode.", nil)
|
||||||
}
|
}
|
||||||
DockerUXOptimizer = dockerux.NewDockerOptimizer(*runningInDocker, SystemWideLogger)
|
DockerUXOptimizer = dockerux.NewDockerOptimizer(*runningInDocker, SystemWideLogger)
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ import (
|
|||||||
|
|
||||||
// List upstreams from a endpoint
|
// List upstreams from a endpoint
|
||||||
func ReverseProxyUpstreamList(w http.ResponseWriter, r *http.Request) {
|
func ReverseProxyUpstreamList(w http.ResponseWriter, r *http.Request) {
|
||||||
endpoint, err := utils.PostPara(r, "ep")
|
endpoint, err := utils.GetPara(r, "ep")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
utils.SendErrorResponse(w, "endpoint not defined")
|
utils.SendErrorResponse(w, "endpoint not defined")
|
||||||
return
|
return
|
||||||
|
@ -1000,7 +1000,7 @@
|
|||||||
*/
|
*/
|
||||||
function enableBlacklist() {
|
function enableBlacklist() {
|
||||||
var isChecked = $('#enableBlacklist').is(':checked');
|
var isChecked = $('#enableBlacklist').is(':checked');
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/api/blacklist/enable',
|
url: '/api/blacklist/enable',
|
||||||
data: { enable: isChecked, id: currentEditingAccessRule},
|
data: { enable: isChecked, id: currentEditingAccessRule},
|
||||||
@ -1028,9 +1028,10 @@
|
|||||||
let counter = 0;
|
let counter = 0;
|
||||||
for(var i = 0; i < ccs.length; i++){
|
for(var i = 0; i < ccs.length; i++){
|
||||||
let thisCountryCode = ccs[i];
|
let thisCountryCode = ccs[i];
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "/api/blacklist/country/add",
|
url: "/api/blacklist/country/add",
|
||||||
|
method: "POST",
|
||||||
data: { cc: thisCountryCode, id: currentEditingAccessRule},
|
data: { cc: thisCountryCode, id: currentEditingAccessRule},
|
||||||
success: function(response) {
|
success: function(response) {
|
||||||
if (response.error != undefined){
|
if (response.error != undefined){
|
||||||
@ -1066,7 +1067,7 @@
|
|||||||
function removeFromBannedList(countryCode){
|
function removeFromBannedList(countryCode){
|
||||||
countryCode = countryCode.toLowerCase();
|
countryCode = countryCode.toLowerCase();
|
||||||
let countryName = getCountryName(countryCode);
|
let countryName = getCountryName(countryCode);
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/blacklist/country/remove",
|
url: "/api/blacklist/country/remove",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: { cc: countryCode, id: currentEditingAccessRule},
|
data: { cc: countryCode, id: currentEditingAccessRule},
|
||||||
@ -1097,7 +1098,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/blacklist/ip/add",
|
url: "/api/blacklist/ip/add",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {ip: targetIp.toLowerCase(), id: currentEditingAccessRule},
|
data: {ip: targetIp.toLowerCase(), id: currentEditingAccessRule},
|
||||||
@ -1119,7 +1120,7 @@
|
|||||||
|
|
||||||
function removeIpBlacklist(ipaddr){
|
function removeIpBlacklist(ipaddr){
|
||||||
if (confirm("Confirm remove blacklist for " + ipaddr + " ?")){
|
if (confirm("Confirm remove blacklist for " + ipaddr + " ?")){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/blacklist/ip/remove",
|
url: "/api/blacklist/ip/remove",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {ip: ipaddr.toLowerCase(), id: currentEditingAccessRule},
|
data: {ip: ipaddr.toLowerCase(), id: currentEditingAccessRule},
|
||||||
@ -1143,7 +1144,7 @@
|
|||||||
*/
|
*/
|
||||||
function enableWhitelist() {
|
function enableWhitelist() {
|
||||||
var isChecked = $('#enableWhitelist').is(':checked');
|
var isChecked = $('#enableWhitelist').is(':checked');
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/api/whitelist/enable',
|
url: '/api/whitelist/enable',
|
||||||
data: { enable: isChecked , id: currentEditingAccessRule},
|
data: { enable: isChecked , id: currentEditingAccessRule},
|
||||||
@ -1165,7 +1166,7 @@
|
|||||||
let counter = 0;
|
let counter = 0;
|
||||||
for(var i = 0; i < ccs.length; i++){
|
for(var i = 0; i < ccs.length; i++){
|
||||||
let thisCountryCode = ccs[i];
|
let thisCountryCode = ccs[i];
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "/api/whitelist/country/add",
|
url: "/api/whitelist/country/add",
|
||||||
data: { cc: thisCountryCode , id: currentEditingAccessRule},
|
data: { cc: thisCountryCode , id: currentEditingAccessRule},
|
||||||
@ -1199,7 +1200,7 @@
|
|||||||
function removeFromWhiteList(countryCode){
|
function removeFromWhiteList(countryCode){
|
||||||
if (confirm("Confirm removing " + getCountryName(countryCode) + " from whitelist?")){
|
if (confirm("Confirm removing " + getCountryName(countryCode) + " from whitelist?")){
|
||||||
countryCode = countryCode.toLowerCase();
|
countryCode = countryCode.toLowerCase();
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/whitelist/country/remove",
|
url: "/api/whitelist/country/remove",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: { cc: countryCode , id: currentEditingAccessRule},
|
data: { cc: countryCode , id: currentEditingAccessRule},
|
||||||
@ -1230,7 +1231,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/whitelist/ip/add",
|
url: "/api/whitelist/ip/add",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {ip: targetIp.toLowerCase(), "comment": remarks, id: currentEditingAccessRule},
|
data: {ip: targetIp.toLowerCase(), "comment": remarks, id: currentEditingAccessRule},
|
||||||
@ -1253,7 +1254,7 @@
|
|||||||
|
|
||||||
function removeIpWhitelist(ipaddr){
|
function removeIpWhitelist(ipaddr){
|
||||||
if (confirm("Confirm remove whitelist for " + ipaddr + " ?")){
|
if (confirm("Confirm remove whitelist for " + ipaddr + " ?")){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/whitelist/ip/remove",
|
url: "/api/whitelist/ip/remove",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {ip: ipaddr.toLowerCase(), id: currentEditingAccessRule},
|
data: {ip: ipaddr.toLowerCase(), id: currentEditingAccessRule},
|
||||||
|
@ -257,7 +257,7 @@
|
|||||||
//Delete the certificate by its domain
|
//Delete the certificate by its domain
|
||||||
function deleteCertificate(domain){
|
function deleteCertificate(domain){
|
||||||
if (confirm("Confirm delete certificate for " + domain + " ?")){
|
if (confirm("Confirm delete certificate for " + domain + " ?")){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/cert/delete",
|
url: "/api/cert/delete",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {domain: domain},
|
data: {domain: domain},
|
||||||
@ -316,7 +316,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/acme/autoRenew/email",
|
url: "/api/acme/autoRenew/email",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {"set": newDefaultEmail},
|
data: {"set": newDefaultEmail},
|
||||||
@ -330,7 +330,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/acme/autoRenew/ca",
|
url: "/api/acme/autoRenew/ca",
|
||||||
data: {"set": newDefaultCA},
|
data: {"set": newDefaultCA},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
@ -87,7 +87,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addGANet() {
|
function addGANet() {
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/network/add",
|
url: "/api/gan/network/add",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
@ -191,7 +191,7 @@
|
|||||||
//Remove the given GANet
|
//Remove the given GANet
|
||||||
function removeGANet(netid){
|
function removeGANet(netid){
|
||||||
if (confirm("Confirm remove Network " + netid + " PERMANENTLY ?"))
|
if (confirm("Confirm remove Network " + netid + " PERMANENTLY ?"))
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/network/remove",
|
url: "/api/gan/network/remove",
|
||||||
type: "POST",
|
type: "POST",
|
||||||
dataType: "json",
|
dataType: "json",
|
||||||
|
@ -214,7 +214,7 @@
|
|||||||
//Get CIDR from selected range group
|
//Get CIDR from selected range group
|
||||||
var cidr = $(".iprange.active").attr("cidr");
|
var cidr = $(".iprange.active").attr("cidr");
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/network/setRange",
|
url: "/api/gan/network/setRange",
|
||||||
metohd: "POST",
|
metohd: "POST",
|
||||||
data:{
|
data:{
|
||||||
@ -240,7 +240,7 @@
|
|||||||
if (object != undefined){
|
if (object != undefined){
|
||||||
$(object).addClass("loading");
|
$(object).addClass("loading");
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/network/name",
|
url: "/api/gan/network/name",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -287,7 +287,7 @@
|
|||||||
|
|
||||||
//Handle delete IP from memeber
|
//Handle delete IP from memeber
|
||||||
function deleteIpFromMemeber(memberid, ip){
|
function deleteIpFromMemeber(memberid, ip){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/members/ip",
|
url: "/api/gan/members/ip",
|
||||||
metohd: "POST",
|
metohd: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -334,7 +334,7 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/members/ip",
|
url: "/api/gan/members/ip",
|
||||||
metohd: "POST",
|
metohd: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -461,7 +461,7 @@
|
|||||||
$(".memberName").each(function(){
|
$(".memberName").each(function(){
|
||||||
let addr = $(this).attr("addr");
|
let addr = $(this).attr("addr");
|
||||||
let targetDOM = $(this);
|
let targetDOM = $(this);
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/members/name",
|
url: "/api/gan/members/name",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -487,7 +487,7 @@
|
|||||||
|
|
||||||
let newname = prompt("Enter a easy manageable name for " + targetMemberAddr, "");
|
let newname = prompt("Enter a easy manageable name for " + targetMemberAddr, "");
|
||||||
if (newname != null && newname.trim() != "") {
|
if (newname != null && newname.trim() != "") {
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/members/name",
|
url: "/api/gan/members/name",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -553,7 +553,7 @@
|
|||||||
function handleMemberAuth(object){
|
function handleMemberAuth(object){
|
||||||
let targetMemberAddr = $(object).attr("addr");
|
let targetMemberAddr = $(object).attr("addr");
|
||||||
let isAuthed = object.checked;
|
let isAuthed = object.checked;
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/members/authorize",
|
url: "/api/gan/members/authorize",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -580,7 +580,7 @@
|
|||||||
|
|
||||||
function handleMemberDelete(addr){
|
function handleMemberDelete(addr){
|
||||||
if (confirm("Confirm delete member " + addr + " ?")){
|
if (confirm("Confirm delete member " + addr + " ?")){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/members/delete",
|
url: "/api/gan/members/delete",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -605,7 +605,7 @@
|
|||||||
$(".addControllerToNetworkBtn").addClass("disabled");
|
$(".addControllerToNetworkBtn").addClass("disabled");
|
||||||
$(".addControllerToNetworkBtn").addClass("loading");
|
$(".addControllerToNetworkBtn").addClass("loading");
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/network/join",
|
url: "/api/gan/network/join",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -630,7 +630,7 @@
|
|||||||
$(".removeControllerFromNetworkBtn").addClass("disabled");
|
$(".removeControllerFromNetworkBtn").addClass("disabled");
|
||||||
$(".removeControllerFromNetworkBtn").addClass("loading");
|
$(".removeControllerFromNetworkBtn").addClass("loading");
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/gan/network/leave",
|
url: "/api/gan/network/leave",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -400,7 +400,7 @@
|
|||||||
let rateLimit = $(row).find(".RateLimit").val();
|
let rateLimit = $(row).find(".RateLimit").val();
|
||||||
let bypassGlobalTLS = $(row).find(".BypassGlobalTLS")[0].checked;
|
let bypassGlobalTLS = $(row).find(".BypassGlobalTLS")[0].checked;
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/edit",
|
url: "/api/proxy/edit",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -422,6 +422,28 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Generic functions for delete rp endpoints
|
||||||
|
function deleteEndpoint(epoint){
|
||||||
|
epoint = decodeURIComponent(epoint).hexDecode();
|
||||||
|
if (confirm("Confirm remove proxy for :" + epoint + "?")){
|
||||||
|
$.cjax({
|
||||||
|
url: "/api/proxy/del",
|
||||||
|
method: "POST",
|
||||||
|
data: {ep: epoint},
|
||||||
|
success: function(data){
|
||||||
|
if (data.error == undefined){
|
||||||
|
listProxyEndpoints();
|
||||||
|
msgbox("Proxy Rule Deleted", true);
|
||||||
|
reloadUptimeList();
|
||||||
|
}else{
|
||||||
|
msgbox(data.error, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* button events */
|
/* button events */
|
||||||
function editBasicAuthCredentials(uuid){
|
function editBasicAuthCredentials(uuid){
|
||||||
@ -474,7 +496,7 @@
|
|||||||
function handleProxyRuleToggle(object){
|
function handleProxyRuleToggle(object){
|
||||||
let endpointUUID = $(object).attr("eptuuid");
|
let endpointUUID = $(object).attr("eptuuid");
|
||||||
let isChecked = object.checked;
|
let isChecked = object.checked;
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/toggle",
|
url: "/api/proxy/toggle",
|
||||||
data: {
|
data: {
|
||||||
"ep": endpointUUID,
|
"ep": endpointUUID,
|
||||||
|
@ -339,7 +339,7 @@ function setWoLAddress() {
|
|||||||
$("#wol_mac").parent().removeClass("error");
|
$("#wol_mac").parent().removeClass("error");
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: wake_on_lan_API,
|
url: wake_on_lan_API,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -363,7 +363,7 @@ function setWoLAddress() {
|
|||||||
|
|
||||||
function delWoLAddr(mac, name) {
|
function delWoLAddr(mac, name) {
|
||||||
if (confirm(`Confirm remove WoL record for ${name} (${mac}) ?`)){
|
if (confirm(`Confirm remove WoL record for ${name} (${mac}) ?`)){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: wake_on_lan_API,
|
url: wake_on_lan_API,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -385,7 +385,7 @@ function wakeWoL(mac, object=undefined) {
|
|||||||
if (object != undefined){
|
if (object != undefined){
|
||||||
$(object).addClass("loading").addClass("disabled");
|
$(object).addClass("loading").addClass("disabled");
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: wake_on_lan_API,
|
url: wake_on_lan_API,
|
||||||
type: "POST",
|
type: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -594,7 +594,7 @@ function initForwardProxyInfo(){
|
|||||||
initForwardProxyInfo();
|
initForwardProxyInfo();
|
||||||
|
|
||||||
function toggleForwadProxy(enabled){
|
function toggleForwadProxy(enabled){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/tools/fwdproxy/enable",
|
url: "/api/tools/fwdproxy/enable",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -620,7 +620,7 @@ function updateForwardProxyPort(){
|
|||||||
$("#newPortNumber").parent().removeClass('error');
|
$("#newPortNumber").parent().removeClass('error');
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/tools/fwdproxy/port",
|
url: "/api/tools/fwdproxy/port",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -116,7 +116,7 @@
|
|||||||
let forwardChildpath = document.querySelector('input[name="forward-childpath"]').checked;
|
let forwardChildpath = document.querySelector('input[name="forward-childpath"]').checked;
|
||||||
let redirectType = document.querySelector('input[name="redirect-type"]:checked').value;
|
let redirectType = document.querySelector('input[name="redirect-type"]:checked').value;
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/redirect/add",
|
url: "/api/redirect/add",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -141,7 +141,7 @@
|
|||||||
let targetURL = $(obj).attr("rurl");
|
let targetURL = $(obj).attr("rurl");
|
||||||
targetURL = JSON.parse(decodeURIComponent(targetURL));
|
targetURL = JSON.parse(decodeURIComponent(targetURL));
|
||||||
if (confirm("Confirm remove redirection from " + targetURL + " ?")){
|
if (confirm("Confirm remove redirection from " + targetURL + " ?")){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/redirect/delete",
|
url: "/api/redirect/delete",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -191,8 +191,9 @@
|
|||||||
|
|
||||||
//Bind event to the checkbox
|
//Bind event to the checkbox
|
||||||
$("#redirectRegex").on("change", function(){
|
$("#redirectRegex").on("change", function(){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/redirect/regex",
|
url: "/api/redirect/regex",
|
||||||
|
method: "POST",
|
||||||
data: {"enable": $(this)[0].checked},
|
data: {"enable": $(this)[0].checked},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
|
@ -181,8 +181,9 @@
|
|||||||
targetDomain = targetDomain.substring(8);
|
targetDomain = targetDomain.substring(8);
|
||||||
$("#proxyRoot").val(targetDomain);
|
$("#proxyRoot").val(targetDomain);
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/tlscheck",
|
url: "/api/proxy/tlscheck",
|
||||||
|
method: "POST",
|
||||||
data: {url: targetDomain},
|
data: {url: targetDomain},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -232,7 +233,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create the endpoint by calling add
|
//Create the endpoint by calling add
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/add",
|
url: "/api/proxy/add",
|
||||||
data: {
|
data: {
|
||||||
"type": "root",
|
"type": "root",
|
||||||
|
@ -212,8 +212,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create the endpoint by calling add
|
//Create the endpoint by calling add
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/add",
|
url: "/api/proxy/add",
|
||||||
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
type: "host",
|
type: "host",
|
||||||
rootname: rootname,
|
rootname: rootname,
|
||||||
@ -270,22 +271,6 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Generic functions for delete rp endpoints
|
|
||||||
function deleteEndpoint(epoint){
|
|
||||||
epoint = decodeURIComponent(epoint).hexDecode();
|
|
||||||
if (confirm("Confirm remove proxy for :" + epoint + "?")){
|
|
||||||
$.ajax({
|
|
||||||
url: "/api/proxy/del",
|
|
||||||
data: {ep: epoint, },
|
|
||||||
success: function(){
|
|
||||||
listProxyEndpoints();
|
|
||||||
msgbox("Proxy Rule Deleted", true);
|
|
||||||
reloadUptimeList();
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//Clearn the proxy target value, make sure user do not enter http:// or https://
|
//Clearn the proxy target value, make sure user do not enter http:// or https://
|
||||||
//and auto select TLS checkbox if https:// exists
|
//and auto select TLS checkbox if https:// exists
|
||||||
function autoFillTargetTLS(input){
|
function autoFillTargetTLS(input){
|
||||||
@ -307,12 +292,12 @@
|
|||||||
|
|
||||||
//Automatic check if the site require TLS and check the checkbox if needed
|
//Automatic check if the site require TLS and check the checkbox if needed
|
||||||
function autoCheckTls(targetDomain){
|
function autoCheckTls(targetDomain){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/tlscheck",
|
url: "/api/proxy/tlscheck",
|
||||||
data: {url: targetDomain},
|
data: {url: targetDomain},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
|
msgbox(data.error, false);
|
||||||
}else if (data == "https"){
|
}else if (data == "https"){
|
||||||
$("#reqTls").parent().checkbox("set checked");
|
$("#reqTls").parent().checkbox("set checked");
|
||||||
}else if (data == "http"){
|
}else if (data == "http"){
|
||||||
|
@ -315,26 +315,39 @@
|
|||||||
|
|
||||||
//Start and stop service button
|
//Start and stop service button
|
||||||
function startService(){
|
function startService(){
|
||||||
$.post("/api/proxy/enable", {enable: true}, function(data){
|
$.cjax({
|
||||||
if (data.error != undefined){
|
url: "/api/proxy/enable",
|
||||||
msgbox(data.error, false, 5000);
|
method: "POST",
|
||||||
|
data: {enable: true},
|
||||||
|
success: function(data){
|
||||||
|
if (data.error != undefined){
|
||||||
|
msgbox(data.error, false, 5000);
|
||||||
|
}
|
||||||
|
initRPStaste();
|
||||||
}
|
}
|
||||||
initRPStaste();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function stopService(){
|
function stopService(){
|
||||||
$.post("/api/proxy/enable", {enable: false}, function(data){
|
$.cjax({
|
||||||
if (data.error != undefined){
|
url: "/api/proxy/enable",
|
||||||
msgbox(data.error, false, 5000);
|
method: "POST",
|
||||||
|
data: {enable: false},
|
||||||
|
success: function(data){
|
||||||
|
if (data.error != undefined){
|
||||||
|
msgbox(data.error, false, 5000);
|
||||||
|
}
|
||||||
|
initRPStaste();
|
||||||
}
|
}
|
||||||
initRPStaste();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleP80ListenerStateChange(enabled){
|
function handleP80ListenerStateChange(enabled){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/listenPort80",
|
url: "/api/proxy/listenPort80",
|
||||||
|
method: "POST",
|
||||||
data: {"enable": enabled},
|
data: {"enable": enabled},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -361,16 +374,21 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.post("/api/proxy/setIncoming", {incoming: newPortValue}, function(data){
|
$.cjax({
|
||||||
if (data.error != undefined){
|
url: "/api/proxy/setIncoming",
|
||||||
msgbox(data.error, false, 5000);
|
method: "POST",
|
||||||
return;
|
data: {incoming: newPortValue},
|
||||||
}
|
success: function(data){
|
||||||
msgbox("Listening Port Updated");
|
if (data.error != undefined){
|
||||||
initRPStaste();
|
msgbox(data.error, false, 5000);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
msgbox("Listening Port Updated");
|
||||||
|
initRPStaste();
|
||||||
|
|
||||||
//Hide the reminder text
|
//Hide the reminder text
|
||||||
$("#applyButtonReminder").hide();
|
$("#applyButtonReminder").hide();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,8 +420,9 @@
|
|||||||
//Initiate the input listener on the checkbox
|
//Initiate the input listener on the checkbox
|
||||||
$("#redirect").find("input").on("change", function(){
|
$("#redirect").find("input").on("change", function(){
|
||||||
let thisValue = $("#redirect").checkbox("is checked");
|
let thisValue = $("#redirect").checkbox("is checked");
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/useHttpsRedirect",
|
url: "/api/proxy/useHttpsRedirect",
|
||||||
|
method: "POST",
|
||||||
data: {set: thisValue},
|
data: {set: thisValue},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -440,9 +459,10 @@
|
|||||||
//Bind events to the checkbox
|
//Bind events to the checkbox
|
||||||
$("#tlsMinVer").find("input").on("change", function(){
|
$("#tlsMinVer").find("input").on("change", function(){
|
||||||
let thisValue = $("#tlsMinVer").checkbox("is checked");
|
let thisValue = $("#tlsMinVer").checkbox("is checked");
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/cert/tlsRequireLatest",
|
url: "/api/cert/tlsRequireLatest",
|
||||||
data: {"set": thisValue},
|
data: {"set": thisValue},
|
||||||
|
method: "POST",
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
msgbox(data.error, false, 5000);
|
msgbox(data.error, false, 5000);
|
||||||
@ -498,15 +518,15 @@
|
|||||||
}else{
|
}else{
|
||||||
$(".tlsEnabledOnly").addClass('disabled');
|
$(".tlsEnabledOnly").addClass('disabled');
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/cert/tls",
|
url: "/api/cert/tls",
|
||||||
|
method: "POST",
|
||||||
data: {set: thisValue},
|
data: {set: thisValue},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
alert(data.error);
|
msgbox(data.error, false);
|
||||||
}else{
|
}else{
|
||||||
//Updated
|
//Updated
|
||||||
|
|
||||||
//Check for case if the port is invalid default ports
|
//Check for case if the port is invalid default ports
|
||||||
if ($("#incomingPort").val() == "80" && thisValue == true){
|
if ($("#incomingPort").val() == "80" && thisValue == true){
|
||||||
confirmBox("Change listen port to :443?", function(choice){
|
confirmBox("Change listen port to :443?", function(choice){
|
||||||
|
@ -100,7 +100,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send the AJAX POST request
|
// Send the AJAX POST request
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/api/streamprox/config/add',
|
url: '/api/streamprox/config/add',
|
||||||
data: form.serialize(),
|
data: form.serialize(),
|
||||||
@ -285,7 +285,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send the AJAX POST request
|
// Send the AJAX POST request
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/api/streamprox/config/edit',
|
url: '/api/streamprox/config/edit',
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -316,7 +316,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deleteTCPProxyConfig(configUUID){
|
function deleteTCPProxyConfig(configUUID){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/streamprox/config/delete",
|
url: "/api/streamprox/config/delete",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {uuid: configUUID},
|
data: {uuid: configUUID},
|
||||||
@ -333,7 +333,7 @@
|
|||||||
|
|
||||||
//Start a TCP proxy by their config UUID
|
//Start a TCP proxy by their config UUID
|
||||||
function startStreamProx(configUUID){
|
function startStreamProx(configUUID){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/streamprox/config/start",
|
url: "/api/streamprox/config/start",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {uuid: configUUID},
|
data: {uuid: configUUID},
|
||||||
@ -351,7 +351,7 @@
|
|||||||
|
|
||||||
//Stop a TCP proxy by their config UUID
|
//Stop a TCP proxy by their config UUID
|
||||||
function stopStreamProx(configUUID){
|
function stopStreamProx(configUUID){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/streamprox/config/stop",
|
url: "/api/streamprox/config/stop",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {uuid: configUUID},
|
data: {uuid: configUUID},
|
||||||
|
@ -233,7 +233,7 @@
|
|||||||
const newPassword = document.getElementsByName('newPassword')[0].value;
|
const newPassword = document.getElementsByName('newPassword')[0].value;
|
||||||
const confirmNewPassword = document.getElementsByName('confirmNewPassword')[0].value;
|
const confirmNewPassword = document.getElementsByName('confirmNewPassword')[0].value;
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "/api/auth/changePassword",
|
url: "/api/auth/changePassword",
|
||||||
data: {
|
data: {
|
||||||
@ -279,7 +279,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "/api/tools/smtp/set",
|
url: "/api/tools/smtp/set",
|
||||||
data: data,
|
data: data,
|
||||||
|
@ -190,7 +190,7 @@
|
|||||||
function updateVDTargetTLSState(){
|
function updateVDTargetTLSState(){
|
||||||
var targetDomain = $("#virtualDirectoryDomain").val().trim();
|
var targetDomain = $("#virtualDirectoryDomain").val().trim();
|
||||||
if (targetDomain != ""){
|
if (targetDomain != ""){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/tlscheck",
|
url: "/api/proxy/tlscheck",
|
||||||
data: {url: targetDomain},
|
data: {url: targetDomain},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
@ -252,7 +252,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Create a virtual directory endpoint
|
//Create a virtual directory endpoint
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/vdir/add",
|
url: "/api/proxy/vdir/add",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -295,7 +295,7 @@
|
|||||||
epType = "root";
|
epType = "root";
|
||||||
path = "";
|
path = "";
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/vdir/del",
|
url: "/api/proxy/vdir/del",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -384,7 +384,7 @@
|
|||||||
|
|
||||||
//console.log(mathingPath, newDomain, requireTLS, skipValidation);
|
//console.log(mathingPath, newDomain, requireTLS, skipValidation);
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/vdir/edit",
|
url: "/api/proxy/vdir/edit",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -164,7 +164,7 @@
|
|||||||
|
|
||||||
$("#webserv_enableDirList").off("change").on("change", function(){
|
$("#webserv_enableDirList").off("change").on("change", function(){
|
||||||
let enable = $(this)[0].checked;
|
let enable = $(this)[0].checked;
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/webserv/setDirList",
|
url: "/api/webserv/setDirList",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {"enable": enable},
|
data: {"enable": enable},
|
||||||
@ -186,7 +186,7 @@
|
|||||||
confirmBox("This setting might cause port conflict. Continue Anyway?", function(choice){
|
confirmBox("This setting might cause port conflict. Continue Anyway?", function(choice){
|
||||||
if (choice == true){
|
if (choice == true){
|
||||||
//Continue anyway
|
//Continue anyway
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/webserv/setPort",
|
url: "/api/webserv/setPort",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {"port": newPort},
|
data: {"port": newPort},
|
||||||
@ -206,7 +206,7 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/webserv/setPort",
|
url: "/api/webserv/setPort",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {"port": newPort},
|
data: {"port": newPort},
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="theme-color" content="#4b75ff">
|
<meta name="theme-color" content="#4b75ff">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="icon" type="image/png" href="./favicon.png" />
|
<link rel="icon" type="image/png" href="./favicon.png" />
|
||||||
<title>Control Panel | Zoraxy</title>
|
<title>Control Panel | Zoraxy</title>
|
||||||
<link rel="stylesheet" href="script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="script/semantic/semantic.min.css">
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="icon" type="image/png" href="./favicon.png" />
|
<link rel="icon" type="image/png" href="./favicon.png" />
|
||||||
<title>Login | Zoraxy</title>
|
<title>Login | Zoraxy</title>
|
||||||
<link rel="stylesheet" href="script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="script/semantic/semantic.min.css">
|
||||||
@ -250,10 +251,10 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
$("#regsiterbtn").on("click", function(event){
|
$("#regsiterbtn").on("click", function(event){
|
||||||
var username = $("#username").val();
|
let username = $("#username").val();
|
||||||
var magic = $("#magic").val();
|
let magic = $("#magic").val();
|
||||||
var repeatMagic = $("#repeatMagic").val();
|
let repeatMagic = $("#repeatMagic").val();
|
||||||
|
let csrfToken = document.getElementsByTagName("meta")["zoraxy.csrf.Token"].getAttribute("content");
|
||||||
if (magic !== repeatMagic) {
|
if (magic !== repeatMagic) {
|
||||||
alert("Password does not match");
|
alert("Password does not match");
|
||||||
return;
|
return;
|
||||||
@ -262,6 +263,9 @@
|
|||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/auth/register",
|
url: "/api/auth/register",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
beforeSend: function(request) {
|
||||||
|
request.setRequestHeader("X-CSRF-Token",csrfToken);
|
||||||
|
},
|
||||||
data: {
|
data: {
|
||||||
username: username,
|
username: username,
|
||||||
password: magic
|
password: magic
|
||||||
@ -297,29 +301,45 @@
|
|||||||
|
|
||||||
//Login system with the given username and password
|
//Login system with the given username and password
|
||||||
function login(){
|
function login(){
|
||||||
var username = $("#username").val();
|
let username = $("#username").val();
|
||||||
var magic = $("#magic").val();
|
let magic = $("#magic").val();
|
||||||
var rmbme = document.getElementById("rmbme").checked;
|
let rmbme = document.getElementById("rmbme").checked;
|
||||||
|
let csrfToken = document.getElementsByTagName("meta")["zoraxy.csrf.Token"].getAttribute("content");
|
||||||
$("#errmsg").stop().finish().slideUp("fast");
|
$("#errmsg").stop().finish().slideUp("fast");
|
||||||
$("input").addClass('disabled');
|
$("input").addClass('disabled');
|
||||||
$.post(loginAddress, {"username": username, "password": magic, "rmbme": rmbme}).done(function(data){
|
$.ajax({
|
||||||
if (data.error !== undefined){
|
url: loginAddress,
|
||||||
//Something went wrong during the login
|
type: "POST",
|
||||||
$("#errmsg").html(`<i class="red remove icon"></i> ${data.error}`);
|
beforeSend: function(request) {
|
||||||
$("#errmsg").stop().finish().slideDown('fast');
|
request.setRequestHeader("X-CSRF-Token",csrfToken);
|
||||||
}else if(data.redirect !== undefined){
|
},
|
||||||
//LDAP Related Code
|
data: {
|
||||||
window.location.href = data.redirect;
|
"username": username,
|
||||||
}else{
|
"password": magic,
|
||||||
//Login succeed
|
"rmbme": rmbme,
|
||||||
if (redirectionAddress == ""){
|
},
|
||||||
//Redirect back to index
|
success: function(data){
|
||||||
window.location.href = "./";
|
if (data.error !== undefined){
|
||||||
|
//Something went wrong during the login
|
||||||
|
$("#errmsg").html(`<i class="red remove icon"></i> ${data.error}`);
|
||||||
|
$("#errmsg").stop().finish().slideDown('fast');
|
||||||
|
}else if(data.redirect !== undefined){
|
||||||
|
//LDAP Related Code
|
||||||
|
window.location.href = data.redirect;
|
||||||
}else{
|
}else{
|
||||||
window.location.href = redirectionAddress;
|
//Login succeed
|
||||||
|
if (redirectionAddress == ""){
|
||||||
|
//Redirect back to index
|
||||||
|
window.location.href = "./";
|
||||||
|
}else{
|
||||||
|
window.location.href = redirectionAddress;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
$("input").removeClass('disabled');
|
||||||
|
},
|
||||||
|
error: function(){
|
||||||
|
alert("Something went wrong.")
|
||||||
}
|
}
|
||||||
$("input").removeClass('disabled');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<meta name="robots" content="noindex" />
|
<meta name="robots" content="noindex" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<link rel="icon" type="image/png" href="./favicon.png" />
|
<link rel="icon" type="image/png" href="./favicon.png" />
|
||||||
@ -255,25 +256,36 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Send POST request with input values as data
|
// Send POST request with input values as data
|
||||||
$.post('/api/account/new', { username: username, token: token, newpw: newPassword })
|
let csrfToken = document.getElementsByTagName("meta")["zoraxy.csrf.Token"].getAttribute("content");
|
||||||
.done(function(data) {
|
$.ajax({
|
||||||
// Handle successful response
|
url: "/api/account/new",
|
||||||
if (data.error != undefined){
|
method: "POST",
|
||||||
$("#errmsg").html(`<i class="red circle times icon"></i> ` + data.error);
|
data: {
|
||||||
$("#errmsg").show();
|
username: username,
|
||||||
}else{
|
token: token,
|
||||||
$("#errmsg").hide();
|
newpw: newPassword
|
||||||
$("#countdown").hide();
|
},
|
||||||
$("#succmsg").show();
|
headers: {
|
||||||
setTimeout(function(){
|
"X-CSRF-Token": csrfToken,
|
||||||
window.location.href = "/";
|
},
|
||||||
}, 3000);
|
success: function(data){
|
||||||
|
// Handle successful response
|
||||||
|
if (data.error != undefined){
|
||||||
|
$("#errmsg").html(`<i class="red circle times icon"></i> ` + data.error);
|
||||||
|
$("#errmsg").show();
|
||||||
|
}else{
|
||||||
|
$("#errmsg").hide();
|
||||||
|
$("#countdown").hide();
|
||||||
|
$("#succmsg").show();
|
||||||
|
setTimeout(function(){
|
||||||
|
window.location.href = "/";
|
||||||
|
}, 3000);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(){
|
||||||
|
console.error(error);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fail(function(error) {
|
|
||||||
// Handle error response
|
|
||||||
console.error(error);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -26,4 +26,18 @@ Object.defineProperty(String.prototype, 'capitalize', {
|
|||||||
return this.charAt(0).toUpperCase() + this.slice(1);
|
return this.charAt(0).toUpperCase() + this.slice(1);
|
||||||
},
|
},
|
||||||
enumerable: false
|
enumerable: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//Add a new function to jquery for ajax override with csrf token injected
|
||||||
|
$.cjax = function(payload){
|
||||||
|
let requireTokenMethod = ["POST", "PUT", "DELETE"];;
|
||||||
|
if (requireTokenMethod.includes(payload.method) || requireTokenMethod.includes(payload.type)){
|
||||||
|
//csrf token is required
|
||||||
|
let csrfToken = document.getElementsByTagName("meta")["zoraxy.csrf.Token"].getAttribute("content");
|
||||||
|
payload.headers = {
|
||||||
|
"X-CSRF-Token": csrfToken,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$.ajax(payload);
|
||||||
|
}
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#refreshAccessRuleListBtn{
|
#refreshAccessRuleListBtn{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -94,7 +96,7 @@
|
|||||||
$("#accessRuleForm input[name='accessRuleName']").val("");
|
$("#accessRuleForm input[name='accessRuleName']").val("");
|
||||||
$("#accessRuleForm textarea[name='description']").val("");
|
$("#accessRuleForm textarea[name='description']").val("");
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/access/create",
|
url: "/api/access/create",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -162,7 +164,7 @@
|
|||||||
console.log('Access Rule Name:', accessRuleName);
|
console.log('Access Rule Name:', accessRuleName);
|
||||||
console.log('Description:', description);
|
console.log('Description:', description);
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/access/update",
|
url: "/api/access/update",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -238,7 +240,7 @@
|
|||||||
}
|
}
|
||||||
let accessRuleName = $("#modifyRuleInfo input[name='accessRuleName']").val();
|
let accessRuleName = $("#modifyRuleInfo input[name='accessRuleName']").val();
|
||||||
if (confirm("Confirm removing access rule " + accessRuleName + "?")){
|
if (confirm("Confirm removing access rule " + accessRuleName + "?")){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/access/remove",
|
url: "/api/access/remove",
|
||||||
data: {
|
data: {
|
||||||
"id": accessRuleUUID
|
"id": accessRuleUUID
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.disabled.table{
|
.disabled.table{
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
@ -234,8 +236,9 @@
|
|||||||
initRenewerConfigFromFile();
|
initRenewerConfigFromFile();
|
||||||
|
|
||||||
function saveEmailToConfig(btn){
|
function saveEmailToConfig(btn){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/acme/autoRenew/email",
|
url: "/api/acme/autoRenew/email",
|
||||||
|
method: "POST",
|
||||||
data: {set: $("#caRegisterEmail").val()},
|
data: {set: $("#caRegisterEmail").val()},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -256,27 +259,29 @@
|
|||||||
|
|
||||||
function toggleAutoRenew(){
|
function toggleAutoRenew(){
|
||||||
var enabled = $("#enableCertAutoRenew").parent().checkbox("is checked");
|
var enabled = $("#enableCertAutoRenew").parent().checkbox("is checked");
|
||||||
$.post("/api/acme/autoRenew/enable?enable=" + enabled, function(data){
|
$.cjax({
|
||||||
if (data.error){
|
url: "/api/acme/autoRenew/enable",
|
||||||
parent.msgbox(data.error, false, 5000);
|
method: "POST",
|
||||||
if (enabled){
|
data: {"enable": enabled},
|
||||||
enableTrigerOnChangeEvent = false;
|
success: function(data){
|
||||||
$("#enableCertAutoRenew").parent().checkbox("set unchecked");
|
if (data.error){
|
||||||
enableTrigerOnChangeEvent = true;
|
parent.msgbox(data.error, false, 5000);
|
||||||
}
|
if (enabled){
|
||||||
if (parent && parent.setACMEEnableStates){
|
enableTrigerOnChangeEvent = false;
|
||||||
parent.setACMEEnableStates(!enabled);
|
$("#enableCertAutoRenew").parent().checkbox("set unchecked");
|
||||||
}
|
enableTrigerOnChangeEvent = true;
|
||||||
}else{
|
}
|
||||||
$("#enableToggleSucc").stop().finish().fadeIn("fast").delay(3000).fadeOut("fast");
|
if (parent && parent.setACMEEnableStates){
|
||||||
if (parent && parent.setACMEEnableStates){
|
parent.setACMEEnableStates(!enabled);
|
||||||
parent.setACMEEnableStates(enabled);
|
}
|
||||||
|
}else{
|
||||||
|
$("#enableToggleSucc").stop().finish().fadeIn("fast").delay(3000).fadeOut("fast");
|
||||||
|
if (parent && parent.setACMEEnableStates){
|
||||||
|
parent.setACMEEnableStates(enabled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Render the domains table that exists in this zoraxy host
|
//Render the domains table that exists in this zoraxy host
|
||||||
@ -630,7 +635,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/acme/autoRenew/setDNS",
|
url: "/api/acme/autoRenew/setDNS",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -843,8 +848,9 @@
|
|||||||
function saveAutoRenewPolicy(){
|
function saveAutoRenewPolicy(){
|
||||||
let autoRenewAll = $("#renewAllSupported").parent().checkbox("is checked");
|
let autoRenewAll = $("#renewAllSupported").parent().checkbox("is checked");
|
||||||
if (autoRenewAll == true){
|
if (autoRenewAll == true){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/acme/autoRenew/setDomains",
|
url: "/api/acme/autoRenew/setDomains",
|
||||||
|
method: "POST",
|
||||||
data: {opr: "setAuto"},
|
data: {opr: "setAuto"},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
parent.msgbox("Renew policy rule updated")
|
parent.msgbox("Renew policy rule updated")
|
||||||
@ -856,8 +862,9 @@
|
|||||||
checkedNames.push($(this).attr('name'));
|
checkedNames.push($(this).attr('name'));
|
||||||
});
|
});
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/acme/autoRenew/setDomains",
|
url: "/api/acme/autoRenew/setDomains",
|
||||||
|
method: "POST",
|
||||||
data: {opr: "setSelected", domains: JSON.stringify(checkedNames)},
|
data: {opr: "setSelected", domains: JSON.stringify(checkedNames)},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
parent.msgbox("Renew policy rule updated")
|
parent.msgbox("Renew policy rule updated")
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<br>
|
<br>
|
||||||
@ -46,7 +48,7 @@
|
|||||||
|
|
||||||
function handleResetStats(){
|
function handleResetStats(){
|
||||||
if (confirm("Confirm remove statistics from " + startDate + " to " + endDate +"?")){
|
if (confirm("Confirm remove statistics from " + startDate + " to " + endDate +"?")){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/analytic/resetRange?start=" + startDate + "&end=" + endDate,
|
url: "/api/analytic/resetRange?start=" + startDate + "&end=" + endDate,
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
success: function(data){
|
success: function(data){
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<br>
|
<br>
|
||||||
@ -71,7 +73,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function initAliasNames(){
|
function initAliasNames(){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/detail",
|
url: "/api/proxy/detail",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -130,7 +132,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveCurrentAliasList(callback=undefined){
|
function saveCurrentAliasList(callback=undefined){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/setAlias",
|
url: "/api/proxy/setAlias",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data:{
|
data:{
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<br>
|
<br>
|
||||||
@ -174,7 +176,7 @@
|
|||||||
parent.msgbox("Matching prefix cannot be empty!", false, 5000);
|
parent.msgbox("Matching prefix cannot be empty!", false, 5000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/auth/exceptions/add",
|
url: "/api/proxy/auth/exceptions/add",
|
||||||
data:{
|
data:{
|
||||||
ep: editingEndpoint.ep,
|
ep: editingEndpoint.ep,
|
||||||
@ -195,7 +197,7 @@
|
|||||||
|
|
||||||
function removeExceptionPath(object){
|
function removeExceptionPath(object){
|
||||||
let matchingPrefix = $(object).attr("prefix");
|
let matchingPrefix = $(object).attr("prefix");
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/auth/exceptions/delete",
|
url: "/api/proxy/auth/exceptions/delete",
|
||||||
data:{
|
data:{
|
||||||
ep: editingEndpoint.ep,
|
ep: editingEndpoint.ep,
|
||||||
@ -290,7 +292,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveCredentials(){
|
function saveCredentials(){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/updateCredentials",
|
url: "/api/proxy/updateCredentials",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<br>
|
<br>
|
||||||
@ -70,10 +72,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById("uploadForm").addEventListener("submit", function(event) {
|
$("#uploadForm").submit(function(event) {
|
||||||
event.preventDefault(); // Prevent the form from submitting normally
|
event.preventDefault(); // Prevent the form from submitting normally
|
||||||
|
|
||||||
var fileInput = document.getElementById("fileInput");
|
var fileInput = $("#fileInput")[0];
|
||||||
var file = fileInput.files[0];
|
var file = fileInput.files[0];
|
||||||
if (!file) {
|
if (!file) {
|
||||||
alert("Missing file.");
|
alert("Missing file.");
|
||||||
@ -83,18 +85,19 @@
|
|||||||
var formData = new FormData();
|
var formData = new FormData();
|
||||||
formData.append("file", file);
|
formData.append("file", file);
|
||||||
|
|
||||||
var xhr = new XMLHttpRequest();
|
$.cjax({
|
||||||
xhr.open("POST", "/api/conf/import", true);
|
url: "/api/conf/import",
|
||||||
xhr.onreadystatechange = function() {
|
type: "POST",
|
||||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
data: formData,
|
||||||
if (xhr.status === 200) {
|
processData: false, // Not to process the data
|
||||||
parent.msgbox("Config restore succeed. Restart Zoraxy to apply changes.")
|
contentType: false, // Not to set contentType
|
||||||
} else {
|
success: function(response) {
|
||||||
parent.msgbox("Restore failed: " + xhr.responseText, false, 5000);
|
parent.msgbox("Config restore succeed. Restart Zoraxy to apply changes.");
|
||||||
}
|
},
|
||||||
|
error: function(xhr) {
|
||||||
|
parent.msgbox("Restore failed: " + xhr.responseText, false, 5000);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
xhr.send(formData);
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.ui.tabular.menu .item.narrowpadding{
|
.ui.tabular.menu .item.narrowpadding{
|
||||||
padding: 0.6em !important;
|
padding: 0.6em !important;
|
||||||
@ -92,9 +94,6 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<br>
|
<br>
|
||||||
<div class="ui yellow message">
|
|
||||||
<p><i class="exclamation triangle icon"></i>Settings in this section are for advanced users. Invalid settings might cause werid, unexpected behavior.</p>
|
|
||||||
</div>
|
|
||||||
<div class="ui container">
|
<div class="ui container">
|
||||||
<h4>Overwrite Host Header</h4>
|
<h4>Overwrite Host Header</h4>
|
||||||
<p>Manual override the automatic "Host" header rewrite logic. Leave empty for automatic.</p>
|
<p>Manual override the automatic "Host" header rewrite logic. Leave empty for automatic.</p>
|
||||||
@ -112,7 +111,9 @@
|
|||||||
<label>Remove Hop-by-hop Header<br>
|
<label>Remove Hop-by-hop Header<br>
|
||||||
<small>This should be ON by default</small></label>
|
<small>This should be ON by default</small></label>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui divider"></div>
|
<div class="ui yellow message">
|
||||||
|
<p><i class="exclamation triangle icon"></i>Settings in this section are for advanced users. Invalid settings might cause werid, unexpected behavior.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -247,8 +248,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/header/add",
|
url: "/api/proxy/header/add",
|
||||||
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
"type": getHeaderEditMode(),
|
"type": getHeaderEditMode(),
|
||||||
"domain": editingEndpoint.ep,
|
"domain": editingEndpoint.ep,
|
||||||
@ -279,10 +281,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deleteCustomHeader(name){
|
function deleteCustomHeader(name){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/header/remove",
|
url: "/api/proxy/header/remove",
|
||||||
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
//"type": editingEndpoint.ept,
|
|
||||||
"domain": editingEndpoint.ep,
|
"domain": editingEndpoint.ep,
|
||||||
"name": name,
|
"name": name,
|
||||||
},
|
},
|
||||||
@ -299,6 +301,7 @@
|
|||||||
$("#headerTable").html(`<tr><td colspan="3"><i class="ui loading spinner icon"></i> Loading</td></tr>`);
|
$("#headerTable").html(`<tr><td colspan="3"><i class="ui loading spinner icon"></i> Loading</td></tr>`);
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/proxy/header/list",
|
url: "/api/proxy/header/list",
|
||||||
|
method: "GET",
|
||||||
data: {
|
data: {
|
||||||
"type": editingEndpoint.ept,
|
"type": editingEndpoint.ept,
|
||||||
"domain": editingEndpoint.ep,
|
"domain": editingEndpoint.ep,
|
||||||
@ -307,7 +310,6 @@
|
|||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
alert(data.error);
|
alert(data.error);
|
||||||
}else{
|
}else{
|
||||||
|
|
||||||
$("#headerTable").html("");
|
$("#headerTable").html("");
|
||||||
data.forEach(header => {
|
data.forEach(header => {
|
||||||
let editModeIcon = header.IsRemove?`<i class="ui red times circle icon"></i>`:`<i class="ui green add circle icon"></i>`;
|
let editModeIcon = header.IsRemove?`<i class="ui red times circle icon"></i>`:`<i class="ui green add circle icon"></i>`;
|
||||||
@ -351,7 +353,7 @@
|
|||||||
/* Bind events to toggles */
|
/* Bind events to toggles */
|
||||||
$("#enableHSTS").on("change", function(){
|
$("#enableHSTS").on("change", function(){
|
||||||
let HSTSEnabled = $("#enableHSTS")[0].checked;
|
let HSTSEnabled = $("#enableHSTS")[0].checked;
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/header/handleHSTS",
|
url: "/api/proxy/header/handleHSTS",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -426,7 +428,7 @@
|
|||||||
$("#permissionPolicyEditor").addClass("disabled");
|
$("#permissionPolicyEditor").addClass("disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/header/handlePermissionPolicy",
|
url: "/api/proxy/header/handlePermissionPolicy",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -532,7 +534,7 @@
|
|||||||
let permissionPolicy = generatePermissionPolicyObject();
|
let permissionPolicy = generatePermissionPolicyObject();
|
||||||
let domain = editingEndpoint.ep;
|
let domain = editingEndpoint.ep;
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/header/handlePermissionPolicy",
|
url: "/api/proxy/header/handlePermissionPolicy",
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
data: {
|
data: {
|
||||||
@ -576,7 +578,7 @@
|
|||||||
|
|
||||||
function updateManualHostOverwriteVal(callback=undefined){
|
function updateManualHostOverwriteVal(callback=undefined){
|
||||||
let newHostname = $("#manualHostOverwrite").val().trim();
|
let newHostname = $("#manualHostOverwrite").val().trim();
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/header/handleHostOverwrite",
|
url: "/api/proxy/header/handleHostOverwrite",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -615,7 +617,7 @@
|
|||||||
//Bind event to the checkbox
|
//Bind event to the checkbox
|
||||||
$("#removeHopByHop").on("change", function(evt){
|
$("#removeHopByHop").on("change", function(evt){
|
||||||
let isChecked = $(this)[0].checked;
|
let isChecked = $(this)[0].checked;
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/header/handleHopByHop",
|
url: "/api/proxy/header/handleHopByHop",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.accessRule{
|
.accessRule{
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -124,12 +126,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initAccessRuleList(function(){
|
initAccessRuleList(function(){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/detail",
|
url: "/api/proxy/detail",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {"type":"host", "epname": editingEndpoint.ep },
|
data: {"type":"host", "epname": editingEndpoint.ep },
|
||||||
@ -160,7 +160,7 @@
|
|||||||
function applyChangeAndClose(){
|
function applyChangeAndClose(){
|
||||||
let newAccessRuleID = $(".accessRule.active").attr("ruleid");
|
let newAccessRuleID = $(".accessRule.active").attr("ruleid");
|
||||||
let targetEndpoint = editingEndpoint.ep;
|
let targetEndpoint = editingEndpoint.ep;
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/access/attach",
|
url: "/api/access/attach",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -2,9 +2,11 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
body{
|
body{
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -3,9 +3,11 @@
|
|||||||
<head>
|
<head>
|
||||||
<!-- Notes: This should be open in its original path-->
|
<!-- Notes: This should be open in its original path-->
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
<link rel="stylesheet" href="../script/semantic/semantic.min.css">
|
||||||
<script src="../script/jquery-3.6.0.min.js"></script>
|
<script src="../script/jquery-3.6.0.min.js"></script>
|
||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.upstreamActions{
|
.upstreamActions{
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -133,7 +135,7 @@
|
|||||||
function initOriginList(){
|
function initOriginList(){
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: "/api/proxy/upstream/list",
|
url: "/api/proxy/upstream/list",
|
||||||
method: "POST",
|
method: "GET",
|
||||||
data: {
|
data: {
|
||||||
"type":"host",
|
"type":"host",
|
||||||
"ep": editingEndpoint.ep
|
"ep": editingEndpoint.ep
|
||||||
@ -284,8 +286,9 @@
|
|||||||
}else{
|
}else{
|
||||||
//URL does not contains https or http protocol tag
|
//URL does not contains https or http protocol tag
|
||||||
//sniff header
|
//sniff header
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/tlscheck",
|
url: "/api/proxy/tlscheck",
|
||||||
|
method: "POST",
|
||||||
data: {url: targetDomain},
|
data: {url: targetDomain},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -313,7 +316,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/upstream/add",
|
url: "/api/proxy/upstream/add",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data:{
|
data:{
|
||||||
@ -365,7 +368,7 @@
|
|||||||
let newConfig = getUpstreamSettingFromDOM(targetDOM);
|
let newConfig = getUpstreamSettingFromDOM(targetDOM);
|
||||||
let isActive = $(targetDOM).find(".enableState")[0].checked;
|
let isActive = $(targetDOM).find(".enableState")[0].checked;
|
||||||
console.log(newConfig);
|
console.log(newConfig);
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/upstream/update",
|
url: "/api/proxy/upstream/update",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -418,8 +421,9 @@
|
|||||||
}else{
|
}else{
|
||||||
//URL does not contains https or http protocol tag
|
//URL does not contains https or http protocol tag
|
||||||
//sniff header
|
//sniff header
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/tlscheck",
|
url: "/api/proxy/tlscheck",
|
||||||
|
method: "POST",
|
||||||
data: {url: targetDomain},
|
data: {url: targetDomain},
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -460,7 +464,7 @@
|
|||||||
|
|
||||||
//Set a weight of a upstream
|
//Set a weight of a upstream
|
||||||
function setUpstreamWeight(originIP, newWeight){
|
function setUpstreamWeight(originIP, newWeight){
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/upstream/setPriority",
|
url: "/api/proxy/upstream/setPriority",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
@ -489,7 +493,7 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//Remove the upstream
|
//Remove the upstream
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/proxy/upstream/remove",
|
url: "/api/proxy/upstream/remove",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -2,12 +2,14 @@
|
|||||||
<head>
|
<head>
|
||||||
<title>File Manager</title>
|
<title>File Manager</title>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0 user-scalable=no">
|
||||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" />
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css" />
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.js"></script>
|
||||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.6.0/jszip.min.js"></script>
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.6.0/jszip.min.js"></script>
|
||||||
<link rel="stylesheet" href="fs.css">
|
<link rel="stylesheet" href="fs.css">
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
@ -199,7 +201,7 @@
|
|||||||
let counter = $(".fileObject.selected").length;
|
let counter = $(".fileObject.selected").length;
|
||||||
$(".fileObject.selected").each(function(){
|
$(".fileObject.selected").each(function(){
|
||||||
let thisFilepath = $(this).attr("filepath");
|
let thisFilepath = $(this).attr("filepath");
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/fs/del?target=" + thisFilepath,
|
url: "/api/fs/del?target=" + thisFilepath,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
success: function(data){
|
success: function(data){
|
||||||
@ -241,22 +243,9 @@
|
|||||||
let filename = $(this).attr("filename");
|
let filename = $(this).attr("filename");
|
||||||
if (ftype != "folder"){
|
if (ftype != "folder"){
|
||||||
let ext = filepath.split(".").pop();
|
let ext = filepath.split(".").pop();
|
||||||
if (isCodeFiles(ext)){
|
openthis($(this), evt);
|
||||||
editableCodeFiles.push({
|
|
||||||
"filename": filename,
|
|
||||||
"filepath": filepath
|
|
||||||
});
|
|
||||||
}else{
|
|
||||||
openthis($(this), evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (editableCodeFiles.length > 0){
|
|
||||||
let hash = encodeURIComponent(JSON.stringify(editableCodeFiles))
|
|
||||||
window.open("notepad/index.html#" + hash);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function refresh(){
|
function refresh(){
|
||||||
@ -571,12 +560,19 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$.post("/api/fs/newFolder?path=" + currentPath + folderName, function(data){
|
$.cjax({
|
||||||
if (data.error != undefined){
|
url: "/api/fs/newFolder",
|
||||||
msgbox(data.error, false);
|
method: "POST",
|
||||||
}else{
|
data: {
|
||||||
msgbox("Folder Created");
|
"path": currentPath + folderName,
|
||||||
refresh();
|
},
|
||||||
|
success: function(data){
|
||||||
|
if (data.error != undefined){
|
||||||
|
msgbox(data.error, false);
|
||||||
|
}else{
|
||||||
|
msgbox("Folder Created");
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -597,8 +593,12 @@
|
|||||||
if (newName && newName != oldName) {
|
if (newName && newName != oldName) {
|
||||||
// User entered a new name, perform renaming logic here
|
// User entered a new name, perform renaming logic here
|
||||||
console.log(oldPath, currentPath + newName);
|
console.log(oldPath, currentPath + newName);
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/fs/move?srcpath=" + oldPath + "&destpath=" + currentPath + newName,
|
url: "/api/fs/move",
|
||||||
|
data: {
|
||||||
|
"srcpath": oldPath,
|
||||||
|
"destpath": currentPath + newName
|
||||||
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -826,6 +826,7 @@
|
|||||||
ajax.addEventListener("error", errorHandler, false);
|
ajax.addEventListener("error", errorHandler, false);
|
||||||
ajax.addEventListener("abort", abortHandler, false);
|
ajax.addEventListener("abort", abortHandler, false);
|
||||||
ajax.open("POST", "/api/fs/upload?dir=" + dir);
|
ajax.open("POST", "/api/fs/upload?dir=" + dir);
|
||||||
|
ajax.setRequestHeader("X-CSRF-Token", document.getElementsByTagName("meta")["zoraxy.csrf.Token"].getAttribute("content"));
|
||||||
ajax.send(formdata);
|
ajax.send(formdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -914,8 +915,12 @@
|
|||||||
let filename = fileToPaste.filename;
|
let filename = fileToPaste.filename;
|
||||||
let filepath = fileToPaste.filepath;
|
let filepath = fileToPaste.filepath;
|
||||||
|
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/fs/move?srcpath=" + filepath + "&destpath=" + currentPath + filename,
|
url: "/api/fs/move",
|
||||||
|
data:{
|
||||||
|
"srcpath": filepath,
|
||||||
|
"destpath": currentPath + filename,
|
||||||
|
},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
success: function(data){
|
success: function(data){
|
||||||
if (data.error != undefined){
|
if (data.error != undefined){
|
||||||
@ -939,7 +944,7 @@
|
|||||||
function copyFirstItemInQueueUntilAllCopied(){
|
function copyFirstItemInQueueUntilAllCopied(){
|
||||||
let file = copyPendingFiles.shift();
|
let file = copyPendingFiles.shift();
|
||||||
let startingDir = currentPath;
|
let startingDir = currentPath;
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/fs/copy",
|
url: "/api/fs/copy",
|
||||||
method: "POST",
|
method: "POST",
|
||||||
data: {
|
data: {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
@ -13,6 +14,7 @@
|
|||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
<script src="../script/tablesort.js"></script>
|
<script src="../script/tablesort.js"></script>
|
||||||
<link rel="stylesheet" href="../main.css">
|
<link rel="stylesheet" href="../main.css">
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
.offlinehost{
|
.offlinehost{
|
||||||
display: none;
|
display: none;
|
||||||
@ -86,9 +88,14 @@
|
|||||||
<div class="ui basic segment" align="center">
|
<div class="ui basic segment" align="center">
|
||||||
<i class="loading spinner icon"></i> Scanning
|
<i class="loading spinner icon"></i> Scanning
|
||||||
</div>`);
|
</div>`);
|
||||||
$.post("/api/tools/ipscan", {start: start, end: end}, function(data) {
|
$.cjax({
|
||||||
displayResults(data);
|
url: "/api/tools/ipscan",
|
||||||
$(".scanbtn").removeClass("disabled");
|
data: {start: start, end: end},
|
||||||
|
method: "POST",
|
||||||
|
success: function(data){
|
||||||
|
displayResults(data);
|
||||||
|
$(".scanbtn").removeClass("disabled");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -109,9 +116,14 @@
|
|||||||
<div class="ui basic segment" align="center">
|
<div class="ui basic segment" align="center">
|
||||||
<i class="loading spinner icon"></i> Scanning
|
<i class="loading spinner icon"></i> Scanning
|
||||||
</div>`);
|
</div>`);
|
||||||
$.post("/api/tools/ipscan", {cidr: cidr}, function(data) {
|
$.cjax({
|
||||||
displayResults(data);
|
url: "/api/tools/ipscan",
|
||||||
$(".scanbtn").removeClass("disabled");
|
method: "POST",
|
||||||
|
data: {cidr: cidr},
|
||||||
|
success: function(data) {
|
||||||
|
displayResults(data);
|
||||||
|
$(".scanbtn").removeClass("disabled");
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
@ -13,6 +14,7 @@
|
|||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
<script src="../script/tablesort.js"></script>
|
<script src="../script/tablesort.js"></script>
|
||||||
<link rel="stylesheet" href="../main.css">
|
<link rel="stylesheet" href="../main.css">
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
body{
|
body{
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
@ -54,7 +56,7 @@
|
|||||||
var domain = $("#domain").val();
|
var domain = $("#domain").val();
|
||||||
$("#discover").addClass("loading").addClass('disabled');
|
$("#discover").addClass("loading").addClass('disabled');
|
||||||
setCountdown();
|
setCountdown();
|
||||||
$.ajax({
|
$.cjax({
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "/api/mdns/discover",
|
url: "/api/mdns/discover",
|
||||||
data: { domain: domain },
|
data: { domain: domain },
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
|
<meta name="zoraxy.csrf.Token" content="{{.csrfToken}}">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
@ -13,6 +14,7 @@
|
|||||||
<script src="../script/semantic/semantic.min.js"></script>
|
<script src="../script/semantic/semantic.min.js"></script>
|
||||||
<script src="../script/tablesort.js"></script>
|
<script src="../script/tablesort.js"></script>
|
||||||
<link rel="stylesheet" href="../main.css">
|
<link rel="stylesheet" href="../main.css">
|
||||||
|
<script src="../script/utils.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#loadingUI{
|
#loadingUI{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -153,7 +155,7 @@
|
|||||||
//Try to ask the server side to create a ssh proxy object
|
//Try to ask the server side to create a ssh proxy object
|
||||||
function createSSHProxy(remoteAddr, remotePort, username){
|
function createSSHProxy(remoteAddr, remotePort, username){
|
||||||
//Request to create a ssh session instance
|
//Request to create a ssh session instance
|
||||||
$.ajax({
|
$.cjax({
|
||||||
url: "/api/tools/webssh",
|
url: "/api/tools/webssh",
|
||||||
data: {ipaddr: remoteAddr, port: remotePort, username:username},
|
data: {ipaddr: remoteAddr, port: remotePort, username:username},
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
Reference in New Issue
Block a user