Force google account chooser - google-oauth

Is there is a way I can force the google account chooser to appear even if the user is logged in just with one account.
I have tried by redirecting to this URL:
https://accounts.google.com/AccountChooser?service=lso&continue=[authorizeurl]
and it seems to work, but I don't know if there are any other conditions in which it might fail.

The following parameter is supported in OAuth2 authorization URLs:
prompt
Currently it can have values none, select_account, and consent.
none: Will cause Google to not show any UI, and therefore fail if user needs to login, or select an account in case of multi-login, or consent if first approval. It can be run in an invisible i-frame to obtain a token from previously authorized users before you decide, for instance, to render an authorization button.
consent: Will force the approval page to be displayed even if the user has previously authorized your application. May be useful in a few corner cases, for instance if you lost the refresh_token for the user, as Google only issues refresh_tokens on explicit consent action.
select_account: Will cause the account selector to display, even if there's a single logged-in user, just as you asked.
select_account can be combined with consent, as in:
prompt=select_account consent

Also, you can add "prompt" parameter in HTML tags as data-prompt="select_account":
<div class="g-signin2" data-onsuccess="onSignIn" data-prompt="select_account">
and it will force account chooser every time, even if you are logged in with only one account

Some people may end up here looking for an answer about how to do this in Microsoft.AspNetCore.Authentication.
We were able to accomplish it via the following code in the Startup.ConfigureServices method:
services.AddAuthentication()
.AddGoogle(options =>
{
options.ClientId = configHelper.GoogleOAuthClientID;
options.ClientSecret = configHelper.GoogleOAuthSecret;
options.CallbackPath = "/signin-google";
options.AuthorizationEndpoint = string.Concat(options.AuthorizationEndpoint, "?prompt=select_account");
});

If you are using gapi than just add prompt: 'select_account'
Example:
gapi.load('auth2', function () {
gapi.auth2.init({
client_id: "client_id.apps.googleusercontent.com",
scope: "profile email", // this isn't required
ux_mode: 'redirect',
redirect_uri: 'https://www.example.com',
prompt: 'select_account'
}).then(function (auth2) {
console.log("signed in: " + auth2.isSignedIn.get());
x = auth2.isSignedIn.get();
auth2.isSignedIn.listen(onSignIn);
var button = document.querySelector('#signInButton');
button.addEventListener('click', function () {
auth2.signIn();
});
});
});

For google api php client (https://github.com/google/google-api-php-client) you manage to do that as following:
$client = new Google_Client();
$client->setApprovalPrompt("force");
$client->createAuthUrl();

Related

Cognito unable to signup users that have unconfirmed status already

A Cognito User Pool is configured for the users to use their "email address" to sign up and sign in.
If a user signs up with the email of someone else then that email will get stuck in UNCONFIRMED state and the owner will not be able to use it appropriately.
Having said that let me provide an example with the following scenario:
User signs in with an email address the user doesn't own, let's say it is someone#mail.com. In this step (registration form) some more data is sent like organization name, and user full name.
Verification code is sent to the email
Now the user that owns someone#email.com wants to create an account (maybe some days in the future), so he goes and fills the registration form but an error is thrown by cognito {"__type":"UsernameExistsException","message":"An account with the given email already exists."}
Thinks to consider:
* If the email already exists but is in unconfirmed state then provide the user the option to resend the link. This option is not optimal because additional data might be already in the user profile as the 1st step exemplifies.
* A custom lambda can be done to delete the unconfirmed user before signup or as a maintenance process every day, but I am not sure if this is the best approach.
There is also this configuration under Policies in cognito consol: "How quickly should user accounts created by administrators expire if not used?", but as he name implies this setting will only apply to users if they are invited by admins.
Is there a proper solution for this predicament?
Amazon Cognito has provided pre-signup triggers for these functionality and auto signup also.Your thought is the same way as i have implemented that according to the cognito documentations.
Here I am using the amplify/cli which is the toolchain for my development purpose hence the lambda function used in the trigger is as below:
`
"use strict";
console.log("Loading function");
var AWS = require("aws-sdk"),
uuid = require("uuid");
var cognitoIdentityServiceProvider = new AWS.CognitoIdentityServiceProvider();
exports.handler = (event, context, callback) => {
const modifiedEvent = event;
// check that we're acting on the right trigger
if (event.triggerSource === "PreSignUp_SignUp") {
var params = {
UserPoolId: event.userPoolId,
Username: event.userName
};
cognitoIdentityServiceProvider.adminGetUser(params, function(err, data) {
if (err) {
console.log(err, err.stack);
} // an error occurred
else {
console.log("cognito service", data);
if (data.UserStatus == "UNCONFIRMED") {
cognitoIdentityServiceProvider.adminDeleteUser(params, function(
err,
data
) {
if (err) console.log(err, err.stack);
// an error occurred
else console.log("Unconfirmed user delete successful ");
// successful response
});
}
// successful response
}
});
return;
}
// Throw an error if invoked from the wrong trigger
callback('Misconfigured Cognito Trigger '+ event.triggerSource);
};
`
this will actually check and delete if the status is UNCONFIRMED using the aws-sdk methods adminGetUser and adminDeleteUser
hope this will help ;)
I got around this by setting ForceAliasCreation=True. This would allow the real email owner to confirm their account. The draw back is that you end up with 2 users. One CONFIRMED user and another UNCONFIRMED user.
To clean this up, I have a lambda function that calls list-users with filter for unconfirmed user and delete the accounts which were created before a certain period. This function is triggered daily by CloudWatch.
change to confirm from unconfirm:
aws cognito-idp admin-confirm-sign-up \
--user-pool-id %aws_user_pools_web_client_id% \
--username %email_address%

auth0 - email verification - user account does not exist or verification code is invalid

Here is my problem : In auth0 dashboard, I select a user within my users list and click on send a verification email... The user receive the mail, click on the link and get an error "User account doesn't exist or verification code is invalid" But the user exists and I do not use passwordless or sms authentication , my users have to enter their password and are also stored in mongodb. Any ideas to solve this?
-- edited precision added --
#Arcseldon
I'am actually using a customDB and here is my getUser script, but I don't know what to change, could you help me?
Thank you!
function getByEmail (email, callback) {
mongo('mongodb://user:pass#dsXXXX.mlab.com:XXXX/base', function (db) {
var users = db.collection('user');
users.findOne({ email: email }, function (err, user) {
if (err) return callback(new Error("my error message"));
if (!user) return callback(null);
var profile = {
user_id: user._id,
nickname: user.username,
email: user.email,
};
callback(null, profile);
});
});
}
Ok, just re-read your question - where you state "my users have to enter their password and are also stored in mongodb." - are you referring to your own Mongo DB? Are you using an Auth0 Custom DB Connection? Confusingly, Auth0 also uses MongoDB for its own DB storage, hence the clarification. If you are using a Custom DB connection to your own DB, then this may be a misconfiguration of one of your Custom DB Scripts. If using Custom DB Script, please double-check the implementation of your GetUser.js script.
In the event, you are using an Auth0 DB (not a custom DB) then definitely check with Auth0 support team (as per comment and your reply above).

How to get all users by project on Youtrack rest api?

I can't get users by project or by filter on YouTrack REST API;
I wrote the following code:
var login = "mylogin";
var password = "mypassword";
(async function getAllUserByProject(login, password, project) {
var url = ``https://mycompany.myjetbrains.com/hub/api/rest/users?`;
return new Promise((done, fail)=> {
request.get({
url, auth: {user: login, pass: password, sendImmediately: true}
}, (error, body, result)=> {
if (error || !result) {
return fail({
error: JSON.parse(error), result: result ? JSON.parse(result) : null
})
}
console.log(result)
done(JSON.parse(result));
})
})
}
)(login, password, project);
Old question but:
users by project
Use /rest/admin/user?project=<PROJECT_ID>. I tested this on v2017.3 and it works.
Reference: https://www.jetbrains.com/help/youtrack/standalone/GET-Users.html
by filter
As seen in the documentation, the resource url takes the form of /rest/admin/user?{q}&{group}&{role}&{project}&{permission}&{onlineOnly}&{start} where:
q can be part of user login, name, or email
group is the user's groupID
role is the users's role
project see above
permission is one of the user's permissions
onlineOnly get only users which are currently online
start for pagination (page size fixed at 10)
As of YouTrack 2018.3, the old REST API is becoming deprecated in favor of one that allows much more elaborate queries.
With the new API, you can use /hub/api/rest/projectteams/?$top=-1&fields=id to get the full list of ids of all project teams, and, for each of those, /hub/api/rest/projectteams/{project id}/users to get the list of users in a given project team.

Google + sign in with laravel

I have been struggling a lot for G+ sign-in with laravel, I have downloaded the php-sdk using composer. I am also using JavaScript to sign-in, once the once the user signs in I redirect him to a route from JavaScript to /gLogin?email=abc#gmail.com&name=John Doe where I have following code.
$user_profile['email']=Input::get('email');
$user_profile['name']=Input::get('name');
$user_id=DB::table('users') -> where('dyp_user_email', $user_profile['email'])-> pluck('dyp_user_id');
if($user_id)
{
$user_to_be_logged_in=new user();
$user_to_be_logged_in = User::find($user_id);
}
else
{
$password=$token = str_random(16);
$hash=Hash::make($password);
$user_to_be_logged_in = user::create(array('dyp_user_type' => 'IN', 'dyp_name' => $user_profile['name'], 'dyp_user_email' => $user_profile['email'], 'dyp_mobile_number' => '','dyp_password'=> $hash,'dyp_user_status' => 'VF'));
$data = array('name' => $user_to_be_logged_in -> dyp_name, 'password' => $password);
Mail::send('emails.fbUserRegistration', $data, function($message) use ($user_to_be_logged_in) {
$message -> to($user_to_be_logged_in->dyp_user_email, $user_to_be_logged_in->dyp_name) -> subject('Thanks for registering with dreamyourproperty.com');
});
}
Auth::login($user_to_be_logged_in);
There is a serious security problem here, that I am not able to validate the user's session.
I someone manually hits the url /gLoin?email=abc#gmail.com&name=xyz then also my code will authenticate him.
In comparison to G+ signin FB login was pretty simple.Can someone provide me guidance, I am seriously stuck with this part.
They way you want to handle this is /gLogin?access_token=xyz where xyz is the users Google+ access_token. Make a request to people.get authenticated with that access token. That way you have server side validation the current user is validated for the specific Google+ profile.

Google Auth2.0 log out

I'm currently trying to make a site where the user can log in with his google+ account. Most of it is working. I get them to grant access to my website. They can log in and I get their name and user ID, and I show content specific to their google account on my site.
When however someone else wants to log in and I try to 'log out' of the site, the google log in still remembers that it just logged in and after logging out it instantly runs the code to log in again. If I delete the SSID cookie from google it doesn't do this, so I'm assuming that's where google stores the fact that I just logged in with x.
Is there a way to when I log out make google not instantly log in with the same account, but rather ask for the e-mail and password of a google user?
I feel like I'm missing something obvious here, but I can't figure out how to deal with this.
Code I use to Auth and get data:
<button class ="btn btn-primary" id="authorize-button" style="visibility: hidden">Log in</button>
<script>
var clientId = '';
var apiKey = '';
var scopes = '';
function handleClientLoad() {
gapi.client.setApiKey(apiKey);
window.setTimeout(checkAuth,1);
}
function checkAuth() {
//alert("authorize");
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true}, handleAuthResult);
}
function handleAuthResult(authResult) {
//alert("authorized");
//alert(authResult.access_token);
var authorizeButton = document.getElementById('authorize-button');
if (authResult && !authResult.error) {
authorizeButton.style.visibility = 'hidden';
makeApiCall();
} else {
authorizeButton.style.visibility = '';
authorizeButton.onclick = handleAuthClick;
}
var token = document.createElement('h4');
token.appendChild(document.createTextNode(authResult.access_token));
document.getElementById('content').appendChild(token);
}
function handleAuthClick(event) {
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: false}, handleAuthResult);
return false;
}
var x;
function makeApiCall() {
//return;
gapi.client.load('plus', 'v1', function() {
var request = gapi.client.plus.people.get({
'userId': 'me'
});
request.execute(function(resp) {
x = resp.id;
var heading2 = document.createElement('h4');
var heading3 = document.createElement('h4');
heading3.appendChild(document.createTextNode(resp.displayName));
heading2.appendChild(document.createTextNode(resp.id));
document.getElementById('content2').appendChild(heading2);
document.getElementById('content3').appendChild(heading3);
$.post("token.php", {id: x});
});
});
}
When you make the auth call, set approvalprompt to force. This will force the consent dialog to appear every time. It overrides the default setting of "auto." You can learn more at https://developers.google.com/+/web/signin/#sign-in_button_attributes.
gapi.auth.authorize({client_id: clientId, scope: scopes, immediate: true, approvalprompt: force}
After the user authorizes your app, they are basically logged in to your app any time that they are also logged in to Google, especially when immediate mode is turned on.
What some sites do is have a logout link or button that displays a page or dialog that says something along the lines of "You're logged in to Google and this site with account blah#blah.com. If you want to switch accounts, go to google.com and log out of your Google session."
You can also track the logged in status of a user using your own cookies and setting and removing them during the appropriate events in your code. You would want to discard any tokens that your app obtained on behalf of the user during a log out event. When the user logged in again, they would not need to re-authorize your application with the popup (or redirect window), but you'd still get a new access token during the callback.