v0.1.4-pre.012-fix.001
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# file: Cargo.toml
|
||||
# version: 80
|
||||
# version: 81
|
||||
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["crates/ksp-app-config-desk", "crates/ksp-config-lib", "crates/ksp-core-lib", "crates/ksp-logging-lib"]
|
||||
|
||||
[workspace.package]
|
||||
version = "0.1.4-pre.12"
|
||||
version = "0.1.4-pre.12.fix.1"
|
||||
edition = "2024"
|
||||
license = "MIT"
|
||||
repository = "https://git.sasedev.com/Sasedev/khadhroony-solana-project"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-app-config-desk/README.md -->
|
||||
<!-- version: 12 -->
|
||||
<!-- version: 13 -->
|
||||
|
||||
# `ksp-app-config-desk`
|
||||
|
||||
@@ -153,4 +153,6 @@ La vue **Environnement / `.env`** expose la projection sûre de `ConfigManagemen
|
||||
|
||||
Les mutations acceptent un nom existant ou nouveau sous `KSP_*` / `KSPB_*`, présentent explicitement `source_changed`, `effective_changed`, `shadowed_by_process_environment` et `reload_required`, puis rechargent le rapport depuis Config. Une ligne du tableau ne précharge que le nom de variable : aucune ancienne valeur réelle n'est injectée dans le formulaire. Pour un namespace Secret, la nouvelle saisie est masquée ; la consultation d'une valeur réelle reste réservée au flux privilégié de `pre.013`.
|
||||
|
||||
La suppression demande une confirmation via un modal Bootstrap intégré au shell. Les dialogues navigateur natifs `window.alert` / `window.confirm` / `window.prompt` ne sont pas utilisés pour ce flux.
|
||||
|
||||
Les valeurs `KSP_SECRET_*` / `KSPB_SECRET_*` restent redacted par `ksp-config-lib` dans le rapport. La priorité `process > .env > fallback` reste visible : une mutation `.env` shadowed peut changer le desired sans modifier l'effective. Les logs frontend/backend n'enregistrent jamais la valeur soumise, seulement le nom de variable, l'opération et les booléens du rapport de changement.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-app-config-desk/USAGE.md -->
|
||||
<!-- version: 12 -->
|
||||
<!-- version: 13 -->
|
||||
|
||||
# Utilisation de `ksp-app-config-desk`
|
||||
|
||||
@@ -194,4 +194,6 @@ reload_required
|
||||
|
||||
Cliquer une ligne du rapport remplit uniquement le nom de variable. L'ancienne valeur n'est jamais préchargée dans le formulaire. Une saisie `KSP_SECRET_*` / `KSPB_SECRET_*` est masquée ; le reveal de l'ancienne valeur réelle reste hors de cette tranche.
|
||||
|
||||
Le bouton **Supprimer** ouvre un modal Bootstrap indiquant la variable ciblée. **Annuler**, la fermeture du modal ou `Esc` abandonnent l'opération ; **Supprimer** confirme ensuite l'appel à `ConfigManagement::remove_dotenv_value()`. Aucun `window.confirm()` natif n'est utilisé.
|
||||
|
||||
Pour valider le shadowing, lancer ponctuellement l'application avec `KSP_LOGS_DIRECTORY` fourni par le process puis modifier la même variable dans `.env` depuis le panneau. Le résultat attendu est `source_changed=true`, `effective_changed=false`, `shadowed_by_process_environment=true`, `reload_required=false`. Le process hérité reste prioritaire et n'est jamais modifié par Config Desk.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: crates/ksp-app-config-desk/frontend/main.html -->
|
||||
<!-- version: 7 -->
|
||||
<!-- version: 8 -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
|
||||
@@ -306,6 +306,25 @@
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<div id="environmentRemoveConfirmModal" class="modal fade" tabindex="-1" aria-labelledby="environmentRemoveConfirmTitle" aria-hidden="true">
|
||||
<div class="modal-dialog modal-dialog-centered">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h2 id="environmentRemoveConfirmTitle" class="modal-title fs-5">Confirmer la suppression .env</h2>
|
||||
<button class="btn-close" type="button" data-bs-dismiss="modal" aria-label="Annuler"></button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p class="mb-2">Supprimer l'entrée <code id="environmentRemoveConfirmVariable" class="font-monospace"></code> de <code>.env</code> ?</p>
|
||||
<p class="text-body-secondary small mb-0">L'environnement process déjà hérité ne sera pas modifié.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button class="btn btn-outline-secondary" type="button" data-bs-dismiss="modal">Annuler</button>
|
||||
<button id="environmentRemoveConfirmAction" class="btn btn-danger" type="button">Supprimer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="app-footer bg-dark text-light">
|
||||
<div class="container h-100 d-flex align-items-center justify-content-center">
|
||||
<small>© 2026 SASEDEV</small>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
// file: crates/ksp-app-config-desk/frontend/ts/environment.ts
|
||||
// version: 2
|
||||
// version: 3
|
||||
|
||||
//! Safe environment report and `.env` management panel backed exclusively by ConfigManagement.
|
||||
|
||||
import { Modal } from "bootstrap";
|
||||
import DataTable from "datatables.net-bs5";
|
||||
import "datatables.net-bs5/css/dataTables.bootstrap5.css";
|
||||
import type { ConfigEnvironmentChangeDto } from "./bindings/ksp_app_config_desk/environment/ConfigEnvironmentChangeDto";
|
||||
@@ -221,6 +222,35 @@ function setMutationControlsDisabled(disabled: boolean): void {
|
||||
document.querySelector<HTMLButtonElement>("#removeEnvironmentValue")?.toggleAttribute("disabled", disabled);
|
||||
}
|
||||
|
||||
function confirmEnvironmentRemoval(variableName: string): Promise<boolean> {
|
||||
const modalElement = document.querySelector<HTMLElement>("#environmentRemoveConfirmModal");
|
||||
const variable = document.querySelector<HTMLElement>("#environmentRemoveConfirmVariable");
|
||||
const confirmButton = document.querySelector<HTMLButtonElement>("#environmentRemoveConfirmAction");
|
||||
if (!modalElement || !variable || !confirmButton) {
|
||||
frontendDebug("main", "Environment removal confirmation modal is unavailable", { variableName });
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
variable.textContent = variableName;
|
||||
const modal = Modal.getOrCreateInstance(modalElement);
|
||||
frontendDebug("main", "Environment .env removal confirmation opened", { variableName });
|
||||
return new Promise<boolean>(resolve => {
|
||||
let confirmed = false;
|
||||
const onConfirm = (): void => {
|
||||
confirmed = true;
|
||||
modal.hide();
|
||||
};
|
||||
const onHidden = (): void => {
|
||||
confirmButton.removeEventListener("click", onConfirm);
|
||||
variable.textContent = "";
|
||||
frontendDebug("main", "Environment .env removal confirmation answered", { variableName, confirmed });
|
||||
resolve(confirmed);
|
||||
};
|
||||
confirmButton.addEventListener("click", onConfirm, { once: true });
|
||||
modalElement.addEventListener("hidden.bs.modal", onHidden, { once: true });
|
||||
modal.show();
|
||||
});
|
||||
}
|
||||
|
||||
async function refreshEnvironmentReport(): Promise<void> {
|
||||
frontendDebug("main", "Config environment report refresh requested");
|
||||
setEnvironmentStatus("Chargement du rapport environnement sûr...", "primary");
|
||||
@@ -289,14 +319,14 @@ async function removeEnvironmentValue(): Promise<void> {
|
||||
setMutationStatus("Saisis ou sélectionne la variable .env à supprimer.", "warning");
|
||||
return;
|
||||
}
|
||||
const confirmed = window.confirm(`Supprimer l'entrée .env ${variableName} ? L'environnement process hérité ne sera pas modifié.`);
|
||||
frontendTrace("main", "Environment .env removal confirmation answered", { variableName, confirmed });
|
||||
setMutationControlsDisabled(true);
|
||||
const confirmed = await confirmEnvironmentRemoval(variableName);
|
||||
if (!confirmed) {
|
||||
setMutationControlsDisabled(false);
|
||||
return;
|
||||
}
|
||||
const sensitivity = classifyEditorSensitivity(variableName);
|
||||
frontendDebug("main", "Environment .env mutation requested", { operation: "remove", variableName, sensitivity });
|
||||
setMutationControlsDisabled(true);
|
||||
setMutationStatus("Suppression atomique par Config...", "secondary");
|
||||
try {
|
||||
const result = await invokeKsp<ConfigEnvironmentChangeDto>("main", "remove_environment_value", { variableName });
|
||||
|
||||
62
deltas/0.1.4/pre.012-fix.001.md
Normal file
62
deltas/0.1.4/pre.012-fix.001.md
Normal file
@@ -0,0 +1,62 @@
|
||||
<!-- file: deltas/0.1.4/pre.012-fix.001.md -->
|
||||
<!-- version: 1 -->
|
||||
|
||||
# Delta `0.1.4-pre.012-fix.001` — confirmation Bootstrap des suppressions `.env`
|
||||
|
||||
## Statut
|
||||
|
||||
Correctif de `pre.012` livré pour validation locale.
|
||||
|
||||
La validation utilisateur de `pre.012` confirme déjà `fmt`, `check`, `clippy`, les 34 tests Config Desk, les 87 tests Config, les cinq audits ownership et les 12 tests d'API publique. Les mutations `.env` create/update/remove fonctionnent et les valeurs Secret restent redacted. Le défaut corrigé ici est uniquement l'emploi d'un dialogue navigateur natif `window.confirm()` lors d'une suppression.
|
||||
|
||||
## Correctif
|
||||
|
||||
- remplacement de `window.confirm()` par un modal Bootstrap intégré à `main.html` ;
|
||||
- le modal affiche uniquement le nom de la variable ciblée et rappelle que l'environnement process hérité n'est pas modifié ;
|
||||
- **Annuler**, fermeture du modal ou `Esc` annulent la suppression ;
|
||||
- **Supprimer** ferme le modal puis déclenche le flux existant `remove_environment_value` ;
|
||||
- les contrôles de mutation sont désactivés pendant la confirmation afin d'éviter plusieurs confirmations concurrentes ;
|
||||
- ouverture et réponse du modal sont journalisées en `debug` sans valeur `.env` ;
|
||||
- ajout de la règle normative `KSP-APP-032` : les interfaces desk KSP utilisent des modals Bootstrap pour les confirmations destructives/privilégiées au lieu de `window.alert` / `window.confirm` / `window.prompt` ;
|
||||
- README, USAGE et plan `0.1.4` alignés.
|
||||
|
||||
## Sécurité
|
||||
|
||||
Le correctif ne change ni l'ownership Config ni le payload IPC : aucune valeur `.env` supplémentaire n'est projetée, journalisée ou préchargée. La suppression reste exclusivement réalisée par `ConfigManagement::remove_dotenv_value()`.
|
||||
|
||||
## Validation fonctionnelle restante de `pre.012`
|
||||
|
||||
Après validation de ce fix, le seul scénario fonctionnel encore non observé dans les logs fournis est le shadowing réel `process > .env`, car le dernier lancement rapporte `process_count=0`.
|
||||
|
||||
Lancer par exemple :
|
||||
|
||||
```bash
|
||||
KSP_LOGS_DIRECTORY=logs-process-test \
|
||||
cargo tauri dev -c crates/ksp-app-config-desk/tauri.conf.json
|
||||
```
|
||||
|
||||
Puis modifier `KSP_LOGS_DIRECTORY` depuis l'UI. Résultat attendu :
|
||||
|
||||
```text
|
||||
source_changed = true
|
||||
effective_changed = false
|
||||
shadowed_by_process_environment = true
|
||||
reload_required = false
|
||||
```
|
||||
|
||||
## Version technique
|
||||
|
||||
```text
|
||||
workspace.package.version = "0.1.4-pre.12.fix.1"
|
||||
```
|
||||
|
||||
## Validation locale demandée
|
||||
|
||||
```bash
|
||||
cargo fmt --all
|
||||
cargo check --workspace
|
||||
cargo clippy --workspace --all-targets
|
||||
cargo test -p ksp-app-config-desk
|
||||
cargo test -p ksp-config-lib
|
||||
cargo tauri dev -c crates/ksp-app-config-desk/tauri.conf.json
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/plans/006-V0_1_4_CONFIG_DESKTOP_PLAN.md -->
|
||||
<!-- version: 13 -->
|
||||
<!-- version: 14 -->
|
||||
|
||||
# Plan `0.1.4` — `ksp-app-config-desk`
|
||||
|
||||
@@ -1221,6 +1221,7 @@ pre.011 Environnement — rapports [réalisé]
|
||||
pre.012 Environnement — management/test .env [en cours]
|
||||
- create/update via set_dotenv_value
|
||||
- remove via remove_dotenv_value
|
||||
- confirmation destructive via modal Bootstrap, sans dialogue natif window.confirm
|
||||
- résultats source/effective/shadow/reload
|
||||
- démonstration process > .env
|
||||
- démonstration placeholder KSP_LOGS_DIRECTORY
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<!-- file: docs/rules/RULES_KSP.md -->
|
||||
<!-- version: 27 -->
|
||||
<!-- version: 28 -->
|
||||
|
||||
# Règles spécifiques à KSP
|
||||
|
||||
@@ -224,6 +224,7 @@
|
||||
- **KSP-APP-029** — En développement workspace, une application desk Tauri normalise le current working directory du processus Rust vers la racine du workspace avant le bootstrap Config lorsque `cargo tauri ... -c crates/<app>/tauri.conf.json` lance le binaire depuis la crate. Cette adaptation ne lit ni ne parse directement `config/`, `.env` ou les variables `KSP_*`/`KSPB_*` : `ksp-config-lib` reste seul propriétaire de ces ressources. Le comportement de distribution/release reste défini séparément et ne doit pas dépendre d’un checkout source.
|
||||
- **KSP-APP-030** — Lorsqu’une application KSP persiste des logs applicatifs, chaque lancement doit disposer d’un fichier propre et non partagé avec un lancement précédent. Le nom encode au minimum l’identité applicative et un horodatage de démarrage, par exemple `app-name.YYYYMMDD-HHMMSS.log` / `.json` / `.jsonl` selon le format du sink ; une rotation quotidienne ne doit pas fusionner plusieurs exécutions applicatives dans le même fichier.
|
||||
- **KSP-APP-031** — Le niveau de logging spécifique à une application/crate peut être élevé temporairement à `debug` ou `trace` pendant une phase de développement ou correction. Avant la clôture/release de cette application/crate, son niveau de référence est ramené à `info` ou `warn` selon le besoin opératoire ; il n’est remonté que lorsqu’un développement/correctif est explicitement rouvert.
|
||||
- **KSP-APP-032** — Les interfaces desk KSP n’utilisent pas les dialogues bloquants natifs du navigateur (`window.alert`, `window.confirm`, `window.prompt`) pour les interactions applicatives normales. Les confirmations destructives ou privilégiées utilisent un modal Bootstrap intégré à l’UI, instrumenté par le bridge Logging ; toute exception doit être explicitement justifiée et documentée.
|
||||
|
||||
## Data plane / control plane
|
||||
|
||||
|
||||
Reference in New Issue
Block a user