A social knowledge tool for researchers built on ATProto
1// Background script for handling extension messaging and auth state
2chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
3 if (message.type === 'EXTENSION_TOKENS') {
4 handleExtensionTokens(message, sendResponse);
5 return true; // Keep message channel open for async response
6 }
7
8 if (message.type === 'WEBAPP_TOKENS_RECEIVED') {
9 handleWebappTokens(message, sendResponse);
10 return true;
11 }
12});
13
14// Handle tokens received directly via chrome.runtime.sendMessage
15async function handleExtensionTokens(
16 message: any,
17 sendResponse: (response: any) => void,
18) {
19 try {
20 const { accessToken, refreshToken } = message;
21
22 if (!accessToken) {
23 sendResponse({ success: false, error: 'No access token provided' });
24 return;
25 }
26
27 // Store tokens in chrome.storage
28 await chrome.storage.local.set({
29 accessToken,
30 refreshToken,
31 isAuthenticated: true,
32 authTimestamp: Date.now(),
33 });
34
35 // Notify all extension pages about the auth change
36 chrome.runtime
37 .sendMessage({
38 type: 'AUTH_STATE_CHANGED',
39 isAuthenticated: true,
40 })
41 .catch(() => {
42 // Ignore errors if no listeners
43 });
44
45 sendResponse({ success: true });
46 } catch (error) {
47 console.error('Failed to handle extension tokens:', error);
48 sendResponse({ success: false, error: (error as Error).message });
49 }
50}
51
52// Handle tokens forwarded from content script (postMessage)
53async function handleWebappTokens(
54 message: any,
55 sendResponse: (response: any) => void,
56) {
57 try {
58 const { accessToken, refreshToken } = message;
59
60 if (!accessToken) {
61 sendResponse({ success: false, error: 'No access token provided' });
62 return;
63 }
64
65 // Store tokens in chrome.storage
66 await chrome.storage.local.set({
67 accessToken,
68 refreshToken,
69 isAuthenticated: true,
70 authTimestamp: Date.now(),
71 });
72
73 // Notify all extension pages about the auth change
74 chrome.runtime
75 .sendMessage({
76 type: 'AUTH_STATE_CHANGED',
77 isAuthenticated: true,
78 })
79 .catch(() => {
80 // Ignore errors if no listeners
81 });
82
83 sendResponse({ success: true });
84 } catch (error) {
85 console.error('Failed to handle webapp tokens:', error);
86 sendResponse({ success: false, error: (error as Error).message });
87 }
88}
89
90// Handle auth logout
91chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
92 if (message.type === 'LOGOUT') {
93 handleLogout(sendResponse);
94 return true;
95 }
96});
97
98async function handleLogout(sendResponse: (response: any) => void) {
99 try {
100 // Clear all auth data
101 await chrome.storage.local.remove([
102 'accessToken',
103 'refreshToken',
104 'isAuthenticated',
105 'authTimestamp',
106 ]);
107
108 // Notify all extension pages about the auth change
109 chrome.runtime
110 .sendMessage({
111 type: 'AUTH_STATE_CHANGED',
112 isAuthenticated: false,
113 })
114 .catch(() => {
115 // Ignore errors if no listeners
116 });
117
118 sendResponse({ success: true });
119 } catch (error) {
120 console.error('Failed to handle logout:', error);
121 sendResponse({ success: false, error: (error as Error).message });
122 }
123}