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

dsh-login

v0.1.1

Published

Password gate for dsh-web: opening the web port requires a username/password login; account credentials are stored salted+scrypt-hashed and AES-256-GCM encrypted in a local config file under $DSH_HOME. Host-only cordis plugin, no dsh source changes.

Downloads

253

Readme

dsh-login — dsh-web 登录插件

给 dsh-web 加一道登录门:打开 dsh-web 的端口时先要输入用户名和密码,验证通过后才 能看到界面。账号信息不落明文:密码用 scrypt(随机盐)哈希,整个凭据文件再用 AES-256-GCM 加密后写入本地配置文件($DSH_HOME/dsh-login.json,默认 ~/.dsh/dsh-login.json)。

适合部署于服务器上的dsh-web服务 需要自行架设nginx服务,把服务映射到局域网内使用

  • 纯主机侧 Cordis 插件,不修改任何 dsh 源码;
  • 通过 dsh plugin 以 bundle 方式挂载(dsh.bundle.patch),依赖列表只有 cordis / dsh-host-webserver / schemastery 三个 peer;
  • 自带独立 CLI(dsh-login),不启动 web 也能管理账号。

特性

| 能力 | 说明 | | --- | --- | | 全量请求门禁 | 包住 webserver 的 register / registerUpgrade / registerFallback:SPA 回退、/api 传输、WebSocket/SSE 升级全部先过会话校验 | | 会话 | 内存会话 + HttpOnly; SameSite=Strict Cookie(默认 24h,可配置);服务重启全员下线 | | 首启引导 | 没有账号时打开端口显示“创建管理员账号”页(bootstrap),建完即登录 | | 加密存储 | 凭据文件 AES-256-GCM 加密;密钥来自 DSH_LOGIN_SECRET(64 hex 或口令)→ 密钥文件 $DSH_HOME/dsh-login.key(自动生成)→ 明文模式(警告) | | 口令安全 | scrypt(N=2^14, r=8, p=1)随机盐哈希,恒时比较;用户名不存在时烧一次假哈希防枚举 | | 爆破防护 | 每用户名+IP 滑动窗口限速(默认 5 次/30s → 429)+ 失败延时 | | CLI | status / set-user / remove-user / list-users / reset,运行中改账号会被 mtime 轮询热加载 |

安装(本机 web profile)

# 1) 把本插件加入 web profile(等价于 pnpm add link:... 到 ~/.dsh/profiles/web)
dsh plugin --profile web add link:D:\code\dsh\dsh-login-plugin

# 2) 重启 dsh web
#    下次打开 http://127.0.0.1:3080 会先看到登录页;首次访问创建管理员账号。

仓库内 node_modules 是指向 ~/.dsh/profiles/node_modules 的 junction (与 dsh-ssh 等本地开发包的做法一致,测试与 link: 安装后的模块解析都靠它)。 若把仓库挪到别处,重建 junction: New-Item -ItemType Junction -Path <repo>\node_modules -Target $env:USERPROFILE\.dsh\profiles\node_modules

卸载:dsh plugin --profile web remove dsh-login,重启后端口恢复开放。

首次使用(二选一)

A. 网页引导(默认):打开端口 → “创建管理员账号” → 设置用户名密码 → 自动登录。

B. CLI(适合禁掉网页引导)

# 在运行 dsh web 的机器上执行(无需启动 web)
node D:\code\dsh\dsh-login-plugin\lib\cli.js set-user --user admin
# 输入密码(交互式提示,避免命令行历史残留)

之后把 bootstrap 设为 denied(见下)即可禁止网页自助建号。

配置

在 profile 的用户层给插件行加配置(dsh plugin --profile web add 后会自动把 dsh-login 行插入组合;改配置就编辑 ~/.dsh/profiles/web/cordis.patch.yml- insert: 里那行 dsh-login,或直接读插件的 cordis.patch.yml):

- id: dsh-login
  config:
    sessionTtlHours: 12        # 会话有效期(小时),默认 24
    bootstrap: denied          # 禁止网页自助建号,只用 CLI 管账号
    maxAttempts: 10            # 爆破限速:10 次/30s
    cookieName: dsh_session
    loginPath: /login
    logoutPath: /logout
    storePollMs: 2000          # 检测 CLI 改账号的轮询间隔(0=关闭)

全部配置项(均带默认值):enabled(true)、storeFile($DSH_HOME/dsh-login.json)、 keyFile($DSH_HOME/dsh-login.key)、sessionTtlHours(24)、cookieNamebootstrap(auto|denied)、maxAttempts(5)、attemptWindowMs(30000)、 failDelayMs(400)、storePollMs(2000)、loginPath(/login)、logoutPath(/logout)。

主密钥优先级:环境变量 DSH_LOGIN_SECRET(64位 hex 原样使用;任意长口令则 scrypt 派生)→ 密钥文件(不存在则自动生成 64 hex,0600)→ 无密钥时降级明文 JSON(仍 scrypt 哈希,插件会打警告)。

登录机制

  • 未登录导航请求(GET/HEAD + Accept: text/html)→ 返回登录页(200);
  • 未登录其它请求(含对 /api/* 的直接访问、静态资源探测)→ 401 JSON;
  • 未登录 WebSocket/SSE 升级 → 握手直接 401 关闭;
  • 已登录 → 原 handler 照常处理。
  • 公开路径(免登录):登录页、退出页、/api/auth/{login,bootstrap,logout,status}
  • 退出:POST /api/auth/logout(清 Cookie),或访问 /logout 页面;会话只存内存, 重启即全部失效。

CLI 参考

dsh-login status
dsh-login set-user --user <name> [--password <p>]   # 新建或重置密码
dsh-login remove-user --user <name>
dsh-login list-users
dsh-login reset --yes                                # 删除凭据文件(全部账号)

测试

node test/unit.test.mjs          # 14 项:crypto / store / sessions / 页面
node test/integration.test.mjs   # 4 项:真实 webserver + frontend-static + 插件

集成测试覆盖:真实挂载顺序(登录插件最后加载,回退表已注册→原位重包)、反序 (注册期包装)、bootstrap→登录→SPA/API→登出全流程、WebSocket 升级鉴权、密文 存储无明文、CLI 外部改账号被热加载、bootstrap 禁用路径。测试通过 scrypt 实际计算, 运行约 1–2 s。

安全模型(请读)

  • 默认只绑 127.0.0.1:登录门禁解决“端口裸奔”,但明文 HTTP 在网络上可被嗅探。 若 --host 0.0.0.0 暴露到局域网/公网,请在前面加 TLS 反向代理,并设置 强口令DSH_LOGIN_SECRET 建议放环境变量(环境变量与 web 进程同属一个 用户空间,这是本项目能提供的最高一级的主密钥隔离)。
  • 自动生成的密钥文件与凭据文件同目录:防的是“文件被拷贝/误发/备份泄露”这类 意外读取;对能读整个 $DSH_HOME 的攻击者,scrypt 哈希才是最后防线。
  • 首启引导:零账号时第一个到达的人即可建管理员账号,所以在暴露到不可信网络 之前先用 CLI 建号并设 bootstrap: denied
  • 会话令牌 256 位随机,仅存内存与 HttpOnly Cookie;SameSite=Strict 挡住跨站 请求伪造。若把 GUI 暴露给多用户,请自行评估多账号并发(本插件支持多用户, 会话相互独立)。

目录结构

lib/crypto.js        scrypt 哈希/校验、AES-256-GCM、密钥派生
lib/store.js         加密凭据存储(原子写、热重载)
lib/sessions.js      内存会话 + Cookie 工具
lib/login-page.js    登录 / 引导 / 退出页(单文件内联样式脚本)
lib/paths.js         $DSH_HOME 与密钥文件解析
lib/index.js         插件本体:门禁包装 + 公开路由
lib/cli.js           账号管理 CLI
test/unit.test.mjs / test/integration.test.mjs
cordis.patch.yml     bundle 补丁(把 dsh-login 行插入组合)