mirror of https://github.com/calzoneman/sync.git
Add name_dedupe column instead of using LIKE kludge for similar-looking names
This commit is contained in:
parent
4701e767b6
commit
f8183bea1b
|
@ -2,7 +2,7 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "3.31.0",
|
"version": "3.32.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
|
|
|
@ -48,6 +48,7 @@ module.exports.init = function () {
|
||||||
global_ipbans = {};
|
global_ipbans = {};
|
||||||
module.exports.users = require("./database/accounts");
|
module.exports.users = require("./database/accounts");
|
||||||
module.exports.channels = require("./database/channels");
|
module.exports.channels = require("./database/channels");
|
||||||
|
module.exports.pool = pool;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -7,15 +7,6 @@ var Logger = require("../logger");
|
||||||
var registrationLock = {};
|
var registrationLock = {};
|
||||||
var blackHole = function () { };
|
var blackHole = function () { };
|
||||||
|
|
||||||
/**
|
|
||||||
* Replaces look-alike characters with "_" (single character wildcard) for
|
|
||||||
* use in LIKE queries. This prevents guests from taking names that look
|
|
||||||
* visually identical to existing names in certain fonts.
|
|
||||||
*/
|
|
||||||
function wildcardSimilarChars(name) {
|
|
||||||
return name.replace(/_/g, "\\_").replace(/[Il1oO0]/g, "_");
|
|
||||||
}
|
|
||||||
|
|
||||||
function parseProfile(data) {
|
function parseProfile(data) {
|
||||||
try {
|
try {
|
||||||
var profile = JSON.parse(data.profile);
|
var profile = JSON.parse(data.profile);
|
||||||
|
@ -31,12 +22,23 @@ module.exports = {
|
||||||
init: function () {
|
init: function () {
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a username for deduplication purposes.
|
||||||
|
* Collapses visibily similar characters into a single character.
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
dedupeUsername: function dedupeUsername(name) {
|
||||||
|
return name.replace(/[Il1]/ig, '1')
|
||||||
|
.replace(/[o0]/ig, '0')
|
||||||
|
.replace(/[_-]/g, '_');
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a username is taken
|
* Check if a username is taken
|
||||||
*/
|
*/
|
||||||
isUsernameTaken: function (name, callback) {
|
isUsernameTaken: function (name, callback) {
|
||||||
db.query("SELECT name FROM `users` WHERE name LIKE ? ESCAPE '\\\\'",
|
db.query("SELECT name FROM `users` WHERE name = ? or name_dedupe = ?",
|
||||||
[wildcardSimilarChars(name)],
|
[name, module.exports.dedupeUsername(name)],
|
||||||
function (err, rows) {
|
function (err, rows) {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, true);
|
callback(err, true);
|
||||||
|
@ -175,10 +177,10 @@ module.exports = {
|
||||||
}
|
}
|
||||||
|
|
||||||
db.query("INSERT INTO `users` " +
|
db.query("INSERT INTO `users` " +
|
||||||
"(`name`, `password`, `global_rank`, `email`, `profile`, `ip`, `time`)" +
|
"(`name`, `password`, `global_rank`, `email`, `profile`, `ip`, `time`, `name_dedupe`)" +
|
||||||
" VALUES " +
|
" VALUES " +
|
||||||
"(?, ?, ?, ?, '', ?, ?)",
|
"(?, ?, ?, ?, '', ?, ?, ?)",
|
||||||
[name, hash, 1, email, ip, Date.now()],
|
[name, hash, 1, email, ip, Date.now(), module.exports.dedupeUsername(name)],
|
||||||
function (err, res) {
|
function (err, res) {
|
||||||
delete registrationLock[lname];
|
delete registrationLock[lname];
|
||||||
if (err) {
|
if (err) {
|
||||||
|
|
|
@ -8,8 +8,10 @@ const TBL_USERS = "" +
|
||||||
"`profile` TEXT CHARACTER SET utf8mb4 NOT NULL," +
|
"`profile` TEXT CHARACTER SET utf8mb4 NOT NULL," +
|
||||||
"`ip` VARCHAR(39) NOT NULL," +
|
"`ip` VARCHAR(39) NOT NULL," +
|
||||||
"`time` BIGINT NOT NULL," +
|
"`time` BIGINT NOT NULL," +
|
||||||
|
"`name_dedupe` VARCHAR(20) DEFAULT NULL," +
|
||||||
"PRIMARY KEY(`id`)," +
|
"PRIMARY KEY(`id`)," +
|
||||||
"UNIQUE(`name`)) " +
|
"UNIQUE(`name`)," +
|
||||||
|
"UNIQUE(`name_dedupe`)) " +
|
||||||
"CHARACTER SET utf8";
|
"CHARACTER SET utf8";
|
||||||
|
|
||||||
const TBL_CHANNELS = "" +
|
const TBL_CHANNELS = "" +
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
var db = require("../database");
|
var db = require("../database");
|
||||||
var Logger = require("../logger");
|
var Logger = require("../logger");
|
||||||
var Q = require("q");
|
var Q = require("q");
|
||||||
|
import Promise from 'bluebird';
|
||||||
|
|
||||||
const DB_VERSION = 7;
|
const DB_VERSION = 9;
|
||||||
var hasUpdates = [];
|
var hasUpdates = [];
|
||||||
|
|
||||||
module.exports.checkVersion = function () {
|
module.exports.checkVersion = function () {
|
||||||
|
@ -58,6 +59,10 @@ function update(version, cb) {
|
||||||
fixCustomEmbeds(cb);
|
fixCustomEmbeds(cb);
|
||||||
} else if (version < 7) {
|
} else if (version < 7) {
|
||||||
fixCustomEmbedsInUserPlaylists(cb);
|
fixCustomEmbedsInUserPlaylists(cb);
|
||||||
|
} else if (version < 8) {
|
||||||
|
addUsernameDedupeColumn(cb);
|
||||||
|
} else if (version < 9) {
|
||||||
|
populateUsernameDedupeColumn(cb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -330,3 +335,56 @@ function fixCustomEmbedsInUserPlaylists(cb) {
|
||||||
Logger.errlog.log(err.stack);
|
Logger.errlog.log(err.stack);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addUsernameDedupeColumn(cb) {
|
||||||
|
Logger.syslog.log("Adding name_dedupe column on the users table");
|
||||||
|
db.query("ALTER TABLE users ADD COLUMN name_dedupe VARCHAR(20) UNIQUE DEFAULT NULL", (error) => {
|
||||||
|
if (error) {
|
||||||
|
Logger.errlog.log(`Unable to add name_dedupe column: ${error}`);
|
||||||
|
} else {
|
||||||
|
cb();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function populateUsernameDedupeColumn(cb) {
|
||||||
|
const dbUsers = require("./accounts");
|
||||||
|
Logger.syslog.log("Populating name_dedupe column on the users table");
|
||||||
|
db.query("SELECT id, name FROM users WHERE name_dedupe IS NULL", (err, rows) => {
|
||||||
|
if (err) {
|
||||||
|
Logger.errlog.log("Unable to perform database upgrade to add dedupe column: " + err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Promise.map(rows, row => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
db.pool.getConnection((error, conn) => {
|
||||||
|
if (error) {
|
||||||
|
reject(error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const dedupedName = dbUsers.dedupeUsername(row.name);
|
||||||
|
Logger.syslog.log(`Deduping [${row.name}] as [${dedupedName}]`);
|
||||||
|
conn.query("UPDATE users SET name_dedupe = ? WHERE id = ?", [dedupedName, row.id], (error, res) => {
|
||||||
|
conn.release();
|
||||||
|
if (error) {
|
||||||
|
if (error.errno === 1062) {
|
||||||
|
Logger.syslog.log(`WARNING: could not set name_dedupe for [${row.name}] due to an existing row for [${dedupedName}]`);
|
||||||
|
resolve();
|
||||||
|
} else {
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}, { concurrency: 10 }).then(() => {
|
||||||
|
cb();
|
||||||
|
}).catch(error => {
|
||||||
|
Logger.errlog.log("Unable to perform database upgrade to add dedupe column: " + (error.stack ? error.stack : error));
|
||||||
|
})
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue