AWS Cognito - How do I resend an email confirmation code? - amazon-cognito

What happens when an email confirmation code expires? From documentation, it expires after 24hrs. What if the user lost the code somehow, can I let users resend the codes for themselves?

For flutter, simply do this:
var response = await Amplify.Auth.resendSignUpCode(username: username);

As pointed out by #Nghia Do in the comments above, you can use Auth.resendSignup(username) if you are using Amplify.

Related

GetUserAttributeVerificationCode in AWS Cognito without AccessToken

In AWS Cognito, I want to allow the user to login only after confirming both phone number and email. Is there any way similar to GetUserAttributeVerificationCode API call where I can get the code without requiring the AccessToken from the user ?
I am on similar situation where I want to send verification code through lambda. I tried post authentication lambda trigger to check if we get accesstoken but no luck(which is a good thing from security point of view)
So, unfortunately, there is no AdminGetUserAttributeVerificationCode or any other method that lets you send verification code to a user without access token. The idea behind that seems to be that only the logged in user should be able to send verification code to himself and not to anyone else.
May be this restriction is to prevent anyone(including AWS) to send mass verification codes to public without their consent (spamming).

How to handle expired auth tokens in Xamarin MobileServiceClient?

I am using client-flow authentication in Xamarin.Forms and am trying to figure out how to handle when an authentication token expires.
My Code:
Upon initial login, the user logs in with the native Facebook SDK and I pass the access_token to MobileServiceClient to get back an authenticated user.
var user = await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token).ConfigureAwait(false);
I then save the user's UserId and MobileServiceAuthenticationToken in local settings (using the Xam.Plugins.Settings plugin).
The next time the user opens the app, I set the user from settings and skip manual login:
if (!string.IsNullOrWhiteSpace(Settings.AuthToken) && !string.IsNullOrWhiteSpace(Settings.UserId))
{
client.CurrentUser = new MobileServiceUser(Settings.UserId);
client.CurrentUser.MobileServiceAuthenticationToken = Settings.AuthToken;
}
My Question:
This works great. However, I know that the MobileServiceAuthenticationToken has an expiration on it. What will happen in my app when the expiration date is reached? How do I refresh the token without requiring the user to re-log-in to Facebook? I have tried the MobileServiceClient's RefreshUserAsync() method, but I get the following exception:
Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException: Refresh failed with a 400 Bad Request error. The identity provider does not support refresh, or the user is not logged in with sufficient permission.
Is there a way to test this? (since the token expiration is 3 months from now.) Thanks for the help!
Microsoft.WindowsAzure.MobileServices.MobileServiceInvalidOperationException: Refresh failed with a 400 Bad Request error. The identity provider does not support refresh, or the user is not logged in with sufficient permission.
Since you are using client-flow authentication, you could not use RefreshUserAsync() for refreshing the MobileServiceAuthenticationToken. Your mobile backend does not cache the related access_token and refresh_token for renewing the authentication Token.
Is there a way to test this? (since the token expiration is 3 months from now.) Thanks for the help!
AFAIK, the MobileServiceAuthenticationToken expiration is one hour by default, you could use https://jwt.io/ to decode your token and check the exp property, then use https://www.epochconverter.com/ to convert your timestamp to human date.
For your requirement, you could follow adrian hall's blog about Caching Tokens and refer to the IsTokenExpired method for decode your authenticationToken and check the exp, then manually renew the authenticationToken.
Per my understanding, there are two approaches for you to achieve your purpose:
You need to cache the facebook access_token in your mobile client side, after you manually checked the authenticationToken and found that it expired, then you could manually execute the following code for renewing the token and explicitly update your local cache.
var user = await client.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token).ConfigureAwait(false);
Note: Your facebook access_token has the Expiration Date, so if your access_token expired, then you need to force the user to log into Facebook again before acquiring the new authenticationToken.
Or you could build your custom endpoint for refreshing the authenticationToken and explicitly set a long lifetime for your new authenticationToken, details you could follow this similar issue. Note: For your client-side expiration processing, you need to renew the token before your local authenticationToken is about to expire.

What is the first parameter for Firebase.Auth.GoogleAuthProvider.GetCredential?

The new Firebase for Unity support has just been released into Beta and I am trying to implement Auth with it. I already have a Google sign-in that implements the oauth2 flow using an auth code from GooglePlayGames.PlayGamesPlatform.Instance.GetServerAuthCode and sending it to a server that exchanges it for an access token using the https://www.googleapis.com/oauth2/v4/token endpoint.
I assume this access token is the second parameter of the Firebase.Auth.GoogleAuthProvider.GetCredential method, but what is the ID Token that the first parameter is asking for? Is that the token obtained from GooglePlayGames.PlayGamesPlatform.Instance.GetIdToken (same as GoogleAuthUtil.GetToken, if my reading of the docs/code is correct)?
If this is the case, why are both required? I thought the access token was all that was needed to authenticate a user with google cloud services and that the ID Token was being phased out.
Edit: After some testing, I found that passing the ID Token obtained from GooglePlayGames.PlayGamesPlatform.Instance.GetIdToken does allow Firebase to authenticate. Problem is, it asks for the user's email address every time. I'd like to avoid this if possible.
What is the difference between GetToken, GetAccessToken and GetIdToken, aside from the fact that GetIdToken requires a callback?
I managed to "hack" this in order to get it working... But still i think the correct method should only be using GetServerAuthCode but I cannot make it work with that.
Do your normal process of getting idToken and AccessToken the first time, when you log in to firebase get the user's email and store it in playerprefs. Then the second time if you already have the email you do this:
AndroidJavaClass authUtil = new AndroidJavaClass("com.google.android.gms.auth.GoogleAuthUtil");
AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
string idToken = authUtil.CallStatic<string>("getToken", currentActivity, PlayerData.Email, "audience:server:client_id:XXXXXXXXXX-xxxxxxxxxxxxxx.apps.googleusercontent.com"); // your client id, should be a number a dash and then a bunch of numbers and letters
string accessToken = authUtil.CallStatic<string>("getToken", currentActivity, PlayerData.Email, "oauth2:https://www.googleapis.com/auth/plus.me");
Hope it helps although it would be greatif someone posts a solution with GetServerAuthCode cause that is the correct way

Email not present in IDToken from Google Auth

I'm trying to get the email from the IDToken returned by Google, this code has actually worked perfectly for months, until yesterday night.
Nothing was changed, and now for some devices, the Token doesn't contain the email.
I tried checking the OAuth2 playground for the same same accounts, and for all of them, the token provided by the playground actually has the email inside it.
On my phone, with the same account, it's not there.
I still get the name, account_id and stuff, only the email is missing.
On a colleague's phone, for the same account, the token contains the email.
The code for building the api client:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addScope(new Scope(Scopes.PROFILE))
.addScope(new Scope("email"))
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.requestServerAuthCode(SERVER_ID, this)
.build();
If this was only my phone this wouldn't be so much of a problem, but the fact that it happens unpredictably on 1 phone means that it can't be relied upon.
I'd like to know if there's a 100% guaranteed way to make sure the IDToken will always contain the email.
Note: I tried the people.get endpoint, but it didn't fix this issue, and completely blocked some accounts from even receiving a token at all.
If you are requesting the email scope, email should be inside the idtoken. We definitely would like to debug the issue. Can you ping me with some information (through hangout) so we try to have a look?

How to send request to Telegram bot API?

After creating a telegram bot and gain bot token, I want to send a request to the bot API.
This link says we must send the HTTP request like this:
https://api.telegram.org/bot<token>/METHOD_NAME and brings example for easiest method "getme" which has not any input parameters.
Imagine I want to send some messages. I should use the sendMessage method which has two Required input parameters: chat_ID and text.
Now my Questions begins:
How can I write this sendMessage method in above request format with its parameters? I tried sendMessage(param1,param2) and received method not found message.
What is chat_id? if I want to send a message to the contact, how can I know his chat_id?
I searched a lot on the internet, there are plenty of projects on GitHub especially for this purpose, and honestly none of them makes any sense.
for god's sake someone please help me. I am loosing way.
Regards.
You just send a POST request to:
https://api.telegram.org/bot{token}/{method}
For example:
https://api.telegram.org/bot123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11/sendMessage
In the body of the request, you URL encode the parameters:
chat_id=12345&text=hello%20friend
For example, in Python using the requests module:
import requests
response = requests.post(
url='https://api.telegram.org/bot{0}/{1}'.format(token, method),
data={'chat_id': 12345, 'text': 'hello friend'}
).json()
When a user chats with your bot, you get a Message object that has a chat id (and a user id, which you can substitute for a chat id). There's no way to initiate a chat with a user unless you already know their user id, so you have to wait for a user to talk to you. You can simplify that by using deep linking and having the user click on a link that sends a pre-made message when they hit the Start button.
Edit: for those struggling to find chat_id, here's a way:
1.- Create a bot: on Telegram's search look for #BotFather. Click start, write /newbot, give it a name and a username. You should get a token to access the HTTP API. Save this token.
2.- Find your bot on Telegram with its username. Write something to it e.g. 'test'. This will come in handy later.
3.- Print chat_id. Before running this function, make sure that you have at least written one message to your bot on Telegram (step 2)
Javascript code:
var token = "123456:kioASDdjicOljd_ijsdf"; // Fill this in with your token
var telegramUrl = "https://api.telegram.org/bot" + token;
function getChat_id(){
var res = UrlFetchApp.fetch(telegramUrl+"/getUpdates").getContentText();
var res = JSON.parse(res);
Logger.log(res.result[0].message.chat.id.toString());
}
Try this
https://api.telegram.org/bot{token}/sendMessage?chat_id=<chat_id>&text=<Enter your text here>
Example
https://api.telegram.org/bot449123456:AAHSAnSGDm8PW2Z-1ZiwdVDmgv7sM3NMTxg/sendMessage?chat_id=311911234&text=Hi+Everyone