-
Notifications
You must be signed in to change notification settings - Fork 2k
Articles created by deleted users cause server errors #1082
Comments
Ideally articles created by users are still accessible, and we just change the user field to something like "Deleted user". |
There's either an issue that discusses this, or it was asked in the Gitter room. Can't find it now.. I agree with @ilanbiala that they should still be accessible, and displaying something like "Deleted User" on the front-end. However, I think we could come up with a way to handle it on the back-end as well. Perhaps, we'd have a task that performs an update on articles or other artifacts that belong to a user, when that user is deleted. We could set the My worry is that we'd have an orphaned User reference in that MongoDB document. Which might bring up another interesting point.. Maybe we should never delete a User from the system completely, if they have artifacts linked to them. We could do a soft delete of their account. This is sort of an edge case, but I think it can be solved & handled in a graceful manner. |
@mleanos privacy/security issue for that user, and it's deceiving because they technically weren't deleted. |
@ilanbiala You're right. If the developer wanted to have a "soft" delete feature, that would be their call. And probably would need to be a good reason for it. Any thoughts on solving the problem of the orphan User reference in a case like this? |
Create a placeholder user with name "Deleted user" and assign articles to be owned by that user? |
@ilanbiala Yea, that's along the line of what I was trying to describe above. We'd need a post delete hook (if we don't already) on the User model. We would use that as a cleanup of sorts on the User data & any related data. |
@ilanbiala @mleanos I think the placeholder user seems like the best idea. |
I'm +1 for handling a post delete hook. |
@ilanbiala Sounds like we have a consensus. I'll submit a PR, unless @jloveland has already done some work on this and wants to handle it; Jason, I wanted to throw that out there since you were the one that opened this issue. |
@mleanos go for it! I haven't had a lot of time lately. |
I'm having a bit back & forth with myself, on the implementation for this. I like the idea of handling this in a The issue with this is that we would need to reference other models from the User model definition file. For instance, we would need to pull in the Articles model for finding any articles that are related to this deleted User. We can't be sure the model is available when the model is loaded; in the case of referencing the Article model from the User model it's fine because of the issue of the models loaded in alphabetical order. But the inverse will not work. This opens up a whole other issue of how we're loading the models when the app starts. The simple implementation seems to be to add the cleanup here. But it's not DRY enough for my taste. Any thoughts? |
Referencing other models from the User model sounds like a bad idea to me too. If not, then in the Articles module we can show a [deleted] entry instead. By the way, another approach is to also re-think the user deletion in general, where we don't actually remove user entries from the system, but instead have an |
@lirantal security/privacy issue. End users think delete means "gone", not just marked as deleted and kept. |
I agree with @ilanbiala that user privacy is an issue here if we don't actually remove the user's account completely. However, I believe the "policy" would be up to the developer of the app and corresponding to their EULA. I would like to see the default behavior of Mean.js delete the user's data and update the articles they published to be owned by deleted user. @mleanos given @lirantal's feedback, putting the code to delete the user and set the articles to be owned by deleted user in a admin controller instead of the model would decouple the user and article model. This would make it easier for me to remove the article module and not need to worry about repercussions? Is there a clean way to detect existing modules and automatically discover modules? i.e. I remove the articles module, then the admin code would be able to check if it's there before it tries to query for articles? |
@ilanbiala @jloveland @lirantal I still like the idea of a "soft" delete feature, for User's. I know there are concerns over privacy. However, what exactly are those concerns (negative consequences)? It seems standard to have a "soft" delete with a Currently, we don't have a feature that allows the User to delete their own account. The For me the issue comes down to the reasoning behind the need to delete all the User data. Is it because the policy is to remove any traces of existence of that User? If so, then that would mean we'd want to remove every artifact (data) that they created; including Articles. If it's for privacy concerns over their User profile data, then I say we remove any sensitive data; Provider data, tokens, roles, profile image, and any other details we can deem as "sensitive". |
One thing I have to point out is that the database would need a User that we would use to set these articles to be owned by. That might add additional complexity. |
On the issue of the User model references.. I feel like the current implementation of the User models could use some work, or at least discussion. It seems that the current model definition file (e.g. Are the pre/post hooks, statics, and methods of a Mongoose model never intended to interact with anything outside the scope of it's own model? I want to think this is not the case. However, in order to solve this problem (referencing other models from statics/hooks/methods) then we'd need to come up with a more effective way of loading, and defining, our models that would allow for more flexibility. Some exploration I was doing, led me to this discussion, and response.. Automattic/mongoose#1953 (comment) It seems like it's acceptable to reference models from other models' methods? If so, how do we solve the problem of not knowing if a model has been registered with Mongoose at the time that we need to reference said Model from a Model? One route that I went down was to redefine the models like this, using Articles as a simple example... // article.server.model.js
'use strict';
/**
* Module dependencies.
*/
var mongoose = require('mongoose'),
path = require('path'),
User = require(path.resolve('modules/users/server/models/user.server.model.js')).init(),
Schema = mongoose.Schema;
var model = {
schema: getSchema,
init: initModel
};
module.exports = model;
/**
* Initialize Article Model
*/
function initModel (schema) {
schema = schema || getSchema();
return getModelOrCreate(schema);
}
function getModelOrCreate (schema) {
try {
return mongoose.model('Article');
} catch (e) {
mongoose.model('Article', schema);
return mongoose.model('Article');
}
}
/**
* Article Schema
*/
function getSchema () {
var schema = new Schema({
created: {
type: Date,
default: Date.now
},
title: {
type: String,
default: '',
trim: true,
required: 'Title cannot be blank'
},
content: {
type: String,
default: '',
trim: true
},
user: {
type: Schema.ObjectId,
ref: 'User'
}
});
return schema;
} Notice my intention of being able to ensure a model has been registered with Mongoose, and loading it into a different model for use. However, I ran into weird behavior with doing this. You can see the implementation here mleanos@9d55a8e and this is where the problem comes in mleanos@9d55a8e#commitcomment-14810936 |
I'll quickly sum up my points here:
|
I agree with your points @lirantal I got a little carried away with all that model craziness that I was experimenting with :) I think these are our main options..
|
I should clarify in the 2nd option above, I meant that we should remove the reference to the deleted user from the article, and not remove the Article. |
IMO it's either option (1) or (3). |
@codydaig @jloveland @ilanbiala Any feedback? |
I like option 3. When soft-deleting the user, I think we should remove sensitive data where possible. Additionally, since, we are not completely deleting the user, maybe we should update the display name to DISABLED_USER? Rationale about making the user's display name disabled is that the user can no longer register themselves again with that email address and suggesting it was deleted implies the user can re-register one day..right? In the case that we disable the user, maybe in a future PR, we provide a way to re-enable their account? i.e. When a user tries to re-register/sign up with that email address, we could check if the user's account has DISABLED_USER in the display name, it could display a warning at the bottom saying the user's account is disabled and they will receive an email to re-enable it, then the server could send them an email asking if they want to enable their account..they click on a url to confirm.. |
Per my last comment, maybe we delete the users email address too? |
Having a soft delete complicates things a bit like that because we need to "manage" the deleted users. To avoid over-complicating it I suggest we take the simpler approach out of the possible options. Looks to me like it's option (1) ? |
Agreed. I'll start working on option 1. Thanks guys! |
Adds an additional check for the existence of a populated user reference, when determining if the current user has immediate access to the requested article. Without this fix, the server will throw an error if the requested article doesn't have a populated user field. Modified the article & articles list view's to check if the article has a populated user. If not, then it will display "Deleted User" in place of the missing user reference. Added a server-side test that ensures we can get a single article if the article.user field is referencing a deleted user. Fixes meanjs#1082
I create an article with user1, then I delete user1 from the system. I log in as user2 and try to view the article created by user1. This causes a server error:

We could solve this by checking to make sure
article.user
exists inarticles.server.controller.js
here:
https://github.com/meanjs/mean/blob/master/modules/articles/server/controllers/articles.server.controller.js#L107
The text was updated successfully, but these errors were encountered: