Client side JavaScript Google Sign In stopped working in Safari for Mac OS X v.10.15.2 - safari

After upgrading to Mac OS X version 10.15.2 sign in to Google with the google-api-javascript-client library has stopped working for some users in Safari.
The Safari developer console and network tab doesn't really tell me much regarding what the issue is for that specific Safari version.
Example snippet
<script src="https://apis.google.com/js/platform.js" async defer></script>
<meta name="google-signin-client_id" content="REPLACEME.apps.googleusercontent.com">
<div class="g-signin2" data-onsuccess="onSignIn"></div>
<script>
function onSignIn(googleUser) {
var profile = googleUser.getBasicProfile();
console.log('ID: ' + profile.getId()); // Do not send to your backend! Use an ID token instead.
console.log('Name: ' + profile.getName());
console.log('Image URL: ' + profile.getImageUrl());
console.log('Email: ' + profile.getEmail()); // This is null if the 'email' scope is not present.
}
</script>
Documentation: https://developers.google.com/identity/sign-in/web

UPDATE: This specific issue has been resolved with the release of Mac OS X v10.15.3
It seems that with the new update to Mac OS X v10.15.2 with the Safari preference Privacy > Tracking: Prevent cross-site tracking unchecked that sign in with the Google client side JavaScript library is broken.
Though having the Tracking: Prevent cross-site tracking option checked in Safari privacy preferences doesn't make Google Sign In work in Safari Private Windows.
See github issue here:
https://github.com/google/google-api-javascript-client/issues/589
This issue doesn't seem to be limited to the google-api-js-client library: https://www.reddit.com/r/Safari/comments/eaaanh/safari_1304_on_macos_changes_to_prevent_crosssite/

Related

Google One Tap Javascript API/HTML API does not return nonce in JWT in Safari

