Google Sign-In gives error when swiching to secondary Youtube accounts - google-api

I am currently trying to use gapi.auth2 from Google Sign-In for Websites API and this is the code I have:
-- load the library with:
<script src="https://apis.google.com/js/platform.js?onload=onLoadGapiCallback" async defer></script>
-- initialize an auth2 variable:
var auth2;
window.onLoadGapiCallback = () => {
gapi.load('auth2', () => {
auth2 = gapi.auth2.init({
'client_id': 'CLIENT_ID',
'scope': 'profile email https://www.googleapis.com/auth/youtube.readonly'
});
});
};
-- and when a botton is clicked do:
auth2.signIn().then(() => {
console.log('auth is:', auth2.currentUser.get().getAuthResponse().access_token);
});
This works well, it initializes the auth2 variable, when I click the button, it shows the SingIn prompt and I choose one of my Google Accounts. The problem is from now on when I have to choose a YouTube account, if I choose other account than the main one, I'll get an Exception Object like this one:
{type: "tokenFailed", idpId: "google", error: "USER_LOGGED_OUT"}
also there's an XHR request being sent lastly that has this response:
{"error":"USER_LOGGED_OUT","detail":"No active session found."}
So it only works if I choose the main account, but I cannot choose other YouTube accounts.
What am I missing here?
I've looked into all these docs but none helped me:
Getting profile information
Google Sign-In JavaScript client reference
Monitoring the user's session state
Update:
Running the code from this example (but with this scope: 'profile email https://www.googleapis.com/auth/youtube.readonly') will only work if I choose the first Youtube account for each Google account. If I choose any other Youtube account, I'll get this alert error:

Related

Sending a JWT through Direct-line API to authenticate the user, in Microsoft chat bot

I need to send a JWt (access token) to the chatbot via directline. I'm using react as the front end, and the chatbot is integrated into the front end via botframework-webchat.
So far, I was able to send the access token through an activity, which is not recommended as I think.
Right now, the chatbot is asking the user to log in, which is not good because the user is already logged in to the application.
My first question - Is it possible to authenticate the chatbot by an id token instead of connecting with Azure AD, B2C, or any auth service provider?
If it is possible, How can I send the id token to the bot, via botframework-webchat
Thanks in advance
Here is my code for the front end
const Chatbot = (props) => {
const language = localStorage.getItem('language');
const directLine = useMemo(
() => createDirectLine({ token: <my_token>, locale: 'sv-se' }),
[]
);
useEffect(() => {
var activity = {
from: {
id: '001',
name: 'noviral',
},
name: 'startConversation',
type: 'event',
value: 'Hi noviral!',
locale: language === 'en' ? 'en-US' : 'sv-se',
};
directLine.postActivity(activity).subscribe(function (id) {
if (console) {
console.log('welcome message sent to health bot');
}
});
}, []);
return (
<Layout className="login-layout">
<div className="login-div">
<div className="chatbot">
<div className="consent-wrapper">
<ReactWebChat
directLine={directLine}
userID={'001'}
username="Noviral"
locale={language === 'en' ? 'en-US' : 'sv-se'}
></ReactWebChat>
</div>
</div>
</div>
</Layout>
);
};
export default withTranslation()(Chatbot);
Sending the token via an activity is acceptable as activities sent via Direct Line are secure. If you look over the 24.bot-authentication-msgraph sample, you can see that the default action the bot takes is to send an activity displaying the user's token.
As for authentication, the question doesn't seem to be what token you will use but rather how you will authenticate. If you don't use a service provider + login, how is the bot going to verify who the user is? That being said, there are some SSO (single sign-on) options available via Web Chat (see here) that, if a user is already logged in, then SSO could pick it up. You will have to look them over to decide if these options meet your needs.

grantOfflineAccess is not working with scope

