mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2026-08-02 22:51:45 +00:00
fix user cache misses for mixed-case username and email lookups
getUserByUsername/getUserByEmail normalize to lowercase before the cache lookup, but the cache comparators matched case-sensitively, so a mixed-case stored username never cache-hit and every login ran an unindexed LOWER() scan. Compare case-insensitively inside the cache.
This commit is contained in:
parent
65bcc8488a
commit
9a5980e76b
2 changed files with 38 additions and 2 deletions
|
|
@ -18,12 +18,16 @@ class UserCache {
|
|||
}
|
||||
|
||||
getByEmail(email) {
|
||||
const user = this.cache.find((u) => u.email === email)
|
||||
if (!email) return null
|
||||
const normalizedEmail = email.toLowerCase()
|
||||
const user = this.cache.find((u) => u.email && u.email.toLowerCase() === normalizedEmail)
|
||||
return user
|
||||
}
|
||||
|
||||
getByUsername(username) {
|
||||
const user = this.cache.find((u) => u.username === username)
|
||||
if (!username) return null
|
||||
const normalizedUsername = username.toLowerCase()
|
||||
const user = this.cache.find((u) => u.username && u.username.toLowerCase() === normalizedUsername)
|
||||
return user
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,6 +43,38 @@ describe('User model', () => {
|
|||
expect(options.where.attribute.args[0].col).to.equal('email')
|
||||
expect(options.where.logic).to.equal('example.user@example.com')
|
||||
})
|
||||
|
||||
it('should hit the user cache for mixed-case username lookups', async () => {
|
||||
User.sequelize = {
|
||||
models: {
|
||||
mediaProgress: {}
|
||||
}
|
||||
}
|
||||
const cachedUser = { id: 'cache-test-user-1', username: 'CacheTestUser', email: 'cachetest@example.com', extraData: {} }
|
||||
const findOneStub = sinon.stub(User, 'findOne').resolves(cachedUser)
|
||||
|
||||
await User.getUserByUsername('CacheTestUser')
|
||||
await User.getUserByUsername('cachetestuser')
|
||||
await User.getUserByUsername('CACHETESTUSER')
|
||||
|
||||
expect(findOneStub.callCount).to.equal(1)
|
||||
})
|
||||
|
||||
it('should hit the user cache for mixed-case email lookups', async () => {
|
||||
User.sequelize = {
|
||||
models: {
|
||||
mediaProgress: {}
|
||||
}
|
||||
}
|
||||
const cachedUser = { id: 'cache-test-user-2', username: 'CacheEmailUser', email: 'CacheMail@Example.com', extraData: {} }
|
||||
const findOneStub = sinon.stub(User, 'findOne').resolves(cachedUser)
|
||||
|
||||
await User.getUserByEmail('CacheMail@Example.com')
|
||||
await User.getUserByEmail('cachemail@example.com')
|
||||
await User.getUserByEmail('CACHEMAIL@EXAMPLE.COM')
|
||||
|
||||
expect(findOneStub.callCount).to.equal(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('getUserByIdOrOldId', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue