The main problem here is that this implementation is flawed, because if your node application is restarted during the 24-hour window, your timeout will disappear (is an in memory object, not persisted) and the token will remain active, exposing you to security risks.
Manual token verification
A very common solution is to save the token_expiration_date
alongside the token, making a date comparison during the related password reset request. If the token_expiration_date
is expired, the request return an error and the server must delete the token on the db.
You can also make the opposite: store the token_creation_date
and the max-token-ttl
in your app code (e.g. 24 hours). In any case you make the date comparison at request time.
@NikKyriakides suggested (see comments) a more sophisticated version of this approach: you create a single JWT token that contains itself the expiration date. When the user request the reset password page you need only to verify if the token is valid calling a single method (no manual date comparison).
The Mongo expire option
A more elegant and effective solution is to create a different mongoose schema for your forgetpassword_token and use the native mongo/mongoose expire option to auto delete documents after a fixed time from their creation.
const secondsInADay = 60 * 60 * 24;
const tokenSchema = mongoose.Schema({
value: String
}, {timestamps: true});
tokenSchema.index({createdAt: 1},{expireAfterSeconds: secondsInADay});
const Token = mongoose.model('Token', tokenSchema);
Then add to your existing CompanySchema a reference to this schema:
forgetpassword_token: {type: mongoose.Schema.Types.ObjectId, ref: 'Token'}
A lot of question exists on this topic, so please also check them alongside with the related mongoose documentation.
The job scheduler
Another approach is to use a job scheduler like agenda to hourly check for expired tokens and delete them. Yes, you can write a setTimeout
based check as a module for your app, but if the right tools exists yet, why don't use it? Also check @NikKyriakides comments below for potential drawbacks of this solution.