Support encrypt, decrypt & verify + add dark theme + better error handling & UI enhancements

This commit is contained in:
zaelgohary 2025-05-28 09:49:23 +03:00
parent 5bc205b2f7
commit 37764e3861
7 changed files with 1893 additions and 548 deletions

View File

@ -1,6 +1,7 @@
let vault = null;
let isInitialized = false;
let currentSession = null;
let keepAliveInterval = null;
// Utility function to convert Uint8Array to hex
function toHex(uint8Array) {
@ -12,16 +13,31 @@ function toHex(uint8Array) {
// Session persistence functions
async function saveSession(keyspace) {
currentSession = { keyspace, timestamp: Date.now() };
// Save to both session and local storage for better persistence
try {
await chrome.storage.session.set({ cryptoVaultSession: currentSession });
console.log('Session saved:', currentSession);
await chrome.storage.local.set({ cryptoVaultSessionBackup: currentSession });
} catch (error) {
console.error('Failed to save session:', error);
}
}
async function loadSession() {
try {
const result = await chrome.storage.session.get(['cryptoVaultSession']);
// Try session storage first
let result = await chrome.storage.session.get(['cryptoVaultSession']);
if (result.cryptoVaultSession) {
currentSession = result.cryptoVaultSession;
console.log('Session loaded:', currentSession);
return currentSession;
}
// Fallback to local storage
result = await chrome.storage.local.get(['cryptoVaultSessionBackup']);
if (result.cryptoVaultSessionBackup) {
currentSession = result.cryptoVaultSessionBackup;
// Restore to session storage
await chrome.storage.session.set({ cryptoVaultSession: currentSession });
return currentSession;
}
} catch (error) {
@ -32,8 +48,45 @@ async function loadSession() {
async function clearSession() {
currentSession = null;
try {
await chrome.storage.session.remove(['cryptoVaultSession']);
console.log('Session cleared');
await chrome.storage.local.remove(['cryptoVaultSessionBackup']);
} catch (error) {
console.error('Failed to clear session:', error);
}
}
// Keep service worker alive
function startKeepAlive() {
if (keepAliveInterval) {
clearInterval(keepAliveInterval);
}
// Ping every 20 seconds to keep service worker alive
keepAliveInterval = setInterval(() => {
// Simple operation to keep service worker active
chrome.storage.session.get(['keepAlive']).catch(() => {
// Ignore errors
});
}, 20000);
}
function stopKeepAlive() {
if (keepAliveInterval) {
clearInterval(keepAliveInterval);
keepAliveInterval = null;
}
}
// Enhanced session management with keep-alive
async function saveSessionWithKeepAlive(keyspace) {
await saveSession(keyspace);
startKeepAlive();
}
async function clearSessionWithKeepAlive() {
await clearSession();
stopKeepAlive();
}
async function restoreSession() {
@ -43,15 +96,15 @@ async function restoreSession() {
// 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);
// Restart keep-alive for restored session
startKeepAlive();
return session;
} else {
console.log('Session expired, clearing...');
await clearSession();
await clearSessionWithKeepAlive();
}
} catch (error) {
console.error('Error checking session validity:', error);
await clearSession();
await clearSessionWithKeepAlive();
}
}
return null;
@ -68,6 +121,9 @@ import init, {
current_keypair_metadata,
current_keypair_public_key,
sign,
verify,
encrypt_data,
decrypt_data,
lock_session
} from './wasm/wasm_app.js';
@ -91,11 +147,13 @@ async function initVault() {
current_keypair_metadata,
current_keypair_public_key,
sign,
verify,
encrypt_data,
decrypt_data,
lock_session
};
isInitialized = true;
console.log('CryptoVault initialized successfully');
// Try to restore previous session
await restoreSession();
@ -107,8 +165,23 @@ async function initVault() {
}
}
// Handle popup connection/disconnection
chrome.runtime.onConnect.addListener((port) => {
if (port.name === 'popup') {
// If we have an active session, ensure keep-alive is running
if (currentSession) {
startKeepAlive();
}
port.onDisconnect.addListener(() => {
// Keep the keep-alive running even after popup disconnects
// This ensures session persistence across popup closes
});
}
});
// Handle messages from popup and content scripts
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
chrome.runtime.onMessage.addListener((request, _sender, sendResponse) => {
const handleRequest = async () => {
try {
if (!vault) {
@ -122,7 +195,7 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
case 'initSession':
await vault.init_session(request.keyspace, request.password);
await saveSession(request.keyspace);
await saveSessionWithKeepAlive(request.keyspace);
return { success: true };
case 'isUnlocked':
@ -134,37 +207,24 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
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);
@ -188,9 +248,67 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const signature = await vault.sign(new Uint8Array(request.message));
return { success: true, signature };
case 'encrypt':
// Check if session is unlocked
if (!vault.is_unlocked()) {
return { success: false, error: 'Session is not unlocked' };
}
try {
// Convert message to Uint8Array for WASM
const messageBytes = new TextEncoder().encode(request.message);
// Use WASM encrypt_data function with ChaCha20-Poly1305
const encryptedData = await vault.encrypt_data(messageBytes);
// Convert result to base64 for easy handling
const encryptedMessage = btoa(String.fromCharCode(...new Uint8Array(encryptedData)));
return { success: true, encryptedMessage };
} catch (error) {
console.error('Encryption error:', error);
return { success: false, error: error.message };
}
case 'decrypt':
// Check if session is unlocked
if (!vault.is_unlocked()) {
return { success: false, error: 'Session is not unlocked' };
}
try {
// Convert base64 back to Uint8Array
const encryptedBytes = new Uint8Array(atob(request.encryptedMessage).split('').map(c => c.charCodeAt(0)));
// Use WASM decrypt_data function with ChaCha20-Poly1305
const decryptedData = await vault.decrypt_data(encryptedBytes);
// Convert result back to string
const decryptedMessage = new TextDecoder().decode(new Uint8Array(decryptedData));
return { success: true, decryptedMessage };
} catch (error) {
console.error('Decryption error:', error);
return { success: false, error: error.message };
}
case 'verify':
// Check if a keypair is selected
try {
const metadata = vault.current_keypair_metadata();
if (!metadata) {
return { success: false, error: 'No keypair selected' };
}
// Use WASM verify function
const isValid = await vault.verify(new Uint8Array(request.message), request.signature);
return { success: true, isValid };
} catch (error) {
console.error('Verification error:', error);
return { success: false, error: error.message };
}
case 'lockSession':
vault.lock_session();
await clearSession();
await clearSessionWithKeepAlive();
return { success: true };
case 'getStatus':

View File

@ -0,0 +1,280 @@
// Enhanced Error Handling System for CryptoVault Extension
class CryptoVaultError extends Error {
constructor(message, code, retryable = false, userMessage = null) {
super(message);
this.name = 'CryptoVaultError';
this.code = code;
this.retryable = retryable;
this.userMessage = userMessage || message;
this.timestamp = Date.now();
}
}
// Error codes for different types of errors
const ERROR_CODES = {
// Network/Connection errors (retryable)
NETWORK_ERROR: 'NETWORK_ERROR',
TIMEOUT_ERROR: 'TIMEOUT_ERROR',
SERVICE_UNAVAILABLE: 'SERVICE_UNAVAILABLE',
// Authentication errors (not retryable)
INVALID_PASSWORD: 'INVALID_PASSWORD',
SESSION_EXPIRED: 'SESSION_EXPIRED',
UNAUTHORIZED: 'UNAUTHORIZED',
// Crypto errors (not retryable)
CRYPTO_ERROR: 'CRYPTO_ERROR',
INVALID_SIGNATURE: 'INVALID_SIGNATURE',
ENCRYPTION_FAILED: 'ENCRYPTION_FAILED',
// Validation errors (not retryable)
INVALID_INPUT: 'INVALID_INPUT',
MISSING_KEYPAIR: 'MISSING_KEYPAIR',
INVALID_FORMAT: 'INVALID_FORMAT',
// System errors (sometimes retryable)
WASM_ERROR: 'WASM_ERROR',
STORAGE_ERROR: 'STORAGE_ERROR',
UNKNOWN_ERROR: 'UNKNOWN_ERROR'
};
// User-friendly error messages
const ERROR_MESSAGES = {
[ERROR_CODES.NETWORK_ERROR]: 'Connection failed. Please check your internet connection and try again.',
[ERROR_CODES.TIMEOUT_ERROR]: 'Operation timed out. Please try again.',
[ERROR_CODES.SERVICE_UNAVAILABLE]: 'Service is temporarily unavailable. Please try again later.',
[ERROR_CODES.INVALID_PASSWORD]: 'Invalid password. Please check your password and try again.',
[ERROR_CODES.SESSION_EXPIRED]: 'Your session has expired. Please log in again.',
[ERROR_CODES.UNAUTHORIZED]: 'You are not authorized to perform this action.',
[ERROR_CODES.CRYPTO_ERROR]: 'Cryptographic operation failed. Please try again.',
[ERROR_CODES.INVALID_SIGNATURE]: 'Invalid signature. Please verify your input.',
[ERROR_CODES.ENCRYPTION_FAILED]: 'Encryption failed. Please try again.',
[ERROR_CODES.INVALID_INPUT]: 'Invalid input. Please check your data and try again.',
[ERROR_CODES.MISSING_KEYPAIR]: 'No keypair selected. Please select a keypair first.',
[ERROR_CODES.INVALID_FORMAT]: 'Invalid data format. Please check your input.',
[ERROR_CODES.WASM_ERROR]: 'System error occurred. Please refresh and try again.',
[ERROR_CODES.STORAGE_ERROR]: 'Storage error occurred. Please try again.',
[ERROR_CODES.UNKNOWN_ERROR]: 'An unexpected error occurred. Please try again.'
};
// Determine if an error is retryable
const RETRYABLE_ERRORS = new Set([
ERROR_CODES.NETWORK_ERROR,
ERROR_CODES.TIMEOUT_ERROR,
ERROR_CODES.SERVICE_UNAVAILABLE,
ERROR_CODES.WASM_ERROR,
ERROR_CODES.STORAGE_ERROR
]);
// Enhanced error classification
function classifyError(error) {
const errorMessage = getErrorMessage(error);
// Network/Connection errors
if (errorMessage.includes('fetch') || errorMessage.includes('network') || errorMessage.includes('connection')) {
return new CryptoVaultError(
errorMessage,
ERROR_CODES.NETWORK_ERROR,
true,
ERROR_MESSAGES[ERROR_CODES.NETWORK_ERROR]
);
}
// Authentication errors
if (errorMessage.includes('password') || errorMessage.includes('Invalid password')) {
return new CryptoVaultError(
errorMessage,
ERROR_CODES.INVALID_PASSWORD,
false,
ERROR_MESSAGES[ERROR_CODES.INVALID_PASSWORD]
);
}
if (errorMessage.includes('session') || errorMessage.includes('not unlocked') || errorMessage.includes('expired')) {
return new CryptoVaultError(
errorMessage,
ERROR_CODES.SESSION_EXPIRED,
false,
ERROR_MESSAGES[ERROR_CODES.SESSION_EXPIRED]
);
}
// Crypto errors
if (errorMessage.includes('decryption error') || errorMessage.includes('aead::Error')) {
return new CryptoVaultError(
errorMessage,
ERROR_CODES.CRYPTO_ERROR,
false,
'Invalid password or corrupted data. Please check your password.'
);
}
if (errorMessage.includes('Crypto error') || errorMessage.includes('encryption')) {
return new CryptoVaultError(
errorMessage,
ERROR_CODES.CRYPTO_ERROR,
false,
ERROR_MESSAGES[ERROR_CODES.CRYPTO_ERROR]
);
}
// Validation errors
if (errorMessage.includes('No keypair selected')) {
return new CryptoVaultError(
errorMessage,
ERROR_CODES.MISSING_KEYPAIR,
false,
ERROR_MESSAGES[ERROR_CODES.MISSING_KEYPAIR]
);
}
// WASM errors
if (errorMessage.includes('wasm') || errorMessage.includes('WASM')) {
return new CryptoVaultError(
errorMessage,
ERROR_CODES.WASM_ERROR,
true,
ERROR_MESSAGES[ERROR_CODES.WASM_ERROR]
);
}
// Default to unknown error
return new CryptoVaultError(
errorMessage,
ERROR_CODES.UNKNOWN_ERROR,
false,
ERROR_MESSAGES[ERROR_CODES.UNKNOWN_ERROR]
);
}
// Get error message from various error types
function getErrorMessage(error) {
if (!error) return 'Unknown error';
if (typeof error === 'string') {
return error.trim();
}
if (error instanceof Error) {
return error.message;
}
if (error.error) {
return getErrorMessage(error.error);
}
if (error.message) {
return error.message;
}
if (typeof error === 'object') {
try {
const stringified = JSON.stringify(error);
if (stringified && stringified !== '{}') {
return stringified;
}
} catch (e) {
// Ignore JSON stringify errors
}
}
return 'Unknown error';
}
// Retry logic with exponential backoff
async function withRetry(operation, options = {}) {
const {
maxRetries = 3,
baseDelay = 1000,
maxDelay = 10000,
backoffFactor = 2,
onRetry = null
} = options;
let lastError;
for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
return await operation();
} catch (error) {
const classifiedError = classifyError(error);
lastError = classifiedError;
// Don't retry if it's the last attempt or error is not retryable
if (attempt === maxRetries || !classifiedError.retryable) {
throw classifiedError;
}
// Calculate delay with exponential backoff
const delay = Math.min(baseDelay * Math.pow(backoffFactor, attempt), maxDelay);
// Call retry callback if provided
if (onRetry) {
onRetry(attempt + 1, delay, classifiedError);
}
// Wait before retrying
await new Promise(resolve => setTimeout(resolve, delay));
}
}
throw lastError;
}
// Enhanced operation wrapper with loading states
async function executeOperation(operation, options = {}) {
const {
loadingElement = null,
successMessage = null,
showRetryProgress = false,
onProgress = null
} = options;
// Show loading state
if (loadingElement) {
setButtonLoading(loadingElement, true);
}
try {
const result = await withRetry(operation, {
...options,
onRetry: (attempt, delay, error) => {
if (showRetryProgress && onProgress) {
onProgress(`Retrying... (${attempt}/${options.maxRetries || 3})`);
}
if (options.onRetry) {
options.onRetry(attempt, delay, error);
}
}
});
// Show success message if provided
if (successMessage) {
showToast(successMessage, 'success');
}
return result;
} catch (error) {
// Show user-friendly error message
showToast(error.userMessage || error.message, 'error');
throw error;
} finally {
// Hide loading state
if (loadingElement) {
setButtonLoading(loadingElement, false);
}
}
}
// Export for use in other modules
window.CryptoVaultError = CryptoVaultError;
window.ERROR_CODES = ERROR_CODES;
window.classifyError = classifyError;
window.getErrorMessage = getErrorMessage;
window.withRetry = withRetry;
window.executeOperation = executeOperation;

View File

@ -11,9 +11,12 @@
<div class="logo-icon">🔐</div>
<h1>CryptoVault</h1>
</div>
<div class="status-indicator" id="statusIndicator">
<div class="status-dot"></div>
<span id="statusText">Initializing...</span>
<div class="header-actions">
<button id="themeToggle" class="btn-icon-only" title="Switch to dark mode">
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
</svg>
</button>
</div>
</header>
@ -38,13 +41,26 @@
<!-- Main Vault Section -->
<section class="section hidden" id="vaultSection">
<div class="vault-header">
<h2>Your Keypairs</h2>
<button id="lockBtn" class="btn btn-ghost">🔒 Lock</button>
<!-- Status Section -->
<div class="vault-status" id="vaultStatus">
<div class="status-indicator" id="statusIndicator">
<div class="status-content">
<div class="status-dot"></div>
<span id="statusText">Initializing...</span>
</div>
<button id="lockBtn" class="btn btn-ghost btn-small hidden">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect>
<circle cx="12" cy="16" r="1"></circle>
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path>
</svg>
Lock
</button>
</div>
</div>
<!-- Add Keypair Toggle Button -->
<div class="add-keypair-toggle">
<div class="vault-header">
<h2>Your Keypairs</h2>
<button id="toggleAddKeypairBtn" class="btn btn-primary">
<span class="btn-icon">+</span>
Add Keypair
@ -99,25 +115,88 @@
<label>Public Key:</label>
<div class="public-key-container">
<code id="selectedPublicKey">-</code>
<button id="copyPublicKeyBtn" class="btn-copy" title="Copy to clipboard">📋</button>
<button id="copyPublicKeyBtn" class="btn-copy" title="Copy to clipboard">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
</button>
</div>
</div>
</div>
</div>
<!-- Sign Message -->
<!-- Crypto Operations -->
<div class="card">
<h3>Sign Message</h3>
<h3>Crypto Operations</h3>
<!-- Operation Tabs -->
<div class="operation-tabs">
<button class="tab-btn active" data-tab="encrypt">Encrypt</button>
<button class="tab-btn" data-tab="decrypt">Decrypt</button>
<button class="tab-btn" data-tab="sign">Sign</button>
<button class="tab-btn" data-tab="verify">Verify</button>
</div>
<!-- Encrypt Tab -->
<div class="tab-content active" id="encrypt-tab">
<div class="form-group">
<label for="messageInput">Message (hex or text)</label>
<textarea id="messageInput" placeholder="Enter message to sign" rows="3"></textarea>
<label for="encryptMessageInput">Message to Encrypt</label>
<textarea id="encryptMessageInput" placeholder="Enter message to encrypt..." rows="3"></textarea>
</div>
<button id="encryptBtn" class="btn btn-primary" disabled>Encrypt Message</button>
<div class="encrypt-result hidden" id="encryptResult">
</div>
</div>
<!-- Decrypt Tab -->
<div class="tab-content" id="decrypt-tab">
<div class="form-group">
<label for="encryptedMessageInput">Encrypted Message</label>
<textarea id="encryptedMessageInput" placeholder="Enter encrypted message..." rows="3"></textarea>
</div>
<button id="decryptBtn" class="btn btn-primary" disabled>Decrypt Message</button>
<div class="decrypt-result hidden" id="decryptResult">
</div>
</div>
<!-- Sign Tab -->
<div class="tab-content" id="sign-tab">
<div class="form-group">
<label for="messageInput">Message to Sign</label>
<textarea id="messageInput" placeholder="Enter your message here..." rows="3"></textarea>
</div>
<button id="signBtn" class="btn btn-primary" disabled>Sign Message</button>
<div id="signatureResult" class="signature-result hidden">
<div class="signature-result hidden" id="signatureResult">
<label>Signature:</label>
<div class="signature-container">
<code id="signatureValue"></code>
<button id="copySignatureBtn" class="btn-copy" title="Copy to clipboard">📋</button>
<code id="signatureValue">-</code>
<button id="copySignatureBtn" class="btn-copy" title="Copy to clipboard">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
<path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
</svg>
</button>
</div>
</div>
</div>
<!-- Verify Tab -->
<div class="tab-content" id="verify-tab">
<div class="form-group">
<label for="verifyMessageInput">Original Message</label>
<textarea id="verifyMessageInput" placeholder="Enter the original message..." rows="3"></textarea>
</div>
<div class="form-group">
<label for="signatureToVerifyInput">Signature</label>
<input type="text" id="signatureToVerifyInput" placeholder="Enter signature to verify...">
</div>
<button id="verifyBtn" class="btn btn-primary" disabled>Verify Signature</button>
<div class="verify-result hidden" id="verifyResult">
</div>
</div>
</div>
@ -129,10 +208,11 @@
<p>Processing...</p>
</div>
<!-- Toast Notifications -->
<div id="toast" class="toast hidden"></div>
</div>
<!-- Enhanced JavaScript modules -->
<script src="js/errorHandler.js"></script>
<script src="popup.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -202,33 +202,6 @@ function debugString(val) {
// TODO we could test for more things here, like `Set`s and `Map`s.
return className;
}
/**
* Initialize the scripting environment (must be called before run_rhai)
*/
export function init_rhai_env() {
wasm.init_rhai_env();
}
function takeFromExternrefTable0(idx) {
const value = wasm.__wbindgen_export_2.get(idx);
wasm.__externref_table_dealloc(idx);
return value;
}
/**
* Securely run a Rhai script in the extension context (must be called only after user approval)
* @param {string} script
* @returns {any}
*/
export function run_rhai(script) {
const ptr0 = passStringToWasm0(script, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.run_rhai(ptr0, len0);
if (ret[2]) {
throw takeFromExternrefTable0(ret[1]);
}
return takeFromExternrefTable0(ret[0]);
}
/**
* Create and unlock a new keyspace with the given name and password
* @param {string} keyspace
@ -266,6 +239,11 @@ export function lock_session() {
wasm.lock_session();
}
function takeFromExternrefTable0(idx) {
const value = wasm.__wbindgen_export_2.get(idx);
wasm.__externref_table_dealloc(idx);
return value;
}
/**
* Get metadata of the currently selected keypair
* @returns {any}
@ -356,20 +334,81 @@ export function sign(message) {
return ret;
}
/**
* Verify a signature with the current session's selected keypair
* @param {Uint8Array} message
* @param {string} signature
* @returns {Promise<any>}
*/
export function verify(message, signature) {
const ptr0 = passArray8ToWasm0(message, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
const ptr1 = passStringToWasm0(signature, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
const ret = wasm.verify(ptr0, len0, ptr1, len1);
return ret;
}
/**
* Encrypt data using the current session's keyspace symmetric cipher
* @param {Uint8Array} data
* @returns {Promise<any>}
*/
export function encrypt_data(data) {
const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.encrypt_data(ptr0, len0);
return ret;
}
/**
* Decrypt data using the current session's keyspace symmetric cipher
* @param {Uint8Array} encrypted
* @returns {Promise<any>}
*/
export function decrypt_data(encrypted) {
const ptr0 = passArray8ToWasm0(encrypted, wasm.__wbindgen_malloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.decrypt_data(ptr0, len0);
return ret;
}
/**
* Initialize the scripting environment (must be called before run_rhai)
*/
export function init_rhai_env() {
wasm.init_rhai_env();
}
/**
* Securely run a Rhai script in the extension context (must be called only after user approval)
* @param {string} script
* @returns {any}
*/
export function run_rhai(script) {
const ptr0 = passStringToWasm0(script, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
const ret = wasm.run_rhai(ptr0, len0);
if (ret[2]) {
throw takeFromExternrefTable0(ret[1]);
}
return takeFromExternrefTable0(ret[0]);
}
function __wbg_adapter_32(arg0, arg1, arg2) {
wasm.closure89_externref_shim(arg0, arg1, arg2);
wasm.closure121_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_35(arg0, arg1, arg2) {
wasm.closure133_externref_shim(arg0, arg1, arg2);
wasm.closure150_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_38(arg0, arg1, arg2) {
wasm.closure188_externref_shim(arg0, arg1, arg2);
wasm.closure227_externref_shim(arg0, arg1, arg2);
}
function __wbg_adapter_135(arg0, arg1, arg2, arg3) {
wasm.closure1847_externref_shim(arg0, arg1, arg2, arg3);
function __wbg_adapter_138(arg0, arg1, arg2, arg3) {
wasm.closure1879_externref_shim(arg0, arg1, arg2, arg3);
}
const __wbindgen_enum_IdbTransactionMode = ["readonly", "readwrite", "versionchange", "readwriteflush", "cleanup"];
@ -519,7 +558,7 @@ function __wbg_get_imports() {
const a = state0.a;
state0.a = 0;
try {
return __wbg_adapter_135(a, state0.b, arg0, arg1);
return __wbg_adapter_138(a, state0.b, arg0, arg1);
} finally {
state0.a = a;
}
@ -673,16 +712,16 @@ function __wbg_get_imports() {
const ret = false;
return ret;
};
imports.wbg.__wbindgen_closure_wrapper288 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 90, __wbg_adapter_32);
imports.wbg.__wbindgen_closure_wrapper378 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 122, __wbg_adapter_32);
return ret;
};
imports.wbg.__wbindgen_closure_wrapper518 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 134, __wbg_adapter_35);
imports.wbg.__wbindgen_closure_wrapper549 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 151, __wbg_adapter_35);
return ret;
};
imports.wbg.__wbindgen_closure_wrapper776 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 189, __wbg_adapter_38);
imports.wbg.__wbindgen_closure_wrapper857 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 228, __wbg_adapter_38);
return ret;
};
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {