feat: Implement Prompt Builder functionality in Popup and Options
Some checks failed
CI — Test & Build / Test & Build (push) Failing after 39s
Some checks failed
CI — Test & Build / Test & Build (push) Failing after 39s
- Added a new "Prompt Builder" tab in the Popup for generating AI prompts with customizable parameters. - Introduced new state variables for managing prompt styles, personas, formats, and models. - Enhanced the Options page to fetch and display models based on the provided API key. - Updated the actions and types to include the new 'prompt' action and its associated parameters. - Implemented migration logic for legacy plaintext API keys to encrypted storage. - Updated the getSystemPrompt function to incorporate prompt parameters for better instruction generation. - Added tests for the new functionality, including context menu entries and prompt generation logic.
This commit is contained in:
1
.claude/agent-memory/security-auditor/MEMORY.md
Normal file
1
.claude/agent-memory/security-auditor/MEMORY.md
Normal file
@@ -0,0 +1 @@
|
||||
- [API key at-rest model](threat-model-apikey.md) — how LexAI stores/migrates the BYO LLM key and what "secure" does and doesn't mean here
|
||||
18
.claude/agent-memory/security-auditor/threat-model-apikey.md
Normal file
18
.claude/agent-memory/security-auditor/threat-model-apikey.md
Normal file
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: threat-model-apikey
|
||||
description: LexAI API-key at-rest threat model and the storage/migration invariants an auditor must preserve
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
|
||||
LexAI is a BYO-LLM-key MV3 extension with no backend. The user's provider API key is the crown-jewel secret.
|
||||
|
||||
Storage scheme (src/lib/crypto.ts): `encKey` = base64(32-byte secretbox key), `apiKeyEnc` = base64(nonce||ciphertext). Legacy plaintext `apiKey` is back-compat fallback and must not be dropped without a migration. `migratePlaintextApiKey()` runs on background startup: encrypts legacy plaintext into the secretbox scheme, removes plaintext only after the encrypted copy is persisted (and, when one already exists, only after verifying it decrypts).
|
||||
|
||||
**Why:** The secretbox key lives in the same chrome.storage.local as the ciphertext, so this is obfuscation against casual inspection only — anyone who can read extension storage can decrypt. This is honestly documented in crypto.ts and UI copy must not over-promise.
|
||||
|
||||
**How to apply when auditing key-path changes:**
|
||||
- Never log or transmit the key except to the user's chosen provider endpoint. Grep console.* for key/config exposure; error strings in providers.ts must carry only provider label + response message, never headers/key.
|
||||
- Preserve write-before-delete ordering in any migration so an interruption can't lose the only key. Note: getOrCreateEncKey persists encKey fire-and-forget (no awaited callback) — relies on Chrome FIFO storage ordering; awaiting it would be stricter.
|
||||
- Both onMessage listeners (background + content) guard `sender.id !== chrome.runtime.id`. Legit internal messages (content/popup/options + background→content tabs.sendMessage) all carry sender.id === chrome.runtime.id, so the guard is safe. It blocks other extensions / externally_connectable.
|
||||
- Content/popup must never fetch a provider directly — key handling belongs in the background worker.
|
||||
Reference in New Issue
Block a user