307 lines
9.8 KiB
JavaScript
307 lines
9.8 KiB
JavaScript
// Simple non-module JavaScript for browser extension popup
|
|
document.addEventListener('DOMContentLoaded', async function() {
|
|
const root = document.getElementById('root');
|
|
root.innerHTML = `
|
|
<div class="container">
|
|
<h1>Modular Vault Extension</h1>
|
|
<div id="status" class="status">Loading WASM module...</div>
|
|
|
|
<div id="session-controls">
|
|
<div id="keyspace-form" class="form-section">
|
|
<h2>Session</h2>
|
|
<div class="form-group">
|
|
<label for="keyspace">Keyspace:</label>
|
|
<input type="text" id="keyspace" placeholder="Enter keyspace name">
|
|
</div>
|
|
<div class="form-group">
|
|
<label for="password">Password:</label>
|
|
<input type="password" id="password" placeholder="Enter password">
|
|
</div>
|
|
<div class="button-group">
|
|
<button id="unlock-btn">Unlock</button>
|
|
<button id="create-btn">Create New</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="session-info" class="session-info hidden">
|
|
<h2>Active Session</h2>
|
|
<p>Current keyspace: <span id="current-keyspace"></span></p>
|
|
<button id="lock-btn">Lock Session</button>
|
|
|
|
<div id="keypair-section" class="form-section">
|
|
<h2>Keypairs</h2>
|
|
<button id="create-keypair-btn">Create New Keypair</button>
|
|
<div id="keypair-list" class="list"></div>
|
|
</div>
|
|
|
|
<div id="sign-section" class="form-section hidden">
|
|
<h2>Sign Message</h2>
|
|
<div class="form-group">
|
|
<label for="message">Message:</label>
|
|
<textarea id="message" placeholder="Enter message to sign"></textarea>
|
|
</div>
|
|
<button id="sign-btn">Sign</button>
|
|
<div class="form-group">
|
|
<label for="signature">Signature:</label>
|
|
<textarea id="signature" readonly></textarea>
|
|
<button id="copy-btn" class="small">Copy</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
`;
|
|
|
|
// DOM elements
|
|
const statusEl = document.getElementById('status');
|
|
const keyspaceFormEl = document.getElementById('keyspace-form');
|
|
const sessionInfoEl = document.getElementById('session-info');
|
|
const currentKeyspaceEl = document.getElementById('current-keyspace');
|
|
const keyspaceInput = document.getElementById('keyspace');
|
|
const passwordInput = document.getElementById('password');
|
|
const unlockBtn = document.getElementById('unlock-btn');
|
|
const createBtn = document.getElementById('create-btn');
|
|
const lockBtn = document.getElementById('lock-btn');
|
|
const createKeypairBtn = document.getElementById('create-keypair-btn');
|
|
const keypairListEl = document.getElementById('keypair-list');
|
|
const signSectionEl = document.getElementById('sign-section');
|
|
const messageInput = document.getElementById('message');
|
|
const signBtn = document.getElementById('sign-btn');
|
|
const signatureOutput = document.getElementById('signature');
|
|
const copyBtn = document.getElementById('copy-btn');
|
|
|
|
// State
|
|
let wasmModule = null;
|
|
let currentKeyspace = null;
|
|
let keypairs = [];
|
|
let selectedKeypairId = null;
|
|
|
|
// Initialize
|
|
init();
|
|
|
|
async function init() {
|
|
try {
|
|
// Get session state from background
|
|
const sessionState = await getSessionState();
|
|
|
|
if (sessionState.currentKeyspace) {
|
|
// We have an active session
|
|
currentKeyspace = sessionState.currentKeyspace;
|
|
keypairs = sessionState.keypairs || [];
|
|
selectedKeypairId = sessionState.selectedKeypair;
|
|
|
|
updateUI();
|
|
}
|
|
|
|
statusEl.textContent = 'Ready';
|
|
} catch (error) {
|
|
statusEl.textContent = 'Error: ' + (error.message || 'Unknown error');
|
|
}
|
|
}
|
|
|
|
function updateUI() {
|
|
if (currentKeyspace) {
|
|
// Show session info
|
|
keyspaceFormEl.classList.add('hidden');
|
|
sessionInfoEl.classList.remove('hidden');
|
|
currentKeyspaceEl.textContent = currentKeyspace;
|
|
|
|
// Update keypair list
|
|
updateKeypairList();
|
|
|
|
// Show/hide sign section based on selected keypair
|
|
if (selectedKeypairId) {
|
|
signSectionEl.classList.remove('hidden');
|
|
} else {
|
|
signSectionEl.classList.add('hidden');
|
|
}
|
|
} else {
|
|
// Show keyspace form
|
|
keyspaceFormEl.classList.remove('hidden');
|
|
sessionInfoEl.classList.add('hidden');
|
|
}
|
|
}
|
|
|
|
function updateKeypairList() {
|
|
// Clear list
|
|
keypairListEl.innerHTML = '';
|
|
|
|
// Add each keypair
|
|
keypairs.forEach(keypair => {
|
|
const item = document.createElement('div');
|
|
item.className = 'list-item' + (selectedKeypairId === keypair.id ? ' selected' : '');
|
|
item.innerHTML = `
|
|
<span>${keypair.label || keypair.id}</span>
|
|
<button class="select-btn" data-id="${keypair.id}">Select</button>
|
|
`;
|
|
keypairListEl.appendChild(item);
|
|
|
|
// Add select handler
|
|
item.querySelector('.select-btn').addEventListener('click', async () => {
|
|
try {
|
|
statusEl.textContent = 'Selecting keypair...';
|
|
// Use background service to select keypair for now
|
|
await chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keypair_selected',
|
|
data: keypair.id
|
|
});
|
|
selectedKeypairId = keypair.id;
|
|
updateUI();
|
|
statusEl.textContent = 'Keypair selected: ' + keypair.id;
|
|
} catch (error) {
|
|
statusEl.textContent = 'Error selecting keypair: ' + (error.message || 'Unknown error');
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
// Get session state from background
|
|
async function getSessionState() {
|
|
return new Promise((resolve) => {
|
|
chrome.runtime.sendMessage({ action: 'get_session' }, (response) => {
|
|
resolve(response || { currentKeyspace: null, keypairs: [], selectedKeypair: null });
|
|
});
|
|
});
|
|
}
|
|
|
|
// Event handlers
|
|
unlockBtn.addEventListener('click', async () => {
|
|
const keyspace = keyspaceInput.value.trim();
|
|
const password = passwordInput.value;
|
|
|
|
if (!keyspace || !password) {
|
|
statusEl.textContent = 'Please enter keyspace and password';
|
|
return;
|
|
}
|
|
|
|
statusEl.textContent = 'Unlocking session...';
|
|
|
|
try {
|
|
// For now, use the background service worker mock
|
|
await chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keyspace',
|
|
data: keyspace
|
|
});
|
|
|
|
currentKeyspace = keyspace;
|
|
updateUI();
|
|
statusEl.textContent = 'Session unlocked!';
|
|
|
|
// Refresh state
|
|
const state = await getSessionState();
|
|
keypairs = state.keypairs || [];
|
|
selectedKeypairId = state.selectedKeypair;
|
|
updateUI();
|
|
} catch (error) {
|
|
statusEl.textContent = 'Error unlocking session: ' + (error.message || 'Unknown error');
|
|
}
|
|
});
|
|
|
|
createBtn.addEventListener('click', async () => {
|
|
const keyspace = keyspaceInput.value.trim();
|
|
const password = passwordInput.value;
|
|
|
|
if (!keyspace || !password) {
|
|
statusEl.textContent = 'Please enter keyspace and password';
|
|
return;
|
|
}
|
|
|
|
statusEl.textContent = 'Creating keyspace...';
|
|
|
|
try {
|
|
// For now, use the background service worker mock
|
|
await chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keyspace',
|
|
data: keyspace
|
|
});
|
|
|
|
currentKeyspace = keyspace;
|
|
updateUI();
|
|
statusEl.textContent = 'Keyspace created and unlocked!';
|
|
} catch (error) {
|
|
statusEl.textContent = 'Error creating keyspace: ' + (error.message || 'Unknown error');
|
|
}
|
|
});
|
|
|
|
lockBtn.addEventListener('click', async () => {
|
|
statusEl.textContent = 'Locking session...';
|
|
|
|
try {
|
|
await chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'session_locked'
|
|
});
|
|
|
|
currentKeyspace = null;
|
|
keypairs = [];
|
|
selectedKeypairId = null;
|
|
updateUI();
|
|
statusEl.textContent = 'Session locked';
|
|
} catch (error) {
|
|
statusEl.textContent = 'Error locking session: ' + (error.message || 'Unknown error');
|
|
}
|
|
});
|
|
|
|
createKeypairBtn.addEventListener('click', async () => {
|
|
statusEl.textContent = 'Creating keypair...';
|
|
|
|
try {
|
|
// Generate a mock keypair ID
|
|
const keyId = 'key-' + Date.now().toString(16);
|
|
const newKeypair = {
|
|
id: keyId,
|
|
label: `Secp256k1-Key-${keypairs.length + 1}`
|
|
};
|
|
|
|
await chrome.runtime.sendMessage({
|
|
action: 'update_session',
|
|
type: 'keypair_added',
|
|
data: newKeypair
|
|
});
|
|
|
|
// Refresh state
|
|
const state = await getSessionState();
|
|
keypairs = state.keypairs || [];
|
|
updateUI();
|
|
|
|
statusEl.textContent = 'Keypair created: ' + keyId;
|
|
} catch (error) {
|
|
statusEl.textContent = 'Error creating keypair: ' + (error.message || 'Unknown error');
|
|
}
|
|
});
|
|
|
|
signBtn.addEventListener('click', async () => {
|
|
const message = messageInput.value.trim();
|
|
|
|
if (!message) {
|
|
statusEl.textContent = 'Please enter a message to sign';
|
|
return;
|
|
}
|
|
|
|
if (!selectedKeypairId) {
|
|
statusEl.textContent = 'Please select a keypair first';
|
|
return;
|
|
}
|
|
|
|
statusEl.textContent = 'Signing message...';
|
|
|
|
try {
|
|
// For now, generate a mock signature
|
|
const mockSignature = Array.from({length: 64}, () => Math.floor(Math.random() * 16).toString(16)).join('');
|
|
signatureOutput.value = mockSignature;
|
|
statusEl.textContent = 'Message signed!';
|
|
} catch (error) {
|
|
statusEl.textContent = 'Error signing message: ' + (error.message || 'Unknown error');
|
|
}
|
|
});
|
|
|
|
copyBtn.addEventListener('click', () => {
|
|
signatureOutput.select();
|
|
document.execCommand('copy');
|
|
statusEl.textContent = 'Signature copied to clipboard!';
|
|
});
|
|
});
|