When Google One Tap is implemented using Javascript API/HTML API including nonce, the returned JWT is missing nonce for Safari browser. Chrome and Fireforx returns the nonce as expected.
Please refer the code used.
const initializeGSI = () => {
google.accounts.id.initialize({
client_id: '132-xxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com',
cancel_on_tap_outside: false,
nonce: '7342364',
callback: onOneTapSignedIn
});
Browser Version
Safari Version 16.1 (18614.2.9.1.12)
Steps
Integrate Google One Tap using Javascript API/HTML API using a nonce.
Sign in via Google One Tap in Safari
Check retuned JWT
Using "itp_support" did not make any change on this.
This behaviour remains same for both Javascript API and HTML API.
When "Prevent cross-site tracking" is disabled at Safari, the nonce returns and works as expected. Safari has this default setting. Any workaround available other than changing the Safari's default behavior?

What is the RIGHT way to access Google websites from within an electron app? [duplicate]

A user of my app reported an issue today about authorizing the user with Google (using OAuth 2.0). So far the application was opening a new BrowserWindow (node integration disabled, session is separated from the main application). You can see the implementation here since the library is OSS. I am using this to authorize the user to access application data on Google Drive.
Today after logging in I see the following message:
This browser or app may not be secure.
Try using a different browser. If you’re already using a supported browser, you can refresh your screen and try again to sign in.
The learn more link has a section for developers. This section has 2 links. One is how to upgrade the application to PWA. Because the application is an API testing tool it won't be possible to run it in a web browser.
The second link points to a document describing how to migrate to authorization for native application. However described flow requires authorization_code grant. This means I need to include OAuth secret into my application. Electron application, however, is still web application and there's no notion of compiling sources. I would expose client secret to the public which is not secured. Potentially I could build a server application to support it but the app is OSS project. It does not have funding to run a server for authorization.
My question is now how should I implement OAuth 2 for Electron application then. I can't use PWA's and server authorization flow (code grant) is far from ideal in this case.
As Paweł explained, changing the user agent will do the trick. However, you can easily set the user agent by passing an object when loading the URL
win = new BrowserWindow({width: 800, height: 600});
win.loadURL(authUrl, {userAgent: 'Chrome'})
I have tested it and it worked like a charm
Warning: This answer relies on changing the browser's user-agent. As of Jan. 2021, Google disapproves of this and warns not to do this (see EDIT4). Use at your own risk!
The other answers didn't work for me (in Electron 9.0.5), but I eventually found this, which worked:
app.on("ready", ()=> {
session.defaultSession.webRequest.onBeforeSendHeaders((details, callback) => {
details.requestHeaders["User-Agent"] = "Chrome";
callback({ cancel: false, requestHeaders: details.requestHeaders });
});
CreateMainWindow(); // your regular code to create root browser window
});
EDIT: Two other approaches, which I haven't tested, but which may also work:
app.on("ready", ()=>{
session.defaultSession.setUserAgent("Chrome");
...
}
app.userAgentFallback = "Chrome";
EDIT2: Trying again sometime later, approach #2 did not work, but #1 still did. Haven't tried #3 yet.
EDIT3: Trying again later still, it seems that none of these workarounds are needed anymore! Google appears to accept sign-in popups from Electron apps again, without modifications to the user-agent. (odd that they'd revert this; perhaps I just did something wrong in my re-attempt)
EDIT4: While approach #1 still works atm, I recently found this blog post: https://developers.googleblog.com/2020/08/guidance-for-our-effort-to-block-less-secure-browser-and-apps.html Apparently Google is restricting usage of Google sign-in in non-standard browsers (which presumably includes Electron) starting in Jan. 2021, and warns developers not to modify their browser's user-agent (which all three of the possibilities I mention do). Use at your own risk! (they don't make clear what outcome will result, but for my own use, I'm opting to use the alternative shown below from now on)
As an alternative to using a Google sign-in popup in your app (which some might be wary of, since Electron apps could in principle insert code into the popup to read the raw password -- not that it matters that much, since Electron apps could just install keyloggers or the like anyway), you could instead open a tab in the user's regular external browser, pointed to a special page that triggers a sign-in popup there, and then just sends the credentials to your Electron app afterward.
Instructions can be seen here (approach 3): https://stackoverflow.com/a/64328193/2441655
After taking a wild guess I decided to alter the user agent string and to remove application name from it as well as Electron/ with version. After this alteration it started working again.
Example implementation:
const win = new BrowserWindow(params);
let ua = win.webContents.userAgent;
ua = ua.replace(/APPLICATION NAME HERE\/[0-9\.-]*/,'');
ua = ua.replace(/Electron\/*/,'');
win.webContents.userAgent = ua;
This assumes the application is using symver and no pre-release tags. Otherwise you would have to tweak the regexp a bit.

onAuthRequired triggering only once in Chrome version > 72

In our project we are using Selenium to test our Angular Web Application using a docker image and chrome with version 70.0.3538.77 (Official Build) (64-bit). Since the application uses basic authentication on our servers we created our own extension to listen to "onAuthRequired" and whenever this happens we return the username and password (Original Source).
A simple test for our application would be to navigate to the main page (basic auth login required with the popup window) and then to another subpage that is hosted inside of this page in an iframe where the basic authentication is required again.
We added some logging to the extension just to check whether the onAuthRequired gets triggered so the extension currently looks like this:
​if (!chrome.webRequest.onAuthRequired.hasListener(retrieveCredentials)) {
chrome.webRequest.onAuthRequired.addListener(
retrieveCredentials,
{urls: ["<all_urls>"]},
['blocking']
);
}
function retrieveCredentials(details) {
console.log("onAuthRequired");
return {
authCredentials: {
username: username,
password: password
}
};
}
What we found out is that with the Version 72.0.3626 this was still working. The extension would fill out both of the login prompts that occur and we would see two messages with "onAuthRequired" in the console.
However with the Version 73.0.3683 and newer, this seems to not work anymore. Only one time the onAuthRequired (retrieveCredentials-Method) is called and the second popup gets ignored by the extension. This lets the Selenium tests fail with a timeout exception since the navigation doesn't work anymore.
Does anyone know how to handle this in the newer Versions of Chrome or sees a mistake that we made in our extension?
Any help appreciated

Javascript code to Register SIP endpoint from browser

I just want to Register a SIP or PJSIP endpoint of asterisk from browser. I know some libraries which can do this for me.
But I want to know the core code in javascript to register a SIP end point.
It is done like below in jssip.js library
var socket = new JsSIP.WebSocketInterface('wss://' + domain + ':8089/ws')
var configuration = {
sockets: [socket],
uri: 'sip:'+ localUser.value +'#' + domain,
authorization_user: localUser.value,
password: '123456'
}
ua = new JsSIP.UA(configuration)
ua.start()
But in pure/core/plain javascript how will the same be done.
In "Pure Javascript" you have do all what implemented in pjsip library. You can check source code.
You also can use WebRTC code, it slightly less required JS code, but still tens of KB.

Login to Facebook Connect using JavaScript SDK freezes in Opera?

I have a Facebook Connect site under development. The login works great on Firefox, IE, Safari and Chrome. But when I test it using Opera (using the latest version = 11) I run into problems.
I get to the point where I get the login form pop-up, fill it in with my email and password and click the login button. After that the login window becomes empty and the window title says "XD Proxy".
I am using the Facebook Connect JavaScript SDK and there are some iFrames (displayed in the jQuery lightbox-style plugin "ColorBox") in my solution.
Do you know if there are problems with Opera and Facebook Connect, or if there's something in my code that causes this? As I said, the solution has been tested in all the other major browsers and work fine there.
Thanks in advance!
/Thomas
PS. On the development server I'm running the site on port number 8585. I've seen some posts on the net saying this can cause problems.
Facebook connect currently fails because Facebook's scripts "detect" Internet Explorer by checking if the attachEvent method is supported. Unfortunately, Opera supports this method (historically for compatibility with other sites that needed it). Now, if they only did this: https://github.com/facebook/connect-js/pull/240 ..
This broken pseudo-browser-detection causes the problem because Facebook happens to use some IE code that Opera does not support to embed Flash for cross-document messaging in the Flash-based part of the script, while the alternate window.postMessage() part of the script has other problems as described here: http://my.opera.com/hallvors/blog/2010/07/20/postmessage-s-targetorigin-and-security
I have found a solution that seems to work! If I add a channelUrl option to FB.init, I can log in. I got a warning from Opera saying the following:
Warning
http://www.yourdomain.com/channel.html?fb_xd_fragment
A page on the public Internet requests
data from your private intranet. For
security reasons, automatic access is
blocked, but you may choose to
continue.
LINK: Continue
LINK: Always continue when data is
requested from this server on my
private intranet
I clicked the link "Continue" and after that it worked (during this session). The original FB.init line looked like this (appId and some other stuff has been replaced in this example):
// Facebook init
FB.init({ appId: '123456789', status: true, cookie: true, xfbml: true });
After I had added the channelUrl it looked like this:
// Facebook init
FB.init({ appId: '123456789', status: true, cookie: true, xfbml: true, channelUrl: "http://www.yourdomain.com/channel.html" });
The file "channel.html" is a simple file that contains just this line of code:
<script src="http://connect.facebook.net/en_EN/all.js"></script>
Create it and put it on your server at the location you have specified in the channelUrl. The server root is a good place.
The next step is figuring out how to get rid of the Opera warning, if it's possible at all?
Good luck!
/Thomas Kahn
To fix it in Opera, just add the following after FB.init():
if($.browser.opera ) // it uses jQuery library here!
{
FB.XD._transport="postmessage";
FB.XD.PostMessage.init();
}
This channel.html dont work for me
<script src="http://connect.facebook.net/en_EN/all.js"></script>
but when I change it to:
<script src="http://connect.facebook.net/en_GB/all.js"></script>
it works. In this url is not valid content http://connect.facebook.net/en_EN/all.js there is something wr go to this instead http://connect.facebook.net/en_GB/all.js