feat: implement M2 Chrome browser extension

Build the CookieBridge Chrome extension (Manifest V3) with:

- Background service worker: cookie monitoring via chrome.cookies.onChanged,
  WebSocket connection to relay server with auto-reconnect, HTTP polling
  fallback, device registration and pairing flow
- Browser-compatible crypto: libsodium-wrappers-sumo for XChaCha20-Poly1305
  encryption, Ed25519 signing, X25519 key exchange (mirrors server's
  sodium-native API)
- Popup UI: device registration, connection status indicator (gray/blue/
  green/red), cookie/device/sync stats, one-click current site sync,
  whitelist quick-add, device pairing with 6-digit code
- Options page: server URL config, connection mode (auto/WS/polling),
  poll interval slider, auto-sync toggle, domain whitelist/blacklist
  management, paired device list, key export/import, data clearing
- Sync engine: LWW conflict resolution with Lamport clocks (same as
  server), bidirectional cookie sync with all paired peers, echo
  suppression to prevent sync loops
- Badge management: icon color reflects state (gray=not logged in,
  blue=connected, green=syncing with count, red=error)
- Build system: esbuild bundling for Chrome 120+, TypeScript with
  strict mode, clean type checking

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
徐枫
2026-03-17 16:30:18 +08:00
parent 1bd7a34de8
commit dc3be4d73f
36 changed files with 3549 additions and 0 deletions

32
extension/manifest.json Normal file
View File

@@ -0,0 +1,32 @@
{
"manifest_version": 3,
"name": "CookieBridge",
"version": "0.1.0",
"description": "Cross-device cookie synchronization with end-to-end encryption",
"permissions": [
"cookies",
"storage",
"alarms",
"tabs",
"activeTab"
],
"host_permissions": ["<all_urls>"],
"background": {
"service_worker": "dist/background/service-worker.js",
"type": "module"
},
"action": {
"default_popup": "src/popup/popup.html",
"default_icon": {
"16": "src/icons/icon-gray-16.png",
"48": "src/icons/icon-gray-48.png",
"128": "src/icons/icon-gray-128.png"
}
},
"options_page": "src/options/options.html",
"icons": {
"16": "src/icons/icon-blue-16.png",
"48": "src/icons/icon-blue-48.png",
"128": "src/icons/icon-blue-128.png"
}
}