Skip to content

Extension Overview

The Certana Browser Extension enables on-the-fly image verification directly within any website, built with Vue.js 3 and the WXT framework.

Key Features

🔍 In-Browser Verification

  • Right-click context menu on images
  • Inline result display
  • No page reload required

🎨 User Interface

  • Popup for quick verification
  • Settings panel for API key management
  • Verification history
  • Dark mode support

🔐 Security

  • API key storage (encrypted in browser)
  • CORS-compliant requests
  • No data logging on extension

📊 Real-Time Results

  • Confidence scores
  • Watermark detection
  • Blockchain verification
  • Detailed breakdown

Supported Browsers

  • ✅ Chrome (90+)
  • ✅ Edge (90+)
  • ✅ Firefox (88+)
  • ✅ Opera (76+)

Project Structure

browser/
├── src/
│   ├── entrypoints/            # Extension entry points
│   │   ├── background.ts       # Service worker
│   │   ├── content.ts          # Content script
│   │   └── popup/              # Popup UI
│   │       ├── Popup.vue       # Main popup
│   │       ├── views/
│   │       │   ├── VerifyView.vue
│   │       │   ├── SettingsView.vue
│   │       │   ├── HistoryView.vue
│   │       │   └── AboutView.vue
│   │       └── main.ts
│   │
│   ├── components/             # Shared components
│   │   ├── ImageVerifier.vue   # Verification UI
│   │   ├── ResultDisplay.vue   # Results view
│   │   ├── SettingsForm.vue
│   │   ├── LoadingSpinner.vue
│   │   └── ...
│   │
│   ├── api-service.ts          # Backend API client
│   ├── storage-service.ts      # Browser storage
│   ├── types.ts                # TypeScript types
│   └── styles.css              # Global styles
│
├── public/                     # Static assets
│   └── icon/                   # Extension icons
│
├── wxt.config.ts               # WXT configuration
├── manifest.json               # Extension manifest
├── tsconfig.json
├── package.json
└── README.md

Architecture

User Interaction
    ├─► Right-click context menu
    ├─► Popup window
    └─► Settings panel
         │
         ▼
    Content Script (content.ts)
    - Injects UI into page
    - Handles user interactions
    - Communicates with background
         │
         ▼
    Background Service Worker (background.ts)
    - Manages state
    - Communicates with popup
    - Handles storage
         │
         ▼
    API Service (api-service.ts)
    - Sends requests to backend
    - Manages authentication
         │
         ▼
    Certana Backend API
    - Verifies images
    - Returns results

Key Components

Main popup interface with multiple views:

<template>
  <div class="popup">
    <header>
      <img src="@/public/icon/logo.png" alt="Certana" />
      <h1>Certana</h1>
    </header>

    <component :is="currentView" />

    <footer>
      <button @click="showSettings">Settings</button>
    </footer>
  </div>
</template>

Image Verifier Component

<ImageVerifier :image-url="selectedImage" @verify="handleVerify" />

Handles: - Image selection - Upload to backend - Display verification in progress - Show results

Result Display Component

<ResultDisplay 
  :result="verificationResult"
  :loading="isLoading"
/>

Shows: - Verdict (Authentic/Forged/Unknown) - Confidence score - Watermark detection - Blockchain status - Detailed breakdown

API Integration

CertanaApiService

export class CertanaApiService {
  constructor(apiEndpoint: string, apiKey: string);

  // Validate API key
  validateApiKey(): Promise<ApiKeyValidation>;

  // Verify image
  verifyImage(imageBlob: Blob): Promise<VerifyResponse>;

  // Get verification history
  getHistory(page: number): Promise<VerificationHistory>;
}

Storage Service

export class StorageService {
  // Get stored API key
  getApiKey(): Promise<string | null>;

  // Save API key (encrypted)
  saveApiKey(key: string): Promise<void>;

  // Get verification history
  getHistory(): Promise<VerificationLog[]>;

  // Save verification to history
  addToHistory(log: VerificationLog): Promise<void>;
}

Manifest Configuration

{
  "manifest_version": 3,
  "name": "Certana - Image Verification",
  "description": "Verify images on any website with blockchain and ML",
  "version": "1.0.0",
  "permissions": [
    "storage",
    "contextMenus",
    "webRequest"
  ],
  "host_permissions": [
    "<all_urls>"
  ],
  "background": {
    "service_worker": "background.ts"
  },
  "action": {
    "default_popup": "popup/index.html",
    "default_title": "Verify with Certana"
  },
  "context_menus": [
    {
      "id": "verify-image",
      "title": "Verify with Certana",
      "contexts": ["image"]
    }
  ]
}

Content Script (content.ts)

Injected into every webpage:

// Listen for context menu clicks
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.action === 'verify-image') {
    // Get image URL from context
    const imageUrl = request.imageUrl;

    // Send to popup
    chrome.runtime.sendMessage({
      action: 'show-results',
      results: verificationResults,
    });
  }
});

// Right-click menu handler
chrome.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === 'verify-image') {
    // Open popup with image
    chrome.action.openPopup();
  }
});

Background Service Worker (background.ts)

// Handle messages from popup
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === 'verify-image') {
    verifyImage(message.imageBlob).then(result => {
      sendResponse({ success: true, data: result });
    });
  }
});

// Context menu handler
chrome.contextMenus.create({
  id: 'verify-image',
  title: 'Verify with Certana',
  contexts: ['image'],
});

Storage

Uses Chrome Storage API:

// Save API key
chrome.storage.sync.set({ 'api_key': encryptedKey });

// Retrieve API key
chrome.storage.sync.get(['api_key'], (result) => {
  const apiKey = decryptKey(result.api_key);
});

// Save verification history
chrome.storage.local.set({ 'history': [...] });

Permissions

Permission Why
storage Store API key and history
contextMenus Right-click menu
<all_urls> Access images on any site

Security Considerations

API Key Storage

  • Stored encrypted in chrome.storage
  • Never sent to any third party
  • User can revoke at any time

Data Privacy

  • Verification results NOT stored on extension
  • Optional local history storage
  • No tracking or analytics

CORS Handling

  • Uses proper CORS headers
  • Browser enforces same-origin policy
  • API must include Access-Control-Allow-Origin

Next Steps