npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@evarentha/linearpress-easy-2fa

v3.0.0

Published

基于 TOTP 的两步验证(兼容 Google Authenticator 等验证器):关闭/开启/严格开启三种模式,四词还原码单次使用,管理员可对单个用户强制关闭,可选 WebAuthn 通行密钥辅助登录。

Readme

两步验证(easy-2fa)

LinearPress npm Node.js TypeScript License: GPL-3.0-or-later

English | 简体中文

为 LinearPress 登录提供基于 TOTP 的第二因子,兼容各主流验证器应用,配备 10 个一次性还原码,可选 WebAuthn 通行密钥,零外部依赖。严格模式下,所有账号在下次登录时都将被要求完成绑定,启用前请确认此影响。

安装

git clone https://github.com/Evarentha/linearpress-easy-2fa.git src/plugins/easy-2fa

目录名必须与插件 id 一致,安装后需重启 LinearPress。也可以在 base 检出中执行 sh scripts/sync-plugins.sh easy-2fa,或在后台插件页上传 ZIP、填写 npm 包名。用户端需安装任意符合 RFC 6238 的验证器应用。WebAuthn 要求安全上下文:生产环境使用 HTTPS,本地开发 localhost 即可。

登录流程的变化

本插件接管 POST /login。密码校验通过后先挂起会话(尚未登录),跳转至挑战页;尚无第二因子的账号则跳转至绑定页。无须挑战时请求原样放行,因此 advanced-user-management 的登录限流照常工作。另有一道全局强制中间件兜底:任何未完成挑战即登录的会话都将被重定向回挑战页,完成挑战时将重建会话 id。

五分钟内挑战失败 10 次,该账号将被锁定一段时间。

还原码

绑定(或重新绑定)时生成 10 个一次性还原码,每个由 4 个常见英文单词以连字符连接,例如 morning-apple-bed-egg。同一批次内单词不重复;十个还原码取自经洗牌的 83 词表,整批约 240 位熵即来源于此。数据库仅存储 SHA-256 哈希,校验前先行归一化输入。还原码仅在生成时展示一次。10 个全部用尽后,须由管理员对该用户强制关闭两步验证方可重新绑定。

通行密钥

WebAuthn 为可选功能,默认关闭。通行密钥可替代验证码完成登录挑战,且不消耗还原码。凭证支持 ES256 与 RS256。校验覆盖挑战值、来源、RP-ID 哈希、用户在场、用户已验证、签名计数器防克隆检查及签名本身。注册时同步验证 packed 证明签名:携带 x5c 证书链时,叶子证书必须可解析、不得为 CA、公钥类型必须与声明的算法一致、签名必须可由叶子证书公钥验证;自证明时,声明的算法必须与凭证公钥一致,签名必须可由凭证公钥验证。证明证书到信任根的链路校验不在范围内,因为注册请求的证明策略为 none。

Base32、TOTP、绑定页输出 SVG 的字节模式二维码编码器、CBOR 解码器全部在插件内实现,安装时不引入任何外部依赖。

后台

设置位于 /admin/easy-2fa:模式(关闭 / 可选 / 严格)、验证器中显示的签发方名称、TOTP 窗口(0 至 5 个周期,最多 ±150 秒,容忍设备时钟漂移)、WebAuthn 开关。用户在 /profile/security 自助管理:开启、关闭、重新生成还原码、增删通行密钥。登录挑战与首次绑定在 /login/2fa/* 下进行。

easy-2fa:manage 权限开放管理页:逐用户总览(两步验证状态、剩余还原码数量、已绑定通行密钥数量)及逐用户强制关闭(删除密钥、作废还原码、移除通行密钥)。

三张表以跨方言 SQL 编写,跟随站点当前使用的数据库驱动:easy2fa_users(密钥、启用状态、防重放步进锚点)、easy2fa_recovery_codes(哈希与一次性标记)、easy2fa_passkeys(COSE 公钥与签名计数器)。卸载本插件即恢复纯密码登录。

常见问题

验证器丢了,十个还原码也全部用尽,怎么办? 管理员在 /admin/easy-2fa 对该用户执行强制关闭:系统将删除密钥、作废还原码并移除通行密钥,该用户下次登录时即可重新绑定。

通行密钥总是失败,怎么办? WebAuthn 要求安全上下文:生产环境使用 HTTPS,本地开发 localhost 即可。另请确认站点以注册时完全一致的源对外提供服务;来源与 RP-ID 在每次断言校验中均被验证。

与 advanced-user-management 冲突吗? 不冲突。无须挑战时登录请求原样放行,AUM 的限流照常工作;需要挑战时会话先被挂起,AUM 不会看到一次已完成登录。

许可证

本项目以 GPL-3.0-or-later 许可发布,Copyright (C) 2026 Evarentha,完整文本见 LICENSE。