Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to find the bidirectional map between Cognito identity ID and Cognito user information? #54

Open
baharev opened this issue Dec 10, 2017 · 188 comments
Assignees
Labels
Auth Related to Auth components/category Cognito Related to cognito issues feature-request Request a new feature pending-maintainer-response Issue is pending a response from the Amplify team. Service Team Issues asked to the Service Team

Comments

@baharev
Copy link
Contributor

baharev commented Dec 10, 2017

Given the Cognito identity ID, I would like to programmatically find the user name, e-mail address, etc. For example, one issue is that each user gets his/her own folder in S3 (e.g. private/${cognito-identity.amazonaws.com:sub}/ according to the myproject_userfiles_MOBILEHUB_123456789 IAM policy) but I cannot relate that folder name (S3 prefix) to the user attributes in my user pool. The closest thing that I have found is this rather complicated code:

AWS Lambda API gateway with Cognito - how to use IdentityId to access and update UserPool attributes?

Is it my best bet? Is it really this difficult?

(As a workaround, I would be happy with a post confirmation lambda trigger that creates for example a ${cognito-identity.amazonaws.com:sub}/info.txt file in some S3 bucket, and in the info.txt file it could place the user sub from the user pool. I am not sure that this is feasible at all, it was just an idea.)

@mlabieniec mlabieniec added investigating This issue is being investigated feature-request Request a new feature labels Dec 12, 2017
@jonsmirl
Copy link

jonsmirl commented Jan 5, 2018

When the identity is created in the identity pool, can't you add 'logins' to the call? Those logins get stored in the identity pool providing a way to map between Google/Facebook/User Pool ID and the Identity pool ID. 'Logins' are optional, but they are very useful.

--logins (map)
A set of optional name-value pairs that map provider names to provider tokens.

Edit - you have the logins in Auth.ts/setCredentialsFromFederation.
Why aren't these getting stored in the identity pool along with the ID from federation, I'm sure that data used to be in my identity pools, so where did it go?

Here's an identity pool entry from my mobile app, it has the User Pool ID in it. The mobile app is based on code from Mobile Hub.

jonsmirl@ubuntu-16:~$ aws cognito-identity describe-identity --identity-id us-east-1:bea3f57c-4564-47cf-b82c-a515f719d8a5 --profile bill
{
"Logins": [
"cognito-idp.us-east-1.amazonaws.com/us-east-1_Cf6AJpe20"
],
"LastModifiedDate": 1512005509.277,
"CreationDate": 1512005509.237,
"IdentityId": "us-east-1:bea3f57c-4564-47cf-b82c-a515f719d8a5"
}

I checked Google and FB logins and they don't display the Google/FB sub like the user pool entry does.

So my mobile app is storing the User Pool ID. This seems to be missing from amplify. If that data was in the identity pool this issue would be solved.

In Auth.ts there is this code:
private setCredentialsFromFederation(provider, token, user) {
const domains = {
'google': 'accounts.google.com',
'facebook': 'graph.facebook.com',
'amazon': 'www.amazon.com'
};

I wonder if that string is fixed format? Maybe it is legal to say...
'google': 'accounts.google.com/34455444444',

ie add in the Google sub id? That appears to be what the mobile hub code did for Cognito.

@mlabieniec mlabieniec removed the investigating This issue is being investigated label Jan 11, 2018
@richardzcode
Copy link
Contributor

Hi @baharev lookup user attributes by identityId is application specific. Some app may not want this for security concerns, some want to store in S3, and some prefer database. As a library we can't make those assumptions.

With aws-amplify it is pretty easy to implement. Depend on your needs, maybe pick one of the below two implementation.

Save private so only owner of the info can access

When user sign up, or maybe sign in depend on your choice,

  Auth.currentUserInfo()
    .then(info => {
      Storage.put(
        'userInfo.json',
        JSON.stringify(info),
        { level: 'private', contentType: 'application/json' }
      );
    });

Then do this to load user attributes,

  Storage.get('userInfo.json', { level: 'private',  download: true})
    .then(data => console.log('info...', data.Body.toString()));

Save public so just lookup by identityId

  Auth.currentUserInfo()
    .then(info => {
      Storage.put(
        identityId + '_userInfo.json',
        JSON.stringify(info),
        { level: 'public', contentType: 'application/json' }
      );
    });

Then do this to retrieve user attributes,

  Storage.get(identityId + '_userInfo.json', { level: 'public',  download: true})
      .then(data => console.log('info...', data.Body.toString()));

@baharev
Copy link
Contributor Author

baharev commented Jan 27, 2018

@richardzcode Thanks, your first suggestion is an acceptable workaround for the time being. What I don't like about it is that the userInfo.json in your code comes from the user, and therefore cannot be trusted.

lookup user attributes by identityId is application specific.

There is a misunderstanding here: I need this bidirectional map purely on the backend. The user must not be able to access it exactly for security reasons.

The use cases are the followings.

  1. If a user is complaining about a bug, I have to be able to find his/her folder to look at the data and to reproduce the bug (if any). In this use case I know the user but I don't know which folder is his/her folder.
  2. Say I noticed something strange in certain folders of the S3 bucket, and I would like to reach the corresponding users in e-mail and warn them. In this use case I know the folder but I don't know the users' e-mail address.

Note that both use cases must happen purely on the backend, and without any interaction from the user.

The true solution would be to retrieve this bidirectional map purely on the backend, without any user interaction. I think there should be an AWS API for backend code to do that. In my first comment I link to a horribly complicated "solution", but I find that unacceptably complex.

@baharev
Copy link
Contributor Author

baharev commented Jan 27, 2018

I looked at the Cognito API reference, and it is weird too. For example:

  1. AdminGetUser does not seem to give me the identity ID.
  2. DescribeIdentity does not seem give me any user attributes.
  3. Somehow the mapping between users and identity IDs seem to be hidden. The only way I could recover it is through the login tokens.

What is going on here? Or what did I miss / misunderstand?

@richardzcode
Copy link
Contributor

@baharev In my knowledge there is no backend direct mapping between identityId and username. Backend is depend on what services provide. We can only suggest client side solution at this moment.

@jonsmirl
Copy link

jonsmirl commented Feb 1, 2018

The old Mobile Hub code for Android built a two way map. This Indentity pool entry was created by that code when I did a user pool login:

jonsmirl@ubuntu-16:~$ aws cognito-identity describe-identity --identity-id us-east-1:bea3f57c-4564-47cf-b82c-a515f719d8a5 --profile bill
{
"Logins": [
"cognito-idp.us-east-1.amazonaws.com/us-east-1_Cf6AJpe20"
],
"LastModifiedDate": 1512005509.277,
"CreationDate": 1512005509.237,
"IdentityId": "us-east-1:bea3f57c-4564-47cf-b82c-a515f719d8a5"
}

Also, if you use the current hosted UI under user pool it creates a back link like above. It is only Amplify that is not creating the back link.

I just used Amplify to create an entry in my identity pool corresponding to a userpool entry. The entry in the identity pool does not have the linked login info shown above.

jonsmirl@ubuntu-16:~/aosp/demo/foobar/client$ aws cognito-identity describe-identity --identity-id us-east-1:f763ea29-41ce-4b86-bc58-31de68d7cce8
{
"LastModifiedDate": 1517513923.798,
"CreationDate": 1517513923.798,
"IdentityId": "us-east-1:f763ea29-41ce-4b86-bc58-31de68d7cce8"
}

@baharev
Copy link
Contributor Author

baharev commented Feb 1, 2018

@richardzcode This map must exist on the backend, because a given user always gets the same ${cognito-identity.amazonaws.com:sub}. It must be solvable purely on the backend.

@baharev
Copy link
Contributor Author

baharev commented Feb 1, 2018

@jonsmirl Sorry, I don't understand, but it seems to me that you are also struggling with this issue, or with a very similar one.

@jonsmirl
Copy link

jonsmirl commented Feb 1, 2018

When amplify creates an entry in identity pool corresponding to a user pool entry, why is this part missing? Other Amazon Cognito code makes this entry:

"Logins": [
"cognito-idp.us-east-1.amazonaws.com/us-east-1_Cf6AJpe20"
],

That entry lets you map from an identity pool ID back into a user pool ID. You can query the logins off from an identity pool entry to get that string. Then use that string to query all of the attributes for the user out of the user pool.

@baharev
Copy link
Contributor Author

baharev commented Feb 1, 2018

@jonsmirl OK, now we are getting somewhere. Please explain:

Then use that string to query all of the attributes for the user out of the user pool.

How? Which API call will consume this mysterious "cognito-idp.us-east-1.amazonaws.com/us-east-1_Cf6AJpe20" and give me the user attributes?

@jonsmirl
Copy link

jonsmirl commented Feb 1, 2018

We don't use this feature, and I see now that I was misunderstanding what I was seeing. This is the Cognito user pool id, not the sub of the user: cognito-idp.us-east-1.amazonaws.com/us-east-1_Cf6AJpe20
I was thinking that last part was the sub of the user in the pool and it is not.

You would need to be able to access the token that was submitted with this identity and I don't see any obvious way to get to it. 99% of our logins are via Google/FB with only a few using User Pool.

So to make this work, after you get logged in you will need a dynamodb table that maps the cognito identify id to the cognito user id. Then you will be able to find the user in the user pool.

Or you will just end up doing what we did. Since the attributes on Google, FB and user pool are all different we just store a copy of the attributes we care about in our internal user database. Which is what richard said to do.

This might be what you are looking for:

https://stackoverflow.com/questions/42386180/aws-lambda-api-gateway-with-cognito-how-to-use-identityid-to-access-and-update

@baharev
Copy link
Contributor Author

baharev commented Feb 1, 2018

@jonsmirl Thanks for the prompt reply.

As I said, yes, it would be an acceptable workaround for the time being, but it requires a user login and the info comes from the user (hence cannot be trusted). What pisses me is that this map must be available in the backend, so I see no reason why the user pool owner cannot access it. It just does not make sense to me, and I am wondering why the others aren't complaining about it too.

This might be what you are looking for:

https://stackoverflow.com/questions/42386180/aws-lambda-api-gateway-with-cognito-how-to-use-identityid-to-access-and-update

That is the link in my very first comment. :) I know you can do it, but it is unacceptably complex.

