Amplify-cli: Delete user account from AWS Cognito using the Amplify Android SDK

Created on 17 Sep 2019  路  9Comments  路  Source: aws-amplify/amplify-cli

Which AWS Services is the feature request for?
Cognito

Is your feature request related to a problem? Please describe.
Using AWSMobileClient in an Android app allows to do pretty much anything, except deleting a user. A user cannot delete his account by himself from AWS Cognito only using AWSMobileClient.

Describe the solution you'd like
Is it possible to get a function that allows users to delete their accounts from AWS Cognito, using a command like AWSMobileClient.getInstance().deleteUser(...)?

Environment
AWS SDK for Android 2.14.1

auth feature-request

Most helpful comment

Well, what if the users of my mobile app want to delete their accounts? It looks like a pretty relevant use case to me, especially with the GDPR reglementation in Europe.
I already know a workaround by using the CognitoUser.deleteUserInBackground() function, but it's just that I'm surprised that there is not an equivalent in the Amplify SDK.
But maybe it's not good practice and in that case, what is the best practice for my use case?

All 9 comments

@mregnauld Thanks for reaching out. AWSMobileClient does not have a deleteUser method by design. We do not see a very relevant mobile use case for it. Please let us know more about your particular use case so that we can see if there are alternate ways of achieving it. Thanks!

Well, what if the users of my mobile app want to delete their accounts? It looks like a pretty relevant use case to me, especially with the GDPR reglementation in Europe.
I already know a workaround by using the CognitoUser.deleteUserInBackground() function, but it's just that I'm surprised that there is not an equivalent in the Amplify SDK.
But maybe it's not good practice and in that case, what is the best practice for my use case?

@mregnauld We plan on supporting admin operations through Amplify Cli. This is not currently supported by the CLI but is a work in progress. For now, only way would be for the developer to manually delete it from the console or use one of the low-level API.

@mregnauld in order to implement this immediately, you can do something like this:

  1. Create a Lambda with permission to invoke the AdminDeleteUser API
  2. Give your authenticated user role permission to invoke this Lambda
  3. Add a 'delete account' button somewhere in your app that invokes that Lambda with their Cognito id token as a parameter (NOT just the username, otherwise you introduce the ability for someone to maliciously delete other users)
  4. Validate the ID token to ensure it's authentic and then grab the Cognito username from the token
  5. Use the username plus UserPoolId to invoke AdminDeleteUser on behalf of your user.

Something like this should work for you in terms of the Lambda (Node runtime):

const AWS = require('aws-sdk');
const cognitoIdentity = new AWS.CognitoIdentityServiceProvider({ region: 'us-east-1' }); //replace with the region of your user pool

const UserPoolId = process.env.UserPoolId;

exports.handler = async (event) => {
    const { idToken } = event;

    //TODO: validate and decode idToken
    //https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-verifying-a-jwt.html

    const Username = decodedIdToken["cognito:username"];

    const deleteParams = {
        Username,
        UserPoolId
    }

    try {
        const result = await cognitoIdentity.adminDeleteUser(deleteParams).promise();
        return result;
    } catch (e) {
        console.log(`error deleting user ${Username}: ${e}`)
        throw e;
    }
}

Hi we're actually about to release this as a feature in the CLI. You can see the in-progress PR here: https://github.com/aws-amplify/amplify-cli/pull/2443

Once we release this you'll be able to leverage the deployed infra (it will be API Gateway with Lambda) to invoke a route and perform admin tasks, such as deleting a user, from your app.

@undefobj do you have a similar feature in progress for a generic user pool -> user pool (potentially cross account) migration lambda? If not, I've written a lambda that migrates users from user pool in account A to account B while preserving custom attributes that I may be able to contribute. (I don't own the code but will ask if I can release it to you.)

Also my timing on providing code samples to solve common problems is pretty bad, you guys tend to release baked in solutions whenever I offer a custom solution xD

@jkeys-ecg-nmsu migrations aren't currently in scope but could be a good feature in the future. It would need design as we'd most likely need to support it for multiple categories (Auth, Storage, API, etc.). If this is something you have a fair amount of interest in and sample code I think opening up an RFC or simply feature request issue would be a good next step.

@undefobj

It sounds like you're talking about a full-scale migration of all existing resources for each category when you speak of migration, whereas my suggestion was much smaller in scope, simply provide a simple mechanism to migrate users from legacy pools to new pools without data loss.

I'm not sure it's feasible to write push-button migrations for storage or API simply because of the nature of those categories. If you want to migrate a production database, and you cannot withstand data loss or unavailability, you'll have to do some manual reconciliation after the procedure.

I can see a Storage and API category migration that does the works basically the following way, doing only the first leg of the migration (migrate existing data w/o worrying about incoming/future data):

  1. Prewarm Dynamo (assuming DDB as data source) RCU/WCU for source and destination tables
  2. Scan the source tables to determine amount of data to be migrated
  3. For each model / storage category, create a destination bucket (or destination prefix in a single destination bucket)
  4. Spin up a Data Pipeline with cluster size proportional to (2) for maximum efficiency and send the existing Dynamo data from the source environment to the destination S3 bucket
  5. As each pipeline reports success, re-import the data with inverse data pipelines in the destination environment
  6. Spin down RCU/WCU (this pseudocode can be expanded/interleaved to achieve better cost performance on RCU/WCU)
  7. Cutover endpoints and reconcile differences between source and destination databases.

I only accounted for DDB, not S3, with the above pseudocode. The main problem would be (a) this is not necessarily a cheap procedure, although achieving such a migration completely manually will not be much, if any, cheaper, and (b) the process of diffing two Dynamo tables and restoring the diffed records is not exactly simple. Oh, and the plug-n-play solution I propose would probably be very costly compared to a more gradual solution that doesn't require on spinning up potentially massive Hadoop clusters for indeterminate amounts of time.

I might submit an RFC along these lines in the coming days/weeks.

A bit rough, but will leave this here in case it helps anyone. Lets a user delete themselves 馃憤
```
import AWS from 'aws-sdk'
var user = this.props.auth.currentAuthenticatedUser()
.then(user => {
let region = user.pool.userPoolId.split("_")[0];
var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider({
"region": region,
});
var params = {
AccessToken: user.signInUserSession.accessToken.jwtToken
};
cognitoidentityserviceprovider.deleteUser(params, function(err, data) {
if (err) {
this.setState({"display": "showError", "errorText": err});
} else {
this.props.auth.signOut();
}
});
})
````

Was this page helpful?
0 / 5 - 0 ratings

Related issues

onlybakam picture onlybakam  路  3Comments

amlcodes picture amlcodes  路  3Comments

MageMasher picture MageMasher  路  3Comments

darrentarrant picture darrentarrant  路  3Comments

adriatikgashi picture adriatikgashi  路  3Comments