|
| 1 | +const kagiBaseUrl = "https://kagi.com/"; |
| 2 | +let extensionToken = undefined; // use process memory to hold the token |
| 3 | + |
| 4 | +chrome.runtime.onInstalled.addListener((details) => { |
| 5 | + if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) { |
| 6 | + chrome.tabs.create({ url: kagiBaseUrl }); |
| 7 | + } |
| 8 | +}); |
| 9 | + |
| 10 | +async function loadTokenFromCookies() { |
| 11 | + const cookie = await chrome.cookies.get({ |
| 12 | + url: kagiBaseUrl, |
| 13 | + name: "kagi_session", |
| 14 | + }); |
| 15 | + |
| 16 | + if (!cookie || !cookie.value || cookie.value.trim().length === 0) { |
| 17 | + return; |
| 18 | + } |
| 19 | + |
| 20 | + let valuesDiffer = cookie.value !== extensionToken; |
| 21 | + extensionToken = cookie.value; |
| 22 | + if (valuesDiffer) await updateRules(); |
| 23 | +} |
| 24 | + |
| 25 | +chrome.webRequest.onCompleted.addListener(loadTokenFromCookies, { |
| 26 | + urls: [`${kagiBaseUrl}*`], |
| 27 | +}); |
| 28 | + |
| 29 | +async function updateRules() { |
| 30 | + // https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest#dynamic-and-session-rules |
| 31 | + // dynamic needed as the token can't be known ahead of time |
| 32 | + await chrome.declarativeNetRequest.updateDynamicRules({ |
| 33 | + addRules: [ |
| 34 | + { |
| 35 | + id: 1, |
| 36 | + priority: 1, |
| 37 | + action: { |
| 38 | + type: "modifyHeaders", |
| 39 | + requestHeaders: [ |
| 40 | + { |
| 41 | + header: "Authorization", |
| 42 | + value: extensionToken, |
| 43 | + operation: "set", |
| 44 | + }, |
| 45 | + ], |
| 46 | + }, |
| 47 | + condition: { |
| 48 | + urlFilter: `${kagiBaseUrl}*`, |
| 49 | + resourceTypes: ["main_frame"], |
| 50 | + }, |
| 51 | + }, |
| 52 | + ], |
| 53 | + removeRuleIds: [1], |
| 54 | + }); |
| 55 | +} |
| 56 | + |
| 57 | +// Image Search |
| 58 | +function kagiImageSearch(info) { |
| 59 | + const imageUrl = encodeURIComponent(info.srcUrl); |
| 60 | + chrome.tabs.create({ |
| 61 | + url: `${kagiBaseUrl}images?q=${imageUrl}&reverse=reference`, |
| 62 | + }); |
| 63 | +} |
| 64 | + |
| 65 | +chrome.contextMenus.create({ |
| 66 | + id: "kagi-image-search", |
| 67 | + title: "Kagi Image Search", |
| 68 | + contexts: ["image"], |
| 69 | +}); |
| 70 | + |
| 71 | +chrome.contextMenus.onClicked.addListener((info, tab) => { |
| 72 | + if (info.menuItemId === "kagi-image-search") { |
| 73 | + kagiImageSearch(info, tab); |
| 74 | + } |
| 75 | +}); |
0 commit comments