1import type { MessageType } from "../shared/types";23export type MessageContext =4 | "extension-page-only"5 | "content-script-allowed"6 | "background-internal"7 | "page-relay";89export interface MessageSenderShape {10 id?: string;11 url?: string;12}13141516171819export const MESSAGE_CONTEXT_POLICY = {20 21 GET_SYNC_ALERTS: "extension-page-only",22 GET_PENDING_VOUCHED_DEVICES: "extension-page-only",23 CONFIRM_VOUCHED_DEVICE: "extension-page-only",24 REJECT_VOUCHED_DEVICE: "extension-page-only",25 ROTATE_SYNC_IDENTITY: "extension-page-only",26 UNLOCK: "extension-page-only",27 UNLOCK_WITH_PIN: "extension-page-only",28 GET_PIN_STATUS: "extension-page-only",29 LOCK: "extension-page-only",30 IS_UNLOCKED: "extension-page-only",31 HAS_VAULT: "extension-page-only",32 GET_ENTRIES: "extension-page-only",33 EXPORT_ENTRIES: "extension-page-only",34 BATCH_ADD_ENTRIES: "extension-page-only",35 RESTORE_ENTRIES: "extension-page-only",36 CLEAR_VAULT_ENTRIES: "extension-page-only",37 DELETE_ENTRY: "extension-page-only",38 CREATE_VAULT: "extension-page-only",39 CREATE_VAULT_FROM_ROOT_KEY: "extension-page-only",40 CHECK_ALL_BREACHES: "extension-page-only",41 UPDATE_SETTINGS: "extension-page-only",42 SETUP_PIN: "extension-page-only",43 DISABLE_PIN: "extension-page-only",44 ACTIVATE_LICENSE: "extension-page-only",45 GET_LICENSE: "extension-page-only",46 GET_LICENSE_KEY: "extension-page-only",47 IS_DURESS_ENABLED: "extension-page-only",48 SETUP_DURESS: "extension-page-only",49 DISABLE_DURESS: "extension-page-only",50 VERIFY_MAIN_PASSWORD: "extension-page-only",51 CHANGE_PASSWORD: "extension-page-only",52 GET_LOCAL_IDENTITY: "extension-page-only",53 LIST_PAIRED_DEVICES: "extension-page-only",54 RENAME_PAIRED_DEVICE: "extension-page-only",55 UNPAIR_DEVICE: "extension-page-only",56 RENAME_LOCAL_DEVICE: "extension-page-only",57 START_ADOPTION_SOURCE: "extension-page-only",58 START_ADOPTION_RECEIVER: "extension-page-only",59 CANCEL_ADOPTION_SOURCE: "extension-page-only",60 SOURCE_SAS_DECISION: "extension-page-only",61 TRIGGER_SYNC: "extension-page-only",62 GET_SYNC_STATE: "extension-page-only",63 GET_SYNC_SETTINGS: "extension-page-only",64 SET_SYNC_SETTINGS: "extension-page-only",65 GET_PENDING_PASSKEY: "extension-page-only",66 APPROVE_PASSKEY: "extension-page-only",67 DENY_PASSKEY: "extension-page-only",68 GET_PASSKEY_PROVIDER_STATE: "extension-page-only",69 SET_PASSKEY_PROVIDER_ENABLED: "extension-page-only",70 GET_DELETED_ENTRIES: "extension-page-only",71 RESTORE_ENTRY: "extension-page-only",72 PURGE_ENTRY: "extension-page-only",73 PURGE_EXPIRED_TRASH: "extension-page-only",74 GET_VAULT_HISTORY: "extension-page-only",75 RESTORE_VAULT_SNAPSHOT: "extension-page-only",76 COUNT_DUPLICATES: "extension-page-only",77 DEDUPLICATE_ENTRIES: "extension-page-only",78 GET_VAULT_STATUS: "extension-page-only",79 GET_ADVANCED_HEALTH_REPORT: "extension-page-only",80 DEACTIVATE_LICENSE: "extension-page-only",81 GET_IDENTITIES: "extension-page-only",82 DESTROY_VAULT: "extension-page-only",83 COMPLETE_FIREFOX_PASSKEY_CREATE: "extension-page-only",84 VALIDATE_RECOVERY_WORDS: "extension-page-only",85 RECOVER_WITH_WORDS: "extension-page-only",86 GET_RECOVERY_WORDS: "extension-page-only",87 GET_RECOVERY_CONFIRM_PENDING: "extension-page-only",88 SET_RECOVERY_CONFIRM_PENDING: "extension-page-only",89 CLEAR_RECOVERY_CONFIRM_PENDING: "extension-page-only",90 GET_IDENTITY_SUGGESTIONS: "extension-page-only",91 SAVE_NOTE: "extension-page-only",92 DELETE_NOTE: "extension-page-only",93 GET_NOTES: "extension-page-only",94 SEARCH_VAULT: "extension-page-only",95 GET_CODEX_VAULT_DATA: "extension-page-only",96 ESTIMATE_CODEX_PAGES: "extension-page-only",97 GENERATE_CODEX: "extension-page-only",98 RESTORE_FROM_CODEX: "extension-page-only",99 OPEN_DETACHED_POPUP: "extension-page-only",100101 102 103 ADD_ENTRY: "content-script-allowed",104 UPDATE_ENTRY: "content-script-allowed",105 ADD_ADDITIONAL_URL: "content-script-allowed",106 REQUEST_REMEMBER_SITE: "content-script-allowed",107 AUTOFILL_QUERY: "content-script-allowed",108 COPY: "extension-page-only",109 FIRE_CANARY_PING: "content-script-allowed",110 GET_ENTRY_FOR_FILL: "content-script-allowed",111 GET_ENTRY_FOR_EDIT: "extension-page-only",112 GET_SETTINGS: "content-script-allowed",113 GET_SITE_PASSWORD_POLICY: "content-script-allowed",114 RECORD_MANUAL_SUMMON: "content-script-allowed",115 DECLINE_CARD_SAVE: "content-script-allowed",116 IS_CARD_DECLINED: "content-script-allowed",117 PASSKEY_AUTH_RESPONSE: "content-script-allowed",118 ML_INIT: "content-script-allowed",119 ML_PREDICT_BATCH: "content-script-allowed",120 OPEN_PRO_GATE: "content-script-allowed",121 OPEN_POPUP: "content-script-allowed",122 TOUCH_AUTO_LOCK: "extension-page-only",123 MARK_PASSKEY_BANNER_SHOWN: "content-script-allowed",124125 126 INITIATE_FIREFOX_PASSKEY_CREATE: "page-relay",127 PASSKEY_OFFER_DECLINE: "page-relay",128 GET_PASSKEY_OFFER_DECLINED: "page-relay",129 GET_PASSKEY_FOR_DOMAIN: "page-relay",130 PASSKEY_HAS_CREDENTIALS: "page-relay",131 PASSKEY_CREATE: "page-relay",132 PASSKEY_GET: "page-relay",133134 135 CLEAR_CLIPBOARD: "background-internal",136 VOUCHED_DEVICE_PENDING: "background-internal",137 DEVICE_KEY_ROTATED: "background-internal",138 ADOPTION_SOURCE_SAS: "background-internal",139 ADOPTION_SOURCE_RESULT: "background-internal",140 PING: "background-internal",141 SUMMON_AUTOFILL: "background-internal",142 VAULT_LOCKED: "background-internal",143 VAULT_UNLOCKED: "background-internal",144 PRO_GATE_TRIGGERED: "background-internal",145 PASSKEY_PRO_GATE: "background-internal",146 SHOW_PASSKEY_TOAST: "background-internal",147 DISMISS_PASSKEY_TOAST: "background-internal",148 SHOULD_PLAY_CELEBRATION: "extension-page-only",149 MARK_CELEBRATION_PLAYED: "extension-page-only",150} satisfies Record<MessageType, MessageContext>;151152export function getMessageContext(type: unknown): MessageContext | undefined {153 if (typeof type !== "string") return undefined;154 return Object.hasOwn(MESSAGE_CONTEXT_POLICY, type)155 ? MESSAGE_CONTEXT_POLICY[type as MessageType]156 : undefined;157}158159export function isMessageSenderAllowed(160 type: unknown,161 sender: MessageSenderShape,162 extensionId: string | undefined,163 extensionOrigin: string,164): boolean {165 if (sender.id !== undefined && sender.id !== extensionId) return false;166167 const context = getMessageContext(type);168 if (context === "background-internal" || context === undefined) return false;169170 if (context === "extension-page-only") {171 if (!sender.url) return false;172 try {173 return new URL(sender.url).origin === new URL(extensionOrigin).origin;174 } catch {175 return false;176 }177 }178179 if (context === "page-relay") {180 if (!sender.url) return false;181 try {182 return new URL(sender.url).origin !== new URL(extensionOrigin).origin;183 } catch {184 return false;185 }186 }187188 return true;189}