225 lines
6.6 KiB
JavaScript
225 lines
6.6 KiB
JavaScript
let vault = null;
|
|
let isInitialized = false;
|
|
let currentSession = null;
|
|
|
|
// Utility function to convert Uint8Array to hex
|
|
function toHex(uint8Array) {
|
|
return Array.from(uint8Array)
|
|
.map(b => b.toString(16).padStart(2, '0'))
|
|
.join('');
|
|
}
|
|
|
|
// Session persistence functions
|
|
async function saveSession(keyspace) {
|
|
currentSession = { keyspace, timestamp: Date.now() };
|
|
await chrome.storage.session.set({ cryptoVaultSession: currentSession });
|
|
console.log('Session saved:', currentSession);
|
|
}
|
|
|
|
async function loadSession() {
|
|
try {
|
|
const result = await chrome.storage.session.get(['cryptoVaultSession']);
|
|
if (result.cryptoVaultSession) {
|
|
currentSession = result.cryptoVaultSession;
|
|
console.log('Session loaded:', currentSession);
|
|
return currentSession;
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to load session:', error);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function clearSession() {
|
|
currentSession = null;
|
|
await chrome.storage.session.remove(['cryptoVaultSession']);
|
|
console.log('Session cleared');
|
|
}
|
|
|
|
async function restoreSession() {
|
|
const session = await loadSession();
|
|
if (session && vault) {
|
|
try {
|
|
// Check if the session is still valid by testing if vault is unlocked
|
|
const isUnlocked = vault.is_unlocked();
|
|
if (isUnlocked) {
|
|
console.log('Session restored successfully for keyspace:', session.keyspace);
|
|
return session;
|
|
} else {
|
|
console.log('Session expired, clearing...');
|
|
await clearSession();
|
|
}
|
|
} catch (error) {
|
|
console.error('Error checking session validity:', error);
|
|
await clearSession();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Import WASM module functions
|
|
import init, {
|
|
create_keyspace,
|
|
init_session,
|
|
is_unlocked,
|
|
add_keypair,
|
|
list_keypairs,
|
|
select_keypair,
|
|
current_keypair_metadata,
|
|
current_keypair_public_key,
|
|
sign,
|
|
lock_session
|
|
} from './wasm/wasm_app.js';
|
|
|
|
// Initialize WASM module
|
|
async function initVault() {
|
|
try {
|
|
if (vault && isInitialized) return vault;
|
|
|
|
// Initialize with the WASM file
|
|
const wasmUrl = chrome.runtime.getURL('wasm/wasm_app_bg.wasm');
|
|
await init(wasmUrl);
|
|
|
|
// Create a vault object with all the imported functions
|
|
vault = {
|
|
create_keyspace,
|
|
init_session,
|
|
is_unlocked,
|
|
add_keypair,
|
|
list_keypairs,
|
|
select_keypair,
|
|
current_keypair_metadata,
|
|
current_keypair_public_key,
|
|
sign,
|
|
lock_session
|
|
};
|
|
|
|
isInitialized = true;
|
|
console.log('CryptoVault initialized successfully');
|
|
|
|
// Try to restore previous session
|
|
await restoreSession();
|
|
|
|
return vault;
|
|
} catch (error) {
|
|
console.error('Failed to initialize CryptoVault:', error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
// Handle messages from popup and content scripts
|
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
const handleRequest = async () => {
|
|
try {
|
|
if (!vault) {
|
|
await initVault();
|
|
}
|
|
|
|
switch (request.action) {
|
|
case 'createKeyspace':
|
|
await vault.create_keyspace(request.keyspace, request.password);
|
|
return { success: true };
|
|
|
|
case 'initSession':
|
|
await vault.init_session(request.keyspace, request.password);
|
|
await saveSession(request.keyspace);
|
|
return { success: true };
|
|
|
|
case 'isUnlocked':
|
|
const unlocked = vault.is_unlocked();
|
|
return { success: true, unlocked };
|
|
|
|
case 'addKeypair':
|
|
const result = await vault.add_keypair(request.keyType, request.metadata);
|
|
return { success: true, result };
|
|
|
|
case 'listKeypairs':
|
|
console.log('Background: listing keypairs...');
|
|
console.log('Background: vault object:', vault);
|
|
console.log('Background: vault.list_keypairs function:', vault.list_keypairs);
|
|
|
|
// Check if session is unlocked first
|
|
const isUnlocked = vault.is_unlocked();
|
|
console.log('Background: is session unlocked?', isUnlocked);
|
|
|
|
if (!isUnlocked) {
|
|
console.log('Background: Session is not unlocked, cannot list keypairs');
|
|
return { success: false, error: 'Session is not unlocked' };
|
|
}
|
|
|
|
try {
|
|
const keypairsRaw = await vault.list_keypairs();
|
|
console.log('Background: keypairs raw result:', keypairsRaw);
|
|
console.log('Background: keypairs type:', typeof keypairsRaw);
|
|
|
|
// Parse JSON string if needed
|
|
let keypairs;
|
|
if (typeof keypairsRaw === 'string') {
|
|
console.log('Background: Parsing JSON string...');
|
|
keypairs = JSON.parse(keypairsRaw);
|
|
} else {
|
|
keypairs = keypairsRaw;
|
|
}
|
|
|
|
console.log('Background: parsed keypairs:', keypairs);
|
|
console.log('Background: parsed keypairs type:', typeof keypairs);
|
|
console.log('Background: keypairs array length:', Array.isArray(keypairs) ? keypairs.length : 'not an array');
|
|
|
|
return { success: true, keypairs };
|
|
} catch (listError) {
|
|
console.error('Background: Error calling list_keypairs:', listError);
|
|
throw listError;
|
|
}
|
|
|
|
case 'selectKeypair':
|
|
vault.select_keypair(request.keyId);
|
|
return { success: true };
|
|
|
|
case 'getCurrentKeypairMetadata':
|
|
const metadata = vault.current_keypair_metadata();
|
|
return { success: true, metadata };
|
|
|
|
case 'getCurrentKeypairPublicKey':
|
|
const publicKey = vault.current_keypair_public_key();
|
|
const hexKey = toHex(publicKey);
|
|
return { success: true, publicKey: hexKey };
|
|
|
|
case 'sign':
|
|
const signature = await vault.sign(new Uint8Array(request.message));
|
|
return { success: true, signature };
|
|
|
|
case 'lockSession':
|
|
vault.lock_session();
|
|
await clearSession();
|
|
return { success: true };
|
|
|
|
case 'getStatus':
|
|
const status = vault ? vault.is_unlocked() : false;
|
|
const session = await loadSession();
|
|
return {
|
|
success: true,
|
|
status,
|
|
session: session ? { keyspace: session.keyspace } : null
|
|
};
|
|
|
|
default:
|
|
throw new Error('Unknown action: ' + request.action);
|
|
}
|
|
} catch (error) {
|
|
console.error('Background script error:', error);
|
|
return { success: false, error: error.message };
|
|
}
|
|
};
|
|
|
|
handleRequest().then(sendResponse);
|
|
return true; // Keep the message channel open for async response
|
|
});
|
|
|
|
// Initialize vault when extension starts
|
|
chrome.runtime.onStartup.addListener(() => {
|
|
initVault();
|
|
});
|
|
|
|
chrome.runtime.onInstalled.addListener(() => {
|
|
initVault();
|
|
}); |