amplify-js icon indicating copy to clipboard operation
amplify-js copied to clipboard

Add Trigger for when User changes User Attributes

Open henryhuangh opened this issue 2 years ago • 11 comments

Is this related to a new or existing framework?

No response

Is this related to a new or existing API?

Authentication

Is this related to another service?

Lambda

Describe the feature you'd like to request

Not sure if this feature is available but I want a way to trigger a lambda function once a user changes user attributes through Auth.updateUserAttributes method.

Describe the solution you'd like

To add an option in the CLI for creating a trigger in Auth when a user modifies their attributes and also add a option in the cognito userpool triggers

Describe alternatives you've considered

Currently, the solution I can think of is to create a lambda function connected to graphql that takes in the modified parameters. The lambda function then send the request to update user attributes along with the actions I want the lambda function to perform.

Additional context

No response

Is this something that you'd be interested in working on?

  • [ ] 👋 I may be able to implement this feature request
  • [ ] ⚠️ This feature might incur a breaking change

henryhuangh avatar Dec 21 '21 18:12 henryhuangh

@henryhuangh thanks for your feature request. Cognito doesnt support that right now, so there is nothing we can do until the service team add this functionality.

What is the use case or problem you want to solve by using this lambda for when the user attribute change?

elorzafe avatar Dec 23 '21 22:12 elorzafe

I created a User type in gql that stores all the user attributes. Once a user signs up, it will update the db. But if the user changes the attributes, the information will be decoupled.

henryhuangh avatar Dec 28 '21 22:12 henryhuangh

@henryhuangh I'm really late here but I was just wondering - could you use the same info the user is passing to Auth.updateUserAttributes and perform a mutation afterwards with the same data?

Similar to this:

const updateUserInfo = async (attributes) => {
  try {
    const user = await Auth.currentAuthenticatedUser();
    await Auth.updateUserAttributes(user, attributes);
    await API.graphql({
      query: updateUser,
      variables: {
        input: {
          id: user.attributes.sub,
          ...attributes,
        },
      },
    });
  } catch (error) {
    console.log(error);
  }
};

chrisbonifacio avatar Apr 07 '22 14:04 chrisbonifacio

Hi @chrisbonifacio, thank you for your response.

Yes, that is what I am currently doing on my frontend. But since this is on the frontend it might introduce some decoupling between the data from Auth and my database. So, it would be better to have a single lambda call to handle both changes. Could this code be used on the backend?

In another thought, it might be better to store all mutable data on the database. But the problem is that some of the data that can be changed is initialized once the user signs up and might not have access to the database yet. In addition, retrieving the data from Cognito might be cheaper than from Appsync DB.

henryhuangh avatar Apr 07 '22 20:04 henryhuangh

@chrisbonifacio I also have the same use case where I need to update the user details in my DB when user puts new attributes or modifies it. Can AWS please priorities this feature?

ShivamJoker avatar Apr 20 '22 14:04 ShivamJoker

Use case for me is validating preferredUsername before allowing user to update it. Lambda trigger for updating userAttributes would be very helpful.

alionthego avatar May 07 '22 02:05 alionthego

To add another use case:

My team is currently trying to migrate to AWS Pinpoint and we want to keep our Pinpoint endpoints up-to-date with our user data stored in Cognito. For example if we would run email campaigns in Pinpoint the emails should have up-to-date user data like family_name and given_name but especially the email needs to be up-to-date.

Since we update user attributes in more than one place (e.g. user frontend and support backoffice) it would be cumbersome go through all these code parts and trigger a sync everywhere manually. Something similar to a DynamoDB stream would be ideal, since we already use them to sync most of our data.

I already had a look at Cognito Streams and Cognito Events but these doesn't seem to fit here.

Are there any updates or short-term plans?

ysfaran avatar Nov 07 '22 14:11 ysfaran

Use case for me is validating preferredUsername before allowing user to update it. Lambda trigger for updating userAttributes would be very helpful.

In would need this for exactly the same reason. The username validation works fine with the pre sign-up hook but when the user changes their preferred_username i cannot validate it.

Quasarman avatar May 25 '23 18:05 Quasarman

I have a similar use case. When user updates Cognito email, want an event to run to then update SES email and don't want to couple it in the application.

Meags27 avatar Aug 10 '23 19:08 Meags27

Can this trigger contemplate not only "User changes User Attributes" use case, but also when "mapping from Federated Idp after authentication" succeeds use case? Cognito updates the user attributes according the mappings configured for the federation after authentication succeeds. Here again, we have another actor that changes the user attributes of our users in the user pool. Having the chance to react to the change can help us with consistency problems.

arale61 avatar Nov 22 '23 14:11 arale61

This feature request is incredibly relevant and it doesn't seem to be getting any attention. Do we have any updates on it @elorzafe?

ygormartins avatar Feb 12 '24 01:02 ygormartins

Here's a use case. My app has federated users.

Federated users cannot have attributes added at sign-up. Instead, I ask these users whether they would like to receive marketing email after they first log in.

I would like to store that information in my athena analytics DB.

I could listen for sign-in events, and ignore them if the user's info is already saved, but that's a lot of extra compute for something I should be able to listen for once.

Instead, I'm writing my own events endpoint to call out to kinesis. Seems like a huge blindspot for cognito.

5t33 avatar Apr 01 '24 23:04 5t33

For anyone who needs this, I solved it by turning on a management API cloudtrail (free) which sends management api events to an S3 bucket and linking that to EventBridge. I create an eventbridge rule for "ChangePassword" or "VerifyUserAttribute" (for when an email is changed and confirmed). To find the event name, just trigger the event in your application then check your CloudTrail event history, inspect it and you'll see the event name. You may have to refresh it a few times before it shows up.

In code it looks like this (but you can make it in the console)

  const eventRuleCognitoUserVerifiedEmail = new Rule(
    stack,
    "CognitoUserVerifiedEmail",
    {
      //default has default event bus
      eventPattern: {
        source: ["aws.cognito-idp"],
        detail: {
          eventSource: ["cognito-idp.amazonaws.com"],
          eventName: ["VerifyUserAttribute"],
          errorCode: [{ exists: false }],
        },
        detailType: ["AWS API Call via CloudTrail"],
      },
      targets: [stateMachineUpdateEmail]
    },
  );

Then the target of the rule is what gets triggered when the event happens. You can add a lambda function as the target.

So you can make your own Cognito lambda triggers for any events that aren't currently supported by default.

Some more guides: https://docs.aws.amazon.com/awscloudtrail/latest/userguide/logging-management-events-with-cloudtrail.html https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html

Meags27 avatar Apr 03 '24 17:04 Meags27

@Meags27 are you sure that the cloudtrail API is free?

ShivamJoker avatar Apr 03 '24 18:04 ShivamJoker

@Meags27 are you sure that the cloudtrail API is free?

Yes it's free for management API calls being send to S3, but there's just a few cents cost for some API calls to S3 by having cloudtrail logging turned on. As it calls GetBucketAcl every 3 minutes or so. During development I have turned off Cloudtrail logging unless I'm testing this, but overall I estimate it would be about $0.3 a month. I'll know more in production.

Meags27 avatar Apr 03 '24 18:04 Meags27