import type { Item, ItemId, Manifest, ManifestEntry, VaultConfig, SetupState, DeviceSettings, GeneratorRequest, VaultSettings, AttachmentRef, Device, FieldHistoryView, } from './types'; // --- Session timeout config --- export type SessionTimeoutConfig = | { mode: 'inactivity'; minutes: number } | { mode: 'every_time' }; // --- Messages a popup (or setup page) may send --- export type PopupMessage = | { type: 'is_unlocked' } | { type: 'unlock'; passphrase: string } | { type: 'lock' } | { type: 'list_items'; group?: string } | { type: 'get_item'; id: ItemId } | { type: 'add_item'; item: Item } | { type: 'update_item'; id: ItemId; item: Item } | { type: 'delete_item'; id: ItemId } // soft-delete | { type: 'get_totp'; id: ItemId } | { type: 'sync' } | { type: 'get_setup_state' } | { type: 'save_setup'; config: VaultConfig; imageBase64: string } | { type: 'rate_passphrase'; passphrase: string } | { type: 'generate_password'; request: GeneratorRequest } | { type: 'generate_passphrase'; request: GeneratorRequest } | { type: 'fill_credentials'; id: ItemId; capturedTabId: number; capturedUrl: string } | { type: 'ack_autofill_origin'; hostname: string } | { type: 'get_settings' } | { type: 'update_settings'; settings: Partial } | { type: 'get_vault_settings' } | { type: 'update_vault_settings'; settings: VaultSettings } | { type: 'get_blacklist' } | { type: 'remove_blacklist'; hostname: string } | { type: 'get_active_tab_url' } | { type: 'list_groups' } | { type: 'upload_attachment'; itemId: string; filename: string; mimeType: string; bytes: ArrayBuffer } | { type: 'download_attachment'; itemId: string; attachmentId: string } | { type: 'list_devices' } | { type: 'list_revoked' } | { type: 'add_device'; name: string; public_key: string } | { type: 'register_this_device'; name: string } | { type: 'revoke_device'; name: string } | { type: 'list_trashed' } | { type: 'restore_item'; id: ItemId } | { type: 'purge_item'; id: ItemId } | { type: 'purge_all_trash' } | { type: 'get_field_history'; id: ItemId } | { type: 'get_session_config' } | { type: 'update_session_config'; config: SessionTimeoutConfig } | { type: 'export_backup'; passphrase: string; includeImage: boolean } | { type: 'restore_backup'; bytes: ArrayBuffer; passphrase: string; newRemote: { hostType: 'gitea' | 'github'; hostUrl: string; repoPath: string; apiToken: string }; } | { type: 'parse_lastpass_csv'; bytes: ArrayBuffer } | { type: 'import_lastpass_commit'; items: Item[] } | { type: 'preview_totp_from_secret'; secret_b32: string } | { type: 'generate_recovery_qr'; passphrase: string } | { type: 'unwrap_recovery_qr'; payload_b64: string; passphrase: string } | { type: 'create_vault'; config: VaultConfig; passphrase: string; carrierImageBytes: ArrayBuffer; deviceName: string } | { type: 'attach_vault'; config: VaultConfig; passphrase: string; referenceImageBytes: ArrayBuffer; deviceName: string } | { type: 'get_vault_status' }; // --- Messages a content script may send --- // Note deliberate absence of a `url` field — the SW derives origin from sender.tab.url. export type ContentMessage = | { type: 'get_autofill_candidates' } | { type: 'get_credentials'; id: ItemId } | { type: 'check_credential'; username: string; password: string } | { type: 'blacklist_site' } | { type: 'capture_save_login'; username: string; password: string }; // --- Union for chrome.runtime.sendMessage call sites --- export type Request = PopupMessage | ContentMessage; // --- Response --- export type Response = | { ok: true; data?: unknown } | { ok: false; error: string }; // --- Typed response helpers --- export interface IsUnlockedResponse extends Extract { data: { unlocked: boolean }; } export interface ListItemsResponse extends Extract { data: { items: Array<[ItemId, ManifestEntry]> }; } export interface GetItemResponse extends Extract { data: { item: Item }; } export interface TotpResponse extends Extract { data: { code: string; expires_at: number }; } export interface AutofillCandidatesResponse extends Extract { data: { candidates: Array<[ItemId, ManifestEntry]> }; } export interface CredentialsResponse extends Extract { data: | { requires_ack: true; hostname: string } | { username: string; password: string }; } export interface SetupStateResponse extends Extract { data: SetupState; } export interface GeneratePasswordResponse extends Extract { data: { password: string }; } export interface RatePassphraseResponse extends Extract { data: { score: number; guesses_log10: number }; } export interface VaultSettingsResponse extends Extract { data: { settings: VaultSettings }; } export interface UploadAttachmentResponse extends Extract { data: { attachment: AttachmentRef }; } export interface DownloadAttachmentResponse extends Extract { data: { bytes: ArrayBuffer; filename: string; mimeType: string }; } export interface ListDevicesResponse extends Extract { data: { devices: Device[] }; } export interface ListRevokedResponse extends Extract { data: { revoked: Array<{ name: string; public_key: string; revoked_at: number; revoked_by: string }> }; } export interface ListTrashedResponse extends Extract { data: { items: Array<[ItemId, ManifestEntry]> }; } export interface PurgeAllTrashResponse extends Extract { data: { itemCount: number; orphanCount: number }; } export interface FieldHistoryResponse extends Extract { data: { history: FieldHistoryView[] }; } // --- Capability sets (consumed by the router) --- export const POPUP_ONLY_TYPES: ReadonlySet = new Set([ 'is_unlocked', 'unlock', 'lock', 'list_items', 'get_item', 'add_item', 'update_item', 'delete_item', 'get_totp', 'sync', 'get_setup_state', 'save_setup', 'rate_passphrase', 'generate_password', 'generate_passphrase', 'fill_credentials', 'ack_autofill_origin', 'get_settings', 'update_settings', 'get_vault_settings', 'update_vault_settings', 'get_blacklist', 'remove_blacklist', 'get_active_tab_url', 'list_groups', 'upload_attachment', 'download_attachment', 'list_devices', 'list_revoked', 'add_device', 'register_this_device', 'revoke_device', 'list_trashed', 'restore_item', 'purge_item', 'purge_all_trash', 'get_field_history', 'get_session_config', 'update_session_config', 'export_backup', 'restore_backup', 'parse_lastpass_csv', 'import_lastpass_commit', 'preview_totp_from_secret', 'generate_recovery_qr', 'unwrap_recovery_qr', 'create_vault', 'attach_vault', 'get_vault_status', ] as PopupMessage['type'][]); export interface ExportBackupResponse extends Extract { data: { bytes: ArrayBuffer }; } export interface RestoreBackupResponse extends Extract { data: { summary: { itemCount: number; attachmentCount: number; hasImage: boolean }; }; } export interface ParseLastPassCsvResponse extends Extract { data: { items: Item[]; warnings: Array<{ row: number; title?: string; message: string }>; }; } export interface ImportLastPassCommitResponse extends Extract { data: { summary: { itemCount: number }; }; } export interface CreateVaultResponse extends Extract { data: { referenceImageBytes: Uint8Array; deviceName: string; recoveryQrAvailable: true }; } export interface AttachVaultResponse extends Extract { data: { deviceName: string }; } export interface GetVaultStatusResponse extends Extract { data: { ahead: number; behind: number; lastSyncAt: number | null; pendingItems: number }; } export const CONTENT_CALLABLE_TYPES: ReadonlySet = new Set([ 'get_autofill_candidates', 'get_credentials', 'check_credential', 'blacklist_site', 'capture_save_login', ] as ContentMessage['type'][]);