mirror of
https://github.com/sudoxnym/habitica-self-host.git
synced 2026-04-14 19:47:03 +00:00
only store necessary data for social login (continuation of 10352) (#10395)
* feat(gdpr) only store necessary data for social login * feat(gdpr) also store email for social users * fix(social auth): store emails array instead of single email * fix(emails): do not get name from old facebook info * add migration to remove extra data from social profiles * update migration description * fix tests * fix typo in migration file
This commit is contained in:
parent
e81e458e9b
commit
8fb67e7944
5 changed files with 119 additions and 32 deletions
109
migrations/users/remove-social-users-extra-data.js
Normal file
109
migrations/users/remove-social-users-extra-data.js
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
const migrationName = 'remove-social-users-extra-data.js';
|
||||
const authorName = 'paglias'; // in case script author needs to know when their ...
|
||||
const authorUuid = 'ed4c688c-6652-4a92-9d03-a5a79844174a'; // ... own data is done
|
||||
|
||||
/*
|
||||
* Remove not needed data from social profiles
|
||||
*/
|
||||
const connectionString = 'mongodb://localhost:27017/habitrpg?auto_reconnect=true'; // FOR TEST DATABASE
|
||||
|
||||
const monk = require('monk');
|
||||
const dbUsers = monk(connectionString).get('users', { castIds: false });
|
||||
|
||||
function processUsers (lastId) {
|
||||
// specify a query to limit the affected users (empty for all users):
|
||||
let query = {
|
||||
migration: {$ne: migrationName},
|
||||
$or: [
|
||||
{ 'auth.facebook.id': { $exists: true } },
|
||||
{ 'auth.google.id': { $exists: true } },
|
||||
],
|
||||
};
|
||||
|
||||
if (lastId) {
|
||||
query._id = {
|
||||
$gt: lastId,
|
||||
};
|
||||
}
|
||||
|
||||
dbUsers.find(query, {
|
||||
sort: {_id: 1},
|
||||
limit: 250,
|
||||
})
|
||||
.then(updateUsers)
|
||||
.catch((err) => {
|
||||
console.log(err);
|
||||
return exiting(1, `ERROR! ${ err}`);
|
||||
});
|
||||
}
|
||||
|
||||
let progressCount = 1000;
|
||||
let count = 0;
|
||||
|
||||
function updateUsers (users) {
|
||||
if (!users || users.length === 0) {
|
||||
console.warn('All appropriate users found and modified.');
|
||||
displayData();
|
||||
return;
|
||||
}
|
||||
|
||||
let userPromises = users.map(updateUser);
|
||||
let lastUser = users[users.length - 1];
|
||||
|
||||
return Promise.all(userPromises)
|
||||
.then(() => {
|
||||
processUsers(lastUser._id);
|
||||
});
|
||||
}
|
||||
|
||||
function updateUser (user) {
|
||||
count++;
|
||||
|
||||
const isFacebook = user.auth.facebook && user.auth.facebook.id;
|
||||
const isGoogle = user.auth.google && user.auth.google.id;
|
||||
|
||||
const update = { $set: {} };
|
||||
|
||||
if (isFacebook) {
|
||||
update.$set['auth.facebook'] = {
|
||||
id: user.auth.facebook.id,
|
||||
emails: user.auth.facebook.emails,
|
||||
};
|
||||
}
|
||||
|
||||
if (isGoogle) {
|
||||
update.$set['auth.google'] = {
|
||||
id: user.auth.google.id,
|
||||
emails: user.auth.google.emails,
|
||||
};
|
||||
}
|
||||
|
||||
dbUsers.update({
|
||||
_id: user._id,
|
||||
}, update);
|
||||
|
||||
if (count % progressCount === 0) console.warn(`${count } ${ user._id}`);
|
||||
if (user._id === authorUuid) console.warn(`${authorName } processed`);
|
||||
}
|
||||
|
||||
function displayData () {
|
||||
console.warn(`\n${ count } users processed\n`);
|
||||
return exiting(0);
|
||||
}
|
||||
|
||||
function exiting (code, msg) {
|
||||
code = code || 0; // 0 = success
|
||||
if (code && !msg) {
|
||||
msg = 'ERROR!';
|
||||
}
|
||||
if (msg) {
|
||||
if (code) {
|
||||
console.error(msg);
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
}
|
||||
process.exit(code);
|
||||
}
|
||||
|
||||
module.exports = processUsers;
|
||||
|
|
@ -19,7 +19,6 @@ function getUser () {
|
|||
emails: [{
|
||||
value: 'email@facebook',
|
||||
}],
|
||||
displayName: 'fb display name',
|
||||
},
|
||||
},
|
||||
profile: {
|
||||
|
|
@ -100,7 +99,7 @@ describe('emails', () => {
|
|||
|
||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||
|
||||
expect(data).to.have.property('name', user.auth.facebook.displayName);
|
||||
expect(data).to.have.property('name', user.profile.name);
|
||||
expect(data).to.have.property('email', user.auth.facebook.emails[0].value);
|
||||
expect(data).to.have.property('_id', user._id);
|
||||
expect(data).to.have.property('canSend', true);
|
||||
|
|
@ -110,13 +109,12 @@ describe('emails', () => {
|
|||
let attachEmail = requireAgain(pathToEmailLib);
|
||||
let getUserInfo = attachEmail.getUserInfo;
|
||||
let user = getUser();
|
||||
delete user.profile.name;
|
||||
delete user.auth.local.email;
|
||||
delete user.auth.facebook;
|
||||
|
||||
let data = getUserInfo(user, ['name', 'email', '_id', 'canSend']);
|
||||
|
||||
expect(data).to.have.property('name', user.auth.local.username);
|
||||
expect(data).to.have.property('name', user.profile.name);
|
||||
expect(data).not.to.have.property('email');
|
||||
expect(data).to.have.property('_id', user._id);
|
||||
expect(data).to.have.property('canSend', true);
|
||||
|
|
|
|||
|
|
@ -327,7 +327,13 @@ api.loginSocial = {
|
|||
} else { // Create new user
|
||||
user = {
|
||||
auth: {
|
||||
[network]: profile,
|
||||
[network]: {
|
||||
id: profile.id,
|
||||
emails: profile.emails,
|
||||
},
|
||||
},
|
||||
profile: {
|
||||
name: profile.displayName || profile.name || profile.username,
|
||||
},
|
||||
preferences: {
|
||||
language: req.language,
|
||||
|
|
|
|||
|
|
@ -35,14 +35,6 @@ export function getUserInfo (user, fields = []) {
|
|||
|
||||
if (fields.indexOf('name') !== -1) {
|
||||
info.name = user.profile && user.profile.name;
|
||||
|
||||
if (!info.name) {
|
||||
if (user.auth.local && user.auth.local.username) {
|
||||
info.name = user.auth.local.username;
|
||||
} else if (user.auth.facebook) {
|
||||
info.name = user.auth.facebook.displayName || user.auth.facebook.username;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (fields.indexOf('email') !== -1) {
|
||||
|
|
|
|||
|
|
@ -171,29 +171,11 @@ function _setUpNewUser (user) {
|
|||
return _populateDefaultTasks(user, taskTypes);
|
||||
}
|
||||
|
||||
function _getFacebookName (fb) {
|
||||
if (!fb) {
|
||||
return;
|
||||
}
|
||||
let possibleName = fb.displayName || fb.name || fb.username;
|
||||
|
||||
if (possibleName) {
|
||||
return possibleName;
|
||||
}
|
||||
|
||||
if (fb.first_name && fb.last_name) {
|
||||
return `${fb.first_name} ${fb.last_name}`;
|
||||
}
|
||||
}
|
||||
|
||||
function _setProfileName (user) {
|
||||
let google = user.auth.google;
|
||||
|
||||
let localUsername = user.auth.local && user.auth.local.username;
|
||||
let googleUsername = google && google.displayName;
|
||||
let anonymous = 'profile name not found';
|
||||
|
||||
return localUsername || _getFacebookName(user.auth.facebook) || googleUsername || anonymous;
|
||||
return localUsername || anonymous;
|
||||
}
|
||||
|
||||
schema.pre('validate', function preValidateUser (next) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue