update timestamp when user logs in (#15489)

* update timestamp when user logs in

* fix(comment): typo

---------

Co-authored-by: Kalista Payne <sabrecat@gmail.com>
This commit is contained in:
Phillip Thelen
2025-08-19 21:04:33 +02:00
committed by GitHub
parent 3a2f5e724d
commit 836cbdb81e
4 changed files with 37 additions and 4 deletions

View File

@@ -110,6 +110,18 @@ describe('POST /user/auth/local/login', () => {
expect(isValidPassword).to.equal(true); expect(isValidPassword).to.equal(true);
}); });
it('sets auth.timestamps.updated', async () => {
const oldUpdated = new Date(user.auth.timestamps.updated);
// login
await api.post(endpoint, {
username: user.auth.local.email,
password,
});
await user.sync();
expect(user.auth.timestamps.updated).to.be.greaterThan(oldUpdated);
});
it('user uses social authentication and has no password', async () => { it('user uses social authentication and has no password', async () => {
await user.unset({ await user.unset({
'auth.local.hashed_password': 1, 'auth.local.hashed_password': 1,

View File

@@ -167,5 +167,24 @@ describe('POST /user/auth/social', () => {
await expect(getProperty('users', user._id, '_ABtests')).to.eventually.be.a('object'); await expect(getProperty('users', user._id, '_ABtests')).to.eventually.be.a('object');
}); });
it('sets auth.timestamps.updated', async () => {
let oldUpdated = new Date(user.auth.timestamps.updated);
await user.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});
await user.sync();
expect(user.auth.timestamps.updated).to.be.greaterThan(oldUpdated);
oldUpdated = new Date(user.auth.timestamps.updated);
// Do it again to ensure it updates even when nothing else changes
await api.post(endpoint, {
authResponse: { access_token: randomAccessToken }, // eslint-disable-line camelcase
network,
});
await user.sync();
expect(user.auth.timestamps.updated).to.be.greaterThan(oldUpdated);
});
}); });
}); });

View File

@@ -121,8 +121,10 @@ api.loginLocal = {
// convert the hashed password to bcrypt from sha1 // convert the hashed password to bcrypt from sha1
if (user.auth.local.passwordHashMethod === 'sha1') { if (user.auth.local.passwordHashMethod === 'sha1') {
await passwordUtils.convertToBcrypt(user, password); await passwordUtils.convertToBcrypt(user, password);
await user.save();
} }
// Force the updated timestamp to update, so that we know they logged in
user.auth.timestamps.updated = new Date();
await user.save();
res.analytics.track('login', { res.analytics.track('login', {
category: 'behaviour', category: 'behaviour',

View File

@@ -67,10 +67,10 @@ export async function loginSocial (req, res) { // eslint-disable-line import/pre
} }
if (!user.auth.local.email) { if (!user.auth.local.email) {
user.auth.local.email = await socialEmailToLocal(user); user.auth.local.email = await socialEmailToLocal(user);
if (user.auth.local.email) {
await user.save();
}
} }
// Force the updated timestampt to update, so that we know they logged in
user.auth.timestamps.updated = new Date();
await user.save();
return loginRes(user, req, res); return loginRes(user, req, res);
} }