Ahh, yes you’re quite right - many thanks for pointing this out. The MeteorRestAuthentication middleware needs to honour the tokenExpires mechanism. In my tests the following seems to do this:
// express middleware for authenticating a user resume token
export const MeteorRestAuthentication = (opts) => {
const bearerTokenMiddleware = bearerToken(opts)
const authMiddleware = async (req, res, next) => {
if (req.token) {
const hashedToken = Accounts._hashLoginToken(req.token)
const user = await Meteor.users.findOneAsync(
{
'services.resume.loginTokens.hashedToken': hashedToken,
},
{ fields: { 'services.resume.loginTokens': 1 } },
)
if (user) {
let resume = user.services.resume.loginTokens.find(
(token) => token.hashedToken == hashedToken,
)
if (resume) {
const tokenExpires = Accounts._tokenExpiration(resume.when)
if (new Date() <= tokenExpires) {
// update resume when
Meteor.users.updateAsync(
{ _id: user._id, 'services.resume.loginTokens': resume },
{
$set: {
'services.resume.loginTokens.$': {
hashedToken: resume.hashedToken,
when: new Date(),
},
},
},
)
req.userId = user._id
} else {
// token has expired so remove it
Meteor.users.updateAsync(
{ _id: user._id },
{ $pull: { 'services.resume.loginTokens': resume } },
)
}
}
}
}
next()
}
return [bearerTokenMiddleware, authMiddleware]
}
This approach will remove expired tokens but you might want to combine this with a periodic calling of Accounts._expireTokens() to remove those that are created and then forgotten. Im a little unsure of the consequences of asynchronously updating the user document like this but abstractly it seems sensible.
I found this later thread Simple:rest Meteor 3.x useful for more tips of what other people had done.