|
1 | 1 | package directadmin |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "encoding/json" |
4 | 5 | "errors" |
5 | 6 | "fmt" |
6 | 7 | "net/http" |
@@ -203,37 +204,46 @@ func (c *UserContext) SoftaculousInstallScript(script *SoftaculousScript, script |
203 | 204 |
|
204 | 205 | // SoftaculousListInstallations lists all installations accessible to the authenticated user. |
205 | 206 | func (c *UserContext) SoftaculousListInstallations() ([]*SoftaculousInstallation, error) { |
206 | | - response := struct { |
207 | | - Error map[string]string `json:"error"` |
208 | | - Installations map[string]map[string]*SoftaculousInstallation `json:"installations"` |
209 | | - }{ |
210 | | - Error: make(map[string]string), |
211 | | - Installations: make(map[string]map[string]*SoftaculousInstallation), |
| 207 | + type rawResponse struct { |
| 208 | + Error map[string]string `json:"error"` |
| 209 | + Installations json.RawMessage `json:"installations"` |
212 | 210 | } |
213 | 211 |
|
214 | | - // Softaculous requires a genuine session ID |
| 212 | + var raw rawResponse |
| 213 | + |
215 | 214 | if c.sessionID == "" { |
216 | 215 | if err := c.CreateSession(); err != nil { |
217 | 216 | return nil, fmt.Errorf("failed to create user session: %w", err) |
218 | 217 | } |
219 | 218 | } |
220 | 219 |
|
221 | | - if _, err := c.makeRequestOld(http.MethodPost, "PLUGINS/softaculous/index.raw?act=installations&api=json", nil, &response); err != nil { |
| 220 | + if _, err := c.makeRequestOld(http.MethodPost, "PLUGINS/softaculous/index.raw?act=installations&api=json", nil, &raw); err != nil { |
222 | 221 | return nil, err |
223 | 222 | } |
224 | 223 |
|
225 | | - if len(response.Error) > 0 { |
226 | | - return nil, fmt.Errorf("failed to uninstall script: %v", response.Error) |
| 224 | + if len(raw.Error) > 0 { |
| 225 | + return nil, fmt.Errorf("failed to list installations: %v", raw.Error) |
227 | 226 | } |
228 | 227 |
|
229 | | - installations := make([]*SoftaculousInstallation, 0, len(response.Installations)) |
230 | | - for _, userInstallations := range response.Installations { |
231 | | - for _, installation := range userInstallations { |
232 | | - installations = append(installations, installation) |
| 228 | + // Try unmarshalling as a map first. |
| 229 | + var installationsMap map[string]map[string]*SoftaculousInstallation |
| 230 | + if err := json.Unmarshal(raw.Installations, &installationsMap); err == nil { |
| 231 | + var installations []*SoftaculousInstallation |
| 232 | + for _, userInstalls := range installationsMap { |
| 233 | + for _, install := range userInstalls { |
| 234 | + installations = append(installations, install) |
| 235 | + } |
233 | 236 | } |
| 237 | + return installations, nil |
| 238 | + } |
| 239 | + |
| 240 | + // Fallback: Check if it's an empty array. |
| 241 | + var installationsArray []any |
| 242 | + if err := json.Unmarshal(raw.Installations, &installationsArray); err == nil && len(installationsArray) == 0 { |
| 243 | + return []*SoftaculousInstallation{}, nil |
234 | 244 | } |
235 | 245 |
|
236 | | - return installations, nil |
| 246 | + return nil, errors.New("unexpected format for installations field") |
237 | 247 | } |
238 | 248 |
|
239 | 249 | // SoftaculousUninstallScript calls Softaculous's install script API endpoint. |
|
0 commit comments