Thanks again for the prompt feedback!

@WolfWalter
Copy link

Totally agreeing with @baharev. In my use case I have stored the Cognito Identity IDs in my database and now tried to get the username of the associated userpool user. None of the APIs seems to expose this functionality.

@ffxsam
Copy link
Contributor

ffxsam commented Mar 4, 2018

I was advised to retrieve the Cognito identity ID via Auth.currentUserInfo() and store it as an attribute in the user object in the user pool.

@ffxsam
Copy link
Contributor

ffxsam commented Mar 4, 2018

However, I can't figure out when the right time is to grab this info. Upon login, when I call Auth.currentUserInfo(), the id property is undefined.

  async signIn({ commit }, { username, password }) {
    const user = await Auth.signIn(username, password);
    const userInfo = await Auth.currentUserInfo();
    console.log(userInfo);
    authenticate(commit, user);
  },

@ffxsam
Copy link
Contributor

ffxsam commented Mar 4, 2018

Ok, this works for me:

  async signIn({ commit }, { username, password }) {
    const user = await Auth.signIn(username, password);
    const credentials = await Auth.currentCredentials();
    console.log('Cognito identity ID:', credentials.identityId);
    authenticate(commit, user);
  },

So within this code block, you could just update the user's attributes and set their Cognito identity ID in there, and you'd have immediate access to it once they're authenticated.

@baharev
Copy link
Contributor Author

baharev commented Mar 4, 2018

@ffxsam Interesting, thanks for letting us know. I recognize Auth.signIn() and Auth.currentCredentials() but could you explain what authenticate is in your code?

If I understand correctly what you are suggesting, it is essentially the same as richardzcode's suggestion. See my previous objections why I am not happy with it as a solution. It is an acceptable workaround for the time being though.

@ffxsam
Copy link
Contributor

ffxsam commented Mar 5, 2018

authenticate isn't relevant here, just my own function that commits data to a Vuex store.

@gbrits
Copy link

gbrits commented Mar 13, 2018

This is how I overcame the obstacle of not having the identityId on hand for my users:

login() {
    let loading = this.loadingCtrl.create({
      content: 'Please wait...'
    });
    loading.present();

    let details = this.loginDetails;
    Auth.signIn(details.username, details.password)
      .then(user => {
        Auth.currentCredentials().then(credentials => {
          var identityId = credentials.identityId;
          let params = {
             "AccessToken": user.signInUserSession.accessToken.jwtToken,
             "UserAttributes": [
                {
                   "Name": "custom:identityId",
                   "Value": identityId
                }
             ]
          }
          // Save the identityId custom attribute to the user
          this.db.getCognitoClient()
          .then((client) => {
            client.updateUserAttributes(params, function(err, data) {
                if (err) console.log(err, err.stack);// an error occurred
                else {
                  console.log(data);
                }
            });
          });
        });
        logger.debug('signed in user', user);

        if (user.challengeName === 'SMS_MFA') {
          this.navCtrl.push(ConfirmSignInPage, { 'user': user });
        } else {
          this.navCtrl.setRoot(TabsPage);
        }
      })
      .catch(err => {
        logger.debug('errrror', err);
        this.error = err;
      })
      .then(() => loading.dismiss());
  }

Ref: inside of my DynamoDB (public db) class, my getCognitoClient method invokes the CognitoIdentityServiceProvider endpoint from the aws-sdk

getCognitoClient() {
      return Auth.currentCredentials()
        .then(credentials => new AWS.CognitoIdentityServiceProvider({ credentials: credentials }))
        .catch(err => logger.debug('error getting document client', err));
  }

Important Note You have to log into Cognito's User Pool and click Attributes and add IdentityId (as a string) to your custom attributes, for it to be populated.

Hope this helps someone. Because it had me thinking I'm an idiot who should stop programming, so hopefully someone out there can reassure me to continue!

@baharev
Copy link
Contributor Author

baharev commented Mar 17, 2018

@gbrits I think that we should get official support through the SDK, and we really should not be implementing our workarounds. Especially not in ways that involve data coming from the user (untrusted data).

As far as I understand your code, it has the same issues as richardzcode's workaround.

@ffxsam
Copy link
Contributor

ffxsam commented Mar 18, 2018

Totally agree. The SDK should handle these sorts of lower level operations for us.

@acrolink
Copy link

acrolink commented May 5, 2022

@v1pz3n
You deserve an award for that solution! Thank you.

Hope it does not break other things related to authentication.

@johnf
Copy link
Contributor

johnf commented May 31, 2022

I've managed to get this working and mostly automated by making the following changes

