diff --git a/server/auth/index.js b/server/auth/index.js index 405ace2..9a1d907 100644 --- a/server/auth/index.js +++ b/server/auth/index.js @@ -13,6 +13,14 @@ const checkStatus = async (res) => { throw await res.json(); }; +const deserializeUser = async (userModel, id, done) => { + try { + done(null, await userModel.findOne({ id })); + } catch (error) { + done(error); + } +}; + module.exports = (app, passport) => { const router = express.Router(); const config = app.get('config'); @@ -80,15 +88,15 @@ module.exports = (app, passport) => { const profile = meRes.me; - User.findOneAndUpdate({ + const user = await User.findOneAndUpdate({ id: +profile.id, }, buildWcaUserUpdate(profile, tokenRes.access_token), { upsert: true, useFindAndModify: false, new: true, - }, (err, user) => { - done(err, user.toObject()); }); + + done(null, user.toObject()); } catch (e) { done(e); } @@ -98,11 +106,7 @@ module.exports = (app, passport) => { done(null, user.id); }); - passport.deserializeUser((id, done) => { - User.findOne({ id }, (err, user) => { - done(err, user); - }); - }); + passport.deserializeUser((id, done) => deserializeUser(User, id, done)); router.post('/code', (req, res, next) => { @@ -144,3 +148,5 @@ module.exports = (app, passport) => { return router; }; + +module.exports.deserializeUser = deserializeUser; diff --git a/server/auth/index.test.js b/server/auth/index.test.js new file mode 100644 index 0000000..da5774a --- /dev/null +++ b/server/auth/index.test.js @@ -0,0 +1,27 @@ +/** @jest-environment node */ +/* eslint-env jest */ + +const { deserializeUser } = require('./index'); + +describe('session user deserialization', () => { + it('uses the Mongoose promise API and returns the loaded user', async () => { + const user = { id: 990001 }; + const User = { findOne: jest.fn().mockResolvedValue(user) }; + const done = jest.fn(); + + await deserializeUser(User, 990001, done); + + expect(User.findOne).toHaveBeenCalledWith({ id: 990001 }); + expect(done).toHaveBeenCalledWith(null, user); + }); + + it('passes persistence errors to Passport', async () => { + const error = new Error('database unavailable'); + const User = { findOne: jest.fn().mockRejectedValue(error) }; + const done = jest.fn(); + + await deserializeUser(User, 990001, done); + + expect(done).toHaveBeenCalledWith(error); + }); +});