Commit 85c9db6b authored by Eric Eastwood's avatar Eric Eastwood

Add UI option in delete account modal to turn account into ghost user

parent 46c96e81
# 19.9.0 - *upcoming*
- Add ghost option to account deletion in order to disassociate personal data, https://gitlab.com/gitlab-org/gitter/webapp/merge_requests/1197
# 19.8.0 - 2018-6-29
- Restore token revoked logging, https://gitlab.com/gitlab-org/gitter/webapp/merge_requests/1192
......
......@@ -38,4 +38,27 @@ You can delete your account by using the profile menu dropdown in the top-right
![](https://i.imgur.com/j3Gowl7.png)
This could leave some communities/rooms orphaned without an admin (make sure to set another admin before deletion).
We can't recover your data after deletion but you can re-create your account at any time by signing back in.
### Ghost user
If you want to remove/disassociate all of your personal information from your Gitter account,
you can use the **Remove personal information and turn my account into a "ghost"** checkbox in the delete account modal.
This will:
- Clear any backing identities (such as GitLab/Twitter) including GitHub tokens
- Clear any emails
- Change your username to `ghost~<id>` and your display name to "Ghost"
- Clear your avatar
- Mark your ghost user account as removed
This will **NOT**:
- Delete your messages
- Delete your communities/rooms
- Change mentions of your username
![](https://i.imgur.com/rX3plq5.png)
......@@ -13,33 +13,21 @@ var template = require('./tmpl/delete-account-view.hbs');
var View = Marionette.ItemView.extend({
tagName: 'p',
attributes: { style: '' },
ui: {
ghostUserCheckbox: '.js-delete-account-ghost-user-checkbox'
},
events: {
'input @ui.ghostUserCheckbox': 'onGhostCheckboxChanged'
},
modelEvents: {
'change': 'render'
},
initialize: function() {
this.listenTo(this, 'menuItemClicked', this.menuItemClicked);
this.model.set('ghostUsername', `ghost~${context.getUserId()}`);
},
template: template,
menuItemClicked: function(button) {
switch(button) {
case 'delete':
// Notify others, that they shouldn't redirect while we are trying to logout
appEvents.trigger('account.delete-start');
apiClient.user.delete()
.then(() => {
return logout();
})
.catch((err) => {
log.error('Error while deleting account', { exception: err });
this.model.set('error', `Error while deleting account: ${err} (status: ${err.status})`);
});
break;
case 'cancel':
this.dialog.hide();
break;
}
onGhostCheckboxChanged: function() {
this.model.set('ghost', this.ui.ghostUserCheckbox.is(':checked'));
}
});
......@@ -55,17 +43,42 @@ var Modal = ModalView.extend({
className: 'modal--default__footer__btn--negative'
}];
var lock = new DelayLock();
this.lockModel = new DelayLock();
this.listenTo(lock, 'change:locked', function() {
this.listenTo(this.lockModel, 'change:locked', function() {
this.setButtonState('delete', true);
});
ModalView.prototype.initialize.call(this, options);
this.view = new View({
model: lock
model: this.lockModel
});
}
this.listenTo(this, 'menuItemClicked', this.menuItemClicked);
},
menuItemClicked: function(button) {
switch(button) {
case 'delete':
// Notify others, that they shouldn't redirect while we are trying to logout
appEvents.trigger('account.delete-start');
apiClient.user.delete('/', {
ghost: this.lockModel.get('ghost') || false
})
.then(() => {
return logout();
})
.catch((err) => {
log.error('Error while deleting account', { exception: err });
this.model.set('error', `Error while deleting account: ${err} (status: ${err.status})`);
});
break;
case 'cancel':
this.dialog.hide();
break;
}
},
});
module.exports = Modal;
<input type="checkbox" class="js-delete-account-ghost-user-checkbox" id="form-delete-account-ghost-user-checkbox" {{#if ghost }}checked{{/if}}>
<label for="form-delete-account-ghost-user-checkbox">
Remove personal information and turn my account into a "ghost"
</label>
<hr>
Doing this will:
<ul>
<li>Clear your GitHub tokens (doesn't apply to GitLab/Twitter)</li>
<li>Clear your GitHub tokens</li>
<li>Clear your email</li>
<li>Mark your account as removed</li>
<li>Remove you from all rooms</li>
<li>This could leave some communities/rooms orphaned without an admin (make sure to set another admin before deletion)</li>
{{#if ghost }}
<li>Change your username to "{{ghostUsername}}" and display name to "Ghost"</li>
<li>Remove your avatar</li>
<li>Clear any backing OAuth identities (GitLab/Twitter)</li>
{{/if}}
</ul>
This will <strong>NOT</strong>:
<ul>
<li>Delete your messages</li>
<li>Delete your communities/rooms</li>
<li>Change mentions of your username</li>
</ul>
You can sign back in at any time to re-create your account.
......
......@@ -49,7 +49,14 @@ module.exports = {
destroy: function(req) {
if(!req.user) throw new StatusError(401);
return userRemovalService.removeByUsername(req.user.username)
let ghost = false;
if (typeof req.body.ghost === 'boolean') {
ghost = req.body.ghost;
}
return userRemovalService.removeByUsername(req.user.username, {
ghost: ghost
})
.then(function() {
return { success: true };
});
......
......@@ -73,4 +73,19 @@ describe('user-api', function() {
});
});
it('DELETE /v1/user/:userId with ghost option', function() {
return request(app)
.delete('/v1/user/me')
.send({
ghost: true
})
.set('x-access-token', fixture.user1.accessToken)
.expect(200)
.then(function(result) {
assert.strictEqual(result.status, 200);
assert.deepEqual(result.body, {
success: true
});
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment