Deleting  a user’s own account in Open Event

Deleting a user’s own account in Open Event

This blog post will showcase an option using which a user can delete his/her account in Open Event Frontend. In Open Event we allow a user who is not associated with any event and/or orders to delete his/her own account. User can create a new account with same email later if they want. 

It is a 2-step process just to ensure that user doesn’t deletes the account accidentally.

The user needs to get to the Account section where he/she is required to select Danger Zone tab. If user is not associated with any event and/or order, he/she will get an option to delete his/her account along with the following text :

All user data will be deleted. Your user data will be entirely erased and any data that will stay in the system for accounting purposes will be anonymized and there will be no link to any of your personal information. Once you delete this account, you will no longer have access to the system.
Option to delete account in Open Event Frontend

If the user is associated with any event and/or order, the option to delete the account is disabled along with the following text :

Your account currently cannot be deleted as active events and/or orders are associated with it. Before you can delete your account you must transfer the ownership of your event(s) to another organizer or cancel your event(s). If you have tickets orders stored in the system, please cancel your orders first too.
Disabled option to delete account in Open Event Frontend

For above toggle we need to check if a user is deletable or not. For that we must check if a user is associated with any event and/or order. The code snippet which checks this is given below :

     isUserDeletable: computed('data.events', 
       'data.orders', function() {
         if (this.get('data.events').length || this.get('data.orders').length) {
             return false;
         }
         return true;
     })

When a user clicks on the option to delete his/her account, a modal pops up asking the user to confirm his/her email. Once user fills in correct email ID the Proceed button becomes active.

Modal to confirm email ID

The code snippet which triggers the action to open the modal deleteUserModal is given below:

<button {{action 'openDeleteUserModal' data.user.id data.user.email}} class='ui red button'>     
    {{t 'Delete Your Account'}} 
</button>
   openDeleteUserModal(id, email) {     
     this.setProperties({
       'isUserDeleteModalOpen' : true,
       'confirmEmail'          : '',
       'userEmail'             : email,
       'userId'                : id
     });
   }

The code snippet which deals with the email confirmation:

isEmailDifferent : computed('confirmEmail', function() {
   return this.userEmail ? this.confirmEmail !== this.userEmail : true;
 })

When user confirms his/her email and hits Proceed button, a new modal appears which asks the user to confirm his/her action to delete account.

Final confirmation to delete account

The code snippet which triggers the action to open the modal confirmDeleteUserModal is given below: 

<button {{action openConfirmDeleteUserModal}} class="ui red button {{if isEmailDifferent 'disabled'}}">
   {{t 'Proceed'}}
</button>
   openConfirmDeleteUserModal() {
     this.setProperties({
       'isUserDeleteModalOpen'        : false,
       'confirmEmail'                 : '',
       'isConfirmUserDeleteModalOpen' : true,
       'checked'                      : false
     });
   }

When user clicks the Delete button, it triggers deleteUser function, which finally deletes the user’s account and redirect him/her to index page. 

The code snippet for deleteUser function:

  deleteUser(user) {
     this.set('isLoading', true);
     user.destroyRecord()
       .then(() => {
         this.authManager.logout();
         this.routing.transitionTo('index');
         this.notify.success(this.l10n.t('Your account has been deleted successfully.'));
       })
       .catch(() => {
         this.notify.error(this.l10n.t('An unexpected error has occurred.'));
       })
       .finally(() => {
         this.setProperties({
           'isLoading'                    : false,
           'isConfirmUserDeleteModalOpen' : false,
           'checked'                      : false
         });
       });
   }

To ensure that a user cannot delete his/her account via API call, if he/she is associated with event and/or orders, there is a check on server. 

The code snippet for this check:

if data.get('deleted_at') != user.deleted_at:
    if has_access('is_user_itself', user_id=user.id) or  has_access('is_admin'):
        if data.get('deleted_at'):
             if len(user.events) != 0:
                 raise ForbiddenException({'source': ''},  "Users associated with events cannot  be deleted")
             elif len(user.orders) != 0:
                 raise ForbiddenException({'source': ''}, "Users associated with orders cannot be deleted")
             else:
                 modify_email_for_user_to_be_deleted(user)
        else:
             modify_email_for_user_to_be_restored(user)
             data['email'] = user.email
        user.deleted_at = data.get('deleted_at')
else:
     raise ForbiddenException({'source': ''}, "You are not authorized to update this information.")

The helpers modify_email_for_user_to_be_deleted and modify_email_for_user_to_be_restored used in the above code snippet are responsible to update the email of user before deleting him/her or before restoring him/her respectively.

The helper modify_email_for_user_to_be_deleted updates the email ID of user which is to be deleted. It adds ‘.deleted’ substring to email of a user to be deleted.

The helper modify_email_for_user_to_be_restored updates the email ID of user to be restored. It removes ‘.deleted’ substring from a user to be restored. If the email ID obtained after removing ‘.deleted’ from the email ID, we get an email ID which already exists in the system then an error is raised – This email is already registered! Manually edit and then try restoring

We understand that in today’s era, everyone is a bit sceptical about their data and so we now provide freedom to our user to delete their account whenever they want. 

Resources:

Related work and code repo:

Close Menu