I am using google API's in my angular 8 website. I have to integrate Google Drive and YouTube account on different buttons.
YouTube Connect button
Google Drive Connect button
I init gapi as
initGoogleAccounts() {
gapi.load('auth2', () => {
this.googleUser = gapi.auth2.init({
client_id: this.env.google_client_id,
fetch_basic_profile: false,
scope: 'profile'
});
});
}
On Youtube button click
this.googleUser.grantOfflineAccess('https://www.googleapis.com/auth/youtube.force-ssl').then(({code}) => {
this.youtubeCodeConnect(code);
});
But this is not asking for Youtube permissions.
Is there anything which i am doing wrong?

Single sign on in Teams application between tabs and the bot

Using the Bot Framework w/ Microsoft.Bot.Builder v4.6.3
Is it possible to have users sign in only once using the web-based authentication flow, doesn't matter if they sign in via tabs or via bot conversation? If they sign in via a link from a tab, I'd like to have the bot know about this.
I have tried the following for test, omitting any security checks:
All pages are with the following js files imported:
https://statics.teams.microsoft.com/sdk/v1.4.2/js/MicrosoftTeams.min.js
https://cdnjs.cloudflare.com/ajax/libs/oidc-client/1.9.1/oidc-client.min.js
On load, the tab page executes microsoftTeams.initialize();
Add a button to the tab page:
<button onclick="authenticate()">Authenticate</button>
The authenticate function contains the following:
function authenticate() {
microsoftTeams.authentication.authenticate({
url: window.location.origin + "/tabs/tabAuthStart",
width: 600,
height: 535,
successCallback: function (result) {
// The debug function just displays what's sent to it using document.write()
debug(result);
},
failureCallback: function (reason) {
debug(reason);
}
});
}
The tabAuthStart page contains the following script which is executed on page load:
microsoftTeams.initialize();
const mgr = new Oidc.UserManager({
userStore: new Oidc.WebStorageStateStore(),
authority: '<my-identity-server>',
client_id: '<my-id-srv-client>',
redirect_uri: window.location.origin + '/tabs/tabAuthCallback',
response_type: 'id_token token',
scope: '<my-requested-scopes>',
accessTokenExpiringNotificationTime: 10,
automaticSilentRenew: true,
filterProtocolClaims: true,
loadUserInfo: true
});
mgr.signinRedirect();
After a successful sign in at the identity provider, I'm redirected back to /tabs/tabAuthCallback
On load, the /tabs/tabAuthCallback executes the following code:
microsoftTeams.initialize();
var mgr = new Oidc.UserManager({ userStore: new Oidc.WebStorageStateStore(), loadUserInfo: true, filterProtocolClaims: true });
mgr.signinRedirectCallback().then(function (user) {
// I expected something involving a bot to happen after calling this
microsoftTeams.authentication.notifySuccess({
idToken: user.id_token,
accessToken: user.access_token,
tokenType: user.token_type,
expiresIn: user.expires_at
})
}).catch(function (err) {
microsoftTeams.authentication.notifyFailure("UnexpectedFailure: " + err);
});
The pop-up window is closed and the successCallback function from the tab is executed successfully with the user information that I have sent. However, the bot is not in any way notified about this (as far as I know). I have set a breakpoint in the bot controller action resolved by POST /api/messages but it's never hit.
Do I need to handle this manually? I.e. pass the user info to the back-end? But even if so, how do I know which Teams user to associate this user info (i.e. access token) to?
If this is possible to do in a reliable and secure way, would it also be possible in the opposite direction, i.e. having the user token available to the tab if they have already been authenticated from a bot conversation or a messaging extension? Is there a reliable way to identify a Teams user who's navigating tabs, in order to obtain their access token from the back-end, assuming the back-end already obtained them via the authentication mechanism?

Migrating Google Sign-In auth2 (browser popup) away from Google+ API

