diff --git a/server/models/User.js b/server/models/User.js index 936efde13..c7ee78dbd 100644 --- a/server/models/User.js +++ b/server/models/User.js @@ -422,9 +422,11 @@ class User extends Model { const cachedUser = userCache.getById(userId) || userCache.getByOldId(userId) if (cachedUser) return cachedUser + const idMatcher = this.sequelize.getDialect() === 'postgres' ? sequelize.where(sequelize.cast(sequelize.col('user.id'), 'text'), userId) : { id: userId } + const user = await this.findOne({ where: { - [sequelize.Op.or]: [{ id: userId }, { 'extraData.oldUserId': userId }] + [sequelize.Op.or]: [idMatcher, { 'extraData.oldUserId': userId }] }, include: this.sequelize.models.mediaProgress }) diff --git a/test/server/models/User.test.js b/test/server/models/User.test.js new file mode 100644 index 000000000..9e2bf5888 --- /dev/null +++ b/test/server/models/User.test.js @@ -0,0 +1,42 @@ +const { expect } = require('chai') +const sinon = require('sinon') +const sequelize = require('sequelize') + +const User = require('../../../server/models/User') + +describe('User model', () => { + describe('getUserByIdOrOldId', () => { + let originalSequelize + + beforeEach(() => { + originalSequelize = User.sequelize + }) + + afterEach(() => { + User.sequelize = originalSequelize + sinon.restore() + }) + + it('should cast id to text on postgres when checking legacy token ids', async () => { + User.sequelize = { + getDialect: () => 'postgres', + models: { + mediaProgress: {} + } + } + + const findOneStub = sinon.stub(User, 'findOne').resolves(null) + + await User.getUserByIdOrOldId('root') + + expect(findOneStub.calledOnce).to.equal(true) + + const options = findOneStub.firstCall.args[0] + const whereOr = options.where[sequelize.Op.or] + + expect(whereOr).to.have.length(2) + expect(whereOr[0].attribute.type).to.equal('text') + expect(whereOr[1]).to.deep.equal({ 'extraData.oldUserId': 'root' }) + }) + }) +})