Merge pull request #463 from dannycoates/normalizeEmail
normalize email on create account using mysql lower()
This commit is contained in:
Коммит
1cbbca3206
|
@ -63,6 +63,8 @@ module.exports = function (
|
|||
email: data && data.email
|
||||
}
|
||||
)
|
||||
data.rawEmail = data.email
|
||||
data.email = data.email.toLowerCase()
|
||||
this.accounts[data.uid.toString('hex')] = data
|
||||
this.emailRecords[data.email] = data.uid.toString('hex')
|
||||
data.devices = {}
|
||||
|
@ -134,7 +136,7 @@ module.exports = function (
|
|||
|
||||
Heap.prototype.accountExists = function (email) {
|
||||
log.trace({ op: 'Heap.accountExists', email: email })
|
||||
return P(!!this.emailRecords[email])
|
||||
return P(!!this.emailRecords[email.toLowerCase()])
|
||||
}
|
||||
|
||||
Heap.prototype.accountDevices = function (uid) {
|
||||
|
@ -201,7 +203,7 @@ module.exports = function (
|
|||
|
||||
Heap.prototype.emailRecord = function (email) {
|
||||
log.trace({ op: 'Heap.emailRecord', email: email })
|
||||
var uid = this.emailRecords[email]
|
||||
var uid = this.emailRecords[email.toLowerCase()]
|
||||
if (!uid) { return P.reject(error.unknownAccount(email)) }
|
||||
return this.account(uid)
|
||||
}
|
||||
|
|
18
db/mysql.js
18
db/mysql.js
|
@ -134,7 +134,8 @@ module.exports = function (
|
|||
email: data && data.email
|
||||
}
|
||||
)
|
||||
var sql = 'INSERT INTO accounts (uid, email, emailCode, verified, kA, wrapWrapKb, authSalt, verifyHash) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'
|
||||
data.rawEmail = data.email
|
||||
var sql = 'INSERT INTO accounts (uid, email, rawEmail, emailCode, verified, kA, wrapWrapKb, authSalt, verifyHash) VALUES (?, LOWER(?), ?, ?, ?, ?, ?, ?, ?)'
|
||||
return this.getMasterConnection()
|
||||
.then(function(con) {
|
||||
var d = P.defer()
|
||||
|
@ -143,6 +144,7 @@ module.exports = function (
|
|||
[
|
||||
data.uid,
|
||||
data.email,
|
||||
data.rawEmail,
|
||||
data.emailCode,
|
||||
data.verified,
|
||||
data.kA,
|
||||
|
@ -296,7 +298,7 @@ module.exports = function (
|
|||
|
||||
MySql.prototype.accountExists = function (email) {
|
||||
log.trace({ op: 'MySql.accountExists', email: email })
|
||||
var sql = 'SELECT uid FROM accounts WHERE email = ?'
|
||||
var sql = 'SELECT uid FROM accounts WHERE email = LOWER(?)'
|
||||
|
||||
return this.getSlaveConnection()
|
||||
.then(function(con) {
|
||||
|
@ -335,7 +337,7 @@ module.exports = function (
|
|||
|
||||
MySql.prototype.sessionToken = function (id) {
|
||||
log.trace({ op: 'MySql.sessionToken', id: id })
|
||||
var sql = 'SELECT t.tokendata, t.uid, a.verified, a.email, a.emailCode' +
|
||||
var sql = 'SELECT t.tokendata, t.uid, a.verified, a.email, a.rawEmail, a.emailCode' +
|
||||
' FROM sessionTokens t, accounts a WHERE t.tokenid = ? AND t.uid = a.uid'
|
||||
return this.getSlaveConnection()
|
||||
.then(function(con) {
|
||||
|
@ -415,7 +417,7 @@ module.exports = function (
|
|||
|
||||
MySql.prototype.passwordForgotToken = function (id) {
|
||||
log.trace({ op: 'MySql.passwordForgotToken', id: id })
|
||||
var sql = 'SELECT t.tokendata, t.uid, a.email, t.passcode, t.created, t.tries ' +
|
||||
var sql = 'SELECT t.tokendata, t.uid, a.email, a.rawEmail, t.passcode, t.created, t.tries ' +
|
||||
' FROM passwordForgotTokens t, accounts a WHERE t.tokenid = ? AND t.uid = a.uid'
|
||||
return this.getSlaveConnection()
|
||||
.then(function(con) {
|
||||
|
@ -469,7 +471,7 @@ module.exports = function (
|
|||
|
||||
MySql.prototype.emailRecord = function (email) {
|
||||
log.trace({ op: 'MySql.emailRecord', email: email })
|
||||
var sql = 'SELECT uid, verified, emailCode, kA, wrapWrapKb, verifyHash, authSalt FROM accounts WHERE email = ?'
|
||||
var sql = 'SELECT uid, email, rawEmail, verified, emailCode, kA, wrapWrapKb, verifyHash, authSalt FROM accounts WHERE email = LOWER(?)'
|
||||
return this.getSlaveConnection()
|
||||
.then(function(con) {
|
||||
var d = P.defer()
|
||||
|
@ -483,7 +485,8 @@ module.exports = function (
|
|||
var result = results[0]
|
||||
return d.resolve({
|
||||
uid: result.uid,
|
||||
email: email,
|
||||
email: result.email,
|
||||
rawEmail: result.rawEmail,
|
||||
emailCode: result.emailCode,
|
||||
verified: !!result.verified,
|
||||
kA: result.kA,
|
||||
|
@ -500,7 +503,7 @@ module.exports = function (
|
|||
MySql.prototype.account = function (uid) {
|
||||
|
||||
log.trace({ op: 'MySql.account', uid: uid })
|
||||
var sql = 'SELECT email, emailCode, verified, kA, wrapWrapKb, verifyHash, authSalt ' +
|
||||
var sql = 'SELECT email, rawEmail, emailCode, verified, kA, wrapWrapKb, verifyHash, authSalt ' +
|
||||
' FROM accounts WHERE uid = ?'
|
||||
return this.getSlaveConnection()
|
||||
.then(function(con) {
|
||||
|
@ -516,6 +519,7 @@ module.exports = function (
|
|||
return d.resolve({
|
||||
uid: uid,
|
||||
email: result.email,
|
||||
rawEmail: result.rawEmail,
|
||||
emailCode: result.emailCode,
|
||||
verified: !!result.verified,
|
||||
kA: result.kA,
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
CREATE TABLE IF NOT EXISTS accounts (
|
||||
uid BINARY(16) PRIMARY KEY,
|
||||
email VARCHAR(255) NOT NULL UNIQUE KEY,
|
||||
rawEmail VARCHAR(255) NOT NULL,
|
||||
emailCode CHAR(8) NOT NULL,
|
||||
verified BOOLEAN NOT NULL DEFAULT FALSE,
|
||||
kA BINARY(32) NOT NULL,
|
||||
|
|
7
error.js
7
error.js
|
@ -108,11 +108,12 @@ module.exports = function(log) {
|
|||
})
|
||||
}
|
||||
|
||||
errors.incorrectPassword = function () {
|
||||
errors.incorrectPassword = function (rawEmail) {
|
||||
return errors.wrap({
|
||||
code: 400,
|
||||
errno: 103,
|
||||
message: 'Incorrect password'
|
||||
message: 'Incorrect password',
|
||||
email: rawEmail
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -157,7 +158,7 @@ module.exports = function(log) {
|
|||
param: param
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
errors.invalidSignature = function (message) {
|
||||
return errors.wrap({
|
||||
code: 401,
|
||||
|
|
|
@ -82,7 +82,7 @@ module.exports = function (config, i18n, log) {
|
|||
}
|
||||
|
||||
Mailer.prototype.sendVerifyCode = function (account, code, service, preferredLang) {
|
||||
log.trace({ op: 'mailer.sendVerifyCode', email: account.email, uid: account.uid })
|
||||
log.trace({ op: 'mailer.sendVerifyCode', email: account.rawEmail, uid: account.uid })
|
||||
var template = templates.verify
|
||||
var link = this.verificationUrl + '?uid=' + account.uid.toString('hex')
|
||||
if (service) {
|
||||
|
@ -98,7 +98,7 @@ module.exports = function (config, i18n, log) {
|
|||
}
|
||||
var message = {
|
||||
sender: this.sender,
|
||||
to: account.email,
|
||||
to: account.rawEmail,
|
||||
subject: values.l10n.gettext(template.subject),
|
||||
text: template.text(values),
|
||||
html: template.html(values),
|
||||
|
@ -113,7 +113,7 @@ module.exports = function (config, i18n, log) {
|
|||
}
|
||||
|
||||
Mailer.prototype.sendRecoveryCode = function (account, code, preferredLang) {
|
||||
log.trace({ op: 'mailer.sendRecoveryCode', email: account.email })
|
||||
log.trace({ op: 'mailer.sendRecoveryCode', email: account.rawEmail })
|
||||
var template = templates.reset
|
||||
var values = {
|
||||
l10n: i18n.localizationContext(preferredLang),
|
||||
|
@ -121,7 +121,7 @@ module.exports = function (config, i18n, log) {
|
|||
}
|
||||
var message = {
|
||||
sender: this.sender,
|
||||
to: account.email,
|
||||
to: account.rawEmail,
|
||||
subject: values.l10n.gettext(template.subject),
|
||||
text: template.text(values),
|
||||
html: template.html(values),
|
||||
|
|
|
@ -158,12 +158,13 @@ module.exports = function (log, crypto, P, uuid, isA, error, db, mailer, isProdu
|
|||
.then(
|
||||
function (verifyHash) {
|
||||
if (!buffersAreEqual(verifyHash, emailRecord.verifyHash)) {
|
||||
throw error.incorrectPassword()
|
||||
throw error.incorrectPassword(emailRecord.rawEmail)
|
||||
}
|
||||
return db.createSessionToken(
|
||||
{
|
||||
uid: emailRecord.uid,
|
||||
email: emailRecord.email,
|
||||
rawEmail: emailRecord.rawEmail,
|
||||
emailCode: emailRecord.emailCode,
|
||||
verified: emailRecord.verified
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ TestServer.start(config.publicUrl)
|
|||
var email = crypto.randomBytes(10).toString('hex') + '@example.com'
|
||||
var password = '123456'
|
||||
var client = null
|
||||
return Client.create('http://127.0.0.1:9000', email, password, {preVerified: true})
|
||||
return Client.create(config.publicUrl, email, password, {preVerified: true})
|
||||
.then(
|
||||
function (c) {
|
||||
client = c
|
||||
|
@ -91,7 +91,52 @@ TestServer.start(config.publicUrl)
|
|||
}
|
||||
)
|
||||
/*/
|
||||
test(
|
||||
test(
|
||||
'signup with same email, different case',
|
||||
function (t) {
|
||||
var email = 'TEST@EXAMPLE.COM'
|
||||
var email2 = 'test@example.com'
|
||||
var password = 'abcdef'
|
||||
return Client.create(config.publicUrl, email, password, { preVerified: true })
|
||||
.then(
|
||||
function (c) {
|
||||
return Client.create(config.publicUrl, email2, password, { preVerified: true })
|
||||
}
|
||||
)
|
||||
.then(
|
||||
fail,
|
||||
function (err) {
|
||||
t.equal(err.code, 400)
|
||||
t.equal(err.errno, 101, 'Account already exists')
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'the rawEmail is returned in the error on Incorrect Password errors',
|
||||
function (t) {
|
||||
var signupEmail = 'TestX@example.com'
|
||||
var loginEmail = 'testx@example.com'
|
||||
var password = 'abcdef'
|
||||
return Client.create(config.publicUrl, signupEmail, password, { preVerified: true})
|
||||
.then(
|
||||
function (c) {
|
||||
return Client.login(config.publicUrl, loginEmail, password)
|
||||
}
|
||||
)
|
||||
.then(
|
||||
fail,
|
||||
function (err) {
|
||||
t.equal(err.code, 400)
|
||||
t.equal(err.errno, 103)
|
||||
t.equal(err.email, signupEmail)
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
test(
|
||||
'teardown',
|
||||
function (t) {
|
||||
server.stop()
|
||||
|
|
|
@ -9,6 +9,7 @@ module.exports = function (log, inherits, now, Token, crypto) {
|
|||
function PasswordForgotToken(keys, details) {
|
||||
Token.call(this, keys, details)
|
||||
this.email = details.email || null
|
||||
this.rawEmail = details.rawEmail || null
|
||||
this.created = details.created || null
|
||||
this.passcode = details.passcode || null
|
||||
this.tries = details.tries || null
|
||||
|
|
|
@ -7,6 +7,7 @@ module.exports = function (log, inherits, Token) {
|
|||
function SessionToken(keys, details) {
|
||||
Token.call(this, keys, details)
|
||||
this.email = details.email || null
|
||||
this.rawEmail = details.rawEmail || null
|
||||
this.emailCode = details.emailCode || null
|
||||
this.verified = !!details.verified
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче