Skip to content

Commit a6a1dca

Browse files
authored
Merge pull request #81 from zecrypt-io/main
main=>preview
2 parents 09a17bf + b5edb9a commit a6a1dca

File tree

12 files changed

+420
-54
lines changed

12 files changed

+420
-54
lines changed

.gitignore

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,4 +189,13 @@ pnpm-lock.yaml
189189
packages/*/node_modules
190190
packages/*/dist
191191
packages/*/build
192-
packages/*/.next
192+
packages/*/.next
193+
194+
# Cursor
195+
cursor.rules
196+
197+
.cursor/
198+
.cursorrules
199+
.cursorignore
200+
201+

packages/Extenstions/.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Environment files
2+
.env
3+
.env.local
4+
.env.development
5+
.env.test
6+
.env.production
7+
8+
# Node modules (if any build tools are added)
9+
node_modules/
10+
11+
# Build outputs
12+
dist/
13+
build/
14+
15+
# Temporary files
16+
*.tmp
17+
*.temp
18+
19+
# IDE files
20+
.vscode/
21+
.idea/
22+
*.swp
23+
*.swo
24+
25+
# OS generated files
26+
.DS_Store
27+
Thumbs.db

packages/Extenstions/README.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,26 @@ This Chrome extension allows users to autofill card and email details from their
1111

1212
## Setup
1313

14+
### Environment Configuration
15+
16+
⚠️ **IMPORTANT**: Before setting up the extension, you must configure the environment variables for security.
17+
18+
**See [SETUP.md](./SETUP.md) for detailed environment configuration instructions.**
19+
20+
Quick setup:
21+
1. Create a `.env` file in this directory
22+
2. Add: `INDEXED_DB_AES_KEY="your_key_here"`
23+
3. Get the key from your team or the frontend-web `.env.local` file
24+
1425
### Development Setup
1526

1627
1. Clone this repository
17-
2. Open Chrome and navigate to `chrome://extensions/`
18-
3. Enable "Developer mode" in the top-right corner
19-
4. Click "Load unpacked" and select the `packages/Extenstions` directory
20-
5. Note the Extension ID assigned by Chrome (you'll need it for the next step)
21-
6. Update the `EXTENSION_ID` constant in `packages/frontend-web/app/extension-login/page.tsx` with your extension ID
28+
2. **Configure environment variables** (see SETUP.md)
29+
3. Open Chrome and navigate to `chrome://extensions/`
30+
4. Enable "Developer mode" in the top-right corner
31+
5. Click "Load unpacked" and select the `packages/Extenstions` directory
32+
6. Note the Extension ID assigned by Chrome (you'll need it for the next step)
33+
7. Update the `EXTENSION_ID` constant in `packages/frontend-web/app/extension-login/page.tsx` with your extension ID
2234

2335
### Frontend Setup
2436

packages/Extenstions/SETUP.md

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# Zecrypt Browser Extension Setup
2+
3+
## Environment Configuration
4+
5+
⚠️ **SECURITY NOTICE**: This extension requires proper environment configuration to work securely. Never commit sensitive keys to version control.
6+
7+
### Development Setup
8+
9+
1. **Create Environment File**
10+
11+
Create a `.env` file in the `packages/Extenstions/` directory:
12+
13+
```bash
14+
cd packages/Extenstions/
15+
cp .env.example .env # If example exists, or create manually
16+
```
17+
18+
2. **Configure Environment Variables**
19+
20+
Add the following to your `.env` file:
21+
22+
```
23+
INDEXED_DB_AES_KEY="HxmfPmPwqQZ3gHKwfHXi6TmPwVDppr0oDKyPwCdopDI="
24+
```
25+
26+
**Note**: The key should match the `NEXT_PUBLIC_INDEXED_DB_AES_KEY` from the frontend-web `.env.local` file.
27+
28+
3. **Verify Setup**
29+
30+
- The `.env` file should NOT be committed to git (it's already in `.gitignore`)
31+
- Check that the extension loads without console errors
32+
- Verify that crypto operations work correctly
33+
34+
### Production Deployment
35+
36+
For production environments, consider:
37+
38+
1. **Build-time Injection**: Use a build script to inject environment variables
39+
2. **Secure Key Management**: Use proper secrets management systems
40+
3. **Key Rotation**: Implement regular key rotation procedures
41+
42+
### File Structure
43+
44+
```
45+
packages/Extenstions/
46+
├── .env # Your environment file (NOT committed)
47+
├── .gitignore # Ensures .env is ignored
48+
├── config.js # Configuration loader
49+
├── crypto-utils.js # Crypto utilities (uses config)
50+
├── background.js # Background script (initializes config)
51+
└── ... other files
52+
```
53+
54+
### Troubleshooting
55+
56+
**Error: "Extension configuration not loaded"**
57+
- Ensure `.env` file exists in the extensions directory
58+
- Check that `INDEXED_DB_AES_KEY` is properly set in `.env`
59+
- Verify the key format (should be base64 encoded)
60+
61+
**Error: "Configuration key not found"**
62+
- Check that the key in `.env` matches exactly: `INDEXED_DB_AES_KEY`
63+
- Ensure there are no extra spaces or characters
64+
- Verify the file is saved properly
65+
66+
**Error: "Invalid encryption key format"**
67+
- The key should be a valid base64 string
68+
- Check that the key length is correct (32 bytes when decoded)
69+
- Ensure the key matches the one used in the web application
70+
71+
### Security Best Practices
72+
73+
1. **Never hardcode keys** in source code
74+
2. **Use different keys** for different environments (dev/staging/prod)
75+
3. **Rotate keys regularly** and update all environments
76+
4. **Restrict access** to environment files and key management systems
77+
5. **Monitor usage** and implement key usage auditing
78+
79+
### Getting the Key
80+
81+
The `INDEXED_DB_AES_KEY` should be obtained from:
82+
1. Your development team's secure key management system
83+
2. The frontend-web application's environment configuration
84+
3. Your organization's secrets management platform
85+
86+
Contact your development team if you don't have access to the required keys.

packages/Extenstions/background.js

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
// Base API URL
22
const API_BASE_URL = 'https://preview.api.zecrypt.io/api/v1/web';
33

4-
// Import crypto utilities
4+
// Import configuration and crypto utilities
5+
importScripts('config.js');
56
importScripts('crypto-utils.js');
67

8+
// Initialize configuration when extension starts
9+
(async function initializeExtension() {
10+
try {
11+
await ExtensionConfig.initConfig();
12+
} catch (error) {
13+
console.error('Failed to load extension configuration:', error);
14+
console.error('Please ensure you have created a .env file in the extensions directory with the required keys');
15+
}
16+
})();
17+
718
// Helper function to check if URL is accessible for script injection
819
function isValidUrl(url) {
920
// Exclude chrome:// URLs, chrome-extension:// URLs, and other restricted schemes
@@ -56,7 +67,6 @@ async function storeProjectAesKey(projectAesKey) {
5667
chrome.storage.local.set({
5768
zecryptProjectAesKey: encryptedKey
5869
});
59-
console.log('Project AES key stored securely');
6070
} catch (error) {
6171
console.error('Error storing project AES key:', error);
6272
}
@@ -69,7 +79,6 @@ async function getDecryptedProjectAesKey() {
6979
if (result.zecryptProjectAesKey) {
7080
try {
7181
const decryptedKey = await CryptoUtils.decryptFromLocalStorage(result.zecryptProjectAesKey);
72-
console.log('Project AES key retrieved and decrypted');
7382
resolve(decryptedKey);
7483
} catch (error) {
7584
console.error('Error decrypting project AES key:', error);
@@ -107,7 +116,6 @@ async function processCardData(cardRaw) {
107116
const decryptedData = await CryptoUtils.decryptDataField(cardRaw.data, projectAesKey);
108117
const parsedData = JSON.parse(decryptedData);
109118

110-
console.log('Card data decrypted successfully');
111119
return {
112120
...cardRaw,
113121
cardNumber: parsedData.number || 'undefined',
@@ -174,8 +182,6 @@ async function processEmailData(emailRaw) {
174182
const decryptedData = await CryptoUtils.decryptDataField(emailRaw.data, projectAesKey);
175183
const parsedData = JSON.parse(decryptedData);
176184

177-
console.log('Email data decrypted successfully');
178-
console.log("[Zecrypt Debug] Decrypted Email Password:", parsedData.password);
179185
return {
180186
...emailRaw,
181187
email: parsedData.email_address || 'undefined',
@@ -192,7 +198,6 @@ async function processEmailData(emailRaw) {
192198
// Data might not be encrypted (legacy format)
193199
try {
194200
const parsedData = JSON.parse(emailRaw.data);
195-
console.log("[Zecrypt Debug] Decrypted Email Password (legacy):", parsedData.password);
196201
return {
197202
...emailRaw,
198203
email: parsedData.email_address || 'undefined',
@@ -268,7 +273,6 @@ function getCards() {
268273
apiRequest(ENDPOINTS.cards)
269274
.then(async function(response) {
270275
const cards = response.data || [];
271-
console.log(`Processing ${cards.length} cards for decryption`);
272276
const processedCards = await Promise.all(cards.map(processCardData));
273277

274278
resolve({
@@ -291,7 +295,6 @@ function getEmails() {
291295
apiRequest(ENDPOINTS.emails)
292296
.then(async function(response) {
293297
const emails = response.data || [];
294-
console.log(`Processing ${emails.length} emails for decryption`);
295298
const processedEmails = await Promise.all(emails.map(processEmailData));
296299

297300
resolve({
@@ -311,7 +314,6 @@ function getEmails() {
311314
// Enhanced external message listener to handle project AES key
312315
chrome.runtime.onMessageExternal.addListener(
313316
(message, sender, sendResponse) => {
314-
console.log('External message received:', message);
315317
if (message.type === 'LOGIN' && message.token) {
316318
// Store the token and workspace/project IDs securely in chrome.storage.local
317319
chrome.storage.local.set({
@@ -323,12 +325,9 @@ chrome.runtime.onMessageExternal.addListener(
323325
console.error('Error storing tokens:', chrome.runtime.lastError);
324326
sendResponse({ success: false, error: chrome.runtime.lastError.message });
325327
} else {
326-
console.log('Token and workspace data stored successfully');
327-
328328
// Store project AES key securely if provided
329329
if (message.projectAesKey) {
330330
await storeProjectAesKey(message.projectAesKey);
331-
console.log('Project AES key stored successfully');
332331
}
333332

334333
sendResponse({ success: true });
@@ -372,7 +371,6 @@ function checkLocalStorageAuth() {
372371
}
373372
}, (results) => {
374373
if (chrome.runtime.lastError) {
375-
console.log('Script execution failed:', chrome.runtime.lastError.message);
376374
resolve({ success: false, error: chrome.runtime.lastError.message });
377375
return;
378376
}
@@ -389,12 +387,9 @@ function checkLocalStorageAuth() {
389387
console.error('Error storing auth data:', chrome.runtime.lastError);
390388
resolve({ success: false, error: chrome.runtime.lastError.message });
391389
} else {
392-
console.log('Auth data retrieved from localStorage and stored');
393-
394390
// Store project AES key securely if provided
395391
if (authData.projectAesKey) {
396392
await storeProjectAesKey(authData.projectAesKey);
397-
console.log('Project AES key from localStorage stored successfully');
398393
}
399394

400395
resolve({ success: true, authData });
@@ -404,7 +399,6 @@ function checkLocalStorageAuth() {
404399
resolve({ success: false, error: 'No auth data found' });
405400
}
406401
}); } else {
407-
console.log('No valid tab found for localStorage check. Current tab:', tabs[0]?.url || 'No tab');
408402
resolve({ success: false, error: 'No accessible tab found' });
409403
}
410404
});
@@ -432,7 +426,6 @@ function startAuthCheck() {
432426

433427
// Stop checking after max attempts
434428
if (authCheckAttempts > MAX_AUTH_CHECK_ATTEMPTS) {
435-
console.log('Auth check timeout after', MAX_AUTH_CHECK_ATTEMPTS, 'attempts');
436429
stopAuthCheck();
437430
return;
438431
}
@@ -442,18 +435,15 @@ function startAuthCheck() {
442435
if (result.success) {
443436
clearInterval(authCheckInterval);
444437
authCheckInterval = null;
445-
console.log('Authentication successful via localStorage polling');
446438

447439
// Notify popup if it's open
448440
try {
449441
chrome.runtime.sendMessage({ type: 'AUTH_SUCCESS' });
450442
} catch (e) {
451443
// Popup might not be open, that's ok
452-
console.log('Could not notify popup:', e.message);
453444
}
454445
} else if (result.error && result.error.includes('Cannot access')) {
455446
// If we get access errors, reduce polling frequency
456-
console.log('Access error during auth check, slowing down polling');
457447
}
458448
} catch (error) {
459449
console.error('Error during auth check:', error);
@@ -491,10 +481,8 @@ function checkAuth() {
491481

492482
// Listen for messages from popup or content scripts
493483
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
494-
console.log('Internal message received:', message);
495484
if (message.type === 'CHECK_AUTH') {
496485
checkAuth().then(result => {
497-
console.log('Auth check result:', result);
498486

499487
// If not authenticated, try checking localStorage as fallback
500488
if (!result.isAuthenticated) {
@@ -509,8 +497,6 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
509497
// Only start periodic checking if we don't have access errors
510498
if (!localResult.error || !localResult.error.includes('Cannot access')) {
511499
startAuthCheck();
512-
} else {
513-
console.log('Skipping periodic auth check due to access restrictions');
514500
}
515501
}
516502
});
@@ -541,10 +527,9 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
541527
}
542528
// Handle logout request
543529
if (message.type === 'LOGOUT') {
544-
chrome.storage.local.remove(['zecryptToken', 'zecryptWorkspaceId', 'zecryptProjectId', 'zecryptProjectAesKey'], () => {
545-
console.log('Tokens and project key removed');
546-
sendResponse({ success: true });
547-
});
530+
chrome.storage.local.remove(['zecryptToken', 'zecryptWorkspaceId', 'zecryptProjectId', 'zecryptProjectAesKey'], () => {
531+
sendResponse({ success: true });
532+
});
548533
return true;
549534
}
550535

@@ -555,12 +540,9 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
555540
zecryptWorkspaceId: message.workspaceId,
556541
zecryptProjectId: message.projectId
557542
}, async () => {
558-
console.log('Token and workspace data stored successfully from popup');
559-
560543
// Store project AES key securely if provided
561544
if (message.projectAesKey) {
562545
await storeProjectAesKey(message.projectAesKey);
563-
console.log('Project AES key stored successfully from popup');
564546
}
565547

566548
sendResponse({ success: true });
@@ -630,5 +612,5 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
630612

631613
// Initialize when the extension is installed or updated
632614
chrome.runtime.onInstalled.addListener(() => {
633-
console.log('Zecrypt extension installed');
615+
// Extension installed
634616
});

0 commit comments

Comments
 (0)