diff --git a/build/sysroot/etc/casaos/user-service.conf.sample b/build/sysroot/etc/casaos/user-service.conf.sample index 5c459ea..5f985d1 100755 --- a/build/sysroot/etc/casaos/user-service.conf.sample +++ b/build/sysroot/etc/casaos/user-service.conf.sample @@ -11,12 +11,21 @@ UserDataPath = /var/lib/casaos [oidc] AuthServer = https://account.nextzenvn.com ClientID = WzN5QB9e0LfCSAYTB542RLpIGKcAWNNZgVbeTLaz -ClientSecret = D1mbEz1VHkPnhvMGPfj5aAmjOuZ1ZIYGm7qAReMCivdXwiQ60BJoa4cpdX5m9Z5aKgtR8d56xgmYAy7TR86MEV6zJXfjxy2lf0TTAPXc8ftEcst8fPi6B9IFe3aDBo8x +ClientSecret = D1mbEz1VHkPnhvMGPfj5aAmjOuZ1ZIYGm7qAReMCivdXwiQ60BJoa4cpdX5m9Z5aKgtR8d56xgmYAy7TR86MEV6zJXfjxy2lf0TTAPXc8ftEcst8fP +i6B9IFe3aDBo8x AuthURL = https://account.nextzenvn.com/application/o/nextzenos/ CallbackURL = https://home.nextzenvn.com/v1/users/oidc/callback [nextweb] -Server = https://127.0.0.1:10086 +Server = http://127.0.0.1:10086 UserName = nextzen Password = Smartyourlife123@* -EntranceCode = \ No newline at end of file +EntranceCode = + +[default-app] +NextFireWall = NextFirewall-https://firewall.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/ded8610b855ac31cb08514460e78b93fff9ea127/NextFirewall/nextfirewall.png-DefaultApp-running +NextWeb = NextWeb-https://web.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/c68656087a0387281a1345ff78c89eb36cb925a4/NextWeb/nextweb.png-DefaultApp-running +AccountCenter = AccountCenter-https://account.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/f8c809f8ade653db6cec0915d1e7fadfcdb15241/AccountManager/account.png-DefaultApp-running +NextVPN = NextVPN-https://vpn.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/f5507a5bfa811eae29b67b1f1fc5ac5d8fc5c3e8/NextVPN/nextvpn.png-DefaultApp-running +NextNAS = NextNAS-https://nas.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/0693ac3497cb5c46b7e797ec7afb511fdb5d8804/NextNAS/nextnas.jpg-DefaultApp-running +NextDNS = NextDNS-https://dns.nextzenvn.com-https://cdn.nextzenos.com/CDN/Images/raw/commit/874a16e2647e8633f60845dd2d770bbd4aaccfd4/NextDNS/nextdns.png-DefaultApp-running \ No newline at end of file diff --git a/main.go b/main.go index f26786e..d9cfb1f 100644 --- a/main.go +++ b/main.go @@ -5,6 +5,7 @@ package main import ( "context" _ "embed" + "encoding/json" "flag" "fmt" "net" @@ -21,9 +22,11 @@ import ( "github.com/KaySar12/NextZen-Common/utils/logger" "github.com/KaySar12/NextZen-UserService/codegen/message_bus" "github.com/KaySar12/NextZen-UserService/common" + model2 "github.com/KaySar12/NextZen-UserService/model" "github.com/KaySar12/NextZen-UserService/pkg/config" "github.com/KaySar12/NextZen-UserService/pkg/sqlite" "github.com/KaySar12/NextZen-UserService/pkg/utils/encryption" + "github.com/KaySar12/NextZen-UserService/pkg/utils/file" "github.com/KaySar12/NextZen-UserService/pkg/utils/random" "github.com/KaySar12/NextZen-UserService/route" "github.com/KaySar12/NextZen-UserService/service" @@ -122,7 +125,19 @@ func main() { if err != nil { panic(err) } - + // create default app path + defaultDir := config.AppInfo.UserDataPath + "/" + "default" + if err := file.IsNotExistMkDir(defaultDir); err != nil { + panic(err) + } + appData := convertMapToSlice(config.DefaultAppInfo.Apps) + initApp, err := json.Marshal(appData) + if err != nil { + panic(err) + } + if err := file.WriteToPath(initApp, defaultDir, "link.json"); err != nil { + panic(err) + } apiPaths := []string{ "/v1/users", "/v1/1panel", @@ -130,6 +145,7 @@ func main() { route.V2DocPath, "/" + jwt.JWKSPath, } + for _, v := range apiPaths { err = service.MyService.Gateway().CreateRoute(&model.Route{ Path: v, @@ -184,7 +200,15 @@ func main() { panic(err) } } +func convertMapToSlice(appsMap map[string]model2.AppInfo) []model2.AppInfo { + appsSlice := make([]model2.AppInfo, 0, len(appsMap)) + for _, app := range appsMap { + appsSlice = append(appsSlice, app) + } + + return appsSlice +} func writeAddressFile(runtimePath string, filename string, address string) (string, error) { err := os.MkdirAll(runtimePath, 0o755) if err != nil { diff --git a/model/sys_common.go b/model/sys_common.go index 698017e..8df41d7 100644 --- a/model/sys_common.go +++ b/model/sys_common.go @@ -26,6 +26,18 @@ type NextWebModel struct { Password string EntranceCode string } + +type DefaultModel struct { + Apps map[string]AppInfo +} + +type AppInfo struct { + Hostname string `json:"hostname,omitempty"` + Name string `json:"name,omitempty"` + Icon string `json:"icon,omitempty"` + AppType string `json:"app_type,omitempty"` + Status string `json:"status,omitempty"` +} type Result struct { Success int `json:"success" example:"200"` Message string `json:"message" example:"ok"` diff --git a/pkg/config/init.go b/pkg/config/init.go index fa576cf..325d657 100644 --- a/pkg/config/init.go +++ b/pkg/config/init.go @@ -4,6 +4,7 @@ import ( "fmt" "log" "os" + "strings" "github.com/KaySar12/NextZen-Common/utils/constants" "github.com/KaySar12/NextZen-UserService/model" @@ -37,7 +38,9 @@ var ( Password: "", EntranceCode: "", } - + DefaultAppInfo = &model.DefaultModel{ + Apps: map[string]model.AppInfo{}, + } Cfg *ini.File ConfigFilePath string ) @@ -77,9 +80,33 @@ func InitSetup(config string, sample string) { mapTo("nextweb", NextWebInfo) mapTo("common", CommonInfo) mapTo("app", AppInfo) - + mapToDefaultApp("default-app", DefaultAppInfo) + fmt.Println(DefaultAppInfo) } +func mapToDefaultApp(section string, v interface{}) { + sectionData := Cfg.Section(section) + dm, ok := v.(*model.DefaultModel) + if !ok { + log.Fatal("Invalid type passed to mapToDefaultApp") + } + // Iterate through all keys in the section + for key, value := range sectionData.KeysHash() { + // Split the value string into components (Name, URL, Icon) + parts := strings.Split(value, "-") + if len(parts) == 5 { + dm.Apps[key] = model.AppInfo{ + Name: parts[0], + Hostname: parts[1], + Icon: parts[2], + AppType: parts[3], + Status: parts[4], + } + } else { + log.Printf("Invalid app info format for key: %s, value: %s", key, value) + } + } +} func SaveSetup(config string) { reflectFrom("common", CommonInfo) reflectFrom("app", AppInfo) diff --git a/route/v1/user.go b/route/v1/user.go index 8a49c15..a1a06e0 100644 --- a/route/v1/user.go +++ b/route/v1/user.go @@ -1581,7 +1581,6 @@ func GetUserCustomConf(c *gin.Context) { return } id := c.GetHeader("user_id") - user := service.MyService.User().GetUserInfoById(id) // user := service.MyService.User().GetUserInfoByUsername(Username) if user.Id == 0 { @@ -1589,14 +1588,23 @@ func GetUserCustomConf(c *gin.Context) { model.Result{Success: common_err.USER_NOT_EXIST, Message: common_err.GetMsg(common_err.USER_NOT_EXIST)}) return } - filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json" - - data := file.ReadFullFile(filePath) - if !gjson.ValidBytes(data) { - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)}) - return + if name == "default-app" { + filePath := config.AppInfo.UserDataPath + "/default/link.json" + data := file.ReadFullFile(filePath) + if !gjson.ValidBytes(data) { + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)}) + return + } + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))}) + } else { + filePath := config.AppInfo.UserDataPath + "/" + id + "/" + name + ".json" + data := file.ReadFullFile(filePath) + if !gjson.ValidBytes(data) { + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: string(data)}) + return + } + c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))}) } - c.JSON(common_err.SUCCESS, model.Result{Success: common_err.SUCCESS, Message: common_err.GetMsg(common_err.SUCCESS), Data: json2.RawMessage(string(data))}) } /** @@ -1619,20 +1627,32 @@ func PostUserCustomConf(c *gin.Context) { return } data, _ := io.ReadAll(c.Request.Body) - filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + if name == "default-app" { + filePath := config.AppInfo.UserDataPath + "/default" + if err := file.IsNotExistMkDir(filePath); err != nil { + c.JSON(common_err.SERVICE_ERROR, + model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) + return + } + if err := file.WriteToPath(data, filePath, "link.json"); err != nil { + c.JSON(common_err.SERVICE_ERROR, + model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) + return + } + } else { + filePath := config.AppInfo.UserDataPath + "/" + strconv.Itoa(user.Id) + if err := file.IsNotExistMkDir(filePath); err != nil { + c.JSON(common_err.SERVICE_ERROR, + model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) + return + } - if err := file.IsNotExistMkDir(filePath); err != nil { - c.JSON(common_err.SERVICE_ERROR, - model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) - return + if err := file.WriteToPath(data, filePath, name+".json"); err != nil { + c.JSON(common_err.SERVICE_ERROR, + model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) + return + } } - - if err := file.WriteToPath(data, filePath, name+".json"); err != nil { - c.JSON(common_err.SERVICE_ERROR, - model.Result{Success: common_err.SERVICE_ERROR, Message: common_err.GetMsg(common_err.SERVICE_ERROR)}) - return - } - if name == "system" { dataMap := make(map[string]string, 1) dataMap["system"] = string(data)