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>
84 lines
1.7 KiB
TypeScript
84 lines
1.7 KiB
TypeScript
/**
|
|
* Protocol types — mirrors the server's protocol/spec.ts for use in the extension.
|
|
*/
|
|
|
|
export const PROTOCOL_VERSION = "2.0.0";
|
|
export const MAX_STORED_COOKIES_PER_DEVICE = 10_000;
|
|
export const PAIRING_CODE_LENGTH = 6;
|
|
export const PAIRING_TTL_MS = 5 * 60 * 1000;
|
|
export const NONCE_BYTES = 24;
|
|
export const PING_INTERVAL_MS = 30_000;
|
|
export const PONG_TIMEOUT_MS = 10_000;
|
|
export const POLL_INTERVAL_MS = 5_000;
|
|
|
|
export const MESSAGE_TYPES = {
|
|
COOKIE_SYNC: "cookie_sync",
|
|
COOKIE_DELETE: "cookie_delete",
|
|
ACK: "ack",
|
|
PING: "ping",
|
|
PONG: "pong",
|
|
ERROR: "error",
|
|
} as const;
|
|
|
|
export type MessageType = (typeof MESSAGE_TYPES)[keyof typeof MESSAGE_TYPES];
|
|
|
|
export interface Envelope {
|
|
type: MessageType;
|
|
from: string;
|
|
to: string;
|
|
nonce: string;
|
|
payload: string;
|
|
timestamp: string;
|
|
sig: string;
|
|
}
|
|
|
|
export interface CookieEntry {
|
|
domain: string;
|
|
name: string;
|
|
value: string;
|
|
path: string;
|
|
secure: boolean;
|
|
httpOnly: boolean;
|
|
sameSite: "strict" | "lax" | "none";
|
|
expiresAt: string | null;
|
|
}
|
|
|
|
export interface CookieSyncPayload {
|
|
action: "set" | "delete";
|
|
cookies: CookieEntry[];
|
|
lamportTs: number;
|
|
}
|
|
|
|
export interface EncryptedCookieBlob {
|
|
id: string;
|
|
deviceId: string;
|
|
domain: string;
|
|
cookieName: string;
|
|
path: string;
|
|
nonce: string;
|
|
ciphertext: string;
|
|
lamportTs: number;
|
|
updatedAt: string;
|
|
}
|
|
|
|
export interface DeviceRegisterRequest {
|
|
deviceId: string;
|
|
name: string;
|
|
platform: string;
|
|
encPub: string;
|
|
}
|
|
|
|
export interface DeviceInfo {
|
|
deviceId: string;
|
|
name: string;
|
|
platform: string;
|
|
encPub: string;
|
|
token: string;
|
|
createdAt: string;
|
|
}
|
|
|
|
export interface PairingResult {
|
|
peerDeviceId: string;
|
|
peerX25519PubKey: string;
|
|
}
|