Chrome Extension: CRX file not working properly - javascript

I am trying to install my Extension's CRX version but it is not loading some of image files on extension button placed on address bar.I have even put try/catch but it is not giving any error either. The Developer/Unpack version is working just fine.
What's wrong am I doing? What I guess my all image files are not compressed in CRX file. Unfortunately I can't extract CRX content either as renamig to .ZIP is not letting me to unzip on MacoSX
I am installing CRX by dragging on to extensions page.
How do I test the issue?
Code is given below:
Manifest.jsonn
{
"name": "Domain Colors",
"version": "1.0",
"manifest_version": 2,
"description": "Change Button Color for domains.",
"content_scripts": [
{
"matches": ["http://*/*","https://*/*"],
"js": ["script.js"]
}
],
"permissions": [
"tabs", "http://*/*"
],
"browser_action": {
"default_title": "Colry",
"default_icon": "blue.png"
},
"background": {
"scripts": ["background41.js"]
}
}
script.js
alert("Testing Version..Wait for a while");
var request = new XMLHttpRequest();
if (request == null)
{
alert("Unable to create request");
}
else
{
try
{
var timestamp = new Date().getTime(); //to avoid cache ajax calls
var randomnumber=Math.floor(Math.random()*11);
timestamp = timestamp * randomnumber;
var _domain = document.domain;
_domain = _domain.replace("www.","");
var url = "http://xxxxnet/xxx/xxx.asp?xx="+_domain+"&ts="+timestamp;
request.onreadystatechange = function()
{
//request.setRequestHeader('Cache-Control', 'no-cache');
//request.setRequestHeader('Pragma', 'no-cache');
if(request.readyState == 4)
{
LDResponse(request.responseText);
}
}
request.open("GET", url, true);
request.send(null);
}
catch(e){
alert('An error has occurred in AJAX Call: '+e.message)
}
}
function LDResponse(response)
{
var json = JSON.parse(response);
alert(response);
var msg = document.domain+","+json["buttonColour"]+","+json["buttonTip"];
chrome.extension.sendMessage(msg);
}
background file
var currentUrl = "";
var currentColor = "";
var currentTip = "";
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) {
if (changeInfo.status === 'loading')
{
chrome.browserAction.setIcon({
path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/gray.png',
tabId:tabId
});
chrome.extension.onMessage.addListener(function(message, sender)
{
try
{
var stuff = message.split(",");
currentUrl = stuff[0];
currentUrl = currentUrl.replace("www.","");
currentColor = stuff[1];
currentTip = stuff[2];
}
catch(e)
{
alert('An error in onMessage method: '+e.message)
}
});
}
else if (changeInfo.status === 'complete')
{
try
{
chrome.browserAction.setIcon({
path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/'+currentColor+".png",
tabId:tabId
});
chrome.browserAction.setTitle({
tabId:tabId,
title:currentTip
});
}
catch(e)
{
alert('An error in Complete method: '+e.message)
}
}
});
Thanks

Replace path:'chrome-extension://lkhgldilknhpmdodeblhnbniahbjcdcm/'+currentColor+".png with path: chrome.extension.getURL("currentColor.png") to get it to work.
Your runtime extension id is not lkhgldilknhpmdodeblhnbniahbjcdcm, so to use dynamic generated content you should use chrome.extension.getURL()

Related

JavaScript & Chrome Extensions: Pass Variable with Custom Events

