feat(ui): encryption-vault panel in Settings privacy (enable/unlock/lock/change) (T8.8)
This commit is contained in:
@@ -63,6 +63,58 @@
|
|||||||
let showConsent = $state(false);
|
let showConsent = $state(false);
|
||||||
let testResult = $state<{ ok: boolean; message: string } | null>(null);
|
let testResult = $state<{ ok: boolean; message: string } | null>(null);
|
||||||
|
|
||||||
|
// ---- At-rest encryption vault (T8.8, FR-SEC-3) ----
|
||||||
|
let vault = $state<{ enabled: boolean; unlocked: boolean } | null>(null);
|
||||||
|
let vaultPw = $state("");
|
||||||
|
let vaultPw2 = $state("");
|
||||||
|
let vaultMsg = $state<string | null>(null);
|
||||||
|
async function loadVault() {
|
||||||
|
try {
|
||||||
|
vault = await api.vaultStatus();
|
||||||
|
} catch {
|
||||||
|
vault = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onMount(loadVault);
|
||||||
|
async function enableVault() {
|
||||||
|
vaultMsg = null;
|
||||||
|
try {
|
||||||
|
await api.enableVault(vaultPw);
|
||||||
|
vaultPw = "";
|
||||||
|
vaultMsg = "Vault enabled and unlocked.";
|
||||||
|
await loadVault();
|
||||||
|
} catch (e) {
|
||||||
|
vaultMsg = `${e}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function unlockVault() {
|
||||||
|
vaultMsg = null;
|
||||||
|
try {
|
||||||
|
await api.unlockVault(vaultPw);
|
||||||
|
vaultPw = "";
|
||||||
|
vaultMsg = "Unlocked.";
|
||||||
|
await loadVault();
|
||||||
|
} catch (e) {
|
||||||
|
vaultMsg = `${e}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function lockVault() {
|
||||||
|
await api.lockVault();
|
||||||
|
vaultMsg = "Locked.";
|
||||||
|
await loadVault();
|
||||||
|
}
|
||||||
|
async function changeVaultPassword() {
|
||||||
|
vaultMsg = null;
|
||||||
|
try {
|
||||||
|
await api.changeVaultPassword(vaultPw, vaultPw2);
|
||||||
|
vaultPw = "";
|
||||||
|
vaultPw2 = "";
|
||||||
|
vaultMsg = "Password changed.";
|
||||||
|
} catch (e) {
|
||||||
|
vaultMsg = `${e}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---- NPU package download (T3.4) ----
|
// ---- NPU package download (T3.4) ----
|
||||||
let npuBusy = $state(false);
|
let npuBusy = $state(false);
|
||||||
let npuMsg = $state<string | null>(null);
|
let npuMsg = $state<string | null>(null);
|
||||||
@@ -612,6 +664,56 @@
|
|||||||
{:else}
|
{:else}
|
||||||
<p class="muted">Privacy self-check unavailable.</p>
|
<p class="muted">Privacy self-check unavailable.</p>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
{#if vault}
|
||||||
|
<h4>Encryption vault</h4>
|
||||||
|
{#if !vault.enabled}
|
||||||
|
<p class="muted">
|
||||||
|
Encrypt notes, transcripts, and summaries at rest with a password. (Audio files are
|
||||||
|
not encrypted yet.)
|
||||||
|
</p>
|
||||||
|
<div class="grid">
|
||||||
|
<label class="wide"
|
||||||
|
>Vault password<input type="password" bind:value={vaultPw} /></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<button class="primary" onclick={enableVault} disabled={vaultPw.length < 8}
|
||||||
|
>Enable vault</button
|
||||||
|
>
|
||||||
|
<p class="muted">
|
||||||
|
Use at least 8 characters. If you forget it, encrypted content can't be recovered.
|
||||||
|
</p>
|
||||||
|
{:else if !vault.unlocked}
|
||||||
|
<p class="muted">
|
||||||
|
Vault is <strong>locked</strong>. Unlock to read encrypted meetings.
|
||||||
|
</p>
|
||||||
|
<div class="grid">
|
||||||
|
<label class="wide">Password<input type="password" bind:value={vaultPw} /></label>
|
||||||
|
</div>
|
||||||
|
<button class="primary" onclick={unlockVault} disabled={!vaultPw}>Unlock</button>
|
||||||
|
{:else}
|
||||||
|
<p class="muted">
|
||||||
|
Vault is <strong>unlocked</strong>. New notes, transcripts, and summaries are
|
||||||
|
encrypted at rest.
|
||||||
|
</p>
|
||||||
|
<button onclick={lockVault}>Lock now</button>
|
||||||
|
<details>
|
||||||
|
<summary>Change password</summary>
|
||||||
|
<div class="grid">
|
||||||
|
<label class="wide"
|
||||||
|
>Current password<input type="password" bind:value={vaultPw} /></label
|
||||||
|
>
|
||||||
|
<label class="wide"
|
||||||
|
>New password<input type="password" bind:value={vaultPw2} /></label
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<button onclick={changeVaultPassword} disabled={!vaultPw || vaultPw2.length < 8}
|
||||||
|
>Change password</button
|
||||||
|
>
|
||||||
|
</details>
|
||||||
|
{/if}
|
||||||
|
{#if vaultMsg}<p class="muted">{vaultMsg}</p>{/if}
|
||||||
|
{/if}
|
||||||
</section>
|
</section>
|
||||||
{/if}
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user