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",
|
||||
"name": "CyTube",
|
||||
"description": "Online media synchronizer and chat",
|
||||
"version": "3.31.0",
|
||||
"version": "3.32.0",
|
||||
"repository": {
|
||||
"url": "http://github.com/calzoneman/sync"
|
||||
},
|
||||
|
|
|
@ -48,6 +48,7 @@ module.exports.init = function () {
|
|||
global_ipbans = {};
|
||||
module.exports.users = require("./database/accounts");
|
||||
module.exports.channels = require("./database/channels");
|
||||
module.exports.pool = pool;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -7,15 +7,6 @@ var Logger = require("../logger");
|
|||
var registrationLock = {};
|
||||
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) {
|
||||
try {
|
||||
var profile = JSON.parse(data.profile);
|
||||
|
@ -31,12 +22,23 @@ module.exports = {
|
|||
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
|
||||
*/
|
||||
isUsernameTaken: function (name, callback) {
|
||||
db.query("SELECT name FROM `users` WHERE name LIKE ? ESCAPE '\\\\'",
|
||||
[wildcardSimilarChars(name)],
|
||||
db.query("SELECT name FROM `users` WHERE name = ? or name_dedupe = ?",
|
||||
[name, module.exports.dedupeUsername(name)],
|
||||
function (err, rows) {
|
||||
if (err) {
|
||||
callback(err, true);
|
||||
|
@ -175,10 +177,10 @@ module.exports = {
|
|||
}
|
||||
|
||||
db.query("INSERT INTO `users` " +
|
||||
"(`name`, `password`, `global_rank`, `email`, `profile`, `ip`, `time`)" +
|
||||
"(`name`, `password`, `global_rank`, `email`, `profile`, `ip`, `time`, `name_dedupe`)" +
|
||||
" VALUES " +
|
||||
"(?, ?, ?, ?, '', ?, ?)",
|
||||
[name, hash, 1, email, ip, Date.now()],
|
||||
"(?, ?, ?, ?, '', ?, ?, ?)",
|
||||
[name, hash, 1, email, ip, Date.now(), module.exports.dedupeUsername(name)],
|
||||
function (err, res) {
|
||||
delete registrationLock[lname];
|
||||
if (err) {
|
||||
|
|
|
@ -8,8 +8,10 @@ const TBL_USERS = "" +
|
|||
"`profile` TEXT CHARACTER SET utf8mb4 NOT NULL," +
|
||||
"`ip` VARCHAR(39) NOT NULL," +
|
||||
"`time` BIGINT NOT NULL," +
|
||||
"`name_dedupe` VARCHAR(20) DEFAULT NULL," +
|
||||
"PRIMARY KEY(`id`)," +
|
||||
"UNIQUE(`name`)) " +
|
||||
"UNIQUE(`name`)," +
|
||||
"UNIQUE(`name_dedupe`)) " +
|
||||
"CHARACTER SET utf8";
|
||||
|
||||
const TBL_CHANNELS = "" +
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
var db = require("../database");
|
||||
var Logger = require("../logger");
|
||||
var Q = require("q");
|
||||
import Promise from 'bluebird';
|
||||
|
||||
const DB_VERSION = 7;
|
||||
const DB_VERSION = 9;
|
||||
var hasUpdates = [];
|
||||
|
||||
module.exports.checkVersion = function () {
|
||||
|
@ -58,6 +59,10 @@ function update(version, cb) {
|
|||
fixCustomEmbeds(cb);
|
||||
} else if (version < 7) {
|
||||
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);
|
||||
});
|
||||
}
|
||||
|
||||
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