Closed nnurmano closed 4 years ago
Through the console:
Sorry, I was not specific. I wanted to do it with the help of aws-amplify API. The user should be able to delete his account.
Hi @nomadus currently is not posible delete a user using aws-amplify. I know is possible using amazon-cognito-identity-js sdk. Take a look on this https://github.com/aws/aws-amplify/blob/master/packages/amazon-cognito-identity-js/src/CognitoUser.js#L948 I never tried, but I will do it in the next couple of days.
Thank you @elorzafe!
@elorzafe how about disabling a user?
We're having an issue with an app where users may only use their email address as a username to log in. We also allow them to update this email address. When a user does this they are left in a strange state where the user is confirmed, but the email address isn't verified. The user can log in to the app successfully with the new email address (unlike when they first create an account but have yet to complete verification), so there's nothing to stop them from continuing to use the app without verifying this email address.
This leaves the user in a strange state and ideally we'd like to disable them via the API to force them through the verification flow again.
Hi there - any update on this?
We used the amazon-cognito-identity-js to do this, but this has recently started to fail because crypto is no longer defined. I've been digging in to this, but it would seem amazon-cognito-identity-js is simply outdated and it looks like all your efforts are now on amplitude (?)
Should amazon-cognito-identity-js still work? it seems it needs to update the crypto-browserify it uses?
Or is there a different way to achieve this? (We need to be able to delete a cognito user for our integration tests, but also in order to comply with the new GDPR rules (and we'd rather avoid having to do things manually))
Friendly ping
with GDPR deadline looming, I'd love to understand if there is at lease some thoughts on an ETA on this issue?
The aws-sdk includes an adminDeleteUser and deleteUser that might help with some of the use cases mentioned in this thread.
deleteUser just does the job, no need to overcomplicate it.
Thanks @buggy and @sielay - I know you can use the aws-sdk itself directly, or indeed by using cognito JS
My understanding was that AWS wants amplify to be the new client people use though - so rather than using multiple sdks, I'm curious to know when support for deleteUser will be built in to amplify so that we dont have one way to do one thing and another to do something else...
@jliebrand the CognitoUser
object you get back from a successful sign in (https://aws.github.io/aws-amplify/api/classes/authclass.html#signin) via the aws-amplify AuthClass
, is the cognito-js SDK. cognito-js seems to be a dependency of aws-amplify. In fact if you take a look through the code for AuthClass
in a lot of cases it acts as a facade for cognito-js.
You can therefore use the deleteUser
method on the CognitoUser
object.
Great, thanks @baseten - what about for returning users? We use the session to determine if they are still logged in:
let session = Auth.currentSession();
// CognitoUserSession => { idToken, refreshToken, accessToken }
Can we get the CognitoUser from the token somehow?
@jliebrand ss for me it's close enough to use Amplify
(my code that works)
import { CognitoUser } from "amazon-cognito-identity-js";
import { Auth } from 'aws-amplify';
...
public onRemoveAccount() {
Auth
.currentAuthenticatedUser()
.then((user: CognitoUser) => new Promise((resolve, reject) => {
user.deleteUser(error => {
if (error) {
return reject(error);
}
if (this.props.onSessionChange) {
this.props.onSessionChange();
}
document.location.href = "/login";
resolve();
});
}))
.catch(this.onError);
}
Aha! That's the missing piece! The api guide only talks about the currentSession and not the currentAuthenticatedUser.... should have done a bit more digging in the API - apologies...
That sorts me, thanks @sielay
@jliebrand was beaten to it, but yes currentAuthenticatedUser
is the key :)
👍
This is a solution with observables (used in Angular):
import { Auth } from 'aws-amplify';
public deleteUser(): Observable<any> {
return from(Auth.currentAuthenticatedUser()).pipe(
mergeMap(user => {
return new Observable<any>(observer => {
user.deleteUser((err, data) => {
if (err) observer.error(err);
else observer.next(data);
observer.complete();
});
});
})
);
}
What about only disabling the user? I don't find a way to do it with Amplify.
Is it possible to do it like deleteUser
?
@JohanRin Currently there is not an option to disableUser on Amplify. We will keep this marked as feature request
@elorzafe this is a related issue.
Hopefully this feature request will be able to achieve what is described in https://github.com/aws-amplify/amplify-js/issues/606: to disable user and user's access to API Gateway endpoint authorized by Cognito token immediately? It seems that the tokens are valid for at least an hour which I saw on IAM Roles console.
maybe Amplify can expose a function to check if user is disabled
@Jun711 could you take a look at the RFC we have posted for the Amplify CLI here: https://github.com/aws-amplify/amplify-cli/issues/766 The "Admin Queries" might be what you are looking for. If so could you comment in the RFC with more details of how you might like this DX to work?
Disabling the user would be the proper way to go. You have to keep in mind, that if you're just deleting the user from the cognito pool (over the dashboard or API) this does not delete the data associated with the user.
If you have somewhere @auth()
rules for the owner (multi-user app) you'll get in trouble if you delete the user. Because if someone else register then the same username, he will have access to all the data.
I first wanted to write this as a comment here, but then decided to open it as a new issue:
I think this is still a problem. There should be a method Auth.deleteUser
that:
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
Stalebot that's a bad idea, because this issue still persists.
This should not be closed. There is a big short coming with AWS amplify when it comes to disabling/deleting users.
AWS deleteUser()
function should automatically sign users out globally and clear all cache data. Because of this I have to be wire-rigging a userpool
object from AWSConfiguration
and even with userpool.getCurrentUser().deleteUserInBackground(genericHandler)
data of the previous logged in user is still on the device. AWSMobileClient needs some form of "delete user" of its own.
A way I came up with for those using AWSMobileClient; do the following in the same order:
AWSConfiguration awsConfiguration = AWSMobileClient.getInstance().getConfiguration();
userpool = new CognitoUserPool(this, awsConfiguration); // CognitoUserPool object
userpool.getCurrentUser().globalSignOutInBackground(genericHandler);
userpool.getCurrentUser().deleteUserInBackground(genericHandler);
This way it signs the user out globally from all devices after which it deletes the user. Using Android/Java of course.
Is it possible to add a layer of security to the deleteUser
? Something like a "confirm password before deletion"?
How about "DisableUser" support ?
I would want to disable a cognito user for temporary purpose. How to do it, since I couldn't find a API to achieve that goal.
Thanks.
Is there a API/function/method to disable/enable user of userpool ? So that I can disable/enable user using the webapp using API
userpool.getCurrentUser().disableUserInBackground(genericHandler);
userpool.getCurrentUser().enableUserInBackground(genericHandler);
Please look at the Admin Actions functionality that was added last year to Amplify CLI to provide this capability: https://docs.amplify.aws/cli/auth/admin
You can add this to any Amplify project or use it as a template for non-Amplify CLI projects.
Using cognito.adminLinkProviderForUser
in a preSignUp lambda, can result in multiple accounts for the same user.
For example, if there is federated sign-in with Google, an account such as Google_1012514589345043xxxxx
will be present.
Amazon, Facebook, and Apple, will add their own with a potential of 4, including the original, email/username, based user entry.
There really should be an easy, straight-forward way to remove all entries for a user programmatically via an Amplify Auth
method.
Having said that, the below is pretty straight-forward for deleting a single user, and does not require amazon-cognito-identity-js
to work.
const handleDeleteCognitoUser = async () => {
const user = await Auth.currentAuthenticatedUser();
user.deleteUser((error, data) => {
if (error) {
throw error;
}
// do stuff after deletion
});
};
@kimfucious It doesn't seem to remove a social IdP linked user (for example, user who logs in with Google)
@mauerbac how to delete a social IdP linked user?
Hi @Jun711,
My use case may be different from yours, as I require--in this case--users to first have a user/password Cognito user before they can create a social/federated user.
Regardless, how I've been able to delete a social/federated user is by using the below (node.js
) in a lambda function (as part of a larger function that does other stuff).
In short, the adminDeleteUser()
method is your friend. You just need to pass it the correct params. This can't be run on the client side, as far as I ken.
const deleteLinkedProviderUser = async (user) => {
const params = { Username: user, UserPoolId: userPoolId };
const result = await new Promise((resolve, reject) => {
cognito.adminDeleteUser(params, (err, data) => {
if (err) {
reject(err);
return;
}
resolve(data);
});
});
return result;
};
@kimfucious thanks for replying. I figured it out after checking other issues. I had to go to my user pool on AWS Console for Cognito > "App client settings" > "Allowed OAuth Scopes" and check "aws.cognito.signin.user.admin" to authorize delete account action.
@kimfucious Could you try deleting a cognito account + linked google account? I found out that it only deletes the cognito account from user pool in this case.
Considering these 3 cases in user pool
https://github.com/aws-amplify/amplify-js/issues/6121#issuecomment-649790071
Hi Jun,
For me, it's a two step process. Here's a code block with some annotation, which may help.
This particular app is using Redux, which is what all the dispatching is about, and I'm too lazy to clean this up for you.
cognitoUser.attributes
. I'm only checking for Apple and Google.It's ain't pretty, could use a refactor but it works 😉
I hope this helps.
const handleRemoveUser = async (e) => {
e.preventDefault();
try {
setIsDeleting(true);
dispatch({ type: "DELETE_USER_START" });
const cognitoAppleMusicUsername = identities
? JSON.parse(identities)
.filter((item) => item.providerName === "SignInWithApple")
.map((item) => "SignInWithApple_" + item.userId)[0]
: null;
const cognitoGoogleUsername = identities
? JSON.parse(identities)
.filter((item) => item.providerName === "Google")
.map((item) => "Google_" + item.userId)[0]
: null;
const providerUsernames = [];
if (cognitoAppleMusicUsername) {
providerUsernames.push(cognitoAppleMusicUsername);
}
if (cognitoGoogleUsername) {
providerUsernames.push(cognitoGoogleUsername);
}
const cognitoAppleMusicUserId = identities
? JSON.parse(identities)
.filter((item) => item.providerName === "SignInWithApple")
.map((item) => item.userId)[0]
: null;
const cognitoGoogleUserId = identities
? JSON.parse(identities)
.filter((item) => item.providerName === "Google")
.map((item) => item.userId)[0]
: null;
const users = [];
if (cognitoAppleMusicUserId) {
users.push(cognitoAppleMusicUsername);
}
if (cognitoGoogleUserId) {
users.push(cognitoGoogleUsername);
}
// This is clearing the db data, not the Cognito stuff
await dispatch(deleteUserAccountData());
// Deleting Cognito accounts
dispatch({
type: "UPDATE_APP_LOADING_STATUS",
payload: "Removing user account..."
});
const user = await Auth.currentAuthenticatedUser();
// **STEP ONE: Delete Cognito username/password account**
user.deleteUser(async (error) => {
if (error) {
throw error;
}
// **STEP TWO: Delete Cognito (via lambda) linked accounts if they exist**
if (users.length) {
dispatch({
type: "UPDATE_APP_LOADING_STATUS",
payload: "Final cleanup..."
});
try {
const response = await API.post("myAPI", `/cognito`, {
body: {
users: JSON.stringify(users)
}
});
console.log("🗑️", response);
} catch (error) {
dispatch({
type: "UPDATE_APP_LOADING_STATUS",
payload: "Something's not right..."
});
throw error;
}
}
const stream = primaryMusicStream;
Auth.signOut({ global: true });
dispatch({ type: "DELETE_USER_SUCCESS" });
history.replace("/aloha", { primaryMusicStream: stream });
});
return;
} catch (error) {
setIsDeleting(false);
console.warn(error.response ? error.response.data.error.message : error);
if (error.Error) {
dispatch({ type: "DELETE_USER_FAIL", payload: new Error(error.Error) });
} else {
dispatch({ type: "DELETE_USER_FAIL", payload: error });
}
}
};
@kimfucious I see. In short, it is not totally done using Amplify then as it would involves sending a request if the account is linked.
@kimfucious
I noticed that you use Auth.signOut({ global: true });
. Could you tell me how to set up the scope for this?
I got this error when I used it for linked google account logout.
Access Token does not have required scopes
Hi @Jun711,
My use case may be different from yours, as I require--in this case--users to first have a user/password Cognito user before they can create a social/federated user.
Regardless, how I've been able to delete a social/federated user is by using the below (
node.js
) in a lambda function (as part of a larger function that does other stuff).In short, the
adminDeleteUser()
method is your friend. You just need to pass it the correct params. This can't be run on the client side, as far as I ken.const deleteLinkedProviderUser = async (user) => { const params = { Username: user, UserPoolId: userPoolId }; const result = await new Promise((resolve, reject) => { cognito.adminDeleteUser(params, (err, data) => { if (err) { reject(err); return; } resolve(data); }); }); return result; };
Can I know what the var cognito is?
Hi @Ladvace,
That code block is from a lambda using AWS SDK for Node.js.
In this case, cognito
is a variable assigned to the CognitoIdentityServiceProvider
. You can name it anything you want, really, when declaring it.
This can be configured like the below in the lambda function:
const AWS = require("aws-sdk");
const cognito = new AWS.CognitoIdentityServiceProvider();
I hope that helps.
Hi @Jun711,
I've never come across that error, and I've not done anything (intentionally) to affect the scopes.
I believe this is referring to the settings found in User Pool => App Client Settings => OAuth 2.0 => Allowed OAuth Scopes.
In my case, related to the examples I've shared prior, these are all checked (phone, email. openid, aws.cognito.signin.user.admin, and profile), and these have been set when I initially ran amplify add auth
.
Try to have a look at yours to see if you've possibly unchecked something.
Again, my situation may differ from yours, as I require users to create a password/username user in Cognito before allowing them to create a federated user (which gets linked to the password/username user).
Thanks @kimfucious I will look into it more.
My app client has all scopes but phone checked. https://github.com/aws-amplify/amplify-js/issues/5744#issuecomment-652021202
Here I have disabled a user in cognito userpool. But the user still access the app.
Auth.currentAuthenticatedUser(); not returns any error immediately the user is disabled? How can I know the user is disabled? How long the user will access the app after disabled in this case?
Hub.listen('auth', (data) => {
console.log('Hub.auth event:', data);
const { payload } = data;
Auth.currentAuthenticatedUser({ bypassCache: true })
.then(u => {
}, err => {
}
I am using aws-amplify-react-native and aws-amplify.
Hi, @nihp
I'd recommend doing a global signOut and redirecting the user to a page that is public, if you're using protected routes.
Also, do note the "Note" in the link I cited, as it says:
Note: although the tokens are revoked, the AWS credentials will remain valid until they expire (which by default is 1 hour)
@kimfucious Thanks for your reply. I have done global signout as you mentioned. But still i needs to reload the app to go for login screen.
I am using mobile app. Here the user may be in any of the screen.
Admin will disable the user at any time. So i need a quick response. Then only I can able to make the globalsignOut.
Hi @nihp ,
I don't quite follow exactly what you're saying, but I have a feeling that you want the user to be re-directed to the login page automatically upon signOut.
It's important to note that signing out does not tell your app what to do, if simply defines what your app has access to (e.g. back-end resources).
That said, you app will not go to the login page by itself upon signOut. You need to tell it how to behave.
My recommendation would be for you to do one of the following:
history.push("/login"
).I hope that helps.
@Kim ford
My question is after disabling the user, I need to get any response from amplify.
Then only I can immediately make the user to logout the app. Else he can able to access the app up to 1 hour.
So I need any error response immediately after disabling the user.
On Sun, Jul 12, 2020 at 12:41 AM Kim Ford notifications@github.com wrote:
Hi @nihp https://github.com/nihp ,
I don't quite follow exactly what you're saying, but I have a feeling that you want the user to be re-directed to the login page automatically upon signOut.
It's important to note that signing out does not tell your app what to do, if simply defines what your app has access to (e.g. back-end resources).
That said, you app will not go to the login page by itself upon signOut. You need to tell it how to behave.
My recommendation would be for you to do one of the following:
- Use react-router to redirect the user to the login screen after you call the global signOut (e.g. history.push("/login").
- (Better) Setup protected routes (see here https://reactrouter.com/web/example/auth-workflow), using react-router, to ensure that signedIn/signedOut users are redirected to private/public pages accordingly.
- You may also want to take a look at Hub https://docs.amplify.aws/lib/utilities/hub/q/platform/js, to perform specific actions, when auth events occur.
I hope that helps.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/aws-amplify/amplify-js/issues/469#issuecomment-657113859, or unsubscribe https://github.com/notifications/unsubscribe-auth/AI2HKUXSRARAUGZ5N54A7HDR3C2MLANCNFSM4EV3S4VQ .
I could not find info on how to disable or delete user. Could you please provide a documentation link or update documentation?