First update the auth roles to use${aws:PrincipalTag/username}`` in amplify/backend/storage/YourStorage/override.ts```

Note: I've only updated for protected since it doesn't matter for private. I've left the code for that below but I hit a bug when enabling it where the override wouldn't work anymore and ran out of time to solve it.

import { AmplifyS3ResourceTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyS3ResourceTemplate) {
  resources.s3AuthProtectedPolicy.policyDocument.Statement = resources.s3AuthProtectedPolicy.policyDocument.Statement.map((statement) => ({
    ...statement,
    Resource: JSON.parse(JSON.stringify(statement.Resource).replace('${cognito-identity.amazonaws.com:sub}', '${aws:PrincipalTag/username}')),
  }));

  // NOTE: We don't need these for our app and also they don't work
  // resources.s3AuthPrivatePolicy.policyDocument.Statement = resources.s3AuthPrivatePolicy.policyDocument.Statement.map((statement) => ({
  //   ...statement,
  //   Resource: JSON.parse(JSON.stringify(statement.Resource).replace('${cognito-identity.amazonaws.com:sub}', '${aws:PrincipalTag/username}')),
  // }));
  //
  // resources.s3AuthReadPolicy.policyDocument.statements = resources.s3AuthReadPolicy.policyDocument.statements.map((statement) => ({
  //   ...statement,
  //   condition: JSON.parse(JSON.stringify(statement.condition).replace(/\${cognito-identity.amazonaws.com:sub}/g, '${aws:PrincipalTag/username}')),
  // }));

  // console.debug(JSON.stringify(resources.s3AuthProtectedPolicy.policyDocument.Statement, null, 2));
  // console.debug(JSON.stringify(resources.s3AuthPrivatePolicy.policyDocument.Statement, null, 2));
  // console.debug(JSON.stringify(resources.s3AuthReadPolicy.policyDocument.statements, null, 2));
}

I added a post push hook to set up the principal tag attributes, you can't do this in an override using cdk as cloudformation doesn't support it yet. aws-cloudformation/cloudformation-coverage-roadmap#779

const fixPrincipalTags = async (data, error) => {
  console.log('ease');
  if (error) {
    console.error('Error setting up sentry release', error);
    return;
  }
  const env = data.amplify.environment.envName;
  process.env.AWS_PROFILE = `gladly-${env}`;

  const client = new CognitoIdentity({ region: 'ap-southeast-2' });

  const credentials = await client.config.credentials();
  process.env.AWS_ACCESS_KEY_ID = credentials.accessKeyId;
  process.env.AWS_SECRET_ACCESS_KEY = credentials.secretAccessKey;
  process.env.AWS_SESSION_TOKEN = credentials.sessionToken;

  // NOTE: Change mobile to the name of your auth in amplify
  const identityPoolId = amplify.auth.mobile.output.IdentityPoolId;
  const identityPool = await client.describeIdentityPool({ IdentityPoolId: identityPoolId });
  const identityProviderName = (identityPool.CognitoIdentityProviders || [null])[0]?.ProviderName;

  try {
    const tagMap = await client.getPrincipalTagAttributeMap({ IdentityPoolId: identityPoolId, IdentityProviderName: identityProviderName });
    if (tagMap?.PrincipalTags?.client === 'aud' && tagMap?.PrincipalTags?.username === 'sub') {
      console.debug('No tags to fix');
      return;
    }
  } catch (e) {
    console.debug('Fixing tags');
    await client.setPrincipalTagAttributeMap({
      IdentityPoolId: identityPoolId,
      IdentityProviderName: identityProviderName,
      UseDefaults: true,
    });
  }

  delete process.env.AWS_PROFILE;
};

This most important change and why I suspect this workaround stopped working for people is changing the trust relationship on the auth role.

const addStsSessionTag = async (data, error) => {
  if (error) {
    console.error('Error:', error);
    return;
  }
  const env = data.amplify.environment.envName;
  process.env.AWS_PROFILE = `gladly-${env}`;

  const client = new IAM({ region: 'ap-southeast-2' });

  const credentials = await client.config.credentials();
  process.env.AWS_ACCESS_KEY_ID = credentials.accessKeyId;
  process.env.AWS_SECRET_ACCESS_KEY = credentials.secretAccessKey;
  process.env.AWS_SESSION_TOKEN = credentials.sessionToken;

  const roleName = amplify.providers.awscloudformation.AuthRoleName;

  const role = await client.getRole({ RoleName: roleName });
  const policyJSON = role.Role?.AssumeRolePolicyDocument;
  if (!policyJSON) {
    throw new Error(`Role ${roleName} does not have an AssumeRolePolicyDocument`);
  }
  const policy = JSON.parse(decodeURIComponent(policyJSON));
  const actions = policy.Statement[0].Action;

  if (actions.includes('sts:TagSession')) {
    console.debug('Role already has sts:TagSession');
    return;
  }

  actions.push('sts:TagSession');

  console.debug('Adding sts:TagSession to policy');
  await client.updateAssumeRolePolicy({ RoleName: roleName, PolicyDocument: JSON.stringify(policy) });
};

@Guneetgstar
Copy link

Guneetgstar commented May 31, 2022

Ok, so after dwelling ~day and reading the same page again and again I found this:

If you are using developer authenticated identities, Amazon Cognito includes an API for looking up Cognito identity IDs for your users to make this process easier.

And now it makes sense to me at least that why, JUST WHY they added examples of Limiting Access to Specific Identities when there is no way to even find the ID from the backend/without involving users.

@wtrevena
Copy link

For anyone else still struggling to obtain the IdentityId in a Lambda Function invoked via API-Gateway with a Cognito User Pool Authorizer, I finally was able to use the jwtToken passed into the Authorization header to get the IdentityId by using the following code in my JavaScript Lambda Function:

const IDENTITY_POOL_ID = "us-west-2:7y812k8a-1w26-8dk4-84iw-2kdi849sku72"
const USER_POOL_ID = "cognito-idp.us-west-2.amazonaws.com/us-west-2_an976DxVk"
const { CognitoIdentityClient } = require("@aws-sdk/client-cognito-identity");
const { fromCognitoIdentityPool } = require("@aws-sdk/credential-provider-cognito-identity");

exports.handler = async (event,context) => {
        const cognitoidentity = new CognitoIdentityClient({
            credentials:  fromCognitoIdentityPool({
                client: new CognitoIdentityClient(),
                identityPoolId: IDENTITY_POOL_ID,
                logins: {
                    [USER_POOL_ID]:event.headers.Authorization
                }
            }),
        });

        var credentials = await cognitoidentity.config.credentials()
        var identity_ID =  credentials.identityId
        console.log( identity_ID)

        const response = {
            statusCode: 200,
            headers: {
                "Access-Control-Allow-Headers": "*",
                "Access-Control-Allow-Origin": "*",
                "Access-Control-Allow-Methods" : "OPTIONS,POST,GET,PUT"
             }, 
            body:JSON.stringify(identity_ID)
        };
        return response;
}

After the user has signed in I can use aws-amplify's Auth directive and fetch() in my React-Native app to invoke the lambda function by sending a request to my API-Gateway trigger by calling the following code:

var APIGatewayEndpointURL = 'https://5lstgsolr2.execute-api.us-west-2.amazonaws.com/default/-'
var response = {}

async function getIdentityId () {
   
   var session = await Auth.currentSession()
   var IdToken = await session.getIdToken()
   var jwtToken = await IdToken.getJwtToken()

   var payload = {}
   
   await fetch(APIGatewayEndpointURL, {method:"POST", body:JSON.stringify(payload), headers:{Authorization:jwtToken}})
     .then(async(result) => {
         response = await result.json()
         console.log(response)
      })
}

@abdallahshaban557
Copy link
Contributor

Hi @baharev - is the solution provided by @wtrevena acceptable? Should I close this issue?

@baharev
Copy link
Contributor Author

baharev commented Nov 17, 2022

@abdallahshaban557 I re-wrote everything I needed back in 2019 and I haven't used Amplify since. As far as I am concerned, you could have closed this issue in 2019. Having said that: I am a happy and satisfied customer of AWS, the services are well-documented and have well-thought-out REST API and they are, for the most part, pleasant to work with. It is Amplify that I am not willing to use.

@abdallahshaban557
Copy link
Contributor

@baharev - apologies that we could not get to this sooner.

@ashrafabdul
Copy link

@wtrevena Your solution looks great. However, how do you get the IDENTITY_POOL_ID? Amplify only include the USERPOOL_ID in the process environment. I also can't seem to find an identity pool in the console.

@aspahwa
Copy link

aspahwa commented Dec 10, 2022

I use a GraphQL API and store this info in DynamoDB table where I can use a Lambda to make queries.

Sample GraphQL mutation:

type Uploader
  @model
  @auth(rules: [{ allow: owner, operations: [create, update] }]) {
  username: String!
  userIdentity: String! @primaryKey
}

Sample Query that I use in App.js:

import { createUploader } from "./graphql/mutations";
import { Hub } from "aws-amplify";

Hub.listen("auth", async (data) => {
  switch (
    data.payload.event // listens to authentication events from cognito
  ) {
    case "signIn":
      console.log("user signed in");
      try {
        const currentUserCredentials = await Auth.currentCredentials(); // Fetch the current authenticated user from Cognito Identity Pool
        const currentAuthenticatedUser = await Auth.currentAuthenticatedUser(); // Fetch the current user from Cognito User pool
        const response = await API.graphql(
          graphqlOperation(createUploader, {
            // Adds an entry for the below data to DynamoDB table that maps Cognito Identity ID to the user from user pool
            input: {
              userIdentity: currentUserCredentials.identityId, // Cognito identity ID for the authenticated user
              username: currentAuthenticatedUser.username, // Cognito username for the authenticated user
            },
          })
        );
      } catch (error) {
        console.log(error);
      }
      break;
  }
});

This creates stores the username and Identity ID of the user in a DynamoDB table which I can programmatically query to map the folder name in S3 to the username of the user uploading objects.

@DiegoNuptum
Copy link

Hi!
Just to confirm, Still there is no direct and easy way to get the user who owns a folder in S3 using the Storage component. Or as the title says a bidirectional map between the Cognito Identity ID and Cognito user information. Right?

stocaaro added a commit that referenced this issue Aug 2, 2023
* feat: Actions for pr testing (#12)

* feat: Add working e2e example (#14)

* chore: Add configurable e2e tests to GH workflows (#15)

* feat(e2e): add integ test runner and test

* fix(e2e): retain existing workflows

* fix(e2e): remove old e2e example

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser auth tests (#16)

* chore: add e2e browser auth tests

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser predictions interactions tests (#17)

* chore: add e2e integ_react_predictions

* chore: add browser e2e interactions

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>

* chore: limit PR concurrency (#19)

* chore: add build_type and enable retry (#18)

* prod & dev

* -n 3

* turn off fail-fast

---------

Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>

* chore: add e2e browser datastore tests (#20)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser api,storage tests (#21)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: fix single browser provided in integ-config (#22)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Run dev and prod on the same runner

* chore: Add detox testing (#26)

* Feat/GitHub actions/test ashwinkumar6 (#27)

* chore: Re-arrange integ test configurations and improve prebuild (#29)

* chore: Re-arrange integ test configurations and inprove preflight

* Fix is-preflight flag

* Change preflight to prebuild for consistencu

* Disable fast fail on unit tests

* feat: Change yaml load output pattern

* chore: fix e2e integ_datastore_auth_v2 test

* chore: disable playwright tests (#33)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add google env variables for e2e datastore tests (#35)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add support for uploading artifacts  (#34)

* chore: test upload artifacts

* chore: test uploading artifact

* chore: Detox fix and step cleanup

* chore: Increase detox time limit

* chore: Turn warn to ignore for upload artifact misses

* chore: Disable broken detox tests

* chore: Disable PN testing and remove datastore test not running in circle

* chore: e2e add configurable time_out and retry_count (#36)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Increase deviceTracking timeout

* chore: add deploy workflow (#37)

* chore: add deploy workflow

* chore: gh actions publish code clean up

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Model full CI/CD flow - improve preid release (#38)

* fix: Cache on the single yarn.lock instead of all

* fix: Sync with main

* chore: Revert to relative path use (#40)

* chore: Revert to relative path use

* fix: Remove path from workflows

* chore: Add post-release merge to main

* chore: Remove orphaned workflow files

* chore: e2e add integ_auth_test_cypress_no_ui test (#39)

* chore: e2e add integ_auth_test_cypress_no_ui test

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: change github name and email

* chore: update yarn.log

* chore: move additional e2e commented tests (#43)

* chore: move additional e2e commented tests

* chore: add required permissions to script file

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: e2e keep test_name same as CCI (#45)

* chore: e2e keep test_name same as CCI
* chore: e2e re-arrange integ config
---------
Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: update actions typo

Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>

* chore: update actions typo

Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>

* chore: cleanup github_email and github_name (#46)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: cleanup load verdaccio action (#47)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: actions code cleanup (#48)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Remove unused actions and use env vars instead of injection in run commands (#49)

* chore: add retention period and timeout for cache (#50)

* chore: add retention period and timeout for cache

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Chanke js token name

* chore: Filter preid content

* chore: Move file names around and consume env vars

* fix: Rest bundle size increase

* chore: Compactify on syntax

* chore: dynamically fetch the repo_owner_name (#52)

* chore: dynamically fetch the repo_owner_name

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Configure staging to use corresponding branch name

* chore: Naming and cleanup

* chore: Naming and dependency workflow improvements

* chore: Fix vars use for gh user/email

* chore: run e2e Rollup + DataStore test on just chrome (#54)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Add preid protection (#57)

* chore: Only publish to npm from the aws-amplify org

* chore: add concurrency to push workflows (#56)

* chore: add concurrency to push workflows

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Prepare for merge to main

* chore: Fix circle build

* chore: Okay, this will fix circle!

* chore: Integrate license checking into pr check

* chore: Add github action static tests

* chore: Fix test command

---------

Co-authored-by: Ashwin Kumar <ashwinkumar2468@gmail.com>
Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Lucas Yingshyan Ku <99565133+yingku@users.noreply.github.com>
Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>
stocaaro added a commit that referenced this issue Aug 3, 2023
* feat: Actions for pr testing (#12)

* feat: Add working e2e example (#14)

* chore: Add configurable e2e tests to GH workflows (#15)

* feat(e2e): add integ test runner and test

* fix(e2e): retain existing workflows

* fix(e2e): remove old e2e example

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser auth tests (#16)

* chore: add e2e browser auth tests

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser predictions interactions tests (#17)

* chore: add e2e integ_react_predictions

* chore: add browser e2e interactions

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>

* chore: limit PR concurrency (#19)

* chore: add build_type and enable retry (#18)

* prod & dev

* -n 3

* turn off fail-fast

---------

Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>

* chore: add e2e browser datastore tests (#20)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser api,storage tests (#21)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: fix single browser provided in integ-config (#22)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Run dev and prod on the same runner

* chore: Add detox testing (#26)

* Feat/GitHub actions/test ashwinkumar6 (#27)

* chore: Re-arrange integ test configurations and improve prebuild (#29)

* chore: Re-arrange integ test configurations and inprove preflight

* Fix is-preflight flag

* Change preflight to prebuild for consistencu

* Disable fast fail on unit tests

* feat: Change yaml load output pattern

* chore: fix e2e integ_datastore_auth_v2 test

* chore: disable playwright tests (#33)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add google env variables for e2e datastore tests (#35)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add support for uploading artifacts  (#34)

* chore: test upload artifacts

* chore: test uploading artifact

* chore: Detox fix and step cleanup

* chore: Increase detox time limit

* chore: Turn warn to ignore for upload artifact misses

* chore: Disable broken detox tests

* chore: Disable PN testing and remove datastore test not running in circle

* chore: e2e add configurable time_out and retry_count (#36)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Increase deviceTracking timeout

* chore: add deploy workflow (#37)

* chore: add deploy workflow

* chore: gh actions publish code clean up

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Model full CI/CD flow - improve preid release (#38)

* fix: Cache on the single yarn.lock instead of all

* fix: Sync with main

* chore: Revert to relative path use (#40)

* chore: Revert to relative path use

* fix: Remove path from workflows

* chore: Add post-release merge to main

* chore: Remove orphaned workflow files

* chore: e2e add integ_auth_test_cypress_no_ui test (#39)

* chore: e2e add integ_auth_test_cypress_no_ui test

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: change github name and email

* chore: update yarn.log

* chore: move additional e2e commented tests (#43)

* chore: move additional e2e commented tests

* chore: add required permissions to script file

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: e2e keep test_name same as CCI (#45)

* chore: e2e keep test_name same as CCI
* chore: e2e re-arrange integ config
---------
Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: update actions typo

Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>

* chore: update actions typo

Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>

* chore: cleanup github_email and github_name (#46)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: cleanup load verdaccio action (#47)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: actions code cleanup (#48)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Remove unused actions and use env vars instead of injection in run commands (#49)

* chore: add retention period and timeout for cache (#50)

* chore: add retention period and timeout for cache

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Chanke js token name

* chore: Filter preid content

* chore: Move file names around and consume env vars

* fix: Rest bundle size increase

* chore: Compactify on syntax

* chore: dynamically fetch the repo_owner_name (#52)

* chore: dynamically fetch the repo_owner_name

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Configure staging to use corresponding branch name

* chore: Naming and cleanup

* chore: Naming and dependency workflow improvements

* chore: Fix vars use for gh user/email

* chore: run e2e Rollup + DataStore test on just chrome (#54)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Add preid protection (#57)

* chore: Only publish to npm from the aws-amplify org

* chore: add concurrency to push workflows (#56)

* chore: add concurrency to push workflows

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Prepare for merge to main

* chore: Fix circle build

* chore: Okay, this will fix circle!

* chore: Integrate license checking into pr check

* chore: Add github action static tests

* chore: Fix test command

* Update .github/actions/npm-publish/action.yml

Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>

* chore: Fix names and descriptions

---------

Co-authored-by: Ashwin Kumar <ashwinkumar2468@gmail.com>
Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Lucas Yingshyan Ku <99565133+yingku@users.noreply.github.com>
Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>
Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>
svidgen added a commit that referenced this issue Aug 10, 2023
* feat(data): add CCI config for GraphQL API optimistic UI E2E tests (#11585)

* chore: update size limit that is too tight (#11652)

* chore: update size limit that is too tight

* chore(prediction): update size limit after custom s3 client

* fix: duplicate entry in connection states (#11579)

Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>
Co-authored-by: AllanZhengYP <zheallan@amazon.com>

* fix(api-rest): refactor ajax method to not relying on side effects (#11498)

* fix(api-rest): refactor ajax method to not relying on side effects

the previous Signer.sign() implementation not only returns signed
request, but also sets the signed headers to input request. The
recent refactor makes it side-effect-less.

However this change breaks RestClient.ajax() clock skew correction
which relies on the x-amz-date header set by signer to the input
request object to indicate the current client side time.

this fix resolves #11480

* chore: Enable automatic license checking (#11604)

* chore(release): Publish [ci skip]

 - @aws-amplify/analytics@6.4.1
 - @aws-amplify/api-graphql@3.4.5
 - @aws-amplify/api-rest@3.4.0
 - @aws-amplify/api@5.3.5
 - @aws-amplify/auth@5.5.5
 - aws-amplify@5.3.5
 - @aws-amplify/cache@5.1.5
 - @aws-amplify/core@5.7.0
 - @aws-amplify/datastore-storage-adapter@2.0.42
 - @aws-amplify/datastore@4.6.5
 - @aws-amplify/geo@2.2.0
 - @aws-amplify/interactions@5.2.5
 - @aws-amplify/notifications@1.5.0
 - @aws-amplify/predictions@5.4.5
 - @aws-amplify/pubsub@5.4.1
 - @aws-amplify/pushnotification@5.0.39
 - @aws-amplify/storage@5.8.0

* chore(release): update API docs [ci skip]

* chore: Move Storage TS dependency to `devDependencies` (#11666)

* chore: pin @smtihy/types to 1.1.0 to prevent build failure in TS3.8 (#11673)

chore: ping @smtihy/types to 1.1.0 to prevent build failure in TS3.8

This is ok because the AWS SDK and crypto dependencies have been pinned
already

* chore: remove smithy resolution (#11682)

* feat: custom user agent Geo changes for UI handoff (#11632)

* feat: custom user agent Storage changes for UI handoff (#11627)

* chore: move storage code to InternalStorage.ts

* chore: update class and module name to InternalStorage and update imports

* feat: add customUserAgentDetails param to public methods

* feat: add customUserAgentDetails to getProperties methods, fix cancel overload

* feat: make Storage extend internal storage and override public methods

* feat: export InternalStorage from internals scope

* feat: send user agent details from public copy api to service call

* fix: add missing storage action, fix other minor issues

* feat: add userAgentValue with received user agent details to AWSS3Provider options

* fix: send getproperties instead of copy from getproperties method

* test: update tests to handle new form of passing user agent

* Revert "test: update tests to handle new form of passing user agent"

This reverts commit 4bc7c48.

* fix: fix jumbled StorageActions

* test: update CustomUserAgent test

* test: remove storageAction param and asserts from test

* chore: increase bundle size limits

* chore: publish feature branch for testing

* Feat/custom user agent UI/inappmessaging (#11656)

* chore: copy InAppMessaging to InternalInAppMessaging

* feat: add customUserAgentDetails param to InternalInAppMessaging

* feat: make InAppMessaging extend InternalInAppMessaging

* feat: send sync userAgentDetails through to service call

* fix: add SyncMessages value to InAppMessagingAction

* chore: remove extra parameter from non-service-call functions

* fix: fix typo in InAppMessagingAction

* feat: send user agent details through identify user to service call

* chore: remove unused import

* feat: allow InAppMessaging to be configured independently of Notifications

* test: update tests for internal changes

* build: export InternalInAppMessaging from scoped path

* fix: resolve bundle size

* chore: bundle size settings

* chore: increase bundle size limits

* chore: fix typo

* fix: update references to type with typo

* Feat/custom user agent UI/geo (#11657)

* chore: copy Geo code into InternalGeo

* feat: add geo actions

* feat: add customUserAgentDetails to geo provider

* feat: add customUserAgentDetails to public api's and send to service calls

* feat: make Geo extend InternalGeo and override public API's

* build: export InternalGeo from scoped geo/internals path

* chore: increase bundle size limits

* chore: increase bundle size limits

* feat: add user agent param to action that was missed

* chore: update doc-strings with new param

* Revert "Merge branch 'feat/custom-user-agent-ui/main' into feat/custom-user-agent-ui/storage"

This reverts commit f0e8657, reversing
changes made to ec1ed1a.

* fix: remove userAgentValue from CommonStorageOptions

* feat: add userAgentValue param to StorageProvider and implement

* fix: update config type to param type at position

* test: update test class based on changes

* chore: add new param to jsdocs

* chore: update comment from LastParameter (now ConfigParameter)

* chore: add comment explaining StorageProviderApiOptionsIndexMap

* chore: increase bundle size limits

* fix: send userAgentValue through storage put and list

* chore: remove outdated TODO comment

* chore: increase bundle size limits

* feat: custom user agent InAppMessaging changes for UI handoff (#11639)

* chore: copy InAppMessaging to InternalInAppMessaging

* feat: add customUserAgentDetails param to InternalInAppMessaging

* feat: make InAppMessaging extend InternalInAppMessaging

* feat: send sync userAgentDetails through to service call

* fix: add SyncMessages value to InAppMessagingAction

* chore: remove extra parameter from non-service-call functions

* fix: fix typo in InAppMessagingAction

* feat: send user agent details through identify user to service call

* chore: remove unused import

* feat: allow InAppMessaging to be configured independently of Notifications

* test: update tests for internal changes

* build: export InternalInAppMessaging from scoped path

* fix: resolve bundle size

* chore: bundle size settings

* chore: increase bundle size limits

* chore: fix typo

* fix: update references to type with typo

* chore: update jsdocs in InternalInAppMessaging

* chore: increase bundle size limit

* chore: shorten jsdocs comment

* fix: first attempt to fix InAppMessaging internals

* fix: fix internals package.json paths

* test: fix import form internals

* chore: increase bundle size limits

* chore(release): Publish [ci skip]

 - @aws-amplify/analytics@6.5.0
 - @aws-amplify/api-graphql@3.4.6
 - @aws-amplify/api-rest@3.5.0
 - @aws-amplify/api@5.4.0
 - @aws-amplify/auth@5.6.0
 - aws-amplify@5.3.6
 - @aws-amplify/cache@5.1.6
 - @aws-amplify/core@5.8.0
 - @aws-amplify/datastore-storage-adapter@2.0.43
 - @aws-amplify/datastore@4.7.0
 - @aws-amplify/geo@2.3.0
 - @aws-amplify/interactions@5.2.6
 - @aws-amplify/notifications@1.6.0
 - @aws-amplify/predictions@5.5.0
 - @aws-amplify/pubsub@5.5.0
 - @aws-amplify/pushnotification@5.0.40
 - @aws-amplify/storage@5.9.0

* chore(release): update API docs [ci skip]

* chore: Migrate CI/CD to GitHub Actions (#11638)

* feat: Actions for pr testing (#12)

* feat: Add working e2e example (#14)

* chore: Add configurable e2e tests to GH workflows (#15)

* feat(e2e): add integ test runner and test

* fix(e2e): retain existing workflows

* fix(e2e): remove old e2e example

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser auth tests (#16)

* chore: add e2e browser auth tests

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser predictions interactions tests (#17)

* chore: add e2e integ_react_predictions

* chore: add browser e2e interactions

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>

* chore: limit PR concurrency (#19)

* chore: add build_type and enable retry (#18)

* prod & dev

* -n 3

* turn off fail-fast

---------

Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>

* chore: add e2e browser datastore tests (#20)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add e2e browser api,storage tests (#21)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: fix single browser provided in integ-config (#22)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Run dev and prod on the same runner

* chore: Add detox testing (#26)

* Feat/GitHub actions/test ashwinkumar6 (#27)

* chore: Re-arrange integ test configurations and improve prebuild (#29)

* chore: Re-arrange integ test configurations and inprove preflight

* Fix is-preflight flag

* Change preflight to prebuild for consistencu

* Disable fast fail on unit tests

* feat: Change yaml load output pattern

* chore: fix e2e integ_datastore_auth_v2 test

* chore: disable playwright tests (#33)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add google env variables for e2e datastore tests (#35)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: add support for uploading artifacts  (#34)

* chore: test upload artifacts

* chore: test uploading artifact

* chore: Detox fix and step cleanup

* chore: Increase detox time limit

* chore: Turn warn to ignore for upload artifact misses

* chore: Disable broken detox tests

* chore: Disable PN testing and remove datastore test not running in circle

* chore: e2e add configurable time_out and retry_count (#36)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Increase deviceTracking timeout

* chore: add deploy workflow (#37)

* chore: add deploy workflow

* chore: gh actions publish code clean up

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Model full CI/CD flow - improve preid release (#38)

* fix: Cache on the single yarn.lock instead of all

* fix: Sync with main

* chore: Revert to relative path use (#40)

* chore: Revert to relative path use

* fix: Remove path from workflows

* chore: Add post-release merge to main

* chore: Remove orphaned workflow files

* chore: e2e add integ_auth_test_cypress_no_ui test (#39)

* chore: e2e add integ_auth_test_cypress_no_ui test

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: change github name and email

* chore: update yarn.log

* chore: move additional e2e commented tests (#43)

* chore: move additional e2e commented tests

* chore: add required permissions to script file

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: e2e keep test_name same as CCI (#45)

* chore: e2e keep test_name same as CCI
* chore: e2e re-arrange integ config
---------
Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: update actions typo

Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>

* chore: update actions typo

Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>

* chore: cleanup github_email and github_name (#46)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: cleanup load verdaccio action (#47)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: actions code cleanup (#48)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Remove unused actions and use env vars instead of injection in run commands (#49)

* chore: add retention period and timeout for cache (#50)

* chore: add retention period and timeout for cache

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Chanke js token name

* chore: Filter preid content

* chore: Move file names around and consume env vars

* fix: Rest bundle size increase

* chore: Compactify on syntax

* chore: dynamically fetch the repo_owner_name (#52)

* chore: dynamically fetch the repo_owner_name

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Configure staging to use corresponding branch name

* chore: Naming and cleanup

* chore: Naming and dependency workflow improvements

* chore: Fix vars use for gh user/email

* chore: run e2e Rollup + DataStore test on just chrome (#54)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Add preid protection (#57)

* chore: Only publish to npm from the aws-amplify org

* chore: add concurrency to push workflows (#56)

* chore: add concurrency to push workflows

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: Prepare for merge to main

* chore: Fix circle build

* chore: Okay, this will fix circle!

* chore: Integrate license checking into pr check

* chore: Add github action static tests

* chore: Fix test command

* Update .github/actions/npm-publish/action.yml

Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>

* chore: Fix names and descriptions

---------

Co-authored-by: Ashwin Kumar <ashwinkumar2468@gmail.com>
Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Lucas Yingshyan Ku <99565133+yingku@users.noreply.github.com>
Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>
Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>

* chore: Migrate from circle to github actions (#11714)

* chore: Disable RSC test for firefox (#11719)

* chore: Reintroduce circle without deploy/post-release steps (#11720)

* chore: Reintroduce circle without deploy/post-release steps

* chore: Fix yarn.lock issue

* chore: Update yarn.lock (#11725)

* chore: add canary tests (#11721)

* chore: add canary testing

---------

Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>
Co-authored-by: Francisco Rodriguez <frodriguez.cs@gmail.com>

* fix: update on-schedule-canary-test.yml (#11733)

Update on-schedule-canary-test.yml

* chore: Remove jsdoc (#11731)

* chore: remove unused cypress (#11732)

* chore: update react-native version (#11734)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* feat: custom user agent InternalCognitoUser (#11709)

* chore: port code from CognitoUser and CognitoUserPool to internals

* chore: delete InternalCognitoUserPool - separate PR

* chore: update imports and class name

* feat: add userAgentValue param to cognito client api's

* feat: add userAgentValue param to InternalCognitoUser api's, pass to client

* feat: make CognitoUser extend InternalCognitoUser and override api's

* test: update tests to work with additional param, minor fix

* chore: clean up unused imports and const's

* feat: add missing userAgentValue param

* chore: add new param to documentation comments

* build: export InternalCognitoUser from internals scope

* fix: remove default from InternalCognitoUser to fix scoped export

* fix: fix typo causing signOut failure

* build: correct index.d.ts files with changes

* test: revert auth tests

* chore: increase bundle size limits

* chore: simplify InternalCognitoUser import

---------

Co-authored-by: israx <70438514+israx@users.noreply.github.com>

* chore: run canary everyday at 9am (#11735)

* chore: run canary everyday at 9am

* chore: code cleanup

Co-authored-by: Venkata Ramyasri Kota <34170013+kvramyasri7@users.noreply.github.com>

* chore: update canary cron to 9amPDT

* chore: code cleanup

---------

Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Venkata Ramyasri Kota <34170013+kvramyasri7@users.noreply.github.com>

* feat: custom user agent Auth changes for UI handoff (#11606)

* chore: copy Auth code to InternalAuth

* feat: add customUserAgentDetails param to InternalAuth methods

* feat: make AuthClass extend InternalAuthClass, override functions with extra param

* build: export auth internals from /internals scope

* fix: changes signUp back to method type instead of prop so Auth can extend the method

* chore: update auth lint settings to allow class arrow functions to end in semi-colon

* fix: add overloaded method signature back in - unrelated change

* test: fix auth tests by mocking InternalAuthClass instead of AuthClass

* chore: change arrow methods to normal functions

* fix: remove async from overridden async functions

* chore: increase bundle size limits

* fix: remove internalSignUp and fix rest attr with overload and any

* fix: remove internalSignUp and fix rest attr with overload and any

* chore: update jsdocs

* chore: increase bundle size limits

* chore: Added retries to unstable DataStore canaries (#11740)

* fix(notifications): ios module pod cannot be autolinked in RN version < 0.69 (#11751)

* chore: Remove eslint from `amazon-cognito-identity-js` (#11749)

* feat: custom user agent InternalCognitoUserPool (#11716)

* chore: port CognitoUserPool over to InternalCognitoUserPool

* chore: restore CognitoUserPool

* feat: add userAgentValue parameter to signUp

* feat: update class name and imports

* feat: make CognitoUserPool extend internal and override signUp

* feat: export InternalCognitoUserPool from internals index

* feat: send userAgentValue to client service call

* test: fix internalsIndex test

* build: export InternalCognitoUserPool from internals scope

* chore: update CognitoUserPool type to extend internal

* Apply suggestions from code review

Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>

* chore: remove unnecessary test on internals index

* chore: increase bundle size limit

---------

Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>
Co-authored-by: israx <70438514+israx@users.noreply.github.com>

* chore: Bump DataStore join unit test time limit (#11753)

* chore: Upgrade amazon-cognito-identity-json Webpack & other changes (#11746)

* fix: Remove cpx dependency from pubsub (#11752)

* chore: update increase run count for unstable integ tests (#11758)

Co-authored-by: Sridhar <ashwsrir@amazon.com>

* chore: bump commonmarker from 0.23.9 to 0.23.10 in /docs (#11754)

Bumps [commonmarker](https://github.com/gjtorikian/commonmarker) from 0.23.9 to 0.23.10.
- [Release notes](https://github.com/gjtorikian/commonmarker/releases)
- [Changelog](https://github.com/gjtorikian/commonmarker/blob/v0.23.10/CHANGELOG.md)
- [Commits](gjtorikian/commonmarker@v0.23.9...v0.23.10)

---
updated-dependencies:
- dependency-name: commonmarker
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>

* chore: Update `amazon-cognito-identity-js` to use Webpack 5 (#11757)

* fixed build issues; revert api-graphql package merge changes

* fixed bundle size limits, added empty test command to types package to keep lerna happy

* bundle size limits

* updated preid for api-v6

* fixed branch name for tagged release trigger

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: David McAfee <mcafd@amazon.com>
Co-authored-by: AllanZhengYP <zheallan@amazon.com>
Co-authored-by: takpen <131546291+takpen@users.noreply.github.com>
Co-authored-by: Aaron S <94858815+stocaaro@users.noreply.github.com>
Co-authored-by: Jim Blanchard <jim.l.blanchard@gmail.com>
Co-authored-by: aws-amplify-bot <aws@amazon.com>
Co-authored-by: israx <70438514+israx@users.noreply.github.com>
Co-authored-by: erinleigh90 <106691284+erinleigh90@users.noreply.github.com>
Co-authored-by: Ashwin Kumar <ashwinkumar2468@gmail.com>
Co-authored-by: Sridhar <ashwsrir@amazon.com>
Co-authored-by: Lucas Yingshyan Ku <99565133+yingku@users.noreply.github.com>
Co-authored-by: William Lee <43682783+wlee221@users.noreply.github.com>
Co-authored-by: Francisco Rodriguez <frodriguez.cs@gmail.com>
Co-authored-by: Hui Zhao <10602282+HuiSF@users.noreply.github.com>
Co-authored-by: Venkata Ramyasri Kota <34170013+kvramyasri7@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@maziarzamani
Copy link

Embarrassing that there isn't a solution to this problem not involving the user submitting the identityId to the model. 👀 Why even utilise the identity_id in the S3 path if it's not possible to fetch this information through a lambda function?

@jrrewers
Copy link

I just encountered the problem of getting sub by (federated) user ID. I leave this comment hoping to have such a possibility in the future. This is the glue needed between very practical ${cognito-identity.amazonaws.com:sub} in bucket config and basically any other service in AWS.

@angelusualle
Copy link

hmm the only way I can think of doing this without relying on client supplied information would be to send a message to appsync/apigw with sigv4 to get the cognitoIdentityId from the context.identity (in a lambda function), this is injected by APIGW and not dependent on user. In this same call you can pass an access token (to be validated server side, JWT verify) to associate the two. Its annoying it comes to that but thats the only way. Its annoying because you have to decide when to fire this association and sort of keep track of it locally.

@OperationalFallacy
Copy link

OperationalFallacy commented Jul 5, 2024

I'm storing it in custom metadata (for user owned objects)

const { user } = useAuthenticator((context) => [context.user]);

 
 /**
  * 
  * @param param0 
  * @returns 
  * Sets up custom metadata so the app can read owner as aud
 */
  function processFile({ file, key }: { file: File, key: string }) {
    return {
      file,
      key,
      metadata: {
        aud: user.userId
      },
    };
  };
   
 <StorageManager
  acceptedFileTypes={["pdf/*"]}
  path={({ identityId }) => `private/${identityId}/`}
  maxFileCount={1}
  isResumable
  processFile={processFile}
/>

There is a call in Cognito SDK to check if user id has a respective identity id, which is already recorded in object path.

@OperationalFallacy
Copy link

OperationalFallacy commented Jul 29, 2024

I'm storing it in custom metadata (for user owned objects)

Aaand... that won't help with delete object events, because AWS caches the information about caller identity:

{
    "Records": [
        {
            "eventVersion": "2.1",
            "eventSource": "aws:s3",
            "awsRegion": "us-east-1",
            "eventTime": "2024-07-28T16:10:19.230Z",
            "eventName": "ObjectRemoved:Delete",
            "userIdentity": {
                "principalId": "AWS:xxxxKMS:CognitoIdentityCredentials"
            }
        }
    ]
}

It sends once or twice the user id (email) and then it just sends CognitoIdentityCredentials

@OperationalFallacy
Copy link

Did anybody try postAuthentication hook to link sub and identity id? Similar to @aspahwa idea but it will client independent

@angelusualle
Copy link

Did anybody try postAuthentication hook to link sub and identity id? Similar to @aspahwa idea but it will client independent

Who says that would have identity id?

@OperationalFallacy
Copy link

Did anybody try postAuthentication hook to link sub and identity id? Similar to @aspahwa idea but it will client independent

Who says that would have identity id?

Ah! Of course, there is only identity from the pool. How about getting it from jwt token?

import type { AmplifyGraphQlResolverEvent } from "aws-lambda"
import { env } from "$amplify/env/idLinker"
import { CognitoIdentityClient, GetIdCommand, GetIdCommandInput } from "@aws-sdk/client-cognito-identity"

/**
 * Retrieves the Cognito Identity ID using JWT token from the request context
 *
 * @param {string} jwtToken - The JWT token of the authenticated user.
 * @returns {Promise<string>} - A promise that resolves to the Cognito Identity ID.
 * @throws {Error} - If the authorization token is invalid or there is an error fetching the Identity ID.
 */
async function getCognitoIdentityId(jwtToken: string): Promise<string> {
  const client = new CognitoIdentityClient({ region: process.env.AWS_REGION })
  const loginsKey = `cognito-idp.${env.AWS_REGION}.amazonaws.com/${env.AMPLIFY_AUTH_USERPOOL_ID}`

  const params: GetIdCommandInput = {
    IdentityPoolId: "us-east-1:xxxxxx-xxxx-xxxx-xxx-xxxxxxxx",
    Logins: {
      [loginsKey]: jwtToken
    }
  }

  const command = new GetIdCommand(params)

  try {
    const data = await client.send(command)
    console.debug("Call command data", data)
    if (!data.IdentityId) {
      throw new Error("IdentityId not found in the response.")
    }
    return data.IdentityId
  } catch (error) {
    console.error("Error getting Cognito Identity ID:", error)
    throw error
  }
}

export async function handler(event: AmplifyGraphQlResolverEvent): Promise<boolean> {
  console.log("id linker even", JSON.stringify(event, null, 2))
  if (!event.request.headers.authorization) {
    console.debug("How comes there is no auth token")
    return true
  }
  const cognitoIdentityId = await getCognitoIdentityId(event.request.headers.authorization)
  // make/update kv in database
  return true
}

This works and return identity id.

But man! I don't see amplify backend exposes variable for IdentityPoolId...

Is there any potential security issues with this approach? I assume getCognitoIdentityId would error out if jwt is invalid.
Also, I'm not sure how to limit amount of requests to this graphql mutation, so malicious clients won't try to DDOS it. Any tips?

@angelusualle
Copy link

Did anybody try postAuthentication hook to link sub and identity id? Similar to @aspahwa idea but it will client independent

Who says that would have identity id?

Ah! Of course, there is only identity from the pool. How about getting it from jwt token?

import type { AmplifyGraphQlResolverEvent } from "aws-lambda"
import { env } from "$amplify/env/idLinker"
import { CognitoIdentityClient, GetIdCommand, GetIdCommandInput } from "@aws-sdk/client-cognito-identity"

/**
 * Retrieves the Cognito Identity ID using JWT token from the request context
 *
 * @param {string} jwtToken - The JWT token of the authenticated user.
 * @returns {Promise<string>} - A promise that resolves to the Cognito Identity ID.
 * @throws {Error} - If the authorization token is invalid or there is an error fetching the Identity ID.
 */
async function getCognitoIdentityId(jwtToken: string): Promise<string> {
  const client = new CognitoIdentityClient({ region: process.env.AWS_REGION })
  const loginsKey = `cognito-idp.${env.AWS_REGION}.amazonaws.com/${env.AMPLIFY_AUTH_USERPOOL_ID}`

  const params: GetIdCommandInput = {
    IdentityPoolId: "us-east-1:xxxxxx-xxxx-xxxx-xxx-xxxxxxxx",
    Logins: {
      [loginsKey]: jwtToken
    }
  }

  const command = new GetIdCommand(params)

  try {
    const data = await client.send(command)
    console.debug("Call command data", data)
    if (!data.IdentityId) {
      throw new Error("IdentityId not found in the response.")
    }
    return data.IdentityId
  } catch (error) {
    console.error("Error getting Cognito Identity ID:", error)
    throw error
  }
}

export async function handler(event: AmplifyGraphQlResolverEvent): Promise<boolean> {
  console.log("id linker even", JSON.stringify(event, null, 2))
  if (!event.request.headers.authorization) {
    console.debug("How comes there is no auth token")
    return true
  }
  const cognitoIdentityId = await getCognitoIdentityId(event.request.headers.authorization)
  // make/update kv in database
  return true
}

This works and return identity id.

But man! I don't see amplify backend exposes variable for IdentityPoolId...

Is there any potential security issues with this approach? I assume getCognitoIdentityId would error out if jwt is invalid. Also, I'm not sure how to limit amount of requests to this graphql mutation, so malicious clients won't try to DDOS it. Any tips?

You could secure it with sigv4 (IAM auth). Also validate the JWT.

@OperationalFallacy
Copy link

OperationalFallacy commented Aug 1, 2024

front-end makes a dummy mutation request
Lambda checks if id already added and adds it to user profile
front-end also checks if user profile has this field already, so it can skip request next time

Cognito validates jwt, so it's secure mapping.

Worked well. But what an extreme of heavy lifting!

@giladrv
Copy link

giladrv commented Oct 21, 2024

*** 2024: still no way to map Identity ID and User ID (sub) in a non-convoluted way ***

It was such a frustrating experience trying to deal with this issue, and I feel lucky to have found this thread.
Many thanks to @JesseDavda for the solution!

I still struggled a bit to fully implement this in a CloudFormation template, but now it's all automated and I want to share the essential parts here for anyone else who may need them:


  IamPolicyAuth:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ...
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Action:
              - 's3:GetObject'
              - 's3:PutObject'
            Resource:
              - !Sub 'arn:aws:s3:::{bucket_name}/private/${!aws:PrincipalTag/userSub}/*' # the exclamation mark is required to avoid parsing by Fn::Sub

  IamPolicyNoth:
    Type: AWS::IAM::ManagedPolicy
    ...

  IamRoleAuth:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Federated: cognito-identity.amazonaws.com
            Action:
              - sts:AssumeRoleWithWebIdentity
              - sts:TagSession # required for applying principal tags
            Condition:
              StringEquals:
                cognito-identity.amazonaws.com:aud: !Ref IdentityPool
              ForAnyValue:StringLike:
                cognito-identity.amazonaws.com:amr: authenticated
      ManagedPolicyArns:
        - !Ref IamPolicyAuth
      ...

  IamRoleNoth:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Effect: Allow
            Principal:
              Federated: cognito-identity.amazonaws.com
            Action:
              - sts:AssumeRoleWithWebIdentity
              - sts:TagSession # required for applying principal tags
            Condition:
              StringEquals:
                cognito-identity.amazonaws.com:aud: !Ref IdentityPool
              ForAnyValue:StringLike:
                cognito-identity.amazonaws.com:amr: unauthenticated
      ManagedPolicyArns:
        - !Ref IamPolicyNoth
      ...

  IdentityPool:
    Type: AWS::Cognito::IdentityPool
    Properties:
      AllowUnauthenticatedIdentities: False
      CognitoIdentityProviders:
        - ClientId: !Ref UserPoolClient
          ProviderName: !GetAtt UserPool.ProviderName
      ...

  IdentityPoolPrincipalTag:
    Type: AWS::Cognito::IdentityPoolPrincipalTag
    Properties:
      IdentityPoolId: !Ref IdentityPool
      IdentityProviderName: !GetAtt UserPool.ProviderName
      PrincipalTags:
        userSub: sub       # mapping the 'sub' claim from the JWT token to a principal tag named 'userSub'
      UseDefaults: false   # disable defaults for the custom mapping above to take effect

  IdentityPoolRoles:
    Type: AWS::Cognito::IdentityPoolRoleAttachment
    Properties:
      IdentityPoolId: !Ref IdentityPool
      Roles:
        authenticated: !GetAtt IamRoleAuth.Arn
        unauthenticated: !GetAtt IamRoleNoth.Arn

  UserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      ...
      UserPoolAddOns:
        AdvancedSecurityMode: 'OFF' # advanced security mode is NOT required for principal tags
      ...

  UserPoolClient:
    Type: AWS::Cognito::UserPoolClient
    Properties:
      UserPoolId: !Ref UserPool
      ...

@github-actions github-actions bot added the pending-maintainer-response Issue is pending a response from the Amplify team. label Oct 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Auth Related to Auth components/category Cognito Related to cognito issues feature-request Request a new feature pending-maintainer-response Issue is pending a response from the Amplify team. Service Team Issues asked to the Service Team
Projects
None yet
Development

No branches or pull requests