Home > Net >  (Mongoose) Failed to remove a TTL field
(Mongoose) Failed to remove a TTL field

Time:10-29

I have a authentication system where the user need to validate their email after creating an account, then the status of the account would change from Pending to Active.

I want to implement a feature that if a user does not validate their email within a time frame, the account will be deleted. I was able to get the delete part done by setting an expire field in the Schema:

const userSchema = new mongoose.Schema<IUser>(
    {
        email: {
            type: String,
            required: true,
        },
        status: {
            type: String,
            default: "Pending",
            required: true,
        },
        expiresAt: {
            type: Date,
            default: () => Date.now()   30 * 1000,
            expires: 30
        }
    },
    {
        timestamps: true
    }

However, the expire counter seem to be still counting even I purposely deleted the expiresAt field, and the document still get deleted.

const user = await User.findById(tokenId).exec();

user.status = 'Active';
user.expiresAt = undefined;
const updatedUser = await user.save();

I wonder is there a way to stop or remove the TTL feature entirely after validation?

CodePudding user response:

This is actually a feature provide by the mongoose schema, You are not actually deleting the expiresAt value, the mongoose schema ignored that input as it does not match the type.

By looking at mongoose source code we can see this:

doc: { status: "Active", expiredAt: undefined }

const keys = Object.keys(obj);
let i = keys.length;
while (i--) {
  key = keys[i];
  val = obj[key];

  if (obj[key] === void 0) {
    delete obj[key];
    continue;
  }
}

The expressions obj[key] === void 0 means if obj[key] === undefined like in your case, basically mongoose removes this value from the update body.

What you want to do is just use an operator like $unset:

db.collection.updateOne({ _id: user._id}, {$set: {status: "Active"}, $unset: {expiresAt: ""}})
  • Related