diff --git a/app.go b/app.go index 8c5f98d..72d69eb 100644 --- a/app.go +++ b/app.go @@ -114,6 +114,22 @@ func (a *App) PerformUpdate(downloadURL string) error { } err = backend.PerformUpdate(tmpFile) + if err != nil { + // Si sudo est requis, émettre un événement spécifique + if err == backend.ErrSudoRequired { + runtime.EventsEmit(a.ctx, "update:sudo-required", tmpFile) + return err + } + return err + } + + runtime.EventsEmit(a.ctx, "update:complete") + return nil +} + +// PerformUpdateWithSudo performs the update with sudo password +func (a *App) PerformUpdateWithSudo(tmpFilePath string, password string) error { + err := backend.PerformUpdateWithPassword(tmpFilePath, password) if err != nil { return err } diff --git a/backend/update.go b/backend/update.go index 27de18f..44f9c96 100644 --- a/backend/update.go +++ b/backend/update.go @@ -2,6 +2,7 @@ package backend import ( "encoding/json" + "errors" "fmt" "io" "net/http" @@ -25,6 +26,9 @@ type UpdateInfo struct { DownloadURL string `json:"downloadUrl"` } +// ErrSudoRequired is returned when sudo privileges are required +var ErrSudoRequired = errors.New("sudo_required") + func GetCurrentVersion() string { return CURRENT_VERSION } @@ -167,19 +171,22 @@ func PerformUpdate(tmpFilePath string) error { backupPath := currentExe + ".backup" err = os.Rename(currentExe, backupPath) if err != nil { - cmd := exec.Command("sudo", "mv", currentExe, backupPath) - if err := cmd.Run(); err != nil { - return fmt.Errorf("erreur lors de la sauvegarde de l'ancien binaire: %v", err) + // Si on ne peut pas renommer, on a besoin de sudo + if os.IsPermission(err) { + return ErrSudoRequired } + return fmt.Errorf("erreur lors de la sauvegarde de l'ancien binaire: %v", err) } err = os.Rename(tmpFilePath, currentExe) if err != nil { - cmd := exec.Command("sudo", "mv", tmpFilePath, currentExe) - if err := cmd.Run(); err != nil { - os.Rename(backupPath, currentExe) - return fmt.Errorf("erreur lors du remplacement du binaire: %v", err) + // Restaurer l'ancien binaire + os.Rename(backupPath, currentExe) + // Si on ne peut pas renommer, on a besoin de sudo + if os.IsPermission(err) { + return ErrSudoRequired } + return fmt.Errorf("erreur lors du remplacement du binaire: %v", err) } os.Remove(backupPath) @@ -187,6 +194,49 @@ func PerformUpdate(tmpFilePath string) error { return nil } +// PerformUpdateWithPassword performs the update using sudo with the provided password +func PerformUpdateWithPassword(tmpFilePath string, password string) error { + currentExe, err := os.Executable() + if err != nil { + return fmt.Errorf("erreur lors de la récupération du chemin de l'exécutable: %v", err) + } + + currentExe, err = filepath.EvalSymlinks(currentExe) + if err != nil { + return fmt.Errorf("erreur lors de la résolution du symlink: %v", err) + } + + backupPath := currentExe + ".backup" + + // Créer un script pour effectuer la mise à jour + script := fmt.Sprintf(`#!/bin/bash +mv "%s" "%s" || exit 1 +mv "%s" "%s" || { mv "%s" "%s"; exit 1; } +rm -f "%s" +`, + currentExe, backupPath, + tmpFilePath, currentExe, + backupPath, currentExe, + backupPath) + + // Utiliser sudo avec le mot de passe fourni + cmd := exec.Command("sudo", "-S", "bash", "-c", script) + cmd.Stdin = strings.NewReader(password + "\n") + + output, err := cmd.CombinedOutput() + if err != nil { + // Vérifier si c'est une erreur d'authentification + if strings.Contains(string(output), "incorrect password") || + strings.Contains(string(output), "Désolé, essayez de nouveau") || + strings.Contains(string(output), "Sorry, try again") { + return fmt.Errorf("mot de passe incorrect") + } + return fmt.Errorf("erreur lors de la mise à jour: %v - %s", err, string(output)) + } + + return nil +} + func GetLatestReleaseInfo() (map[string]interface{}, error) { url := fmt.Sprintf("https://api.github.com/repos/aidalinfo/aidalinfo-devcli/releases/latest") diff --git a/frontend/src/components/SudoPasswordDialog.vue b/frontend/src/components/SudoPasswordDialog.vue new file mode 100644 index 0000000..86561fd --- /dev/null +++ b/frontend/src/components/SudoPasswordDialog.vue @@ -0,0 +1,106 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/UpdateDialog.vue b/frontend/src/components/UpdateDialog.vue index a431826..11c7d8c 100644 --- a/frontend/src/components/UpdateDialog.vue +++ b/frontend/src/components/UpdateDialog.vue @@ -50,10 +50,18 @@ + + + \ No newline at end of file