In our app, we have a simple Google-Sign-In flow where a popup opens, users log in and grant us offline permission for accessing Google Analytics.
We just got emailed that we're using a Google+ API (plus.people.getOpenIdConnect method) that is about to get deprecated, but we don't use it in our code.
I can't seem to figure out where we are using Google+ API so I could replace it.
Here is our simple code:
prepareGoogleClient() {
$.ajax({
url: "//apis.google.com/js/client:platform.js",
dataType: "script"
}).done(() => {
gapi.load("auth2", () => {
let auth = gapi.auth2.init({
client_id: ENV.googleClientId,
scope:
"https://www.googleapis.com/auth/analytics.readonly https://www.googleapis.com/auth/webmasters.readonly"
});
this.auth = auth;
});
if (gapi.auth2 && !this.auth) {
this.auth = gapi.auth2.getAuthInstance();
}
});
}
Later on we call this.auth.grantOfflineAccess(params), which returns the token that we save for later.
If I disable Google+ API in our Google Platform dashboard, the Sign-In stops working and the popup responds with a sign-in error. I was also able to confirm that Google+ API (from its metrics panel) is indeed used in the process of our users signing in the popup and granting scope permissions.
How do I need to rewrite this so it won't use the deprecated plus.people.getOpenIdConnect method?
The issue was in Rails back-end code which handles OAuth2. The outdated omniauth-google-oauth2 gem was using the deprecated Google+ endpoint.
I think everyone using Google+ API's in their app, have got that mail.
Don't know if this helps but got this is from google API's site.
The Google+ Sign-in feature has been fully depreciated and will also
be shut down on March 7, 2019. Developers should migrate to the more
comprehensive Google Sign-in authentication system.
https://developers.google.com/+/web/api/javascript
https://developers.google.com/+/integrations-shutdown
Other References:
List of API's to be removed https://developers.google.com/+/api-shutdown
New Sign(identity) https://developers.google.com/identity/
Identity for web app https://developers.google.com/identity/sign-in/web/
Add Google Sign-In to Your Web App
function onSignIn(googleUser) {
// Useful data for your client-side scripts:
var profile=googleUser.getBasicProfile();
console.log("ID: " + profile.getId()); // Don't send this directly to your server!
console.log('Full Name: ' + profile.getName());
console.log('Given Name: ' + profile.getGivenName());
console.log('Family Name: ' + profile.getFamilyName());
console.log("Image URL: " + profile.getImageUrl());
console.log("Email: "+profile.getEmail());
// The ID token you need to pass to your backend:
var id_token=googleUser.getAuthResponse().id_token;
console.log("ID Token: "+id_token);
}
<html lang="en">
<head>
<meta name="google-signin-scope" content="profile email">
<meta name="google-signin-client_id" content="YOUR_CLIENT_ID.apps.googleusercontent.com">
<script src="https://apis.google.com/js/platform.js" async defer></script>
</head>
<body>
<div class="g-signin2" data-onsuccess="onSignIn" data-theme="dark"></div>
</body>
</html>

Google login oauth integration doesn't work in Windows PWA app

I have developed a PWA application with google and microsoft oauth login integration.Now I want the PWA application to run as windows PWA app in windows mobile and desktop applications, so I tried registering the app using AppX as stated in the following link, https://blogs.windows.com/msedgedev/2018/02/06/welcoming-progressive-web-apps-edge-windows-10/#R6xvoOyZeLza5oGW.97
and ran the application in development mode using PowerShell in windows 10 OS version, the microsoft login works great, However when I try to login using google the application starts loading and exits after some time.[the popup to show the login window also doesn't come up].
Could anyone throw a light on what's happening ?.I researched but I couldn't get any solutions.
Edit
The following API is used for login with google, in the client[react]
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: constant.CLIENT_ID,
cookie_policy: 'single_host_origin',
scope: constant.SCOPE,
});
});
loginWithGoogle = () => {
const options = {
scope: constant.SCOPE,
};
options.prompt = 'select_account';
this.provider = 'google';
this.auth2.grantOfflineAccess(options).then((data) => {
this.loginUser(data.code);
});
}
Maybe is because your browser´s popup blocker, anyway you could use redirection instead popup mode, using ux_mode option (you have to configure the redirection url on OAuth 2.0 client IDs options)
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
ux_mode: 'redirect',
client_id: constant.CLIENT_ID,
cookie_policy: 'single_host_origin',
scope: constant.SCOPE,
});
});

Resources