activeTab permissions not working as expected - Chrome Extension - google-chrome-extension

As per permissions documentation, if we have activeTab perimissions, we need not specify the URL based permissions
Any of the following URLs match all hosts:
http://*/*
https://*/*
*://*/*
<all_urls>
Note that you may be able to avoid declaring all host permissions
using the activeTab permission.
But this is working only once, second time getting error (extension UI is open while we try second time), if we launch the popup again by clicking extension icon it works fine.
Unchecked runtime.lastError while running tabs.executeScript:
Cannot access contents of the page.
Extension manifest must request permission to access the respective host.
Following are details
manifest.json
{
"manifest_version": 2,
"name": "Getting started example",
"description": "This is hello world example",
"version": "1.0",
"browser_action": {
"default_icon": "icon.png",
"default_popup": "popup.html"
},
"permissions": [
"activeTab"
]
}
popup.html
<html>
<head>
<title>Getting Started Extension's Popup</title>
<script src="popup.js"></script>
</head>
<body>
<div>Hello World!</div>
<input type="button" id="refreshPage" value="Refresh Page"/>
</body>
</html>
popup.js
document.addEventListener('DOMContentLoaded', function() {
function refreshPage() {
chrome.tabs.executeScript(null, {
code: 'window.location.reload(true)'
}, function(){
console.log("Page refershed");
});
}
document.getElementById("refreshPage").addEventListener("click", refreshPage);
});
If we add "*://localhost/*" (this works for localhost), there is another way to specify for all hosts *://*/* (not sure if this is right and secure way), refresh button is working multiple times without relaunching popup UI. Is there a difference between activeTab vs URL based permissions and any specific way is recommended over another due to specific reasons?

The activeTab gives permission temporarily until the tab is navigated or closed. My guess is that by reloading the tab when hitting refresh revokes the activeTab permissions. Avoid using window.location.reload or specify the url match for the domain you are trying to execute a script on.
https://developer.chrome.com/extensions/activeTab
The activeTab permission gives an extension temporary access to the
currently active tab when the user invokes the extension - for example
by clicking its browser action. Access to the tab lasts until the tab
is navigated or closed.

Related

Error 'Service has been disabled for this account' while running identity.getAuthToken for chrome extension

I am trying to create an extension that uses the selected data and saves it to google sheets. Sounds pretty simple though but I am stuck at the Auth2 part.
Here's what I have done so far:
I have created a manifest.json and uploaded it on the chrome developer dashboard to obtain the "key" and "id".
Used the "id" to get the auth client id and added it to my manifest.json.
Next I have added basic html in "popup.html" and the context menu code part in "options.js" which is defined as the background script in "manifest.json".
Next I am using the "getAuthToken " to get the token in "popup.js". When I run the extension everything works but once I click the button to get the token nothing happens and "undefined" token value is returned.The error message is
Unchecked runtime.lastError while running identity.getAuthToken: OAuth2 request failed: Service responded with error: 'Service has been disabled for this account.'
Manifest.json
{
"name":"ext1",
"manifest_version":2,
"version": "1.0",
"description":"",
"browser_action":{
"default_icon":"icon48.png",
"default_popup":"popup.html"
},
"permissions":[
"identity",
"https://*/*",
"http://*/*",
"contextMenus",
"https://accounts.google.com/o/oauth2/token",
"storage"
],
"background":{
"scripts":["options.js"],
"persistent":false
},
"content_security_policy":"script-src 'self' https://apis.google.com; object-src 'self'",
"oauth2":{
"client_id":"<>.apps.googleusercontent.com",
"scopes":[
"https://www.googleapis.com/auth/spreadsheets"
]
},
"key":"<>"}
Popup.html
<!doctype <!DOCTYPE html>
<html>
<head>
<title>text</title>
<script src="jquery-3.3.1.min.js"></script>
<script src="popup.js"></script>
</head>
<body>
<h1>random text</h1>
<h2> Data: <span id="data"></span></h2>
<input type="submit" id="button" value="Authorize">
</body>
</html>
popup.js
$(function(){
chrome.storage.sync.get('datas', function(values){
$('#data').text(values.datas);
})
$("#button").on("click",function(){
chrome.identity.getAuthToken({"interactive":true},function(token){
alert("getting token......")
console.log("token")
console.log(token);
})
})
})
I have tried searching for similar issues but none solves my issue. kindly help what I am doing wrong.
You may be using an account with Google advanced protection which disables Gmail and Google Drive related API access for non-Google apps:
To keep your data secure, most non-Google apps and services won’t be able to access some data in your Google Account, like Google Drive or Gmail. *
Also see this announcement from Google: https://cloud.google.com/blog/products/identity-security/enhancing-security-controls-for-google-drive-third-party-apps
Today we’re announcing plans to extend the same policy to Google Drive as part of Project Strobe.
With this updated policy, we’ll limit the types of apps that have broad access to content or data via Drive APIs.
You may refer with the suggestion in this link to make it work:
Go to Google Developers Console and create a new project.
Go to APIs & auth > Credentials in the panel to create new Client ID. The application ID of chrome app can be obtained from Chrome Developer Dashboard if your app is uploaded.
Go to APIs & auth > Consent screen and fill in Email Address and Product Name and Save.
Using another Google Account to sign in have worked for me and fixed the issue.

open all the links on a web page with a single click on Chrome Extensions

I want open all the links on a web page with a single click on Chrome Extensions. I try for that وbut I did not get any results. please help me ...
my manifist.json file :
{
"name": "Open Links in New Tabs",
"version": "1.0",
"description": "open all link in page on new tabs with one click",
"background_page" : "background.html",
"browser_action": {
"default_icon": "icon.png"
},
"permissions":
["tabs"],
"manifest_version": 2
}
background.html file :
<!doctype html>
<html>
<head>
<script src="background.js"></script>
</head>
<body>
</body>
</html>
background.js file :
for(i = 0; i < document.links.length; i++)
{ chrome.tabs.create({active: true, url: document.links[i].href});}
Please explain any problems. thanks
When you access the document object in background.js, you're looking at background page, not the currently active tab.
To access the DOM contents of the open page, you will need a content script. It can then send a message to the background script (which has access to chrome.tabs) with the list of links to open.
Please take a moment to read this excellent overview of extension architecture. Also, read on messaging to pass the list.
Actually, if you're going to be injecting the script programmatically via chrome.tabs.executeScript, you can ditch messaging and just use the callback of executeScript.
As a side note, since you don't have any HTML in the background page, you can replace it with an auto-generated script page like this:
manifest.json
"background": {
scripts": ["background.js"]
},
in place of "background_page"
Lastly, consider minimal permissions that you need.
If your extension is supposed to trigger on click on the extension button (wrapped in a chrome.browserAction.onClicked listener), you can inject a script "for free" with activeTab permission, no need for tabs/host pemission.
Same goes to chrome.tabs.create, you don't need the mighty and scary "tabs" permission.
There are quite a few.
A background script doesn't have access to the page DOM of a tab. The only DOM it can access directly is the DOM of the background.html. You should use a content script and message passing.
background_page is an option of Manifest Version 1, you are using Manifest Version 2, for which the option is called background. Usually you provide the background.js directly as a script (see https://developer.chrome.com/extensions/background_pages). You should return after you implemented those suggestions

chrome extension - manifest version 2

I have a chrome extension that has a reference to the jquery file.
this is my popup html (only the head tag):
<head>
<title>My Extention</title>
<script type="text/javascript" src="http://www.MySite.com/Resources/JS/JQuery/jquery-1.7.2.min.js"></script>
<script type="text/javascript" src="MyExtensionScript.js"></script>
</head>
so in "MyExtensionScript.js" i thought i could use jquery but apparently the $ function is not defined.
This is my manifest.json file:
{
"name": "My Test Extension",
"version": "1.0",
"manifest_version": 2,
"description": "Test version of My Extension",
"browser_action": {
"default_icon": "test.ico",
"default_popup": "Test.html"
},
"permissions": [
"cookies",
"tabs",
"<all_urls>"
]
}
in version 1 of the manifest it worked, but now it doesn't. I tried to use the "web_accessible_resources" and add to them "http://www.MySite.com/Resources/JS/JQuery/jquery-1.7.2.min.js" but that didn't work also. any ideas?
also, i have a script injected to the current page and returning me a message (in my case some html source of the current page), will this behavior be affected by the transition to manifest version 2?
Thanks all :)
EDIT: I have a web application that enables cross domain scripting (using JSONP). In my extension i had a script calling a web service in my site with $.getJSON. now it doesn't work. i'm pretty sure that it has to do with the new manifest version but how can i enable again the cross domain scripting?
You need to use a jQuery file stored locally in your extension, rather than referenced from your site.
This is due to Chrome's strict Content Security Policy that only allows local scripts to be executed, with no inline code.
Web Accessible Resources are files inside your extension that may be accessed from the web, rather that resources your extension can access that are on the web. For example, if you wanted to change the background image of a page using an image stored in the extension, you have to add that image to the list in web_accessible_resouces in your manifest.
The change of manifest version should not affect your content scripts, unless they do something that is no longer allowed. You can see what else has changed from the Chrome manifestVersion docs.
I just include jquery in my content scripts. just make sure to load it before your script.
{
"manifest_version": 2,
"default_title": "Babble",
"version": "1.2",
"description": "Chat in your language with friends in their language",
"default_locale": "en",
"default_icons": {
"16": "img/icon16.png",
"48": "img/icon48.png",
"128": "img/icon128.png"
},
"content_scripts":[
{
"matches": ["http://mail.google.com/*", "https://mail.google.com/*"],
"css" : ["css/style.css"],
"js" : ["js/jquery.js" , "js/translate.js" , "js/jquery.cookie.js"]
}
]
}

Using sandboxed pages in chrome extensions

Manifest version 2 of chrome extensions will no longer support use of eval or new Function on regular extension pages. My chrome extension uses a UI Framework (Kendo UI) on the options page that makes use of these mechanisms and therefore I'm looking for a solution.
According to this session from IO 2012 the idea is to put the corresponding page into a sandbox and load it into the extension via an iframe.
Here is a simplified example what I'm trying to do: https://gist.github.com/3058943
manifest.json:
{
"name": "Sandbox test",
"manifest_version": 2,
"options_page": "main.html",
"sandbox": {
"pages": [ "index.html" ]
}
}
main.html:
<html>
<head></head>
<body>
<iframe id="iframe" src="index.html" ></iframe>
</body>
</html>
index.html:
<html>
<head></head>
<body>
<h1>Inside the sandbox</h1>
</body>
</html>
When I load the options page in this example, I'm getting the error message:
Denying load of chrome-extension://fahdnpkbgfjkocogbjlljfbhnljcehoh/index.html. Resources must be listed in the web_accessible_resources manifest key in order to be loaded by web pages.
I don't think that each sandboxed page is also supposed to be a web_accessible_resources.
But even when I try to define the sandboxed pages also as web_accessible_resources in the manifest file, then the sandboxed page gets loaded but use of new Function inside the iframe is still blocked.
The above described error message occurs on Chrome 20.0.1132.47.
I tested with the dev channel version 21.0.1180.15 and here the sandboxed iframe loads without problems.

Google chrome extension issue: popup.html interferes with script execution in background.html

I am learning how to extend Google chrome and I have run into the following problem:
I have the following manifest file:
{
"name": "My First Extension",
"version": "1.0",
"description": "The first extension that I made.",
"background_page": "background.html",
"browser_action": {
"default_icon": "icon.png",
"popup": "popup.html"
},
"permissions": [
"tabs",
"http://*/*",
"https://*/*"
]
}
My background.html file just injects some simple JavaScript into the page:
<script>
// Called when the user clicks on the browser action.
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.executeScript(null, {code:"alert(\"hi from background CODE\");"});
});
</script>
My popup.html file is just simple HTML:
<body>
Sup Playa
</body>
The dialog box from background.html never gets displayed. popup.html functions as expected.
However when I comment out popup.html from the manifest file, the script in background.html works.
What am I doing wrong? Why aren't both the dialog box and the popup showing up?
As it says in the docs:
onClicked event will not fire if the browser action has a popup.
So if you assign any html file to your popup "popup": "popup.html" (rather than just a button without body), onClicked event isn't fired.
You can just put your code right into popup.html (it has same privileges as a background page) if you want something to be executed each time it is opened:
chrome.tabs.executeScript(null, {code:"alert(\"hi from background CODE\");"});

Resources