mirror of
https://github.com/kccleoc/seedpgp-web.git
synced 2026-03-07 09:57:50 +08:00
feat(v1.3.0): add ephemeral session-key encryption for sensitive state
- Add src/lib/sessionCrypto.ts with AES-GCM-256 non-exportable session keys - Integrate into Backup flow: auto-clear plaintext mnemonic after QR generation - Add Lock/Clear button to destroy session key and clear all state - Add cleanup useEffect on component unmount - Add comprehensive GEMINI.md for AI agent onboarding - Fix TypeScript strict mode errors and unused imports Tested: - Session-key encryption working (mnemonic clears after QR gen) - Lock/Clear functionality verified - No plaintext secrets in localStorage/sessionStorage - Production build successful
This commit is contained in:
49
GEMINI.md
49
GEMINI.md
@@ -1,12 +1,14 @@
|
|||||||
# SeedPGP - Gemini Code Assist Project Brief
|
# SeedPGP - Gemini Code Assist Project Brief
|
||||||
|
|
||||||
## Project Overview
|
## Project Overview
|
||||||
|
|
||||||
**SeedPGP v1.3.0**: Client-side BIP39 mnemonic encryption webapp
|
**SeedPGP v1.3.0**: Client-side BIP39 mnemonic encryption webapp
|
||||||
**Stack**: Bun + Vite + React + TypeScript + OpenPGP.js + Tailwind CSS
|
**Stack**: Bun + Vite + React + TypeScript + OpenPGP.js + Tailwind CSS
|
||||||
**Deploy**: GitHub Pages (public repo: `seedpgp-web-app`, private source: `seedpgp-web`)
|
**Deploy**: GitHub Pages (public repo: `seedpgp-web-app`, private source: `seedpgp-web`)
|
||||||
**Live URL**: https://kccleoc.github.io/seedpgp-web-app/
|
**Live URL**: <https://kccleoc.github.io/seedpgp-web-app/>
|
||||||
|
|
||||||
## Core Constraints
|
## Core Constraints
|
||||||
|
|
||||||
1. **Security-first**: Never persist secrets (mnemonic/passphrase/private keys) to localStorage/sessionStorage/IndexedDB
|
1. **Security-first**: Never persist secrets (mnemonic/passphrase/private keys) to localStorage/sessionStorage/IndexedDB
|
||||||
2. **Small PRs**: Max 1-5 files per feature; propose plan before coding
|
2. **Small PRs**: Max 1-5 files per feature; propose plan before coding
|
||||||
3. **Client-side only**: No backend; all crypto runs in browser (Web Crypto API + OpenPGP.js)
|
3. **Client-side only**: No backend; all crypto runs in browser (Web Crypto API + OpenPGP.js)
|
||||||
@@ -14,6 +16,7 @@
|
|||||||
5. **Honest security claims**: Don't overclaim what client-side JS can guarantee
|
5. **Honest security claims**: Don't overclaim what client-side JS can guarantee
|
||||||
|
|
||||||
## Non-Negotiables
|
## Non-Negotiables
|
||||||
|
|
||||||
- Small diffs only: one feature slice per PR (1-5 files if possible)
|
- Small diffs only: one feature slice per PR (1-5 files if possible)
|
||||||
- No big code dumps; propose plan first, then implement
|
- No big code dumps; propose plan first, then implement
|
||||||
- Never persist secrets to browser storage
|
- Never persist secrets to browser storage
|
||||||
@@ -25,10 +28,12 @@
|
|||||||
## Architecture Map
|
## Architecture Map
|
||||||
|
|
||||||
### Entry Points
|
### Entry Points
|
||||||
|
|
||||||
- `src/main.tsx` → `src/App.tsx` (main application)
|
- `src/main.tsx` → `src/App.tsx` (main application)
|
||||||
- Build output: `dist/` (separate git repo for GitHub Pages deployment)
|
- Build output: `dist/` (separate git repo for GitHub Pages deployment)
|
||||||
|
|
||||||
### Directory Structure
|
### Directory Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
src/
|
src/
|
||||||
├── components/ # React UI components
|
├── components/ # React UI components
|
||||||
@@ -51,14 +56,18 @@ src/
|
|||||||
### Key Modules
|
### Key Modules
|
||||||
|
|
||||||
#### `src/lib/seedpgp.ts`
|
#### `src/lib/seedpgp.ts`
|
||||||
|
|
||||||
Core encryption/decryption:
|
Core encryption/decryption:
|
||||||
|
|
||||||
- `encryptToSeedPgp()` - Encrypts mnemonic with PGP public key + optional password
|
- `encryptToSeedPgp()` - Encrypts mnemonic with PGP public key + optional password
|
||||||
- `decryptFromSeedPgp()` - Decrypts with PGP private key + optional password
|
- `decryptFromSeedPgp()` - Decrypts with PGP private key + optional password
|
||||||
- Uses OpenPGP.js for PGP operations
|
- Uses OpenPGP.js for PGP operations
|
||||||
- Output format: `SEEDPGP1:version:base64data:fingerprint`
|
- Output format: `SEEDPGP1:version:base64data:fingerprint`
|
||||||
|
|
||||||
#### `src/lib/sessionCrypto.ts` (v1.3.0+)
|
#### `src/lib/sessionCrypto.ts` (v1.3.0+)
|
||||||
|
|
||||||
Ephemeral session-key encryption:
|
Ephemeral session-key encryption:
|
||||||
|
|
||||||
- `getSessionKey()` - Generates/returns non-exportable AES-GCM-256 key (idempotent)
|
- `getSessionKey()` - Generates/returns non-exportable AES-GCM-256 key (idempotent)
|
||||||
- `encryptJsonToBlob(obj)` - Encrypts to `{v, alg, iv_b64, ct_b64}`
|
- `encryptJsonToBlob(obj)` - Encrypts to `{v, alg, iv_b64, ct_b64}`
|
||||||
- `decryptBlobToJson(blob)` - Decrypts back to original object
|
- `decryptBlobToJson(blob)` - Decrypts back to original object
|
||||||
@@ -66,7 +75,9 @@ Ephemeral session-key encryption:
|
|||||||
- Test: `await window.runSessionCryptoTest()` (DEV only)
|
- Test: `await window.runSessionCryptoTest()` (DEV only)
|
||||||
|
|
||||||
#### `src/lib/types.ts`
|
#### `src/lib/types.ts`
|
||||||
|
|
||||||
Core interfaces:
|
Core interfaces:
|
||||||
|
|
||||||
- `SeedPgpPlaintext` - Decrypted mnemonic data structure
|
- `SeedPgpPlaintext` - Decrypted mnemonic data structure
|
||||||
- `SeedPgpCiphertext` - Encrypted payload structure
|
- `SeedPgpCiphertext` - Encrypted payload structure
|
||||||
- `EncryptedBlob` - Session-key encrypted cache format
|
- `EncryptedBlob` - Session-key encrypted cache format
|
||||||
@@ -76,21 +87,25 @@ Core interfaces:
|
|||||||
## Key Features
|
## Key Features
|
||||||
|
|
||||||
### v1.0 - Core Functionality
|
### v1.0 - Core Functionality
|
||||||
|
|
||||||
- **Backup**: Encrypt mnemonic with PGP public key + optional password → QR display
|
- **Backup**: Encrypt mnemonic with PGP public key + optional password → QR display
|
||||||
- **Restore**: Scan/paste QR → decrypt with private key → show mnemonic
|
- **Restore**: Scan/paste QR → decrypt with private key → show mnemonic
|
||||||
- **PGP support**: Import public/private keys (.asc files or paste)
|
- **PGP support**: Import public/private keys (.asc files or paste)
|
||||||
|
|
||||||
### v1.1 - QR Features
|
### v1.1 - QR Features
|
||||||
|
|
||||||
- **QR Display**: Generate QR codes from encrypted data
|
- **QR Display**: Generate QR codes from encrypted data
|
||||||
- **QR Scanner**: Camera + file upload (uses html5-qrcode library)
|
- **QR Scanner**: Camera + file upload (uses html5-qrcode library)
|
||||||
|
|
||||||
### v1.2 - Security Monitoring
|
### v1.2 - Security Monitoring
|
||||||
|
|
||||||
- **Storage Indicator**: Real-time display of localStorage/sessionStorage contents
|
- **Storage Indicator**: Real-time display of localStorage/sessionStorage contents
|
||||||
- **Security Warnings**: Context-aware alerts about browser memory limitations
|
- **Security Warnings**: Context-aware alerts about browser memory limitations
|
||||||
- **Clipboard Tracker**: Monitor clipboard operations on sensitive fields
|
- **Clipboard Tracker**: Monitor clipboard operations on sensitive fields
|
||||||
- **Read-only Mode**: Toggle to clear state + show CSP/build info
|
- **Read-only Mode**: Toggle to clear state + show CSP/build info
|
||||||
|
|
||||||
### v1.3 - Session-Key Encryption (Current)
|
### v1.3 - Session-Key Encryption (Current)
|
||||||
|
|
||||||
- **Ephemeral encryption**: AES-GCM-256 session key (non-exportable) encrypts sensitive state
|
- **Ephemeral encryption**: AES-GCM-256 session key (non-exportable) encrypts sensitive state
|
||||||
- **Auto-clear**: Plaintext mnemonic cleared from UI immediately after QR generation
|
- **Auto-clear**: Plaintext mnemonic cleared from UI immediately after QR generation
|
||||||
- **Encrypted cache**: Only ciphertext stored in React state; key lives in memory only
|
- **Encrypted cache**: Only ciphertext stored in React state; key lives in memory only
|
||||||
@@ -102,6 +117,7 @@ Core interfaces:
|
|||||||
## Development Workflow
|
## Development Workflow
|
||||||
|
|
||||||
### Commands
|
### Commands
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bun install # Install dependencies
|
bun install # Install dependencies
|
||||||
bun run dev # Dev server (localhost:5173)
|
bun run dev # Dev server (localhost:5173)
|
||||||
@@ -112,11 +128,13 @@ bun run preview # Preview production build
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Deployment Process
|
### Deployment Process
|
||||||
|
|
||||||
1. **Private repo** (`seedpgp-web`): Source code, development
|
1. **Private repo** (`seedpgp-web`): Source code, development
|
||||||
2. **Public repo** (`seedpgp-web-app`): Built files for GitHub Pages
|
2. **Public repo** (`seedpgp-web-app`): Built files for GitHub Pages
|
||||||
3. **Deploy script** (`scripts/deploy.sh`): Builds + copies to dist/ + pushes to public repo
|
3. **Deploy script** (`scripts/deploy.sh`): Builds + copies to dist/ + pushes to public repo
|
||||||
|
|
||||||
### Git Workflow
|
### Git Workflow
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Commit feature
|
# Commit feature
|
||||||
git add src/
|
git add src/
|
||||||
@@ -135,24 +153,29 @@ git push origin main --tags
|
|||||||
## Required Workflow for AI Agents
|
## Required Workflow for AI Agents
|
||||||
|
|
||||||
### 1. Study First
|
### 1. Study First
|
||||||
|
|
||||||
Before implementing any feature:
|
Before implementing any feature:
|
||||||
|
|
||||||
- Read relevant files
|
- Read relevant files
|
||||||
- Explain current architecture + entry points
|
- Explain current architecture + entry points
|
||||||
- List files that will be touched
|
- List files that will be touched
|
||||||
- Identify potential conflicts or dependencies
|
- Identify potential conflicts or dependencies
|
||||||
|
|
||||||
### 2. Plan
|
### 2. Plan
|
||||||
|
|
||||||
- Propose smallest vertical slice (1-5 files)
|
- Propose smallest vertical slice (1-5 files)
|
||||||
- Show API signatures or interface changes first
|
- Show API signatures or interface changes first
|
||||||
- Get approval before generating full implementation
|
- Get approval before generating full implementation
|
||||||
|
|
||||||
### 3. Implement
|
### 3. Implement
|
||||||
|
|
||||||
- Generate code with TypeScript strict mode
|
- Generate code with TypeScript strict mode
|
||||||
- Include JSDoc comments for public APIs
|
- Include JSDoc comments for public APIs
|
||||||
- Show unified diffs, not full file rewrites (when possible)
|
- Show unified diffs, not full file rewrites (when possible)
|
||||||
- Keep changes under 50-100 lines per file when feasible
|
- Keep changes under 50-100 lines per file when feasible
|
||||||
|
|
||||||
### 4. Verify
|
### 4. Verify
|
||||||
|
|
||||||
- Run `bun run typecheck` - no errors
|
- Run `bun run typecheck` - no errors
|
||||||
- Run `bun run build` - successful dist/ output
|
- Run `bun run build` - successful dist/ output
|
||||||
- Provide manual test steps for browser verification
|
- Provide manual test steps for browser verification
|
||||||
@@ -163,25 +186,30 @@ Before implementing any feature:
|
|||||||
## Common Patterns
|
## Common Patterns
|
||||||
|
|
||||||
### State Management
|
### State Management
|
||||||
|
|
||||||
- React `useState` + `useEffect` (no Redux/Zustand/external store)
|
- React `useState` + `useEffect` (no Redux/Zustand/external store)
|
||||||
- Ephemeral state only; avoid persistent storage for secrets
|
- Ephemeral state only; avoid persistent storage for secrets
|
||||||
|
|
||||||
### Styling
|
### Styling
|
||||||
|
|
||||||
- Tailwind utility classes (configured in `tailwind.config.js`)
|
- Tailwind utility classes (configured in `tailwind.config.js`)
|
||||||
- Responsive design: mobile-first with `md:` breakpoints
|
- Responsive design: mobile-first with `md:` breakpoints
|
||||||
- Dark theme primary: slate-900 background, blue-400 accents
|
- Dark theme primary: slate-900 background, blue-400 accents
|
||||||
|
|
||||||
### Icons
|
### Icons
|
||||||
|
|
||||||
- `lucide-react` library
|
- `lucide-react` library
|
||||||
- Common: Shield, QrCode, Lock, Eye, AlertCircle
|
- Common: Shield, QrCode, Lock, Eye, AlertCircle
|
||||||
|
|
||||||
### Crypto Operations
|
### Crypto Operations
|
||||||
|
|
||||||
- **PGP**: OpenPGP.js (`openpgp` package)
|
- **PGP**: OpenPGP.js (`openpgp` package)
|
||||||
- **Session keys**: Web Crypto API (`crypto.subtle`)
|
- **Session keys**: Web Crypto API (`crypto.subtle`)
|
||||||
- **Key generation**: `crypto.subtle.generateKey()` with `extractable: false`
|
- **Key generation**: `crypto.subtle.generateKey()` with `extractable: false`
|
||||||
- **Encryption**: AES-GCM with random 12-byte IV per operation
|
- **Encryption**: AES-GCM with random 12-byte IV per operation
|
||||||
|
|
||||||
### Type Safety
|
### Type Safety
|
||||||
|
|
||||||
- Strict TypeScript (`tsconfig.json`: `strict: true`)
|
- Strict TypeScript (`tsconfig.json`: `strict: true`)
|
||||||
- Check `src/lib/types.ts` for core interfaces
|
- Check `src/lib/types.ts` for core interfaces
|
||||||
- Avoid `any`; use `unknown` + type guards when necessary
|
- Avoid `any`; use `unknown` + type guards when necessary
|
||||||
@@ -191,22 +219,27 @@ Before implementing any feature:
|
|||||||
## Security Architecture
|
## Security Architecture
|
||||||
|
|
||||||
### Threat Model (Honest)
|
### Threat Model (Honest)
|
||||||
|
|
||||||
**What we protect against:**
|
**What we protect against:**
|
||||||
|
|
||||||
- Accidental persistence to localStorage/sessionStorage
|
- Accidental persistence to localStorage/sessionStorage
|
||||||
- Plaintext secrets lingering in React state after use
|
- Plaintext secrets lingering in React state after use
|
||||||
- Clipboard history exposure (with warnings)
|
- Clipboard history exposure (with warnings)
|
||||||
|
|
||||||
**What we DON'T protect against (and must not claim to):**
|
**What we DON'T protect against (and must not claim to):**
|
||||||
|
|
||||||
- Active XSS or malicious browser extensions
|
- Active XSS or malicious browser extensions
|
||||||
- Memory dumps or browser crash reports
|
- Memory dumps or browser crash reports
|
||||||
- JavaScript garbage collection timing (non-deterministic)
|
- JavaScript garbage collection timing (non-deterministic)
|
||||||
|
|
||||||
### Memory Handling
|
### Memory Handling
|
||||||
|
|
||||||
- **Session keys**: Non-exportable CryptoKey objects (Web Crypto API)
|
- **Session keys**: Non-exportable CryptoKey objects (Web Crypto API)
|
||||||
- **Plaintext clearing**: Set to empty string + drop references (but GC timing is non-deterministic)
|
- **Plaintext clearing**: Set to empty string + drop references (but GC timing is non-deterministic)
|
||||||
- **No guarantees**: Cannot force immediate memory wiping in JavaScript
|
- **No guarantees**: Cannot force immediate memory wiping in JavaScript
|
||||||
|
|
||||||
### Storage Policy
|
### Storage Policy
|
||||||
|
|
||||||
- **NEVER write to**: localStorage, sessionStorage, IndexedDB, cookies
|
- **NEVER write to**: localStorage, sessionStorage, IndexedDB, cookies
|
||||||
- **Exception**: Non-sensitive UI state only (theme preferences, etc.) - NOT IMPLEMENTED YET
|
- **Exception**: Non-sensitive UI state only (theme preferences, etc.) - NOT IMPLEMENTED YET
|
||||||
- **Verification**: StorageIndicator component monitors all storage APIs
|
- **Verification**: StorageIndicator component monitors all storage APIs
|
||||||
@@ -216,17 +249,20 @@ Before implementing any feature:
|
|||||||
## What NOT to Do
|
## What NOT to Do
|
||||||
|
|
||||||
### Code Generation
|
### Code Generation
|
||||||
|
|
||||||
- Don't generate full file rewrites unless necessary
|
- Don't generate full file rewrites unless necessary
|
||||||
- Don't add dependencies without discussing bundle size impact
|
- Don't add dependencies without discussing bundle size impact
|
||||||
- Don't use `any` types without explicit justification
|
- Don't use `any` types without explicit justification
|
||||||
- Don't skip TypeScript strict mode checks
|
- Don't skip TypeScript strict mode checks
|
||||||
|
|
||||||
### Security Claims
|
### Security Claims
|
||||||
|
|
||||||
- Don't claim "RAM is wiped" (JavaScript can't force GC)
|
- Don't claim "RAM is wiped" (JavaScript can't force GC)
|
||||||
- Don't claim "offline mode" without real CSP headers (GitHub Pages can't set custom headers)
|
- Don't claim "offline mode" without real CSP headers (GitHub Pages can't set custom headers)
|
||||||
- Don't promise protection against active browser compromise (XSS/extensions)
|
- Don't promise protection against active browser compromise (XSS/extensions)
|
||||||
|
|
||||||
### Storage
|
### Storage
|
||||||
|
|
||||||
- Don't write secrets to storage without explicit approval
|
- Don't write secrets to storage without explicit approval
|
||||||
- Don't cache decrypted data beyond immediate use
|
- Don't cache decrypted data beyond immediate use
|
||||||
- Don't assume browser storage is secure
|
- Don't assume browser storage is secure
|
||||||
@@ -236,6 +272,7 @@ Before implementing any feature:
|
|||||||
## Testing & Verification
|
## Testing & Verification
|
||||||
|
|
||||||
### Manual Test Checklist (Before Marking Feature Complete)
|
### Manual Test Checklist (Before Marking Feature Complete)
|
||||||
|
|
||||||
1. ✅ `bun run typecheck` passes (no TypeScript errors)
|
1. ✅ `bun run typecheck` passes (no TypeScript errors)
|
||||||
2. ✅ `bun run build` succeeds (dist/ generated)
|
2. ✅ `bun run build` succeeds (dist/ generated)
|
||||||
3. ✅ Browser test: Feature works as described
|
3. ✅ Browser test: Feature works as described
|
||||||
@@ -244,6 +281,7 @@ Before implementing any feature:
|
|||||||
6. ✅ DevTools Network tab: No unexpected network calls (if Read-only Mode)
|
6. ✅ DevTools Network tab: No unexpected network calls (if Read-only Mode)
|
||||||
|
|
||||||
### Session-Key Encryption Test (v1.3+)
|
### Session-Key Encryption Test (v1.3+)
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// In browser DevTools console:
|
// In browser DevTools console:
|
||||||
await window.runSessionCryptoTest()
|
await window.runSessionCryptoTest()
|
||||||
@@ -255,17 +293,20 @@ await window.runSessionCryptoTest()
|
|||||||
## Current Version: v1.3.0
|
## Current Version: v1.3.0
|
||||||
|
|
||||||
### Recent Changes (2026-01-29)
|
### Recent Changes (2026-01-29)
|
||||||
|
|
||||||
- ✅ Added `src/lib/sessionCrypto.ts` with ephemeral AES-GCM session keys
|
- ✅ Added `src/lib/sessionCrypto.ts` with ephemeral AES-GCM session keys
|
||||||
- ✅ Integrated into Backup flow: plaintext mnemonic auto-cleared after QR generation
|
- ✅ Integrated into Backup flow: plaintext mnemonic auto-cleared after QR generation
|
||||||
- ✅ Added Lock/Clear button to destroy session key and clear all state
|
- ✅ Added Lock/Clear button to destroy session key and clear all state
|
||||||
- ✅ Added cleanup on component unmount
|
- ✅ Added cleanup on component unmount
|
||||||
|
|
||||||
### Known Limitations
|
### Known Limitations
|
||||||
|
|
||||||
- GitHub Pages cannot set custom CSP headers (need Cloudflare Pages for enforcement)
|
- GitHub Pages cannot set custom CSP headers (need Cloudflare Pages for enforcement)
|
||||||
- Read-only Mode is UI-level only (not browser-enforced)
|
- Read-only Mode is UI-level only (not browser-enforced)
|
||||||
- Session-key encryption doesn't protect against active XSS/extensions
|
- Session-key encryption doesn't protect against active XSS/extensions
|
||||||
|
|
||||||
### Next Priorities (Suggested)
|
### Next Priorities (Suggested)
|
||||||
|
|
||||||
1. Extend session-key encryption to Restore flow
|
1. Extend session-key encryption to Restore flow
|
||||||
2. Migrate to Cloudflare Pages for real CSP header enforcement
|
2. Migrate to Cloudflare Pages for real CSP header enforcement
|
||||||
3. Add "Encrypted in memory" badge when encryptedMnemonicCache exists
|
3. Add "Encrypted in memory" badge when encryptedMnemonicCache exists
|
||||||
@@ -276,12 +317,15 @@ await window.runSessionCryptoTest()
|
|||||||
## Quick Reference
|
## Quick Reference
|
||||||
|
|
||||||
### File a Bug/Feature
|
### File a Bug/Feature
|
||||||
|
|
||||||
1. Describe expected vs actual behavior
|
1. Describe expected vs actual behavior
|
||||||
2. Include browser console errors (if any)
|
2. Include browser console errors (if any)
|
||||||
3. Specify which flow (Backup/Restore/QR Scanner)
|
3. Specify which flow (Backup/Restore/QR Scanner)
|
||||||
|
|
||||||
### Roll Over to Next Session
|
### Roll Over to Next Session
|
||||||
|
|
||||||
Always provide:
|
Always provide:
|
||||||
|
|
||||||
- Current version number
|
- Current version number
|
||||||
- What was implemented this session
|
- What was implemented this session
|
||||||
- Files modified
|
- Files modified
|
||||||
@@ -293,6 +337,7 @@ Always provide:
|
|||||||
## Example Prompts for Gemini
|
## Example Prompts for Gemini
|
||||||
|
|
||||||
### Exploration
|
### Exploration
|
||||||
|
|
||||||
```
|
```
|
||||||
Read GEMINI.md, then explain:
|
Read GEMINI.md, then explain:
|
||||||
1. Where is the mnemonic textarea and how is its value managed?
|
1. Where is the mnemonic textarea and how is its value managed?
|
||||||
@@ -301,6 +346,7 @@ Read GEMINI.md, then explain:
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Feature Request
|
### Feature Request
|
||||||
|
|
||||||
```
|
```
|
||||||
Task: [Feature description]
|
Task: [Feature description]
|
||||||
|
|
||||||
@@ -315,6 +361,7 @@ Plan first: show proposed API/changes before generating code.
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Verification
|
### Verification
|
||||||
|
|
||||||
```
|
```
|
||||||
Audit the codebase to verify [feature] is fully implemented.
|
Audit the codebase to verify [feature] is fully implemented.
|
||||||
Check:
|
Check:
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { StorageIndicator } from './components/StorageIndicator';
|
|||||||
import { SecurityWarnings } from './components/SecurityWarnings';
|
import { SecurityWarnings } from './components/SecurityWarnings';
|
||||||
import { ClipboardTracker } from './components/ClipboardTracker';
|
import { ClipboardTracker } from './components/ClipboardTracker';
|
||||||
import { ReadOnly } from './components/ReadOnly';
|
import { ReadOnly } from './components/ReadOnly';
|
||||||
import { encryptJsonToBlob, destroySessionKey, EncryptedBlob } from './lib/sessionCrypto';
|
import { getSessionKey, encryptJsonToBlob, destroySessionKey, EncryptedBlob } from './lib/sessionCrypto';
|
||||||
|
|
||||||
console.log("OpenPGP.js version:", openpgp.config.versionString);
|
console.log("OpenPGP.js version:", openpgp.config.versionString);
|
||||||
|
|
||||||
@@ -122,6 +122,8 @@ import { encryptJsonToBlob, destroySessionKey, EncryptedBlob } from './lib/sessi
|
|||||||
setRecipientFpr(result.recipientFingerprint);
|
setRecipientFpr(result.recipientFingerprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize session key before encrypting
|
||||||
|
await getSessionKey();
|
||||||
// Encrypt mnemonic with session key and clear plaintext state
|
// Encrypt mnemonic with session key and clear plaintext state
|
||||||
const blob = await encryptJsonToBlob({ mnemonic, timestamp: Date.now() });
|
const blob = await encryptJsonToBlob({ mnemonic, timestamp: Date.now() });
|
||||||
setEncryptedMnemonicCache(blob);
|
setEncryptedMnemonicCache(blob);
|
||||||
|
|||||||
Reference in New Issue
Block a user