diff --git a/backend/configs/system.go b/backend/configs/system.go index ee09507ba..284c3e9b5 100644 --- a/backend/configs/system.go +++ b/backend/configs/system.go @@ -13,4 +13,5 @@ type System struct { BaseDir string `mapstructure:"base_dir"` Mode string `mapstructure:"mode"` RepoUrl string `mapstructure:"repo_url"` + IsDemo bool `mapstructure:"is_demo"` } diff --git a/backend/constant/errs.go b/backend/constant/errs.go index cb1f4ac17..e4a0803fc 100644 --- a/backend/constant/errs.go +++ b/backend/constant/errs.go @@ -45,6 +45,7 @@ var ( ErrTypePasswordExpired = "ErrPasswordExpired" ErrTypeNotSafety = "ErrNotSafety" ErrNameIsExist = "ErrNameIsExist" + ErrDemoEnvironment = "ErrDemoEnvironment" ) // app diff --git a/backend/i18n/lang/en.yaml b/backend/i18n/lang/en.yaml index 2e6e5f3d5..e730d53a4 100644 --- a/backend/i18n/lang/en.yaml +++ b/backend/i18n/lang/en.yaml @@ -15,6 +15,7 @@ ErrRepoNotValid: "Remote repository verification failed!" #common ErrNameIsExist: "Name is already exist" +ErrDemoEnvironment: "Demo server, prohibit this operation!" #app ErrPortInUsed: "{{ .detail }} port already in use" diff --git a/backend/i18n/lang/zh.yaml b/backend/i18n/lang/zh.yaml index f62ab5362..f48994cab 100644 --- a/backend/i18n/lang/zh.yaml +++ b/backend/i18n/lang/zh.yaml @@ -15,6 +15,7 @@ ErrRepoNotValid: "远程仓库校验失败!" #common ErrNameIsExist: "名称已存在" +ErrDemoEnvironment: "演示服务器,禁止此操作!" #app ErrPortInUsed: "{{ .detail }} 端口已被占用!" diff --git a/backend/init/router/router.go b/backend/init/router/router.go index 689a0992a..49e43f754 100644 --- a/backend/init/router/router.go +++ b/backend/init/router/router.go @@ -1,6 +1,7 @@ package router import ( + "github.com/1Panel-dev/1Panel/backend/global" "html/template" "net/http" @@ -45,6 +46,10 @@ func Routers() *gin.Engine { // Router.Use(middleware.CSRF()) // Router.Use(middleware.LoadCsrfToken()) + if global.CONF.System.IsDemo { + Router.Use(middleware.DemoHandle()) + } + setWebStatic(Router) Router.Use(i18n.GinI18nLocalize()) diff --git a/backend/init/viper/viper.go b/backend/init/viper/viper.go index 77f30aaa5..186adfa31 100644 --- a/backend/init/viper/viper.go +++ b/backend/init/viper/viper.go @@ -18,7 +18,7 @@ import ( func Init() { baseDir := "/opt" - mode := "dev" + mode := "" fileOp := files.NewFileOp() v := viper.NewWithOptions() v.SetConfigType("yaml") @@ -68,6 +68,7 @@ func Init() { global.CONF = serverConfig global.CONF.BaseDir = baseDir + global.CONF.System.IsDemo = v.GetBool("system.is_demo") global.CONF.System.DataDir = global.CONF.BaseDir + "/1panel" global.CONF.System.Cache = global.CONF.System.DataDir + "/cache" global.CONF.System.Backup = global.CONF.System.DataDir + "/backup" diff --git a/backend/middleware/demo_handle.go b/backend/middleware/demo_handle.go new file mode 100644 index 000000000..422f1f8ac --- /dev/null +++ b/backend/middleware/demo_handle.go @@ -0,0 +1,40 @@ +package middleware + +import ( + "github.com/1Panel-dev/1Panel/backend/app/dto" + "github.com/1Panel-dev/1Panel/backend/buserr" + "github.com/1Panel-dev/1Panel/backend/constant" + "github.com/gin-gonic/gin" + "net/http" + "strings" +) + +var whiteUrlList = map[string]struct{}{ + "/api/v1/auth/login": {}, + "/api/v1/websites/config": {}, + "/api/v1/websites/waf/config": {}, + "/api/v1/files/loadfile": {}, + "/api/v1/files/size": {}, + "/api/v1/logs/operation": {}, + "/api/v1/logs/login": {}, + "/api/v1/auth/logout": {}, +} + +func DemoHandle() gin.HandlerFunc { + return func(c *gin.Context) { + if strings.Contains(c.Request.URL.Path, "search") || c.Request.Method == http.MethodGet { + c.Next() + return + } + if _, ok := whiteUrlList[c.Request.URL.Path]; ok { + c.Next() + return + } + + c.JSON(http.StatusInternalServerError, dto.Response{ + Code: http.StatusInternalServerError, + Message: buserr.New(constant.ErrDemoEnvironment).Error(), + }) + c.Abort() + } +} diff --git a/backend/router/ro_app.go b/backend/router/ro_app.go index 71bc749eb..01184c322 100644 --- a/backend/router/ro_app.go +++ b/backend/router/ro_app.go @@ -26,7 +26,7 @@ func (a *AppRouter) InitAppRouter(Router *gin.RouterGroup) { appRouter.GET("/installed/loadport/:key", baseApi.LoadPort) appRouter.GET("/installed/loadpassword/:key", baseApi.LoadPassword) appRouter.GET("/installed/delete/check/:appInstallId", baseApi.DeleteCheck) - appRouter.POST("/installed", baseApi.SearchAppInstalled) + appRouter.POST("/installed/search", baseApi.SearchAppInstalled) appRouter.POST("/installed/op", baseApi.OperateInstalled) appRouter.POST("/installed/sync", baseApi.SyncInstalled) appRouter.POST("/installed/backups", baseApi.SearchInstalledBackup) diff --git a/cmd/server/conf/app.yaml b/cmd/server/conf/app.yaml index e7eb127d8..54fe40287 100644 --- a/cmd/server/conf/app.yaml +++ b/cmd/server/conf/app.yaml @@ -3,6 +3,7 @@ system: base_dir: /opt mode: dev repo_url: https://1panel.oss-cn-hangzhou.aliyuncs.com/package + is_demo: false log: level: debug diff --git a/frontend/src/api/helper/check-status.ts b/frontend/src/api/helper/check-status.ts index 3c60b2de5..4c66922ae 100644 --- a/frontend/src/api/helper/check-status.ts +++ b/frontend/src/api/helper/check-status.ts @@ -2,27 +2,22 @@ import i18n from '@/lang'; import router from '@/routers'; import { MsgError } from '@/utils/message'; -/** - * @description: 校验网络请求状态码 - * @param {Number} status - * @return void - */ -export const checkStatus = (status: number): void => { +export const checkStatus = (status: number, msg: string): void => { switch (status) { case 400: - MsgError(i18n.global.t('commons.res.paramError')); + MsgError(msg ? msg : i18n.global.t('commons.res.paramError')); break; case 404: - MsgError(i18n.global.t('commons.res.notFound')); + MsgError(msg ? msg : i18n.global.t('commons.res.notFound')); break; case 403: router.replace({ path: '/' }); - MsgError(i18n.global.t('commons.res.forbidden')); + MsgError(msg ? msg : i18n.global.t('commons.res.forbidden')); break; case 500: - MsgError(i18n.global.t('commons.res.serverError')); + MsgError(msg ? msg : i18n.global.t('commons.res.serverError')); break; default: - MsgError(i18n.global.t('commons.res.commonError')); + MsgError(msg ? msg : i18n.global.t('commons.res.commonError')); } }; diff --git a/frontend/src/api/index.ts b/frontend/src/api/index.ts index 953f34063..da9efb240 100644 --- a/frontend/src/api/index.ts +++ b/frontend/src/api/index.ts @@ -79,7 +79,7 @@ class RequestHttp { async (error: AxiosError) => { const { response } = error; if (error.message.indexOf('timeout') !== -1) MsgError('请求超时!请您稍后重试'); - if (response) checkStatus(response.status); + if (response) checkStatus(response.status, response.data['message']); if (!window.navigator.onLine) router.replace({ path: '/500' }); return Promise.reject(error); }, diff --git a/frontend/src/api/modules/app.ts b/frontend/src/api/modules/app.ts index d173c8f75..f6324f259 100644 --- a/frontend/src/api/modules/app.ts +++ b/frontend/src/api/modules/app.ts @@ -31,7 +31,7 @@ export const ChangePort = (params: App.ChangePort) => { }; export const SearchAppInstalled = (search: App.AppInstallSearch) => { - return http.post>('apps/installed', search); + return http.post>('apps/installed/search', search); }; export const GetAppPort = (key: string) => { @@ -51,7 +51,7 @@ export const AppInstalledDeleteCheck = (appInstallId: number) => { }; export const GetAppInstalled = (search: App.AppInstalledSearch) => { - return http.post('apps/installed', search); + return http.post('apps/installed/search', search); }; export const InstalledOp = (op: App.AppInstalledOp) => { diff --git a/frontend/src/views/website/website/config/basic/limit-conn/index.vue b/frontend/src/views/website/website/config/basic/limit-conn/index.vue index 3ff1b02e8..ad0505a79 100644 --- a/frontend/src/views/website/website/config/basic/limit-conn/index.vue +++ b/frontend/src/views/website/website/config/basic/limit-conn/index.vue @@ -155,6 +155,9 @@ const submit = async (formEl: FormInstance | undefined) => { search(req); }) .finally(() => { + if (req.operate === 'add') { + enable.value = false; + } loading.value = false; }); }); diff --git a/frontend/src/views/website/website/config/safety/ccdeny/index.vue b/frontend/src/views/website/website/config/safety/ccdeny/index.vue index be42c7e4f..f07810344 100644 --- a/frontend/src/views/website/website/config/safety/ccdeny/index.vue +++ b/frontend/src/views/website/website/config/safety/ccdeny/index.vue @@ -102,8 +102,12 @@ const get = async () => { const updateEnable = async (enable: boolean) => { enableUpdate.value.enable = enable; loading.value = true; - await UpdateWafEnable(enableUpdate.value); - loading.value = false; + try { + await UpdateWafEnable(enableUpdate.value); + } catch (error) { + form.enable = !enable; + loading.value = false; + } }; const submit = async (formEl: FormInstance | undefined) => { diff --git a/frontend/src/views/website/website/config/safety/file-block-list/index.vue b/frontend/src/views/website/website/config/safety/file-block-list/index.vue index 88839e2f3..fe07fe504 100644 --- a/frontend/src/views/website/website/config/safety/file-block-list/index.vue +++ b/frontend/src/views/website/website/config/safety/file-block-list/index.vue @@ -87,9 +87,10 @@ const get = async () => { }; const remove = (index: number) => { - data.value.splice(index, 1); + const copyList = data.value.concat(); + copyList.splice(index, 1); const extArray = []; - data.value.forEach((d) => { + copyList.forEach((d) => { extArray.push(d.file); }); submit(extArray); @@ -123,8 +124,12 @@ const submit = async (extArray: string[]) => { const updateEnable = async (enable: boolean) => { enableUpdate.value.enable = enable; loading.value = true; - await UpdateWafEnable(enableUpdate.value); - loading.value = false; + try { + await UpdateWafEnable(enableUpdate.value); + } catch (error) { + enableUpdate.value.enable = !enable; + loading.value = false; + } }; onMounted(() => { diff --git a/frontend/src/views/website/website/config/safety/simple-list/index.vue b/frontend/src/views/website/website/config/safety/simple-list/index.vue index c95daab46..bec900d8c 100644 --- a/frontend/src/views/website/website/config/safety/simple-list/index.vue +++ b/frontend/src/views/website/website/config/safety/simple-list/index.vue @@ -102,9 +102,10 @@ const get = async () => { }; const removeIp = (index: number) => { - data.value.splice(index, 1); + const copyList = data.value.concat(); + copyList.splice(index, 1); let ipArray = []; - data.value.forEach((d) => { + copyList.forEach((d) => { ipArray.push(d.ip); }); submit(ipArray); @@ -146,8 +147,12 @@ const submit = async (ipList: string[]) => { const updateEnable = async (enable: boolean) => { enableUpdate.value.enable = enable; loading.value = true; - await UpdateWafEnable(enableUpdate.value); - loading.value = false; + try { + await UpdateWafEnable(enableUpdate.value); + } catch (error) { + enableUpdate.value.enable = !enable; + loading.value = false; + } }; onMounted(() => { diff --git a/frontend/src/views/website/website/config/safety/value-list/index.vue b/frontend/src/views/website/website/config/safety/value-list/index.vue index 3962db009..9c24cabfd 100644 --- a/frontend/src/views/website/website/config/safety/value-list/index.vue +++ b/frontend/src/views/website/website/config/safety/value-list/index.vue @@ -143,8 +143,12 @@ const openCreate = () => { const updateEnable = async (enable: boolean) => { enableUpdate.value.enable = enable; loading.value = true; - await UpdateWafEnable(enableUpdate.value); - loading.value = false; + try { + await UpdateWafEnable(enableUpdate.value); + } catch (error) { + enableUpdate.value.enable = !enable; + loading.value = false; + } }; const submit = async (addArray: string[]) => { diff --git a/frontend/src/views/website/website/create/index.vue b/frontend/src/views/website/website/create/index.vue index 4206afcef..87a584268 100644 --- a/frontend/src/views/website/website/create/index.vue +++ b/frontend/src/views/website/website/create/index.vue @@ -333,21 +333,25 @@ const submit = async (formEl: FormInstance | undefined) => { return; } loading.value = true; - PreCheck({}).then((res) => { - if (res.data) { + PreCheck({}) + .then((res) => { + if (res.data) { + loading.value = false; + preCheckRef.value.acceptParams({ items: res.data }); + } else { + CreateWebsite(website.value) + .then(() => { + MsgSuccess(i18n.global.t('commons.msg.createSuccess')); + handleClose(); + }) + .finally(() => { + loading.value = false; + }); + } + }) + .catch(() => { loading.value = false; - preCheckRef.value.acceptParams({ items: res.data }); - } else { - CreateWebsite(website.value) - .then(() => { - MsgSuccess(i18n.global.t('commons.msg.createSuccess')); - handleClose(); - }) - .finally(() => { - loading.value = false; - }); - } - }); + }); }); };