我有一个身份验证系统,用户需要在创建帐户后验证他们的邮箱,然后帐户的状态将从待定更改为活动.

我想实现一个功能,如果用户没有在时间框架内验证他们的邮箱,帐户将被删除.通过在模式中设置Expire域,我能够完成删除部分:

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
    }

然而,即使我故意删除了expiresAt字段,过期计数器似乎仍然在计数,文档仍然被删除.

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

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

我想知道有没有办法在验证后停止或完全删除TTL功能?

推荐答案

这实际上是由mongoose模式提供的特性,您实际上并没有删除expiresAt值,mongoose模式忽略了该输入,因为它与类型不匹配.

通过查看mongoose个源代码,我们可以看到:

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;
  }
}

表达式obj[key] === void 0表示If obj[key] === undefined,就像您的例子一样,基本上mongoose会从更新正文中删除此值.

您要做的只是使用像$unset这样的运算符:

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

Node.js相关问答推荐

无法验证叶签名|无法验证第一个证书

购物车是空的状态|本地存储不更新产品数量|Redux|

从MongoDB获取Tree数据

使用参考中断Mongoose模型-Node.js

下一个API路由如何处理多个并发请求?

动态设置元数据,无需重复请求 NextJS 13

如何使用Next.js/Node/TS正确地上传至S3

无法通过 NextJS 访问 HTTP 帖子中的正文

bcrypt.compare 每次都返回 false

有没有办法判断 UUID 是否是使用 node.js 中的特定命名空间生成的?

node-gyp: "..\src\binding.cc: 没有这样的文件或目录"

npm install 在 Mac 上的 Node-gyp 构建错误

在 NodeJS/ESP32 中通过 WebSocket 发送二进制数据 - 如何识别二进制和文本消息

Mongoose,如何一次更新多个?

如果 express.js (node.js) http 请求在完成之前关闭会发生什么?

为什么 JavaScript 的 parseInt(0.0000005) 打印5?

从 Node.js 应用程序查询 Heroku 托管的 Postgres 数据库时出现自签名证书错误

npm WARN 不推荐使用 graceful-fs@3.0.8:graceful-fs 版本 3

名称类型为 mongoose 的字段

如何从 Node.js 应用程序Ping?