Repository navigation
Expand file tree
/
Copy pathbackground.js
More file actions
59 lines (55 loc) · 3.1 KB
/
Copy pathbackground.js
File metadata and controls
59 lines (55 loc) · 3.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import { createEngine } from './engine.js';
// Restrict the store before reading secrets. Content scripts receive a redacted snapshot.
const storageReady = chrome.storage.local.setAccessLevel({ accessLevel: 'TRUSTED_CONTEXTS' });
const engine = createEngine({
storage: {
get: async key => { await storageReady; return chrome.storage.local.get(key); },
set: async value => { await storageReady; return chrome.storage.local.set(value); },
},
onChange: async state => {
const text = !state.settings.enabled ? 'Ⅱ' : state.lastError ? '!' : state.stats.hidden ? String(Math.min(state.stats.hidden, 999)) : '';
await Promise.allSettled([
chrome.action.setBadgeText({ text }),
chrome.action.setBadgeBackgroundColor({ color: state.lastError ? '#a75232' : !state.settings.enabled ? '#69716b' : '#365b43' }),
(async () => {
const tabs = await chrome.tabs.query({ url: ['https://x.com/*', 'https://twitter.com/*'] });
await Promise.allSettled(tabs.map(tab => chrome.tabs.sendMessage(tab.id, { type: 'STATE_UPDATED', revision: state.revision })));
})(),
]);
},
});
export function authorize(message, sender) {
if (sender.id !== chrome.runtime.id) throw new Error('Unrecognized sender.');
const trusted = typeof sender.url === 'string' && sender.url.startsWith(chrome.runtime.getURL(''));
let isFeed = false;
try { const url = new URL(sender.url); isFeed = url.protocol === 'https:' && ['x.com', 'twitter.com'].includes(url.hostname) && sender.frameId === 0; } catch { /* Deny unknown contexts. */ }
if (!trusted && !isFeed) throw new Error('Sift only handles requests from its settings or X feed.');
if (!trusted) {
const allowed = ['GET_STATE', 'CLASSIFY_POSTS', 'SAVE_FEEDBACK', 'OPEN_APP', 'SAVE_SETTINGS'];
if (!allowed.includes(message?.type)) throw new Error('Open Sift settings to perform this action.');
if (message.type === 'SAVE_SETTINGS' && (!message.settings || Object.keys(message.settings).some(key => key !== 'enabled'))) throw new Error('Only filtering can be toggled from the feed.');
}
return trusted;
}
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
(async () => {
const trusted = authorize(message, sender);
if (message.type === 'OPEN_APP') {
const tab = ['preferences', 'review', 'connection'].includes(message.tab) ? message.tab : 'preferences';
await chrome.tabs.create({ url: chrome.runtime.getURL(`app.html#${tab}`) });
return { ok: true };
}
if (message.type === 'OPEN_X') {
await chrome.tabs.create({ url: 'https://x.com/home' });
return { ok: true };
}
return engine.handle(message, trusted);
})().then(sendResponse, error => sendResponse({ ok: false, error: error.message || 'Sift could not complete that action.' }));
return true;
});
chrome.runtime.onInstalled.addListener(async ({ reason }) => {
try {
await engine.handle({ type: 'SAVE_SETTINGS', settings: {} });
if (reason === 'install') await chrome.tabs.create({ url: chrome.runtime.getURL('app.html#connection') });
} catch (error) { console.error('Sift could not initialize:', error.message); }
});