diff --git a/agent_v0/agent_v1/config.py b/agent_v0/agent_v1/config.py index a3b03dacc..207f68e8b 100644 --- a/agent_v0/agent_v1/config.py +++ b/agent_v0/agent_v1/config.py @@ -27,7 +27,7 @@ if platform.system() == "Windows": except Exception: pass -AGENT_VERSION = "1.0.0" +AGENT_VERSION = "1.0.1" # Identifiant unique de la machine (utilisé pour le multi-machine) # Configurable via variable d'environnement, sinon auto-généré depuis hostname + OS diff --git a/deploy/installer/LICENSE.txt b/deploy/installer/LICENSE.txt index 21658bb72..6905583c0 100644 --- a/deploy/installer/LICENSE.txt +++ b/deploy/installer/LICENSE.txt @@ -53,7 +53,7 @@ AIVANOV ne pourra etre tenu responsable d'un usage non conforme. 7. CONTACT ---------- Pour toute question ou demande d'acces/rectification/suppression -de donnees : dpo@aivanov.com +de donnees : dpo@aivanov.eu ============================================================ En cliquant sur "J'accepte", vous confirmez avoir pris connaissance diff --git a/deploy/installer/Lea.iss b/deploy/installer/Lea.iss index 1b8bc160e..8ea15091a 100644 --- a/deploy/installer/Lea.iss +++ b/deploy/installer/Lea.iss @@ -23,7 +23,7 @@ ; ============================================================ #define MyAppName "Lea" -#define MyAppVersion "1.0.0" +#define MyAppVersion "1.0.1" #define MyAppPublisher "AIVANOV" #define MyAppURL "https://lea.labs.laurinebazin.design" #define MyAppExeName "Lea.bat" @@ -89,24 +89,23 @@ Name: "french"; MessagesFile: "compiler:Languages\French.isl" [Files] ; Package complet (code Python + .bat + requirements) -; Note : install.bat EST copie (execute par [Run] pour creer le venv Python) +; Note : install.bat est EXCLU du staging (runtime 100% embedded, plus de venv/pip) ; Note : config.txt n'est PAS copie depuis le staging (il est genere par [Code]) Source: "{#SourceDir}\*"; \ DestDir: "{app}"; \ Flags: ignoreversion recursesubdirs createallsubdirs; \ Excludes: "{#PythonEmbedDir}\*,config.txt,*.log,sessions\*,__pycache__\*" -; Python 3.12 embedded (optionnel, copie conditionnelle via check) +; Python 3.12 embedded (OBLIGATOIRE — runtime 100% autonome, aucune dependance Python systeme) Source: "{#SourceDir}\{#PythonEmbedDir}\*"; \ DestDir: "{app}\python-embed"; \ - Flags: ignoreversion recursesubdirs createallsubdirs skipifsourcedoesntexist; \ - Components: pythonembed + Flags: ignoreversion recursesubdirs createallsubdirs ; Script de desinstallation custom (kill + export logs) Source: "uninstall_lea.ps1"; DestDir: "{app}"; Flags: ignoreversion -; Script de configuration du runtime Python embedded (optionnel) -Source: "configure_embed.ps1"; DestDir: "{app}"; Flags: ignoreversion; Components: pythonembed +; Script de configuration du runtime Python embedded (toujours installe) +Source: "configure_embed.ps1"; DestDir: "{app}"; Flags: ignoreversion ; Licence CGU (affichee dans la page licence ET conservee dans {app}) Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion isreadme @@ -115,37 +114,30 @@ Source: "LICENSE.txt"; DestDir: "{app}"; Flags: ignoreversion isreadme Source: "config_template.txt"; DestDir: "{app}"; Flags: ignoreversion [Components] -Name: "core"; Description: "Lea (obligatoire)"; Types: full compact custom; Flags: fixed -Name: "pythonembed"; Description: "Python 3.12 embedded (recommande si Python non installe sur le poste)"; Types: full -Name: "autostart"; Description: "Demarrer Lea automatiquement au demarrage de Windows"; Types: full +; Composant unique fixe : pas de choix utilisateur (runtime embedded toujours inclus). +; Inno masque la page Composants quand il n'y a aucun composant selectionnable. +Name: "core"; Description: "Lea"; Types: full compact custom; Flags: fixed [Tasks] +Name: "autostart"; Description: "Demarrer Lea automatiquement au demarrage de Windows"; GroupDescription: "Options :" Name: "desktopicon"; Description: "Creer un raccourci sur le bureau"; GroupDescription: "Raccourcis :"; Flags: unchecked Name: "startmenuicon"; Description: "Creer un raccourci dans le menu Demarrer"; GroupDescription: "Raccourcis :" [Icons] Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; WorkingDir: "{app}"; Tasks: startmenuicon Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; WorkingDir: "{app}"; Tasks: desktopicon -; Raccourci autostart (shell:startup) — cree si composant autostart selectionne +; Raccourci autostart (shell:startup) — cree si tache autostart selectionnee Name: "{userstartup}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; \ - WorkingDir: "{app}"; Components: autostart + WorkingDir: "{app}"; Tasks: autostart [Run] -; Apres copie : executer install.bat pour creer le venv et installer les dependances Python -; Skip si bundle embedded (dans ce cas, on utilise python-embed directement) -Filename: "{app}\install.bat"; \ - WorkingDir: "{app}"; \ - StatusMsg: "Installation des composants Python (1-2 minutes)..."; \ - Flags: runhidden waituntilterminated; \ - Components: not pythonembed - -; Configuration Python embedded : creer un Lea.bat qui pointe sur python-embed +; Configuration du runtime embedded : reecrit Lea.bat pour pointer sur python-embed. +; TOUJOURS execute — runtime 100% autonome, aucune branche venv/pip/Python systeme. Filename: "{cmd}"; \ Parameters: "/c copy /y ""{app}\Lea.bat"" ""{app}\Lea.bat.bak"" && powershell -NoProfile -ExecutionPolicy Bypass -File ""{app}\configure_embed.ps1"""; \ WorkingDir: "{app}"; \ - StatusMsg: "Configuration du runtime Python embedded..."; \ - Flags: runhidden waituntilterminated; \ - Components: pythonembed + StatusMsg: "Configuration de Lea..."; \ + Flags: runhidden waituntilterminated ; Lancer Lea a la fin de l'installation (optionnel) Filename: "{app}\{#MyAppExeName}"; \ @@ -161,13 +153,20 @@ Filename: "powershell.exe"; \ [UninstallDelete] Type: filesandordirs; Name: "{app}\.venv" +Type: filesandordirs; Name: "{app}\python-embed" Type: filesandordirs; Name: "{app}\__pycache__" Type: filesandordirs; Name: "{app}\agent_v1\__pycache__" Type: filesandordirs; Name: "{app}\agent_v1\sessions" Type: filesandordirs; Name: "{app}\agent_v1\logs" Type: files; Name: "{app}\lea_agent.lock" Type: files; Name: "{app}\config.txt" +Type: files; Name: "{app}\config.txt.bak.*" Type: files; Name: "{app}\machine_id.txt" +Type: files; Name: "{app}\Lea.bat.bak" +Type: files; Name: "{app}\install.bat" +; Filet de securite : supprime tout residu genere au runtime (caches, *.pyc, logs) +; afin que le dossier applicatif soit entierement supprime (exigence desinstall propre). +Type: filesandordirs; Name: "{app}" ; ============================================================ ; Code Pascal : pages custom + generation config.txt + helpers @@ -176,7 +175,7 @@ Type: files; Name: "{app}\machine_id.txt" const SERVER_URL_DEFAULT = 'https://lea.labs.laurinebazin.design/api/v1'; SERVER_HOST_DEFAULT = 'lea.labs.laurinebazin.design'; - DEFAULT_TOKEN = '86031addb338e449fccdb1a983f61807aec15d42d482b9c7748ad607dc23caab'; + DEFAULT_TOKEN = 'o3_LHqV_7_Gc6OVPHndhsBbvG6HJ5PCgl8yIBhGUIz8'; var EnrollmentPage: TInputQueryWizardPage; diff --git a/deploy/installer/build_installer.sh b/deploy/installer/build_installer.sh index b04d6b17c..7507e8e0a 100755 --- a/deploy/installer/build_installer.sh +++ b/deploy/installer/build_installer.sh @@ -106,6 +106,9 @@ rsync -a \ --exclude='test_lea_*' \ --exclude='_test_paused_toast.py' \ --exclude='tools/test_*' \ + --exclude='install.bat' \ + --exclude='*.bak' \ + --exclude='config.txt.bak*' \ "$BASE_BUILD_DIR/" \ "$STAGING_DIR/" @@ -131,15 +134,38 @@ echo "" # 5. Python embedded (optionnel) # --------------------------------------------------------------- PYTHON_EMBED_SRC="${PYTHON_EMBED_DIR:-$SCRIPT_DIR/python-3.12-embed}" -if [[ -d "$PYTHON_EMBED_SRC" ]]; then - echo "[4/5] Copie de Python 3.12 embedded..." - rsync -a "$PYTHON_EMBED_SRC/" "$STAGING_DIR/python-3.12-embed/" - echo " Python embedded inclus" -else - echo -e "${YELLOW}[4/5] Python 3.12 embedded non trouve dans $PYTHON_EMBED_SRC${NC}" - echo " L'installeur sera produit SANS bundle Python." - echo " Pour bundler Python : voir README.md section 'Python embedded'" +if [[ ! -d "$PYTHON_EMBED_SRC" ]]; then + echo -e "${RED}[4/5] ERREUR : Python 3.12 embedded introuvable dans $PYTHON_EMBED_SRC${NC}" + echo " L'embed est OBLIGATOIRE (runtime 100% autonome, aucune dependance Python systeme)." + echo " Build interrompu." + exit 1 fi +echo "[4/5] Copie de Python 3.12 embedded..." +rsync -a "$PYTHON_EMBED_SRC/" "$STAGING_DIR/python-3.12-embed/" + +# Validation de la completude de l'embed : un embed incomplet = install cassee chez le client. +# La liste doit rester alignee avec configure_embed.ps1 (verification runtime des imports). +EMBED="$STAGING_DIR/python-3.12-embed" +REQUIRED_EMBED=( + "python.exe" "pythonw.exe" "python312._pth" + "_tkinter.pyd" "tcl86t.dll" "tk86t.dll" "zlib1.dll" + "Lib/site-packages/socketio" "Lib/site-packages/tkinter" + "Lib/site-packages/mss" "Lib/site-packages/pynput" + "Lib/site-packages/pystray" "Lib/site-packages/plyer" + "Lib/site-packages/requests" "Lib/site-packages/PIL" + "Lib/site-packages/win32" +) +MISSING_EMBED=() +for f in "${REQUIRED_EMBED[@]}"; do + [[ -e "$EMBED/$f" ]] || MISSING_EMBED+=("$f") +done +if [[ ${#MISSING_EMBED[@]} -gt 0 ]]; then + echo -e "${RED} ERREUR : embed incomplet. Elements manquants :${NC}" + printf ' - %s\n' "${MISSING_EMBED[@]}" + echo " Build interrompu (le runtime doit etre complet et autonome)." + exit 1 +fi +echo " Python embedded complet inclus (${#REQUIRED_EMBED[@]} elements verifies)" echo "" # --------------------------------------------------------------- diff --git a/deploy/installer/configure_embed.ps1 b/deploy/installer/configure_embed.ps1 index 5a28361c6..fffd916ef 100644 --- a/deploy/installer/configure_embed.ps1 +++ b/deploy/installer/configure_embed.ps1 @@ -40,34 +40,24 @@ if ($PthFile) { } # --------------------------------------------------------------- -# 2-3. Dependances Python -# Si l'embed est livre complet (deps + tkinter pre-embarques), -# on saute le bootstrap pip / install : INSTALL HORS-LIGNE possible. -# Sinon (embed nu), on bootstrap pip + installe requirements (mode online). +# 2-3. Verification des dependances embarquees (runtime 100% autonome) +# L'embed DOIT contenir toutes les dependances runtime. +# AUCUN pip, AUCUN reseau : si une dependance manque -> echec explicite. # --------------------------------------------------------------- -$DepsOk = $false -& $PythonExe -c "import socketio, tkinter" 2>$null -if ($LASTEXITCODE -eq 0) { $DepsOk = $true } - -if ($DepsOk) { - Write-Host " Dependances deja embarquees (socketio + tkinter) - pip saute (offline OK)." -} else { - # Bootstrap pip (necessite internet) - $GetPip = Join-Path $env:TEMP "get-pip.py" - Write-Host " Telechargement de get-pip.py..." - Invoke-WebRequest -Uri "https://bootstrap.pypa.io/get-pip.py" -OutFile $GetPip -UseBasicParsing - - Write-Host " Installation de pip..." - & $PythonExe $GetPip --no-warn-script-location - Remove-Item $GetPip -Force - - $Requirements = Join-Path $AppDir "requirements_agent.txt" - if (Test-Path $Requirements) { - Write-Host " Installation des dependances Python..." - & $PythonExe -m pip install --no-warn-script-location -r $Requirements - } +$RequiredModules = @('socketio','tkinter','mss','pynput','pystray','plyer','requests','PIL','win32api') +$Missing = @() +foreach ($m in $RequiredModules) { + & $PythonExe -c "import $m" 2>$null + if ($LASTEXITCODE -ne 0) { $Missing += $m } } +if ($Missing.Count -gt 0) { + Write-Host " ERREUR : runtime Lea incomplet. Modules manquants : $($Missing -join ', ')" + Write-Host " L'embed doit etre livre complet (aucune installation reseau en POC)." + exit 1 +} +Write-Host " Dependances embarquees verifiees ($($RequiredModules.Count) modules) - offline OK." + # --------------------------------------------------------------- # 4. Reecrire Lea.bat pour utiliser python-embed # ---------------------------------------------------------------