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 BATCH_ADD_ENTRIES: "extension-page-only",34 RESTORE_ENTRIES: "extension-page-only",35 CLEAR_VAULT_ENTRIES: "extension-page-only",36 DELETE_ENTRY: "extension-page-only",37 CREATE_VAULT: "extension-page-only",38 CREATE_VAULT_FROM_ROOT_KEY: "extension-page-only",39 CHECK_ALL_BREACHES: "extension-page-only",40 UPDATE_SETTINGS: "extension-page-only",41 SETUP_PIN: "extension-page-only",42 DISABLE_PIN: "extension-page-only",43 ACTIVATE_LICENSE: "extension-page-only",44 GET_LICENSE: "extension-page-only",45 GET_LICENSE_KEY: "extension-page-only",46 IS_DURESS_ENABLED: "extension-page-only",47 SETUP_DURESS: "extension-page-only",48 DISABLE_DURESS: "extension-page-only",49 VERIFY_MAIN_PASSWORD: "extension-page-only",50 CHANGE_PASSWORD: "extension-page-only",51 GET_LOCAL_IDENTITY: "extension-page-only",52 LIST_PAIRED_DEVICES: "extension-page-only",53 RENAME_PAIRED_DEVICE: "extension-page-only",54 UNPAIR_DEVICE: "extension-page-only",55 RENAME_LOCAL_DEVICE: "extension-page-only",56 START_ADOPTION_SOURCE: "extension-page-only",57 START_ADOPTION_RECEIVER: "extension-page-only",58 CANCEL_ADOPTION_SOURCE: "extension-page-only",59 SOURCE_SAS_DECISION: "extension-page-only",60 TRIGGER_SYNC: "extension-page-only",61 GET_SYNC_STATE: "extension-page-only",62 GET_SYNC_SETTINGS: "extension-page-only",63 SET_SYNC_SETTINGS: "extension-page-only",64 GET_PENDING_PASSKEY: "extension-page-only",65 APPROVE_PASSKEY: "extension-page-only",66 DENY_PASSKEY: "extension-page-only",67 GET_PASSKEY_PROVIDER_STATE: "extension-page-only",68 SET_PASSKEY_PROVIDER_ENABLED: "extension-page-only",69 GET_DELETED_ENTRIES: "extension-page-only",70 RESTORE_ENTRY: "extension-page-only",71 PURGE_ENTRY: "extension-page-only",72 PURGE_EXPIRED_TRASH: "extension-page-only",73 GET_VAULT_HISTORY: "extension-page-only",74 RESTORE_VAULT_SNAPSHOT: "extension-page-only",75 COUNT_DUPLICATES: "extension-page-only",76 DEDUPLICATE_ENTRIES: "extension-page-only",77 GET_VAULT_STATUS: "extension-page-only",78 GET_ADVANCED_HEALTH_REPORT: "extension-page-only",79 DEACTIVATE_LICENSE: "extension-page-only",80 GET_IDENTITIES: "extension-page-only",81 DESTROY_VAULT: "extension-page-only",82 COMPLETE_FIREFOX_PASSKEY_CREATE: "extension-page-only",83 VALIDATE_RECOVERY_WORDS: "extension-page-only",84 RECOVER_WITH_WORDS: "extension-page-only",85 GET_RECOVERY_WORDS: "extension-page-only",86 GET_RECOVERY_CONFIRM_PENDING: "extension-page-only",87 SET_RECOVERY_CONFIRM_PENDING: "extension-page-only",88 CLEAR_RECOVERY_CONFIRM_PENDING: "extension-page-only",89 GET_IDENTITY_SUGGESTIONS: "extension-page-only",90 SAVE_NOTE: "extension-page-only",91 DELETE_NOTE: "extension-page-only",92 GET_NOTES: "extension-page-only",93 SEARCH_VAULT: "extension-page-only",94 GET_CODEX_VAULT_DATA: "extension-page-only",95 ESTIMATE_CODEX_PAGES: "extension-page-only",96 GENERATE_CODEX: "extension-page-only",97 RESTORE_FROM_CODEX: "extension-page-only",98 OPEN_DETACHED_POPUP: "extension-page-only",99100 101 102 ADD_ENTRY: "content-script-allowed",103 UPDATE_ENTRY: "content-script-allowed",104 ADD_ADDITIONAL_URL: "content-script-allowed",105 REQUEST_REMEMBER_SITE: "content-script-allowed",106 AUTOFILL_QUERY: "content-script-allowed",107 COPY: "content-script-allowed",108 FIRE_CANARY_PING: "content-script-allowed",109 GET_ENTRY_FOR_FILL: "content-script-allowed",110 GET_ENTRY_FOR_EDIT: "extension-page-only",111 GET_SETTINGS: "content-script-allowed",112 GET_SITE_PASSWORD_POLICY: "content-script-allowed",113 RECORD_MANUAL_SUMMON: "content-script-allowed",114 DECLINE_CARD_SAVE: "content-script-allowed",115 IS_CARD_DECLINED: "content-script-allowed",116 PASSKEY_AUTH_RESPONSE: "content-script-allowed",117 ML_INIT: "content-script-allowed",118 ML_PREDICT_BATCH: "content-script-allowed",119 OPEN_PRO_GATE: "content-script-allowed",120 OPEN_POPUP: "content-script-allowed",121 TOUCH_AUTO_LOCK: "content-script-allowed",122123 124 INITIATE_FIREFOX_PASSKEY_CREATE: "page-relay",125 PASSKEY_OFFER_DECLINE: "page-relay",126 GET_PASSKEY_OFFER_DECLINED: "page-relay",127 GET_PASSKEY_FOR_DOMAIN: "page-relay",128 PASSKEY_HAS_CREDENTIALS: "page-relay",129 PASSKEY_CREATE: "page-relay",130 PASSKEY_GET: "page-relay",131132 133 CLEAR_CLIPBOARD: "background-internal",134 VOUCHED_DEVICE_PENDING: "background-internal",135 DEVICE_KEY_ROTATED: "background-internal",136 ADOPTION_SOURCE_SAS: "background-internal",137 ADOPTION_SOURCE_RESULT: "background-internal",138 PING: "background-internal",139 SUMMON_AUTOFILL: "background-internal",140 VAULT_LOCKED: "background-internal",141 VAULT_UNLOCKED: "background-internal",142 PRO_GATE_TRIGGERED: "background-internal",143 PASSKEY_PRO_GATE: "background-internal",144 SHOW_PASSKEY_TOAST: "background-internal",145 DISMISS_PASSKEY_TOAST: "background-internal",146 SHOULD_PLAY_CELEBRATION: "extension-page-only",147 MARK_CELEBRATION_PLAYED: "extension-page-only",148} satisfies Record<MessageType, MessageContext>;149150export function getMessageContext(type: unknown): MessageContext | undefined {151 if (typeof type !== "string") return undefined;152 return Object.hasOwn(MESSAGE_CONTEXT_POLICY, type)153 ? MESSAGE_CONTEXT_POLICY[type as MessageType]154 : undefined;155}156157export function isMessageSenderAllowed(158 type: unknown,159 sender: MessageSenderShape,160 extensionId: string | undefined,161 extensionOrigin: string,162): boolean {163 if (sender.id !== undefined && sender.id !== extensionId) return false;164165 const context = getMessageContext(type);166 if (context === "background-internal" || context === undefined) return false;167168 if (context === "extension-page-only") {169 if (!sender.url) return false;170 try {171 return new URL(sender.url).origin === new URL(extensionOrigin).origin;172 } catch {173 return false;174 }175 }176177 if (context === "page-relay") {178 if (!sender.url) return false;179 try {180 return new URL(sender.url).origin !== new URL(extensionOrigin).origin;181 } catch {182 return false;183 }184 }185186 return true;187}