Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions ManifestBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,28 @@
const integrations = require('./integrationList.json');

module.exports = {
build: function (isDebug = false) {
build: function (serverProtocol, serverDomain, browser, isDebug = false) {
if (isDebug) {
integrations.push({
"matches": ["*://localhost:*/*"],
"matches": ["*://localhost/*/*"],
"script": ["for-development-only.js"]
})
}

if (browser === "firefox") {
integrations.push({
"matches": [serverProtocol + '://' + serverDomain + '/*'],
"script": ["timecamp-firefox-helper.js"]
})
}

let contentScripts = [];
for (const integration of integrations) {
if (!isDebug && integration.isActiveInProd !== true) {
continue;
}

contentScripts.push({
let item = {
'matches': [
...this.defaults.matches,
...integration.matches
Expand All @@ -31,7 +38,13 @@ module.exports = {
...this.defaults.js,
'scripts-2.0/third_party/' + integration.script,
],
});
};

if (item.exclude_matches.length === 0) {
delete item.exclude_matches;
}

contentScripts.push(item);
}

return contentScripts;
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ TimeCamp Browser Plugin Extension
npm install --legacy-peer-deps
```

## Firefox
To build for Firefox just run: `export BROWSER=firefox`
To switch back to Chrome run: `unset BROWSER`

## Build for production
1. `unset SERVER_DOMAIN` or revert domain changes - just in case if you changed for development
2. `npm run-script build-prod` - it creates archive `dist/timecamp-browser-extension-2.x.x.zip` and directory `dist/plugin` with same unzipped files
Expand Down
6 changes: 6 additions & 0 deletions manifest.chrome.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"background": {
"service_worker": "scripts/background.js"
},
"offline_enabled": false
}
10 changes: 10 additions & 0 deletions manifest.firefox.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"background": {
"scripts": ["scripts/background.js"]
},
"browser_specific_settings": {
"gecko": {
"id": "dev@timecamp.com"
}
}
}
6 changes: 1 addition & 5 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,11 @@
],
"homepage_url": "http://www.timecamp.com/",
"incognito": "spanning",
"offline_enabled": false,
"permissions": [
"tabs",
"storage"
],
"host_permissions": ["https://*.timecamp.com/*"],
"background": {
"service_worker": "scripts/background.js"
},
"web_accessible_resources": [{
"resources":[
"images/*.gif",
Expand All @@ -142,4 +138,4 @@
],
"matches": ["<all_urls>"]
}]
}
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "timecamp-chrome-extension",
"version": "2.85.2",
"version": "2.85.22",
"description": "TimeCamp Google Chrome Time Tracking Extension",
"main": "index.js",
"scripts": {
Expand All @@ -11,7 +11,7 @@
"build-dev": "webpack-cli --mode development && npm run merge-background-files",
"build-prod-unsafe": "webpack-cli --mode production && npm run merge-background-files && npm run zip",
"merge-background-files": "cat 'dist/plugin/scripts-2.0/background-2.0.js' >> 'dist/plugin/scripts/background.js'",
"zip": "bash -c \"pushd dist/plugin && zip -rq ../timecamp-browser-extension-`node -p \"require('./package.json').version\"`.zip * && popd\""
"zip": "bash -c \" pushd dist/plugin && zip -rq ../timecamp-browser-extension-`node -p \"require('./package.json').version\"`-`if [ $BROWSER == \"firefox\" ]; then echo \"firefox\"; else echo \"chromium\"; fi`.zip * && popd\""
},
"babel": {
"presets": [
Expand Down
30 changes: 15 additions & 15 deletions scripts-2.0/ApiService.js
Original file line number Diff line number Diff line change
Expand Up @@ -863,9 +863,9 @@ export default class ApiService {

removeStoredToken() {
return new Promise((resolve, reject) => {
chrome.storage.sync.clear();
chrome.storage.sync.set({ 'removed': true }, function () {
if (chrome.runtime.lastError) {
browser.storage.sync.clear();
browser.storage.sync.set({ 'removed': true }).then(() => {
if (browser.runtime.lastError) {
reject();
} else {
resolve(true);
Expand All @@ -876,31 +876,31 @@ export default class ApiService {

storeToken(token) {
return new Promise((resolve, reject) => {
chrome.storage.sync.set({ 'token': token, 'removed': false }, function () {
browser.storage.sync.set({ 'token': token, 'removed': false }).then(() => {
resolve();
if (chrome.runtime.lastError) {
logger.error(chrome.runtime.lastError.message);
if (browser.runtime.lastError) {
logger.error(browser.runtime.lastError.message);
}
});
});
};

storeNextToken(token) {
return new Promise((resolve, reject) => {
chrome.storage.sync.set({ 'next_token': token, 'removed': false }, function () {
browser.storage.sync.set({ 'next_token': token, 'removed': false }).then(() => {
resolve();
if (chrome.runtime.lastError) {
logger.error(chrome.runtime.lastError.message);
if (browser.runtime.lastError) {
logger.error(browser.runtime.lastError.message);
}
});
});
};

getStoredToken() {
return new Promise((resolve, reject) => {
chrome.storage.sync.get('token', function (items) {
browser.storage.sync.get('token').then((items) => {
var token = items['token'];
if (token && !chrome.runtime.lastError) {
if (token && !browser.runtime.lastError) {
resolve(token);
} else {
reject();
Expand All @@ -911,9 +911,9 @@ export default class ApiService {

getStoredNextToken() {
return new Promise((resolve, reject) => {
chrome.storage.sync.get('next_token', function (items) {
browser.storage.sync.get('next_token').then((items) => {
var token = items['next_token'];
if (token && !chrome.runtime.lastError) {
if (token && !browser.runtime.lastError) {
resolve(token);
} else {
reject();
Expand All @@ -924,8 +924,8 @@ export default class ApiService {

getLoggedOutFlag() {
return new Promise((resolve, reject) => {
chrome.storage.sync.get('removed', function (items) {
if (chrome.runtime.lastError) {
browser.storage.sync.get('removed').then((items) => {
if (browser.runtime.lastError) {
reject();
return;
}
Expand Down
12 changes: 6 additions & 6 deletions scripts-2.0/StorageManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ export default class StorageManager {
browser.storage.sync.get(key).then((items) => {
let data = items[key];

if (browser.runtime.lastError === undefined) {
if (!browser.runtime.lastError) {
resolve(data);
} else {
logger.error(browser.runtime.lastError.message);
reject(browser.runtime.lastError.message);
logger.error(browser.runtime.lastError?.error);
reject(browser.runtime.lastError?.error);
}
}).catch((e) => {
reject(e);
Expand All @@ -34,11 +34,11 @@ export default class StorageManager {
set(key, data) {
return new Promise((resolve, reject) => {
browser.storage.sync.set({[key]: data}).then(() => {
if (browser.runtime.lastError === undefined) {
if (!browser.runtime.lastError) {
resolve();
} else {
logger.error(browser.runtime.lastError.message);
reject(browser.runtime.lastError.message);
logger.error(browser.runtime.lastError?.error);
reject(browser.runtime.lastError?.error);
}
}).catch((e) => {
reject(e);
Expand Down
14 changes: 12 additions & 2 deletions scripts-2.0/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ const TcButton = {
reject(error);
});
break;
case 'tokenUpdate':
TcButton.login(request.token);
break;
}
} catch (e) {
logger.error(e);
Expand All @@ -377,13 +380,13 @@ const TcButton = {
});
},

//used only by chrome
newMessageExternal: (request, sender, sendResponse) => {
return new Promise((resolve, reject) => {
try {
switch (request.type) {
case 'tokenUpdate':
apiService.storeToken(request.token);
TcButton.doAfterLogin();
TcButton.login(request.token);
break;
}
} catch (e) {
Expand Down Expand Up @@ -457,6 +460,11 @@ const TcButton = {
});
},

login: (token) => {
apiService.storeToken(token);
TcButton.doAfterLogin();
},

doAfterLogin: () => {
return new Promise((resolve, reject) => {
TcButton.isUserLogged = true;
Expand Down Expand Up @@ -723,6 +731,8 @@ browser.runtime.onMessage.addListener(function (request, sender, sendResponse) {
//tracking
return analyticsService.logEvent(request, sender, sendResponse)
});

//used only by chrome
browser.runtime.onMessageExternal.addListener(TcButton.newMessageExternal);
setInterval(() => {
const promise = TcButton.updateCurrentEntry();
Expand Down
8 changes: 8 additions & 0 deletions scripts-2.0/third_party/timecamp-firefox-helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
'use strict';

//firefox helper for pass data from website to background script
window.addEventListener("message", (event) => {
if (event.data.type === 'tokenUpdate') {
browser.runtime.sendMessage(event.data);
}
}, false);
18 changes: 13 additions & 5 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const ENV = {
SERVER_PROTOCOL: process.env.SERVER_PROTOCOL || 'https',
SERVER_DOMAIN: process.env.SERVER_DOMAIN || 'app.timecamp.com',
NEXT_SERVER_DOMAIN: "v4.api.timecamp.com",
MARKETING_PAGE_DOMAIN: 'www.timecamp.com',
MARKETING_PAGE_DOMAIN: 'www.timecamp.com',
GOOGLE_ANALYTICS_ID: 'UA-4525089-16'
};

Expand Down Expand Up @@ -214,7 +214,7 @@ function transformOldConfig() {
}

function transformManifest(isDebug = false) {
return function (content) {
return async function (content) {
const manifest = JSON.parse(content.toString());
manifest.homepage_url = ENV.SERVER_PROTOCOL + '://' + ENV.SERVER_DOMAIN + '/';
manifest.host_permissions = [
Expand All @@ -224,16 +224,24 @@ function transformManifest(isDebug = false) {

manifest.externally_connectable.matches = [
...manifest.externally_connectable.matches,
ENV.SERVER_PROTOCOL + '://' + ENV.SERVER_DOMAIN + '/*'
ENV.SERVER_PROTOCOL + '://' + ENV.SERVER_DOMAIN + '/*',
];

const browser = process.env.BROWSER === "firefox" ? "firefox" : "chrome";

manifest.content_scripts = [
...manifest.content_scripts,
...ManifestBuilder.build(isDebug)
...ManifestBuilder.build(ENV.SERVER_PROTOCOL, ENV.SERVER_DOMAIN, browser, isDebug)
];

manifest.version = pkg.version;

return Buffer.from(JSON.stringify(manifest, undefined, 2));
const browserSpecificManifestPath = `manifest.${browser}.json`;

const file = await fs.promises.readFile(browserSpecificManifestPath);
const fileContent = JSON.parse(file.toString());
const manifestResult = Object.assign(manifest, fileContent);

return Buffer.from(JSON.stringify(manifestResult, undefined, 2));
};
}