manifest.json
{
"name": "Omegle IP",
"version": "0.5",
"options_page": "options.html",
"options_ui": {
"page": "options.html",
"open_in_tab": false
},
"background": {
"scripts": ["background.js"],
"persistent": true
},
"manifest_version": 2,
"description": "Become a Hacker; You see the IP in the chat window",
"permissions": ["tabs", "https://*.omegle.com/*", "storage"],
"web_accessible_resources": ["inject.js"],
"content_scripts" : [{
"matches" : ["https://*.omegle.com/*"],
"run_at": "document_end",
"js" : ["contentscript.js"]
}],
"icons": {
"16": "16.png",
"32": "32.png",
"48": "48.png",
"128": "128.png"
}
}
contentscript.js
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('inject.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
inject.js
chrome.storage.sync.get(['tracker', 'api'], function (obj) {
tracker = obj.tracker;
api = obj.api;
getIp(tracker, api);
});
function getIp(tracker, api){
console.log(tracker + api)
}
I cant access chrome.storage.sync.get from inject.js. But I need to... Is there a way to put the chrome request to the contentscript and pass the variables to inject.js
contentscript.js basically just creates a script field and puts the inject.js into it.
the inject.js file is normally larger, but you dont need all of that
There is a post "https://stackoverflow.com/questions/9515704/use-a-content-script-to-access-the-page-context-variables-and-functions" how to implement this, i tried but i didnt achieve to get it to work...
Could you please provide a working method, to get it to work?
Update:
contentscript.js
chrome.storage.sync.get(['tracker'], function (obj) {
tracker = obj.tracker;
ChromeExtensionData(tracker);
});
function ChromeExtensionData(tracker) {
var data = {
tracker: tracker,
};
console.log("Sending:", tracker); // works
console.log(document.dispatchEvent(new CustomEvent('ChromeExtensionData', { detail: data }))); // true
}
inject.js
document.addEventListener('ChromeExtensionData', function (e) {
var tracker = e.detail;
console.log('received', tracker);
});
getIp(tracker); // tracker is not definied
Its in the comments whats wrong. And i really dont know why
Update:
inject.js
document.addEventListener('ChromeExtensionData', function (e) {
console.log("Recieved"); // test -> doesnt work
var tracker = e.detail;
console.log('received', tracker); // doenst log anything
getIp(tracker);
});
contentscript.js
var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('inject.js');
s.onload = function() {
this.remove();
};
(document.head || document.documentElement).appendChild(s);
chrome.storage.sync.get(['tracker'], function (obj) {
tracker = obj.tracker;
ChromeExtensionData(tracker);
});
function ChromeExtensionData(tracker) {
jsontracker = JSON.stringify(tracker);
var data = {
tracker: jsontracker
};
console.log("Sending:", tracker); // works
document.dispatchEvent(new CustomEvent('ChromeExtensionData', { detail: data }));
}
Working Answer
inject.js
document.addEventListener('ChromeExtensionData', function (e) { // waits for variable from contentscript
var data = e.detail;
tracker = data.tracker;
trollChecked = data.trollChecked;
getIp(tracker, trollChecked);
});
contentscript.js
var s = document.createElement('script');
s.src = chrome.runtime.getURL('inject.js');
s.onload = function() {
this.remove();
chrome.storage.sync.get(['tracker', 'troll'], function (obj) {
tracker = obj.tracker;
trollChecked = obj.troll
var data = {
tracker: tracker,
trollChecked: trollChecked
};
document.dispatchEvent(new CustomEvent('ChromeExtensionData', { detail: data })); // gets variable from optionspage and sends to the script
});
};
(document.head || document.documentElement).appendChild(s);
You can learn how to set chrome variables from here
Big Shoutout to wOxxOm for helping me and making this result possible

Chrome Extension Host Registration not working in windows

I want to run console app by clicking button on webpage
Console app will get Information and put in clipboard, and then I will get that information on webpage.
I am following this blog
I did this 3-4 times, all other things looks fine, but console app is not being called/executed.
I am getting these errors.
on webpage console
Unchecked runtime.lastError: The message port closed before a response was received.
on background file
Unchecked runtime.lastError: Specified native messaging host not found.
Unchecked runtime.lastError: The message port closed before a response was received.
my codes are
manifest.json
{
"name": "EID Reader",
"version": "1.0",
"manifest_version": 2,
"description": "Read Emirates ID",
"permissions": [ "contextMenus", "activeTab", "clipboardRead", "nativeMessaging" ],
"icons": {
"16": "eid16.png",
"48": "eid48.png",
"128": "eid128.png"
},
"background": {
"scripts": [ "eid.js" ]
},
"content_scripts": [
{
"matches": [ "http://*/*", "https://*/*", "file://*/*"],
"js": [ "content_script.js", "jquery-3.3.1.js" ],
"all_frames": true,
"run_at": "document_start"
}
]
}
content_script.js
// Listener to catch the event raised by the webpage button
document.addEventListener("EID_EVENT", function (data) {
// send message to background process to read emirates ID and send back the data
chrome.runtime.sendMessage("ifligfijbkpijeafdfbpljjibfbppmeb", function (response) {
});
});
// Listener to catch the data coming from the background process
chrome.extension.onMessage.addListener(function (msg, sender, sendResponse) {
if (msg.action == 'EID_DATA') {
//Parse the data and fill the form accordingly
try {
var json = $.parseJSON(msg.response);
$(json).each(function (i, val) {
$.each(val, function (key, value) {
if (key == 'EIDNumber')
$("#txtNumber").val(value);
if (key == 'Name')
$("#txtName").val(value);
if (key == 'Email')
$("#txtEmail").val(value);
if (key == 'PassportNumber')
$("#txtPassport").val(value);
});
});
}
catch (e) {
var error = "error" + e;
}
}
});
eid.js (background)
var port = null;
var tabId = null;
/* listener for messages coming from the content_scrip */
chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
tabId=sender.tab.id;
var hostName = "ae.eid.chrome";
port = chrome.runtime.connectNative(hostName);
port.onDisconnect.addListener(onDisconnected);
});
/* THIS WILL BE CALLED ONCE EXE FINISH */
function onDisconnected() {
port = null;
SendResponse();
}
function SendResponse() {
//create a textarea, focus on it, and make a "paste" command to get the clipboard, then send the pasted value back to the content_script
bg = chrome.extension.getBackgroundPage();
bg.document.body.innerHTML = ""; // clear the background page
var helper = null;
if (helper == null) {
helper = bg.document.createElement("textarea");
helper.style.position = "absolute";
helper.style.border = "none";
document.body.appendChild(helper);
}
//Focus the textarea
helper.select();
// perform a Paste in the selected control, here the textarea
bg.document.execCommand("Paste");
// Send data back to content_script
chrome.tabs.sendMessage(tabId, { action: "EID_DATA", response: helper.value }, function (response) { });
}
ae.eid.chrome.json
{
"name": "ae.eid.chrome",
"description": "chrome extension to read EID",
"path": "EIDSampleConsole.exe",
"type": "stdio",
"allowed_origins": [
"chrome-extension://ifligfijbkpijeafdfbpljjibfbppmeb/"
]
}
install_host.bat
REG ADD "HKCU\Software\Google\Chrome\NativeMessagingHosts\ae.eid.chrome" /ve /t REG_SZ /d "%~dp0ae.eid.chrome.json" /f
I spent 2 days didnot get anything helpful.
Am I doing some error or Google Chrome prevented or changed the way to register host.
I have solved all the issues and posted all the steps at
http://www.codingsips.com/emirates-id-reader-and-google-chrome-via-extension-and-console-app/
Also I have published chrome extension, it you follow above steps the same extension will also work for you
chrome extension
https://chrome.google.com/webstore/detail/adcs-eid-reader/ipcncgpbppgjclagpdlodiiapmggolkf

