mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-11-10 06:43:00 +00:00
[auth] Add "Lock this device" control to re-lock a kept-unlocked session (#51)
The opt-in "keep unlocked" cache had no user-facing way to undo it mid-session
(it cleared only on logout / clear-site-data). Add a "Lock this device" button to
the profile modal footer (desktop + mobile), shown only when the active account
has a cached key to forget (app.isSessionKeptUnlocked -> client.hasCachedUnlockedKey).
Clicking it runs app.lockKeptUnlockedSession(pubkey), which re-locks in one action
everything the signer unlocks:
- forgets the cached key (both tiers) so future reloads re-prompt for the PIN,
- drops the in-memory signer (logoutSigner) so the CURRENT session re-locks now
(the next signing action prompts again via ensureEncryptionCapableSigner),
- storageService.lock(pubkey), and
- nwcSettingsService.clearCache() (re-hydrates from the signer next time).
Visibility refreshes on renderSavedProfiles + selectPane. Tests: 2 in
tests/profile-modal-controller.test.mjs (shown only when kept-unlocked; click locks
the active pubkey). Lint + build green.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
1 parent
b0a2eeaf72
commit
cebd3dc1e7
7 files changed
+255
-6
No files matched your search
@@ -96,6 +96,7 @@ import {
|
||||
import {
|
||||
getActiveSigner,
|
||||
onActiveSignerChanged,
|
||||
logoutSigner,
|
||||
} from "./nostrClientRegistry.js";
|
||||
import { resolveSignerCapabilities } from "./nostr/signerCapabilities.js";
|
||||
import {
|
||||
@@ -2220,6 +2221,76 @@ class Application {
|
||||
return { ok: true, unlocked: true };
|
||||
}
|
||||
|
||||
// True when the active (or given) account currently has a cached "keep
|
||||
// unlocked" key — i.e. there is something to lock (TODO #51).
|
||||
isSessionKeptUnlocked(pubkey) {
|
||||
const normalized =
|
||||
this.normalizeHexPubkey(pubkey) ||
|
||||
this.normalizeHexPubkey(this.pubkey) ||
|
||||
"";
|
||||
if (!normalized || typeof nostrClient?.hasCachedUnlockedKey !== "function") {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return nostrClient.hasCachedUnlockedKey(normalized);
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// "Lock now": re-lock this device immediately AND forget the cached key so a
|
||||
// future reload re-prompts. Counterpart to the opt-in "keep unlocked" (TODO
|
||||
// #51). Locks everything the signer unlocks — the in-memory signer, storage,
|
||||
// and the decrypted NWC cache — so the account is fully re-locked in one action.
|
||||
lockKeptUnlockedSession(pubkey) {
|
||||
const normalized =
|
||||
this.normalizeHexPubkey(pubkey) ||
|
||||
this.normalizeHexPubkey(this.pubkey) ||
|
||||
"";
|
||||
if (!normalized) {
|
||||
return { ok: false, reason: "no-pubkey" };
|
||||
}
|
||||
|
||||
// 1. Forget the cached key (both tiers) → future reloads re-prompt for the PIN.
|
||||
try {
|
||||
if (typeof nostrClient.forgetUnlockedSigner === "function") {
|
||||
nostrClient.forgetUnlockedSigner(normalized);
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn("[Application] Failed to forget cached unlock on lock:", error);
|
||||
}
|
||||
|
||||
// 2. Remove the in-memory nsec signer → the CURRENT session re-locks now.
|
||||
try {
|
||||
logoutSigner(normalized);
|
||||
} catch (error) {
|
||||
devLogger.warn("[Application] Failed to drop the active signer on lock:", error);
|
||||
}
|
||||
|
||||
// 3. Lock storage (drops the in-memory master key).
|
||||
try {
|
||||
if (typeof storageService.lock === "function") {
|
||||
storageService.lock(normalized);
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn("[Application] Failed to lock storage on lock:", error);
|
||||
}
|
||||
|
||||
// 4. Drop the decrypted NWC cache (re-hydrates from the signer next time).
|
||||
try {
|
||||
if (typeof this.nwcSettingsService?.clearCache === "function") {
|
||||
this.nwcSettingsService.clearCache();
|
||||
}
|
||||
} catch (error) {
|
||||
devLogger.warn("[Application] Failed to drop the NWC cache on lock:", error);
|
||||
}
|
||||
|
||||
this.showSuccess?.(
|
||||
"Locked on this device. You'll re-enter your PIN next time it's needed.",
|
||||
);
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
resetPermissionPromptState() {
|
||||
this.permissionPromptShownForSession = false;
|
||||
this.permissionPromptVisible = false;
|
||||
|
||||
Reference in new issue
Block a user