diff --git a/app/scenes/UserDelete.js b/app/scenes/UserDelete.js index 70f122ff1..ede7e857b 100644 --- a/app/scenes/UserDelete.js +++ b/app/scenes/UserDelete.js @@ -20,13 +20,16 @@ class UserDelete extends React.Component { handleSubmit = async (ev: SyntheticEvent<*>) => { ev.preventDefault(); this.isDeleting = true; - const success = await this.props.auth.deleteUser(); - if (success) { - this.props.auth.logout(); + try { + const success = await this.props.auth.deleteUser(); + + if (success) { + this.props.auth.logout(); + } + } finally { + this.isDeleting = false; } - - this.isDeleting = false; }; render() { diff --git a/server/migrations/20180708231200-serviceid-null.js b/server/migrations/20180708231200-serviceid-null.js new file mode 100644 index 000000000..25af19bf6 --- /dev/null +++ b/server/migrations/20180708231200-serviceid-null.js @@ -0,0 +1,14 @@ +module.exports = { + up: async (queryInterface, Sequelize) => { + await queryInterface.changeColumn('users', 'serviceId', { + type: Sequelize.STRING, + allowNull: true, + }); + }, + down: async (queryInterface, Sequelize) => { + await queryInterface.changeColumn('users', 'serviceId', { + type: Sequelize.STRING, + allowNull: false, + }); + } +} \ No newline at end of file diff --git a/server/models/ApiKey.js b/server/models/ApiKey.js index d2e115914..47d170960 100644 --- a/server/models/ApiKey.js +++ b/server/models/ApiKey.js @@ -31,4 +31,11 @@ const ApiKey = sequelize.define( } ); +ApiKey.associate = models => { + ApiKey.belongsTo(models.User, { + as: 'user', + foreignKey: 'userId', + }); +}; + export default ApiKey; diff --git a/server/models/User.js b/server/models/User.js index 0b720be54..d87da6608 100644 --- a/server/models/User.js +++ b/server/models/User.js @@ -6,6 +6,7 @@ import subMinutes from 'date-fns/sub_minutes'; import { DataTypes, sequelize, encryptedFields } from '../sequelize'; import { publicS3Endpoint, uploadToS3FromUrl } from '../utils/s3'; import { sendEmail } from '../mailer'; +import { Star, ApiKey } from '.'; const User = sequelize.define( 'user', @@ -27,7 +28,7 @@ const User = sequelize.define( lastActiveAt: DataTypes.DATE, lastActiveIp: { type: DataTypes.STRING, allowNull: true }, lastSignedInAt: DataTypes.DATE, - lastSignedInIp: DataTypes.STRING, + lastSignedInIp: { type: DataTypes.STRING, allowNull: true }, suspendedAt: DataTypes.DATE, suspendedById: DataTypes.UUID, }, @@ -48,7 +49,7 @@ const User = sequelize.define( // Class methods User.associate = models => { - User.hasMany(models.ApiKey, { as: 'apiKeys' }); + User.hasMany(models.ApiKey, { as: 'apiKeys', onDelete: 'cascade' }); User.hasMany(models.Document, { as: 'documents' }); User.hasMany(models.View, { as: 'views' }); }; @@ -93,13 +94,17 @@ const setRandomJwtSecret = model => { }; const removeIdentifyingInfo = async model => { + await ApiKey.destroy({ where: { userId: model.id } }); + await Star.destroy({ where: { userId: model.id } }); + model.email = ''; model.name = 'Unknown'; model.avatarUrl = ''; - model.serviceId = ''; + model.serviceId = null; model.username = null; model.slackData = null; model.lastActiveIp = null; + model.lastSignedInIp = null; // this shouldn't be needed once this issue is resolved: // https://github.com/sequelize/sequelize/issues/9318