How to set Cognito User Pool User DeviceAttributes - amazon-web-services

GetDevice seems to return DeviceAttributes I can't find an API for setting them. I would like to use them to store the mobile push notification token with the device
{
"Device": {
"DeviceAttributes": [
{
"Name": "string",
"Value": "string"
}
],
"DeviceCreateDate": number,
"DeviceKey": "string",
"DeviceLastAuthenticatedDate": number,
"DeviceLastModifiedDate": number
}
}
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetDevice.html

I am on the Cognito team. At first we intended DeviceAttributes for a similar use case to the one you are describing, associate the mobile push notification token with the device. However, this has not been released yet and hence there is no API to update the device attributes. I will mention your use case within the team and add a +1 on the feature request.

Related

AWS Kinesis: user address in event encoded / encrypted

In my React Native mobile app, I use AWS Amplify to send info about user actions (screen views, button taps, swipes, etc.) by means of Analytics.record(...) to AWS Pinpoint which in turn feeds them into a AWS Kinesis Data Stream. I have created an AWS Lambda Python 3 function that listens to events in this data stream.
Setup has been a breeze, thanks to outstanding documentation and everything works fine - except for one thing:
When a user logs in, I update the Pinpoint Endpoint with the user ID, email address and some more attributes using Analytics.updateEndpoint(...). In the lambda function, I base64-decode the event payload as shown in this sample code and a sample event payload looks roughly like this:
{
"event_type": "_session.start",
"event_timestamp": 1572345161558,
"application": {
"app_id": "<some app ID>",
"cognito_identity_pool_id": "us-east-1:<some pool ID>",
"sdk": {},
"version_name": "<the app version I put in using updateEndpoint(...)>"
... <snipped for brevity> ...
},
"attributes": {},
"endpoint": {
"ChannelType": "APNS",
"Address": "=ABAQRuUDJD ... <some longish binary value> j0eL+69lsY=",
"EndpointStatus": "ACTIVE",
"Location": {
"Country": "US"
},
"Demographic": {
"Make": "iPhone",
"Model": "iPhone X",
"ModelVersion": "13.1.3",
...
"Platform": "ios"
},
"User": {
"UserId": "us-east-1:<Cognito ID of the user that logged in>",
"UserAttributes": {}
},
... <snipped for brevity> ...
},
"awsAccountId": "<my account ID>"
}
The user email address in the "Address" field above is not contained in the Kinesis Data Stream event as plain text, but encoded (or encrypted ?) somehow.
My question: Can anybody tell me how it is encoded / encrypted ? And, ideally, how to get the plain text address ?
I tried to base64-decode it or decrypt it using my default AWS KMS key (and a combination thereof), but no luck.
Alternatively, I could use the (plain text) user ID to look up the email address in the AWS Cognito user pool used to manage auth & auth, but getting it from the event directly would obviously be a lot simpler...
I have searched the web up and down, asked in the AWS-Amplify channel on gitter, but that Address encoding / encryption just does not seem to be documented anywhere...

How to get user attributes (username, email, etc.) using cognito identity id

I have AWS Cognito Identity Pool that is configured with Cognito User Pool as an authentication provider.
Assume I have identity ID of an identity in Cognito Identity Pool (e.g. us-east-1:XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX) where this identity has a linked login to a user in Cognito User Pool.
Using identity ID, how can I get the linked user details (email, phone, username)?
The ID Token that you exchange with Cognito federated identity service to get the identity id and credentials already has all user attributes. You do not need an extra call to any service.
It is a JWT token and you can use any library on the client to decode the values. You can read this guide for more information about the tokens vended by Cognito user pools.
Alternatively, you can also use the Access Token to call GetUser API which will return all the user information.
Using REST API
AccessToken
Thought that this could be very helpful to someone as I've spent a lot of time trying to figure out how to get UserAttributes with only accessToken and region ( Similar to this but with REST API ( Without using aws-sdk )
You can get UserAttributes with accessToken using this HTTP request. ( GetUser )
Method: POST
Endpoint: https://cognito-idp.{REGION}.amazonaws.com/
Content-Type: application/x-amz-json-1.1
Content-Length: 1162 // Access Token bytes length
X-Amz-Target: AWSCognitoIdentityProviderService.GetUser
Body: {"AccessToken":"ACCESS_TOKEN"}
And if the accessToken is valid, you should receive example response like the following
{
"UserAttributes": [
{
"Name": "sub",
"Value": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
},
{
"Name": "email_verified",
"Value": "true"
},
{
"Name": "name",
"Value": "Jason"
},
{
"Name": "phone_number_verified",
"Value": "true"
},
{
"Name": "phone_number",
"Value": "+xxxxxxxxxxx"
},
{
"Name": "email",
"Value": "xxxx#gmail.com"
}
],
"Username": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx"
}
AWS cognito-idp list-users has a filter option that allows you to filter based on attribute. 'sub' is the attribute that matches the identity id you are describing.
e.g. at the command line:
aws cognito-idp list-users --user-pool-id us-east-1_abcdFghjI --filter "sub=\":XXaXcXXa-XXXX-XXXX-XXX-XXXXXXXXXXXX\""
This also requires the user-pool-id, which I suspect you have. Additionally, I have no idea how this is implemented or how it performances when filtering a large number of users, but I take custom attributes not being usable in filters as a hint that there is some form of indexing behind the curtain.
I faced the similar issue and after too much of scratching i was not able to find the exact way of pulling out the details. My usecase was to get the details in android APP.
After looking into their AWSMobile client API code. I found below and it is working from me.
Log.i(TAG, "User Details"+ AWSMobileClient.getInstance().getUserAttributes().toString());
Recommendation - Try use AWSMobileclient incase you are using it for Android Development as this is new library that is recommended for development.
Just struggled with this for a while, and the way I got the user name, using Java API is:
identityManager.login(this, new DefaultSignInResultHandler() {
#Override
public void onSuccess(Activity activity, IdentityProvider identityProvider) {
...
String userName = ((CognitoUserPoolsSignInProvider) identityProvider).getCognitoUserPool().getCurrentUser().getUserId();
There is a listener we can initialize that will listen to changes in our authentication state and allow us to have access to the type of authentication event that happened and update the application state based on that data.
With Amplify, the Hub module allows us to do this pretty easily:
import { Hub } from 'aws-amplify';
Hub.listen('auth', (data) => {
const {payload} = data;
if (payload.event === 'signOut') {
console.log('signOut');
} else if (payload.event === 'signIn') {
console.log('A new auth event has happened: ', data.payload.data.username + ' has ' + data.payload.event);
}
});
For those who are looking how to get the value of email parameter in Java programmatically
I assume you have already figured out how to get the needed / all users from the pool.
Say I have ListUsersResult with my all users and say I want to check the email value of the first user:
ListUsersResult allUsers = getAllUsers();
UserType userType = allUsers.getUsers().get(0);
First I can get user's all attributes:
List<AttributeType> attributes = userType.getAttributes();
Then loop through the attributes looking for the one we're interested in (our case email):
for (AttributeType att : attributes) {
if (att.getName().equals("email")) {
// do whatever you want
}
}
Remember that printing in to the console will most probably not work since it is sensitive data. But you can compare it like this:
att.getValue().equals("mymail#mail")
Use this piece of code
GetDetailsHandler detailsHandler = new GetDetailsHandler() {
#Override
public void onSuccess(CognitoUserDetails cognitoUserDetails) {
CognitoUserAttributes cognitoUserAttributes=cognitoUserDetails.getAttributes();
stringStringHashMap=new HashMap<>();
stringStringHashMap =cognitoUserAttributes.getAttributes();
userNumber=stringStringHashMap.get("phone_number");
e1.setText(userNumber);
Log.d("Response"," Inside DEATILS HANDLER");
// Store details in the AppHandler
AppHelper.setUserDetails(cognitoUserDetails);
// Trusted devices?
handleTrustedDevice();
// e1.setText(input.getText().toString());
}
#Override
public void onFailure(Exception exception) {
closeWaitDialog();
showDialogMessage("Could not fetch user details!", AppHelper.formatException(exception), true);
}
};
private void getDetails() {
AppHelper.getPool().getUser(username).getDetailsInBackground(detailsHandler);
}
console.log('username is ' + cognitoUser.getUsername());

What are all the steps involved with changing an Alexa Skill name?

I submitted a skill to Amazon for Alexa, and it failed certification due to intellectual property rights. Amazon suggested that I say the service is "for" the IP rights holder, so I modified the name and am now getting this error for everything I try to do.
{
"errorMessage": "Exception: TypeError: Cannot read property 'application' of undefined"
}
So far, I updated the Skill Name, Invocation Name, and Welcome Message. Is there something else I need to update or run on the dev portal to get this to work again?
Update: When I try to start the skill from the Alexa Development portal, I see this in the logs for
console.log("event.session.application.applicationId=" + event.session.application.applicationId);
{
"version": "1.0",
"session": {
"new": true,
"sessionId": "SessionId.8b65b2f5-0193-4307-9bef-88c116d9344b",
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.5987b947-c8e9-4fc4-a0b8-2ba12c57ea59"
},
"attributes": null,
"user": {
"userId": "amzn1.ask.account.ABCDEFG" // masked my account value
}
},
"request": {
"type": "IntentRequest",
"requestId": "EdwRequestId.4d19f589-cdca-4303-99dc-0dc5cec781d2",
"timestamp": "2016-04-18T16:21:04Z",
"intent": {
"name": "DontKnowIntent"
}
}
}
The application ID matches the one supplied in the Alexa Development portal, so I don't think that's causing any issues. The property 'application' is only ever called after 'session', which clearly is defined. I don't know if the null attributes is causing an error. Maybe someone can look at a successful request?
Finally, here is my code: https://github.com/Shwheelz/alexa-skills-kit-js/blob/master/my_skills/pokemonTrivia/src/index.js
I have changed the name twice before on a node app and a Java 8 app. All I had to do was change the name (also changed invocation name) under the skill information. It worked first time out. Now my skill name did not update on alexa app once and did the other time. Since you are not certified, you may want to create the skill for scratch. This should only take about 5 or 10 mins. Just do not forget to change or add the new application Id of you lambda

Facebook graph api. how to list all pages that my app is subscribed to?

So I am aware of how to check each page to get a list of all subscribed apps.
But I would like to get a list of all pages my app has real time update subscriptions for?
so i have tried this
https://graph.facebook.com/v2.5/$app_id/subscriptions?access_token=$app_token
but this just brings back basic info on the app.
I would like a list of pages that it has subscriptions to already?
Can anyone help?
This doesn't look to be possible.
Endpoint you're using - https://developers.facebook.com/docs/graph-api/reference/v2.8/app/subscriptions - is to get list of application webhooks (callback_url and type of changes), which are called subscriptions for some reason. It's not about pages that subscribed to this webhook (or this app in general).
Overall, even in https://developers.facebook.com/apps/ for your app, under e.g. Messenger tab, you will only see subset of all pages that subscribed to this app. The visible subset is limited by your facebook user account permissions, presumably only show pages that you're either Admin or Editor.
Therefore, if such call would be possible, it would be somehow tied to User Access Token as well, not only app token.
You can do this here: https://developers.facebook.com/tools/explorer
Once logged, you can click on right button and select "Get User Access Token". You will need at least manage_pages or pages_show_list permission to accomplish this.
Now, all you have to do is call this endpoint: /me/accounts.
It should list all subscribed pages on your app.
Hope it helps.
As per
https://developers.facebook.com/docs/facebook-login/access-tokens/#apptokens
it is possible (graph api):
GET /oauth/access_token
?client_id={app-id}
&client_secret={app-secret}
&grant_type=client_credentials
And then /<app_id>/subscriptions
which returns something like:
{
"data": [
{
"object": "application",
"callback_url": "https:...",
"active": true,
"fields": [
{
"name": "ads_rules_engine",
"version": "v2.9"
}
]
},
{
"object": "page",
"callback_url": "https://...",
"active": true,
"fields": [
{
"name": "leadgen",
"version": "v2.5"
}
]
}
]
}

Get total number of Custom Actions on Open Graph Object

I want to access number of custom actions (that I've defined) done on my Open Graph object. Facebook will return number of Like actions in response(like this) but they don't include number of custom actions.
Apps can retrieve actions published for the authorized user. For example, a Recipe app can retrieve all the recipes I've cooked or plan on cooking and customize the app experience based the data.
This API returns the action’s metadata including timestamps along with custom properties and their values. Objects referenced from an action are returned a single level deep.
GET /{action-instance-id}
The following retrieves a specific action instance
https://graph.facebook.com/{action-instance-id}?access_token=USER_ACCESS_TOKEN
Response
{
"id": "1538292028372"
"start_time": 1303502229,
"end_time": 1303513029,
"data": {
"type": "recipebox:recipe",
"url": "http://www.example.com/pumpkinpie.html",
"id": "1234567890",
"title": "Pumpkin Pie"
},
}
The above content is from FB Documentaion