v0.2.6-pre.010-fix.001
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
// file: crates/ksp-app-wallet-desk/frontend/ts/main.ts
|
||||
// version: 10
|
||||
// version: 11
|
||||
|
||||
import { Modal } from "bootstrap";
|
||||
import DataTable from "datatables.net-bs5";
|
||||
@@ -234,12 +234,13 @@ function updateOwnerMetadataActions(): void {
|
||||
|
||||
function updateSecurityRotationActions(): void {
|
||||
const ownerOpen = activeSessionState === "owner_open" && authorizedWalletProjection?.capability === "owner";
|
||||
const viewOpen = activeSessionState === "view_open" && authorizedWalletProjection?.capability === "view";
|
||||
document.querySelectorAll<HTMLInputElement | HTMLButtonElement>("[data-owner-rotation-control]").forEach(control => {
|
||||
control.disabled = !ownerOpen;
|
||||
});
|
||||
const viewControls = document.querySelectorAll<HTMLInputElement | HTMLButtonElement>("[data-view-rotation-control]");
|
||||
viewControls.forEach(control => {
|
||||
control.disabled = !ownerOpen || !activeViewEnabled;
|
||||
control.disabled = (!ownerOpen && !viewOpen) || !activeViewEnabled;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -442,8 +443,8 @@ function renderAuthorizedWallet(wallet: WalletAuthorizedDto): void {
|
||||
setText(
|
||||
"#rotationStatus",
|
||||
wallet.capability === "owner"
|
||||
? "OWNER ouvert. Une rotation modifie le fichier Wallet uniquement ; les secrets Config restent inchangés."
|
||||
: "Session OWNER requise pour effectuer une rotation de credential.",
|
||||
? "OWNER ouvert. Rotation OWNER et administration VIEW disponibles ; les secrets Config restent inchangés."
|
||||
: "VIEW ouvert. Self-rotation VIEW disponible ; OWNER reste inaccessible.",
|
||||
);
|
||||
updateSessionActions();
|
||||
frontendDebug("main", "Authorized Wallet session rendered", {
|
||||
@@ -561,6 +562,25 @@ async function recoverOwnerStateConflict(walletId: string): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
async function recoverRotationStateConflict(walletId: string, capability: UnlockCapability): Promise<void> {
|
||||
clearAuthorizedProjection();
|
||||
clearBalanceProjection();
|
||||
const request: WalletSelectionRequestDto = { walletId };
|
||||
try {
|
||||
const wallet = await invokeKsp<LockedWalletDto>("main", "select_wallet", { request });
|
||||
renderLockedWallet(wallet);
|
||||
setText("#rotationStatus", `Conflit d’état : rotation ${capability.toUpperCase()} interrompue, wallet reverrouillé.`);
|
||||
setText("#unlockStatus", `Conflit d’état détecté : réautoriser ${capability.toUpperCase()} explicitement avant une nouvelle rotation.`);
|
||||
await loadWalletInventory("list_wallets", false);
|
||||
activateView("security", "user");
|
||||
frontendWarn("main", "Wallet state conflict forced credential reauthorization", { capability, walletId });
|
||||
} catch {
|
||||
clearSelectedWallet();
|
||||
setText("#rotationStatus", "Conflit d’état détecté ; la réinspection du wallet a échoué.");
|
||||
frontendWarn("main", "Wallet credential rotation state conflict recovery failed", { capability, walletId });
|
||||
}
|
||||
}
|
||||
|
||||
async function runOwnerMetadataMutation(
|
||||
command: "add_wallet_note" | "delete_wallet_note" | "update_wallet_alias" | "update_wallet_note",
|
||||
args: Record<string, unknown>,
|
||||
@@ -963,9 +983,12 @@ async function unlockConfigured(capability: UnlockCapability): Promise<void> {
|
||||
}
|
||||
|
||||
async function rotateWalletPassword(capability: UnlockCapability): Promise<void> {
|
||||
if (activeSessionState !== "owner_open" || !activeWalletId || authorizedWalletProjection?.capability !== "owner") {
|
||||
const sessionCapability = authorizedWalletProjection?.capability;
|
||||
const ownerAuthorized = activeSessionState === "owner_open" && sessionCapability === "owner";
|
||||
const viewAuthorized = activeSessionState === "view_open" && sessionCapability === "view";
|
||||
if (!activeWalletId || (capability === "owner" && !ownerAuthorized) || (capability === "view" && !ownerAuthorized && !viewAuthorized)) {
|
||||
clearRotationSensitiveInputs();
|
||||
setText("#rotationStatus", "Session OWNER requise.");
|
||||
setText("#rotationStatus", capability === "owner" ? "Session OWNER requise." : "Session VIEW ou OWNER requise.");
|
||||
return;
|
||||
}
|
||||
if (capability === "view" && !activeViewEnabled) {
|
||||
@@ -1012,13 +1035,13 @@ async function rotateWalletPassword(capability: UnlockCapability): Promise<void>
|
||||
} catch (caughtError) {
|
||||
clearRotationSensitiveInputs();
|
||||
if (isWalletStateConflict(caughtError)) {
|
||||
await recoverOwnerStateConflict(walletId);
|
||||
await recoverRotationStateConflict(walletId, sessionCapability === "view" ? "view" : "owner");
|
||||
return;
|
||||
}
|
||||
if (activeWalletId === walletId) {
|
||||
activeSessionState = "owner_open";
|
||||
setText("#currentWalletState", "OWNER open");
|
||||
setText("#rotationStatus", "Rotation refusée ; la session OWNER reste ouverte.");
|
||||
if (activeWalletId === walletId && sessionCapability) {
|
||||
activeSessionState = sessionCapability === "view" ? "view_open" : "owner_open";
|
||||
setText("#currentWalletState", `${sessionCapability.toUpperCase()} open`);
|
||||
setText("#rotationStatus", `Rotation refusée ; la session ${sessionCapability.toUpperCase()} reste ouverte.`);
|
||||
updateSessionActions();
|
||||
}
|
||||
frontendWarn("main", "Wallet credential rotation failed", { capability, walletId });
|
||||
|
||||
Reference in New Issue
Block a user