launchWebAuthFlow callback does not run, and the Chrome extension window closes immediately? - javascript

I am using chrome.identity.launchWebAuthFlow to retrieve an authentication code from my Rails app which is set up as an OAuth2 provider using the Doorkeeper gem (the Doorkeeper side of things is working).
So I send then request to my server with this method from the Chrome extension:
requestGrant: function(){
chrome.identity.launchWebAuthFlow(
{
'url': authService.grantEndPoint(),
'interactive': true
}, function(redirect_url){
/* Extract auth code from redirect_url */
var code = authService.extractCode(redirect_url);
alert(code);
authService.getAccessToken(code);
}); //launchWebAuthFlow ends here
}
And my server receives the request and redirects to
https://<my_chrome_extension_name>.chromiumapp.org/oauth2?code=<access_code_generated_by_oauth>
with a 302 found.
But, the Chrome extension immediately closes, and the callback function of launchWebAuthFlow does not run. I know it is not running because I call alert() in the callback (doesn't run), and make another request to my server for the access token (server does not receive the request).
I think part of the problem is that the chrome extension might be closing right when launchWebAuthFlow is called, because the window launchWebAuthFlow opens is a web view of the servers authorization flow, and the extension closes (or is the auth flow just being displayed through the extension?)
For some reason launchWebAuthFlow's default behavior is to close the window according the documentation, but the callback still isn't running.
How can I get the callback function to run, and prevent the chrome extension window from closing?

I was running the launchWebAuthFlow in non background script. I moved the auth logic to a background script and it works fine.

I too was experiencing almost the same issue. I was trying to launch the webauthflow from my popup.html but the popup.html would close once the auth flow began, aborting the code that would execute upon succesful return of a token.
My suggestion is to instead take care of authentication in options.html.
(https://developer.chrome.com/extensions/optionsV2)
This will launch a popup modal that stays open even after your auth flow opens, (as opposed to popup.html closing when it loses focus), meaning the rest of your code will execute.
Hope this helps.

Related

XMLHttpRequest is not being made from FIrefox extension

I am trying to communicate currently playing YouTube data with a node.js Express server via a Firefox extension. The extension loads correctly. However, the request simply isn't made. As in, the function to send the request just isn't called. I made sure that code execution continues before and after the function is called. Here is the code I wrote to send the video title to the main server.
const hostname = "localhost:3621";
console.log("Plugin Started");
function sendTitle(title) {
const request = new XMLHttpRequest();
const url = `http://${hostname}/?song=${title}`;
console.log(url);
request.open("GET", url);
request.send(null);
console.log("Request sent");
console.log(request.url);
}
This sendTitle() function is called periodically by another function, that retrieves the name from the web page. This function is called using the setInterval() function, and is called every 5000ms
function getVideoTitle() {
// Get the current video title by reading page elements
// This will be used to report the video information back to the server
var pageItems = document.getElementsByClassName("ytd-video-primary-info-renderer");
var titleObject = pageItems[6];
console.log(titleObject.innerHTML);
sendTitle(encodeURIComponent(titleObject.innerHTML));
}
I have verified that both of these functions are being called.
One other thing I tried was running the code I wrote in the sendTitle() function directly from the console. This worked and the request was sent. I also enabled Access-Control-Allow-Origin on the node.js Express server as this was causing issues.
I have no idea why Firefox seems to simply skip over the request.send() part. No errors are reported, and code execution continues as normal.
I can also open the URL that the script produces in another tab and the request is sent fine. I have verified that this is not a problem with the server or the code I have written. I'm assuming this has something to do with Firefox's privacy configurations.
Please confirm that the request was not denied by tracking protection.
You could click this shield icon as next pic after you try to send a ajax request.
Then you could see if this request has been blocked by Firefox. If so please close this block and try again.

Outlook error: "Add-in still working" when sending message

I've made a simple enough owa addin that, when the user launches it, a dialog window is opened (Office.context.ui.displayDialogAsync) where the user can modify certain aspects of the message (affects recipients and mail headers). As far as i can tell, all the async requests complete nearly instantly when the user closes the dialog and the add-in completes its work, but the error is still triggered when attempting to send.
What seems to be the cause is that when the dialog is opened, owa starts spamming requests every second or so to an address that does not exist, and the error occurs until several minutes later the requests stop in what seems like a timeout of sorts.
My developer console is filled with this;
aria-web-telemetry.js:1 POST
https://browser.pipe.aria.microsoft.com/Collector/3.0/?qsp=true&content-
type=application%2Fbond-compact-binary&client-id=NO_AUTH&sdk-version=AWT-Web-
JS-1.1.1&x-apikey=db334b301e7b474db5e0f02f07c51a47-a1b5bc36-1bbe-482f-a64a-
c2d9cb606706-7439&client-time-epoch-millis=1532959882460 404 (Not Found)
So far google has not found me anything helpful, and i just cannot comprehend why Microsoft would be calling home to an address that doesn't exist.
Sure enough, https://appsforoffice.microsoft.com/lib/1/hosted//ariatelemetry/aria-web-telemetry.js contains that url hardcoded. What can i do?
edit 1)
I'm hosting my own trial windows server on a virtual machine, and using the exchange accounts of that server.
The error occurs on all browsers.
Firefox gives me Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://browser.pipe.aria.microsoft.com/Collector/3.0/?qsp=true&content-type=application%2Fbond-compact-binary&client-id=NO_AUTH&sdk-version=AWT-Web-JS-1.1.1&content-encoding=base64&x-apikey=a387cfcf60114a43a7699f9fbb49289e-9bceb9fe-1c06-460f-96c5-6a0b247358bc-7238&client-time-epoch-millis=1532965578192. (Reason: CORS request did not succeed).
IE does not really give me anything i can pick out
The example above was from chrome
I have not installed it on desktop, so only web so far.
As for code.
My manifest defines an action for a button control
<Action xsi:type="ExecuteFunction">
<FunctionName>showMessageSecurityDialog</FunctionName>
</Action>
that function in turn shows the dialog
Office.context.ui.displayDialogAsync(window.location.origin + dialogPage, { height: 50, width: 75, displayInIframe: true }, dialogCallback);
On the dialog, when the user presses the save button it runs
Office.context.ui.messageParent(true); to signal we're done
from here
dialog = asyncResult.value;
dialog.addEventHandler(
Microsoft.Office.WebExtension.EventType.DialogMessageReceived,
messageHandler
);
dialog.addEventHandler(
Microsoft.Office.WebExtension.EventType.DialogEventReceived,
eventHandler
);
is called, which neatly flows into the message handler
dialog.close();
if (arg.message == true) {
applyMessageSecurity();
}
applyMessageSecurity in turn runs a whole lot of async requests, and when the promises of those requests are resolved, i let the user know with Office.context.mailbox.item.notificationMessages.addAsync("information", {type: "informationalMessage", persistent: false, message: "success"})
afaik we should be done at this point. All the code is done running, the dialog is closed, yet, something in the background is still on causing owa to think the addin is running
Please ensure to call event.completed() after dialog closing or where your code finishes all of its work so that outlook can be notified that the current uiless code has been completed. You can find more details in this article.

Google Javascript Client library OAUTH asks for Offline Access permission, though it was never requested

My application interacts with Google with Javascript only. It asks for user profile access, email access and contacts management permissions.
Upon loading a page, the application checks if the user has already granted those permissions and obtains an access token if he had.
Here is some sample code:
var GoogleContacts = {
...
checkAuth: function(){
gapi.auth.authorize({
client_id: googleKeys.clientId,
scope: googleKeys.scopes,
immediate: true
},
jQuery.proxy(this.handleAuthResult, this)
);
},
askAuth: function(){
gapi.auth.authorize({
client_id: googleKeys.clientId,
scope: googleKeys.scopes,
immediate: false
},
jQuery.proxy(this.handleAuthResult, this)
);
}
...
}
....
function handleGoogleApiLoad(){
gapi.client.setApiKey(googleKeys.apiKey);
gapi.auth.init(function(){console.info('popup api ready')});
setTimeout(function(){GoogleContacts.checkAuth();}, 300);
}
....
$('#emailButton').click(function() {
if(!accessToken)
GoogleContacts.askAuth();
...
});
Now, if user comes for the first time, he is asked the correct permissions when he pressed the "Send email" button. When user reloads a page, the seamless permissions check returns failure and when user hits a "send email" button, we open the Google authorization popup again, and it now asks for Offline Access permission.
This seems incorrect as the JS api has no actual use for offline access.
Looks like this problem started after Google released the incremental auth feature: http://googleplusplatform.blogspot.co.il/2013/12/google-sign-in-improvements11.html
Is this a bug that will soon be fixed, or should we change the code somehow to not confuse our users with weird permission requests?
Update:
I have tried to use the plus api and gapi.auth.signIn() method but with the same result.
Apparently, this problem is scope-dependant, as when I use only the login scope, everything works as expected, but adding the Google Contacts access scope https:||www.google.com/m8/feeds/ always leads to the Offline Access request when entering page second time. Here is a fiddle to confirm this: http://jsfiddle.net/hjLM6/6/
This must be a bug and I really would like Google to deal with it soon, as it scares users away.
The immediate:false parameter in your askAuth method is the cause. The post that Abraham mentions explains the background.
The gapi.auth.authorize() method should generally be avoided in most cases now that the gapi.auth.signIn() method is available to handle programatic initiation of the authorization flow and also you should make use of the dynamic callbacks. The information on monitoring a user's session state explains how and when to get your sign-in callback function to fire and how you can use the values within the auth result object to determine if they've previously authorized your app, signed in (or out) of your app, or signed in (or out) of google.
Your checkAuth and askAuth functions would effectively be combined to check the status of the auth result object and act accordingly. Your email button click event would trigger instead gapi.auth.signIn() with the necessary parameters and scopes for your app.
I just had exactly the same issue with drive.readonly scope, for what it's worth the way I worked around it is by always calling authorize with immediate = false. This isn't that bad because when you do this for an already authorized user, Google will open the popup for a fraction of a second but then will immediately close it (apparently making use of the chance to open the popup in the browser event handler in case the user does need to authorize).
Curiously, for localhost server where I previously used immediate = true, I continue to see requests for offline access - but on the production server I haven't seen seen them so far, fingers crossed.

Domain Authorization in Chrome Extension

There is a demand to make cross domain request to a remote service in chrome extension via ajax.
All works properly while user is authorized on a service before he/she uses the extension. But when an unathorized user makes a request extension fails with 401 error code (unathorized).
My sake is to accomplish browser like appearance. If you aren't authorized on some webpage browser dialog-box appears suggesting you to input your credentials. Since they are correct browser display webpage content.
I've tried to add to extensions HTML layout some invisible element that lies on a service to force browser built-in domain authorization dialog appear, but id doesn't seem to be correct approach.
Long story short, do you know some strategy to force browser built-in authorization from chrome extension or simply via javascript code without redirecting user to some separate service webpage. Or, maybe, this is impossible and why?
Code that makes request is simple:
$.ajax({
url: 'service url that requires authorization',
dataType: 'json',
success: function (info){
//success handler
},
error: function (){
//error handler
}
});
WBR, Vitaliy
I think it is possible to listen to chrome.webRequest.onAuthRequired ( https://developer.chrome.com/trunk/extensions/webRequest.html#event-onAuthRequired). In the event listener, you can prompt the user to enter credentials, say, by showing a custom window that looks like the built-in authorization dialog. onAuthRequired is the only event in chrome.webRequest which supports asynchronized blocking, which allows you to fetch credentials (from the user) asynchronously and pass the response (credentials).
chrome.webRequest.onAuthRequired.addListener(function(details, callback){
// Prompt the user to enter credentials. Call
// callback({authCredentials: {username: xxx, password: xxx}});
// when they are ready.
}, {.../*request filter*/}, ['asyncBlocking']);

JavaScript - Cross Site Scripting - Permission Denied

I have a web application for which I am trying to use Twitter's OAuth functionality. This application has a link that prompts a user for their Twitter credentials. When a user clicks this link, a new window is opened via JavaScript. This window serves as a dialog. This is accomplished like such:
MainPage:
<div id="promptDiv">Provide Credentials</div>
...
function launchDialog(url) {
var specs = "location=0,menubar=0,status=0,titlebar=0,toolbar=0";
var dialogWindow = window.open(url, "dialog", specs, true);
}
When a user clicks the link, they are redirected to Twitter's site from the prompt.aspx page. On the Twitter site, the user has the option to enter their Twitter credentials. When they have provided their credentials, they are redirected back to my site. This is accomplished through a callback url which can be set for applications on Twitter's site.
When the callback happens, the user is redirected to "/twitter/confirm.aspx" on my site in the dialog window. When this happens I want to update the contents of "promptDiv" to say "You have successfully connected with Twitter" to replace the link and close the dialog. This serves the purpose of notifying the user they have successfully completed this step. I can successfully close the dialog window. However, when I am try to update the HTML DOM, I receive an error that says "Error: Permission denied to get property Window.document". In an attempt to update the HTML DOM, I tried using the following script in "/twitter/confirm.aspx":
// Error is thrown on the first line.
var confirmDiv = window.opener.document.getElementById("confirmDiv");
if (confirmDiv != null)
{
// Update the contents
}
window.close();
I then just tried to read the HTML to see if I could even access the DOM via the following script:
alert(window.opener.document.body.innerHTML);
When I attempted this, I still got a "Permission denied" error. I know this has something to do with cross-site scripting. However, I do not know how to resolve it. How do I fix this problem? Am I structuring my application incorrectly? How do I update the HTML DOM after a user has been redirected back to my site?
Thank you for your help!
When the popup opens the Twitter auth page, you are losing your original ability to communicate with the winodw because its document domain has changed and the window.opener has been reset.
To get around this for SitePen's NetFlix Queued, I used a timer and polled the popup window for changes to its location (which you can continue to access). If it went to an error page or a success page, I knew that and could close the popup (you have control of the window, but not the DOM) and change the content in the main page to reflect the status of authorization.
We also checked for the window closing – in the case of the user not authorizing and closing the popup.
We couldn't make use of the callback because this was done in Adobe AIR, and there was no server to "call back to", which created an extra hurdle.

Categories

Resources