Chrome extension: intercept HTTP Response

I saw many pages talking about how to intercept the HTTP Response from a site. I'm trying this: Chrome Extension - How to get HTTP Response Body?
There are no execuble programs... this is my code:
manifest.json:
{
"manifest_version": 2,
"name": "Extension Name",
"description": "Some Desc.",
"version": "1.1",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "index.html"
},
"permissions": [
"activeTab",
"storage",
"tabs",
"https://*.google.com/"
],
"content_scripts": [
{
"matches": ["https://*.google.com/"],
"run_at": "document_start",
"js": ["contentscript.js", "inject.js"]
}
],
"web_accessible_resources": ["injected.js"]
}
index.html:
<html>
<head>
<script src="contentscript.js"></script>
</head>
<body>
<p>HTTP INTERCEPTOR</p>
</body>
</html>
injected.js:
(function(xhr) {
console.log('injeced file');
var XHR = XMLHttpRequest.prototype;
var open = XHR.open;
var send = XHR.send;
var setRequestHeader = XHR.setRequestHeader;
XHR.open = function(method, url) {
this._method = method;
this._url = url;
this._requestHeaders = {};
this._startTime = (new Date()).toISOString();
return open.apply(this, arguments);
};
XHR.setRequestHeader = function(header, value) {
this._requestHeaders[header] = value;
return setRequestHeader.apply(this, arguments);
};
XHR.send = function(postData) {
this.addEventListener('load', function() {
var endTime = (new Date()).toISOString();
var myUrl = this._url ? this._url.toLowerCase() : this._url;
if(myUrl) {
if (postData) {
if (typeof postData === 'string') {
try {
// here you get the REQUEST HEADERS, in JSON format, so you can also use JSON.parse
this._requestHeaders = postData;
} catch(err) {
console.log('Request Header JSON decode failed, transfer_encoding field could be base64');
console.log(err);
}
} else if (typeof postData === 'object' || typeof postData === 'array' || typeof postData === 'number' || typeof postData === 'boolean') {
// do something if you need
}
}
// here you get the RESPONSE HEADERS
var responseHeaders = this.getAllResponseHeaders();
if ( this.responseType != 'blob' && this.responseText) {
// responseText is string or null
try {
// here you get RESPONSE TEXT (BODY), in JSON format, so you can use JSON.parse
var arr = this.responseText;
// printing url, request headers, response headers, response body, to console
console.log(this._url);
console.log(JSON.parse(this._requestHeaders));
console.log(responseHeaders);
console.log(JSON.parse(arr));
} catch(err) {
console.log("Error in responseType try catch");
console.log(err);
}
}
}
});
return send.apply(this, arguments);
};
})(XMLHttpRequest);
inject.js I set a timeout so I can enable the debugger:
/**
* code in inject.js
* added "web_accessible_resources": ["injected.js"] to manifest.json
*/
setTimeout(function() {
var s = document.createElement('script');
s.src = chrome.extension.getURL('injected.js');
s.onload = function() {
this.remove();
console.log('remove');
};
(document.head || document.documentElement).appendChild(s);
}, 10000);
Why the code is not injected into https://www.google.com/? Inspecting the DOM I don't see the code... the code runs and xhr is started but the methods open, setRequestHeader and send are never called.
The code is from my answer here.
Content Script, in that case, is used to communicate with injected.js.
Sample code is as follows:
/**
* Content script currently only used to communicate extension state on off message to injected.js
* Sends back response to extension (popup.js) after sending message to injected.js
*/
$(function(){
// localStorage is different from chrome.storage
// localStorage for injected script, and chrome.storage for extension script (popup.js) and contentscript.js
chrome.storage.sync.get("state", function (data) {
if (typeof data.state === 'undefined') {
chrome.storage.sync.set({"state": "on"}, function() {}); // async
}
console.log("Content Script State: " + data.state);
});
// message from extension script to this content script.
// will be used to receive enable disable messages
// sends response in 'status' variable
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
console.log(sender.tab ?
"content script receiving message from a content script:" + sender.tab.url :
"content script receiving message from the extension");
if (request.toggle === true) {
chrome.storage.sync.set({"state": "on"}, function() { console.log("Content Script State Updated: on"); }); // async
var data = {
app_state: "on"
};
document.dispatchEvent(new CustomEvent("app_state_message", {detail: data}));
// cannot return state in function since above .set is async and popup.js does not receive the response
sendResponse({state: "on"});
} else if (request.toggle === false) {
chrome.storage.sync.set({"state": "off"}, function() { console.log("Content Script State Updated: off"); }); // async
var data = {
app_state: "off"
};
document.dispatchEvent(new CustomEvent("app_state_message", {detail: data}));
sendResponse({state: "off"});
} else {
sendResponse({state: "error"});
}
});
});
Please read more on Content Scripts. Hope you find this useful.

chrome.runtime.connectNative from external url

I have a Google Chrome extension which contains the following two files...
manifest.json
{
"key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDcBHwzDvyBQ6bDppkIs9MP4ksKqCMyXQ/A52JivHZKh4YO/9vJsT3oaYhSpDCE9RPocOEQvwsHsFReW2nUEc6OLLyoCFFxIb7KkLGsmfakkut/fFdNJYh0xOTbSN8YvLWcqph09XAY2Y/f0AL7vfO1cuCqtkMt8hFrBGWxDdf9CQIDAQAB",
"name": "Native Messaging Example",
"version": "1.0",
"manifest_version": 2,
"description": "Send a message to a native application.",
"app": {
"launch": {
"local_path": "index.html"
}
},
"icons": {
"128": "icon-128.png"
},
"permissions": [
"nativeMessaging"
],
"externally_connectable": {
"matches": ["*://*.chrome-extension.com/*"]
},
"background": {
"scripts": ["background.js"]
}
}
background.js
var sendResponseCallBack;
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
sendResponseCallBack = sendResponse;
var message = {"comment": '*** ' + request['comment'] + ' ***'};
var useNative = false;
if (useNative) {
connect();
sendNativeMessage(message);
}
else {
sendResponseCallBack(message);
}
}
);
function connect() {
var hostName = "com.google.chrome.example.echo";
port = chrome.runtime.connectNative(hostName);
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
}
function sendNativeMessage(message) {
port.postMessage(message);
}
function onNativeMessage(message) {
port.disconnect();
sendResponseCallBack(message);
}
I also configured the virtual host: chrome-extension.com to access to the url from a local server:
http://www.chrome-extension.com/
With the Chrome extension installed and enabled, if I access to:
http://www.chrome-extension.com/
and the variable useNative = false then I get a response from the plugin through: sendResponseCallBack(message);, but if useNative = true then I don't get any response from the plugin, I get: undefined and also the native operation which should take about 5 seconds, doesn't go thru because the undefined response is returned in 0 seconds.
I also have enabled another html page I access thru the extension url:
chrome-extension://knldjmfmopnpolahpmmgbagdohdnhkik/calc-with-os.html
Inside that page I include the calc-with-os.js file which contains the above functions: connect() sendNativeMessage(message) onNativeMessage(message) and the function: chrome.runtime.connectNative works properly performing the native process in all its phases.
Any idea on how can I connect to a native process from an external url?
[EDIT: TRY NUMBER 2]
Based on the comment of: #wOxxOm I did the following modification to the code with the purpose of don't send the message to fast and wait for the native process to start, but it is not still working.
Any other suggestions?
var port = null;
var sendResponseCallBack;
chrome.runtime.onMessageExternal.addListener(
function(request, sender, sendResponse) {
sendResponseCallBack = sendResponse;
connect(request);
}
);
function connect(request) {
chrome.runtime.onConnect.addListener(function(p){
port = p;
port.onMessage.addListener(onNativeMessage);
port.onDisconnect.addListener(onDisconnected);
var message = {"comment": '*** ' + request['comment'] + ' ***'};
sendNativeMessage(message);
});
var hostName = "com.google.chrome.example.echo";
chrome.runtime.connectNative(hostName);
}
function sendNativeMessage(message) {
port.postMessage(message);
}
function onNativeMessage(message) {
port.disconnect();
sendResponseCallBack(message);
}

How do I stop content script execution in the current tab?

I'm working on a Google Chrome Extension, and I'm encountering a bug I can't solve on my own.
It works as expected switching to Youtube's Dark Mode on a single Youtube tab, but if you're on Youtube and Ctrl/Cmd click a link (open in a new tab), content.js is triggered again and the current tab is turned white and the new tab is dark.
If you are in a dark tab, a "child" tab should automatically be dark.
manifest.json:
{
"manifest_version": 2,
"permissions": [
"https://www.youtube.com/*",
"activeTab"
],
"background": {
"scripts": ["background.js"],
"persistant": false
},
"browser_action": {
"default_title": "Engage Youtube Dark Mode."
},
"content_scripts": [
{
"matches": ["https://www.youtube.com/*"],
"js": ["content.js"]
}]
}
background.js:
//var alreadyTriggered = false;
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {file: "clicker.js"});
});
/*
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
alreadyTriggered = false;
});*/
chrome.runtime.onMessage.addListener(function(response, sender, sendResponse) {
//if (!alreadyTriggered) {
chrome.tabs.executeScript(null, {file: "clicker.js"});
//alreadyTriggered = true;
//};
return true;
});
content.js:
var myDate = new Date();
if ((myDate.getHours() <= 7) || (myDate.getHours() >= 19))
{
var darkMode = document.body.getAttribute("dark");
if (!darkMode) {
chrome.runtime.sendMessage(window.location.href, function(result) {});
};
};
I'm guessing that I'm using activeTab incorrectly. Any help would be greatly appreciated. Thanks!
clicker.js:
stepOne();
function stepOne() {
try {
var buttons = document.querySelectorAll("button.ytd-topbar-menu-button-renderer");
buttons[0].click();
stepTwo();
}
catch(error) {
setTimeout(stepOne, 250);
}
}
function stepTwo() {
try {
buttons = document.querySelectorAll("paper-item.ytd-account-settings");
buttons[0].click();
stepThree();
}
catch(error) {
setTimeout(stepTwo, 100);
}
}
function stepThree() {
try {
buttons = document.querySelectorAll("paper-toggle-button.style-scope.ytd-account-settings");
buttons[0].click();
document.body.click();
}
catch(error) {
setTimeout(stepThree, 100);
}
}
What ended up working for me was to use a combination of:
using window.onload = doStuff();
And to make sure that the value for darkMode was null, not undefined.
Hopefully this helps someone who's been endlessly tweaking their code.

Categories

Resources