Skip to content

Latest commit

 

History

History
536 lines (404 loc) · 13.9 KB

File metadata and controls

536 lines (404 loc) · 13.9 KB

TrustVault Chrome Autofill Integration

Complete guide for implementing browser autofill with TrustVault PWA using Credential Management API and Chrome Extension.

🎯 Overview

TrustVault provides two methods for browser autofill:

  1. Native Credential Management API - Built into modern browsers, no extension needed
  2. Chrome Extension - Enhanced autofill with advanced features and better UX

🔐 Security Architecture

K-Anonymity & Origin Validation

User Credential Flow:
┌─────────────────┐
│   TrustVault    │
│   (IndexedDB)   │
└────────┬────────┘
         │ Encrypted Storage
         ↓
┌─────────────────┐
│  Origin Check   │  ← Validates current page origin
│  (example.com)  │
└────────┬────────┘
         │ Match Found
         ↓
┌─────────────────┐
│ Credential      │  ← User confirmation required
│ Management API  │
└────────┬────────┘
         │ Autofill
         ↓
┌─────────────────┐
│  Login Form     │
│  (filled)       │
└─────────────────┘

Security Features

HTTPS-Only - Credentials only autofill on secure connections ✅ Origin Matching - Exact origin validation prevents credential theft ✅ Same-Site Only - No cross-origin credential sharing (unless explicitly configured) ✅ User Confirmation - Requires user interaction before filling (configurable) ✅ Encrypted Storage - All credentials encrypted in IndexedDB ✅ CSP Headers - Content Security Policy prevents exfiltration

📦 Implementation

Method 1: Native Credential Management API

Browser Support

  • ✅ Chrome 51+
  • ✅ Edge 79+
  • ✅ Opera 38+
  • ❌ Firefox (not yet supported)
  • ❌ Safari (not yet supported)

Implementation Files

src/core/autofill/
├── credentialManagementService.ts  # Core API integration
├── autofillSettings.ts             # User preferences
└── README.md                        # Documentation

Usage Example

import {
  storeCredentialInBrowser,
  getCredentialFromBrowser,
  findMatchingCredentials,
} from '@/core/autofill/credentialManagementService';

// After user adds/updates credential
const browserCred = toBrowserCredential(credential, window.location.origin);
await storeCredentialInBrowser(browserCred);

// On login page load
const matches = findMatchingCredentials(allCredentials, window.location.origin);
if (matches.length > 0) {
  // Show autofill UI
}

// Autofill credential
const browserCred = await getCredentialFromBrowser();
if (browserCred) {
  usernameField.value = browserCred.id;
  passwordField.value = browserCred.password;
}

Integration Points

1. After Credential Creation (src/presentation/pages/AddCredentialPage.tsx)

// After successful credential creation
if (credential.category === 'login' && credential.url) {
  const browserCred = toBrowserCredential(credential, window.location.origin);
  await storeCredentialInBrowser(browserCred);
}

2. After Credential Update (src/presentation/pages/EditCredentialPage.tsx)

// After successful credential update
if (credential.category === 'login' && credential.url) {
  const browserCred = toBrowserCredential(credential, window.location.origin);
  await storeCredentialInBrowser(browserCred);
}

3. In Credential Repository (src/data/repositories/CredentialRepositoryImpl.ts)

async create(input: CredentialInput, vaultKey: CryptoKey): Promise<Credential> {
  const credential = await this.saveCredential(input, vaultKey);

  // Store in browser for autofill
  if (credential.category === 'login' && credential.url) {
    const browserCred = toBrowserCredential(credential, window.location.origin);
    await storeCredentialInBrowser(browserCred);
  }

  return credential;
}

Method 2: Chrome Extension (Enhanced)

Features

  • ✅ Works on all websites (not just TrustVault origin)
  • ✅ Detects login forms automatically
  • ✅ Shows inline autofill dropdown
  • ✅ Supports dynamic forms (SPAs)
  • ✅ Better UX with visual indicators
  • ✅ Works offline

Directory Structure

chrome-extension/
├── manifest.json           # Extension manifest (v3)
├── popup.html             # Extension popup UI
├── scripts/
│   ├── background.js      # Service worker
│   ├── content.js         # Content script (form detection)
│   └── popup.js           # Popup logic
└── icons/
    ├── icon-16.png
    ├── icon-32.png
    ├── icon-48.png
    └── icon-128.png

Installation

  1. Build Extension Icons
# Copy from PWA icons
cp public/pwa-192x192.png chrome-extension/icons/icon-128.png

# Or generate specific sizes
npm run generate-extension-icons
  1. Load Extension in Chrome
1. Open chrome://extensions/
2. Enable "Developer mode"
3. Click "Load unpacked"
4. Select chrome-extension/ directory
  1. Test Autofill
1. Navigate to any login page (e.g., github.com)
2. Click on username field
3. See TrustVault autofill dropdown
4. Select credential to autofill

Extension Architecture

Background Service Worker (scripts/background.js)

  • Manages credential storage
  • Communicates with TrustVault PWA
  • Handles cross-origin messaging
  • Syncs credentials

Content Script (scripts/content.js)

  • Detects login forms
  • Injects autofill UI
  • Fills credentials
  • Watches for dynamic forms

Popup (popup.html + scripts/popup.js)

  • Shows credentials count for current site
  • Autofill settings
  • Quick access to TrustVault PWA

⚙️ Configuration

Environment Variables

# Enable autofill features
VITE_AUTOFILL_ENABLED=true

# TrustVault origin for extension communication
VITE_TRUSTVAULT_ORIGIN=https://trust-vault-pwa.vercel.app

User Settings

Settings are stored in localStorage with key trustvault_autofill_settings:

{
  enabled: boolean;              // Master toggle
  autoSubmit: boolean;           // Auto-submit after fill (default: false)
  requireConfirmation: boolean;  // Ask before filling (default: true)
  enableCrossDomain: boolean;    // Allow subdomain matching (default: true)
  onlyHTTPS: boolean;            // HTTPS only (default: true)
  excludedOrigins: string[];     // Blacklist
}

Autofill Settings Page

Add to PWA navigation:

// src/presentation/App.tsx
<Route path="/settings/autofill" element={<AutofillSettingsPage />} />

🔒 Security Considerations

Origin Validation

// SECURE: Exact origin match
if (validateOrigin(credential.url, window.location.origin)) {
  // Safe to autofill
}

// RISKY: Domain-only match (requires user confirmation)
if (validateDomain(credential.url, window.location.origin)) {
  // Show confirmation dialog first
}

HTTPS Enforcement

// Never autofill on HTTP (unless explicitly allowed)
if (settings.onlyHTTPS && !window.location.origin.startsWith('https://')) {
  console.warn('Autofill blocked: HTTP site');
  return;
}

CSP Headers

Add to vercel.json:

{
  "headers": [
    {
      "source": "/(.*)",
      "headers": [
        {
          "key": "Content-Security-Policy",
          "value": "default-src 'self'; connect-src 'self' https://api.pwnedpasswords.com; script-src 'self'; style-src 'self' 'unsafe-inline';"
        }
      ]
    }
  ]
}

Credential Exfiltration Prevention

  1. No External API Calls - Credentials never sent to external servers
  2. Same-Origin Enforcement - Browser enforces origin isolation
  3. No console.log() - Never log sensitive data in production
  4. Content Security Policy - Prevents injection attacks

📱 User Workflows

Workflow 1: Add Credential with Autofill

1. User navigates to TrustVault PWA
2. User adds credential for github.com
3. TrustVault stores in IndexedDB (encrypted)
4. TrustVault calls navigator.credentials.store()
5. Browser saves credential for github.com origin
6. User navigates to github.com/login
7. Browser shows "Use password from TrustVault" suggestion
8. User clicks → credentials autofill

Workflow 2: Chrome Extension Autofill

1. User installs TrustVault Autofill extension
2. Extension syncs credentials from PWA
3. User navigates to github.com/login
4. Content script detects login form
5. User focuses on username field
6. Extension shows inline dropdown with matches
7. User selects credential
8. Extension fills username + password
9. User clicks login

Workflow 3: Cross-Subdomain Autofill

1. User has credential for login.example.com
2. User visits www.example.com
3. Domain matches (example.com)
4. TrustVault shows confirmation dialog
5. User confirms → credentials autofill

🧪 Testing

Manual Testing

  1. Add Test Credential
Title: GitHub Test
Username: testuser
Password: Test123!@#
URL: https://github.com/login
  1. Navigate to GitHub Login
https://github.com/login
  1. Expected Behavior
  • Native API: Browser shows autofill suggestion in dropdown
  • Extension: TrustVault dropdown appears on focus

Automated Testing (Playwright)

test('autofill works on GitHub', async ({ page }) => {
  // Add credential in TrustVault
  await page.goto('http://localhost:3000/credentials/add');
  await page.fill('[name="title"]', 'GitHub Test');
  await page.fill('[name="username"]', 'testuser');
  await page.fill('[name="password"]', 'Test123!@#');
  await page.fill('[name="url"]', 'https://github.com/login');
  await page.click('button[type="submit"]');

  // Navigate to GitHub
  await page.goto('https://github.com/login');

  // Trigger autofill
  await page.click('#login_field');

  // Verify autofill
  const username = await page.inputValue('#login_field');
  expect(username).toBe('testuser');
});

📊 Browser Compatibility

Feature Chrome Edge Opera Firefox Safari
Credential Management API
Chrome Extension (Manifest v3) ⚠️
Auto-submit Prevention

⚠️ Firefox has similar Web Extensions API but requires Manifest v2

🚀 Deployment

PWA Deployment

# Build with autofill enabled
VITE_AUTOFILL_ENABLED=true npm run build

# Deploy to Vercel
vercel deploy --prod

Extension Publishing

  1. Create ZIP
cd chrome-extension
zip -r trustvault-autofill.zip . -x "*.DS_Store" -x "__MACOSX/*"
  1. Upload to Chrome Web Store
https://chrome.google.com/webstore/devconsole
  1. Set Privacy Policy

Privacy policy must explain:

  • What credentials are stored
  • How origin validation works
  • That data never leaves user's device
  • HTTPS-only enforcement

🔧 Troubleshooting

Autofill Not Working

Check:

  1. Is autofill enabled in settings?
  2. Is the site HTTPS?
  3. Does credential URL match current origin?
  4. Is Credential Management API supported?

Debug:

import { isCredentialManagementSupported } from '@/core/autofill/credentialManagementService';

console.log('Supported:', isCredentialManagementSupported());
console.log('Origin:', window.location.origin);
console.log('Settings:', loadAutofillSettings());

Extension Not Loading

Check:

  1. Is extension enabled in chrome://extensions/?
  2. Are there console errors in background service worker?
  3. Is content script injected? (Check in DevTools → Sources)

Debug:

// In chrome://extensions/ → Inspect views: service worker
chrome.storage.local.get(null, (data) => {
  console.log('Extension data:', data);
});

📚 API Reference

credentialManagementService.ts

// Check browser support
isCredentialManagementSupported(): boolean

// Store credential for specific origin
storeCredentialInBrowser(credential: BrowserCredential): Promise<boolean>

// Get credential with optional mediation
getCredentialFromBrowser(): Promise<{ id: string; password: string } | null>

// Get credential with required mediation (shows UI)
getCredentialWithUI(): Promise<{ id: string; password: string } | null>

// Find matching credentials for current origin
findMatchingCredentials(credentials: Credential[], currentOrigin: string): AutofillMatch[]

// Validate exact origin match
validateOrigin(credentialUrl: string, currentOrigin: string): boolean

// Validate domain match (cross-subdomain)
validateDomain(credentialUrl: string, currentUrl: string): boolean

// Prevent silent credential access (after logout)
preventSilentAccess(): Promise<void>

autofillSettings.ts

// Load settings from localStorage
loadAutofillSettings(): AutofillSettings

// Save settings to localStorage
saveAutofillSettings(settings: AutofillSettings): void

// Check if autofill enabled for origin
isAutofillEnabledForOrigin(origin: string, settings?: AutofillSettings): boolean

// Add/remove origin from exclusion list
excludeOrigin(origin: string): void
includeOrigin(origin: string): void

// Toggle autofill globally
toggleAutofill(enabled: boolean): void

📖 Additional Resources

🤝 Contributing

To add autofill support for a new browser:

  1. Research browser's credential management capabilities
  2. Implement adapter in src/core/autofill/adapters/
  3. Add browser detection
  4. Update documentation

📄 License

MIT License - See main project LICENSE file