diff --git a/TODO.md b/TODO.md
index f244f99..738109d 100644
--- a/TODO.md
+++ b/TODO.md
@@ -1,5 +1,7 @@
### Todo
+- [ ] implement CRON logic in normal extension use
+
### In Progress
- [ ] Widget to show unopened emails
diff --git a/chrome-extension/js/inject.js b/chrome-extension/js/inject.js
index c016719..e9cb5ec 100644
--- a/chrome-extension/js/inject.js
+++ b/chrome-extension/js/inject.js
@@ -1,5 +1,5 @@
// Configuration and Logger
-const isDev = false;
+const isDev = true;
const DOMAIN = "stealthbyte.deno.dev";
const LOCALHOST = "localhost:8080";
const baseTrackingPixelUrl = isDev ? `http://${LOCALHOST}` : `https://${DOMAIN}`;
diff --git a/chrome-extension/js/popup.js b/chrome-extension/js/popup.js
new file mode 100644
index 0000000..d27718a
--- /dev/null
+++ b/chrome-extension/js/popup.js
@@ -0,0 +1,31 @@
+chrome.runtime.sendMessage({message: "fetch_user_data"}, function(response) {
+ if (response.error) {
+ console.error('Error:', response.error);
+ document.body.innerHTML = '
Error loading data. Please try again later.
';
+ } else {
+ displayUserInfo(response.userData);
+ displayEmails(response.userEmails);
+ }
+});
+
+function displayUserInfo(userData) {
+ const userInfoDiv = document.getElementById('user-info');
+ userInfoDiv.innerHTML = `
+ Email: ${userData.email}
+ Emails sent this month: ${userData.emailsSentThisMonth}
+ `;
+}
+
+function displayEmails(emails) {
+ const emailListDiv = document.getElementById('email-list');
+ emails.forEach(email => {
+ const emailDiv = document.createElement('div');
+ emailDiv.className = 'email-item';
+ emailDiv.innerHTML = `
+ ${email.subject}
+ Opened: ${email.numberOfOpens} times
+ Sent: ${new Date(Number(email.dateAtTimeOfSend)).toLocaleString()}
+ `;
+ emailListDiv.appendChild(emailDiv);
+ });
+}
\ No newline at end of file
diff --git a/chrome-extension/js/service-worker.js b/chrome-extension/js/service-worker.js
index 9e20cb1..ef32a8a 100644
--- a/chrome-extension/js/service-worker.js
+++ b/chrome-extension/js/service-worker.js
@@ -17,8 +17,8 @@ const logger = {
let authToken = null;
const DOMAIN = "stealthbyte.deno.dev";
const LOCALHOST = "localhost:8080";
-const isDev = false;
-const serverUrl = isDev ? `http://${LOCALHOST}` : `https://${DOMAIN}`;
+const isDev = true;
+const SERVER_URL = isDev ? `http://${LOCALHOST}` : `https://${DOMAIN}`;
// Function to get OAuth2 token
function getAuthToken(interactive) {
return new Promise((resolve, reject) => {
@@ -141,6 +141,10 @@ chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
logger.info("Processing email data:", request.data.subject);
processEmail(request.data, sender); // Pass sender to processEmail
}
+ if (request.message === "fetch_user_data") {
+ fetchUserData().then(sendResponse);
+ return true; // Indicates that the response is sent asynchronously
+ }
});
// Function to process email data and initiate retry mechanism
@@ -282,7 +286,7 @@ chrome.alarms.onAlarm.addListener(async (alarm) => {
// Send a notification to the server
try {
const serverResponse = await fetch(
- `${serverUrl}/${uniqueId}/pixel.png`,
+ `${SERVER_URL}/${uniqueId}/pixel.png`,
{
method: "POST",
headers: {
@@ -333,3 +337,88 @@ chrome.alarms.onAlarm.addListener(async (alarm) => {
logger.error(`Error handling alarm "${sleepId}":`, error.message);
}
});
+
+async function fetchUserData() {
+ logger.info("Fetching user data...");
+ try {
+ const token = await ensureAuthenticated();
+ logger.info("Authentication token obtained");
+
+ const cacheStatus = await fetchCacheStatus(token);
+ logger.info("Cache status:", cacheStatus);
+
+ if (!cacheStatus.cached) {
+ logger.info("Cache is invalid, fetching new data from server");
+ const data = await fetchAllEmailData(token);
+ logger.info("New data fetched from server");
+ await storeDataInLocalStorage(data);
+ logger.info("New data stored in local storage");
+ return data;
+ } else {
+ logger.info("Cache is valid, retrieving data from local storage");
+ return await getDataFromLocalStorage();
+ }
+ } catch (error) {
+ logger.error('Error in fetchUserData:', error);
+ return { error: 'Failed to fetch user data' };
+ }
+}
+
+async function fetchCacheStatus(token) {
+ logger.info("Fetching cache status from server");
+ try {
+ const response = await fetch(`${SERVER_URL}/cache-status`, {
+ headers: {
+ 'Authorization': `Bearer ${token}`
+ }
+ });
+ const data = await response.json();
+ logger.info("Cache status received:", data);
+ return data;
+ } catch (error) {
+ logger.error('Error fetching cache status:', error);
+ throw error;
+ }
+}
+
+async function fetchAllEmailData(token) {
+ logger.info("Fetching all email data from server");
+ try {
+ const response = await fetch(`${SERVER_URL}/all-email-data`, {
+ headers: {
+ 'Authorization': `Bearer ${token}`
+ }
+ });
+ const data = await response.json();
+ logger.info("All email data received");
+ return data;
+ } catch (error) {
+ logger.error('Error fetching all email data:', error);
+ throw error;
+ }
+}
+
+async function storeDataInLocalStorage(data) {
+ logger.info("Storing data in local storage");
+ return new Promise((resolve) => {
+ chrome.storage.local.set({ 'userData': data }, () => {
+ logger.info("Data stored in local storage");
+ resolve();
+ });
+ });
+}
+
+async function getDataFromLocalStorage() {
+ logger.info("Retrieving data from local storage");
+ return new Promise((resolve) => {
+ chrome.storage.local.get('userData', (result) => {
+ if (result.userData) {
+ logger.info("Data retrieved from local storage");
+ resolve(result.userData);
+ } else {
+ logger.warn("No data found in local storage");
+ resolve(null);
+ }
+ });
+ });
+}
diff --git a/chrome-extension/manifest.json b/chrome-extension/manifest.json
index 13f72f4..7fb5d6f 100644
--- a/chrome-extension/manifest.json
+++ b/chrome-extension/manifest.json
@@ -30,5 +30,8 @@
"https://www.googleapis.com/auth/userinfo.profile"
]
},
- "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo+GASpGqfyteWsX4CNqnyRpsDuH/ZbIfQemxI8mJifK2NZC+VsxBTULNsJj+V8vgFeTu5N0R2Gz5mTgiYnzRIo2xUfWUeNnC2xS2XigBYkGBziY7cT/eHFTT5x7pinEKK/FwByhlYfwHm6lOlrqWQJCnliUSfHMRCeVakh7hB6V7G2tt/CohZhmNKxPx3azsqSMq1zhtZc5jzSYcomfDO5SdO1mJ3ZXMweAERXs0AAYJ8vneDc0FzkPIeQVipSQhxSqeObtAK9jaM1SPaIZSoQ997+mrkRXXbvYhNBtiQ/eHoNIovarim0eYLbi80OfLhFqX6EYJGSFLHjYSHlpVeQIDAQAB"
-}
\ No newline at end of file
+ "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo+GASpGqfyteWsX4CNqnyRpsDuH/ZbIfQemxI8mJifK2NZC+VsxBTULNsJj+V8vgFeTu5N0R2Gz5mTgiYnzRIo2xUfWUeNnC2xS2XigBYkGBziY7cT/eHFTT5x7pinEKK/FwByhlYfwHm6lOlrqWQJCnliUSfHMRCeVakh7hB6V7G2tt/CohZhmNKxPx3azsqSMq1zhtZc5jzSYcomfDO5SdO1mJ3ZXMweAERXs0AAYJ8vneDc0FzkPIeQVipSQhxSqeObtAK9jaM1SPaIZSoQ997+mrkRXXbvYhNBtiQ/eHoNIovarim0eYLbi80OfLhFqX6EYJGSFLHjYSHlpVeQIDAQAB",
+ "action": {
+ "default_popup": "popup.html"
+ }
+}
diff --git a/chrome-extension/popup.html b/chrome-extension/popup.html
new file mode 100644
index 0000000..53dcd07
--- /dev/null
+++ b/chrome-extension/popup.html
@@ -0,0 +1,19 @@
+
+
+
+ Email Tracker Summary
+
+
+
+ Email Tracker Summary
+
+ Tracked Emails
+
+
+
+
\ No newline at end of file
diff --git a/web-server/html/home.ts b/web-server/html/home.ts
index 6abbea3..aaf7336 100644
--- a/web-server/html/home.ts
+++ b/web-server/html/home.ts
@@ -71,8 +71,10 @@ export const homePageHtml = `
View Privacy Policy