Token导航 LogoToken导航

Agent Skill · 研究检索

bknd-password-reset(bknd 密码重置)

bknd-password-reset 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

bknd-password-reset 是研究检索类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证信息还不明确,第三方扫描有未通过项,按安装量在研究检索类的 73,675 个 Skill 里排第 62,939。

总安装 324周安装 13GitHub Stars 3下载 105核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
unknown

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:bknd-password-reset(bknd 密码重置)
来源仓库:https://github.com/cameronapak/bknd-skills
仓库路径:skills/bknd-password-reset
安装命令:
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-password-reset
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-password-reset

这个 Skill 是做什么的

研究检索类 Skill 主要解决「找资料、核对事实、把来源整理清楚」的问题,通常会让助手先检索再总结。

用于实现密码重置和修改功能,支持管理员后台操作。不提供内置忘记密码流程,需自行实现令牌生成与邮件发送。适用于服务端密码变更和验证逻辑编写。需启用认证系统并配置邮件发送能力。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

bknd-password-reset 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

来源仓库内路径:skills/bknd-password-reset

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-password-…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

bknd-password-reset 怎么安装?

在终端执行 npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-password-reset。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

bknd-password-reset 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

bknd-password-reset 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

bknd-password-reset 是免费的吗?

公开资料没有标注明确许可证,收费和商用限制都无法确认。正式使用前请到来源仓库核对授权说明。

bknd-password-reset 用的人多吗?

公开数据是累计安装 324 次,近一周安装 13 次,下载 105 次,GitHub 3 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

bknd-password-reset 安全吗?

第三方扫描有未通过项,风险较高。除非你确认过源码,否则不建议直接安装到常用环境。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。

先想清楚的地方

  • 许可证没有明确标注,能不能商用、能不能再分发都不确定。
  • 第三方扫描存在提醒项或未通过项,需要人工逐条确认。
  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理研究检索类任务、又不想每次都手写提示词的人。

不太适合

  • 需要明确授权才能用到公司项目里的场景。
  • 需要厂商级技术支持和 SLA 的生产系统。

研究检索类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
find-skills

寻找技能 · Codex、Claude

31,199,81316,486操作浏览器MIT有提醒
self-improving-agent

自我改进 Agent · OpenClaw

16,464,0023,396接触敏感数据MIT-0通过
soultrace

灵魂追踪 · Codex、Claude

7,588,94412需要联网未明确有提醒
self-improving

自我完善 · OpenClaw

6,829,2841,046需要联网MIT-0通过
microsoft-foundry

微软代工厂 · Codex、Claude

6,614,144764调用外部服务未明确有提醒
bknd-password-reset

bknd 密码重置 · 本页

3243需要联网未明确未通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

Password Reset Flow

Implement password reset and change functionality in Bknd applications.

Prerequisites

  • Bknd project with auth enabled (bknd-setup-auth)
  • Password strategy configured
  • For email-based reset: email sending capability (external service)

Important Context

Bknd provides:

  • Server-side changePassword() method for admin/system password changes
  • No built-in forgot-password flow - you must implement token generation, email sending, and validation

When to Use UI Mode

  • Admin-initiated password resets via admin panel

UI steps: Admin Panel > Data > users > Select user > Edit

Note: Direct password editing via UI sets raw value - use server-side method for proper hashing.

When to Use Code Mode

  • Implementing forgot-password flow with email
  • Adding change-password functionality for logged-in users
  • Admin tools for password resets

Server-Side Password Change

Using changePassword() Method

import { serve } from "bknd/adapter/node";
import { defineConfig } from "bknd";

export default serve(
  defineConfig({ /* config */ }),
  {
    async seed(ctx) {
      // Change password by user ID
      await ctx.app.module.auth.changePassword(1, "newSecurePassword123");

      // Or find user first
      const { data: user } = await ctx.em.repo("users").findOne({
        email: "user@example.com",
      });
      if (user) {
        await ctx.app.module.auth.changePassword(user.id, "newPassword456");
      }
    },
  }
);

Method signature:

changePassword(userId: number | string, newPassword: string): Promise<boolean>

Constraints:

  • User must exist
  • User must use password strategy (not OAuth)
  • Password is automatically hashed using configured hashing method

Building Forgot-Password Flow

Since Bknd doesn't have built-in forgot-password, implement a custom flow:

Step 1: Create Reset Token Entity

import { em, entity, text, date, number } from "bknd";

const schema = em({
  password_resets: entity("password_resets", {
    email: text().required(),
    token: text().required().unique(),
    expires_at: date().required(),
    used: number().default(0), // 0 = unused, 1 = used
  }),
});

Step 2: Request Reset Endpoint

import { randomBytes } from "crypto";

async function requestPasswordReset(email: string, ctx: any) {
  const api = ctx.api;

  // Check if user exists (don't reveal in response)
  const { data: user } = await api.data.readOneBy("users", { email });
  if (!user) {
    return { success: true, message: "If email exists, reset link sent" };
  }

  // Generate secure token
  const token = randomBytes(32).toString("hex");
  const expiresAt = new Date(Date.now() + 60 * 60 * 1000); // 1 hour

  // Store reset token
  await api.data.createOne("password_resets", {
    email,
    token,
    expires_at: expiresAt.toISOString(),
    used: 0,
  });

  // Send email (use your email service: SendGrid, Resend, etc.)
  const resetUrl = `https://yourapp.com/reset-password?token=${token}`;
  // await emailService.send({ to: email, subject: "Password Reset", ... });

  return { success: true, message: "If email exists, reset link sent" };
}

Step 3: Validate and Reset Password

async function resetPassword(token: string, newPassword: string, ctx: any) {
  const api = ctx.api;
  const auth = ctx.app.module.auth;

  // Find valid token
  const { data: resetRecord } = await api.data.readOneBy("password_resets", {
    token,
    used: 0,
  });

  if (!resetRecord) {
    throw new Error("Invalid or expired reset token");
  }

  // Check expiration
  if (new Date(resetRecord.expires_at) < new Date()) {
    throw new Error("Reset token has expired");
  }

  // Find user
  const { data: user } = await api.data.readOneBy("users", {
    email: resetRecord.email,
  });
  if (!user) {
    throw new Error("User not found");
  }

  // Change password (properly hashed)
  await auth.changePassword(user.id, newPassword);

  // Mark token as used
  await api.data.updateOne("password_resets", resetRecord.id, { used: 1 });

  return { success: true };
}

Step 4: React Frontend

Request Reset Form:

function ForgotPasswordForm() {
  const [email, setEmail] = useState("");
  const [status, setStatus] = useState<"idle" | "loading" | "sent">("idle");

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setStatus("loading");

    await fetch("/api/password-reset/request", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ email }),
    });
    setStatus("sent");
  }

  if (status === "sent") {
    return <p>Check your email for reset instructions.</p>;
  }

  return (
    <form onSubmit={handleSubmit}>
      <input
        type="email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        placeholder="Email"
        required
      />
      <button type="submit" disabled={status === "loading"}>
        {status === "loading" ? "Sending..." : "Send Reset Link"}
      </button>
    </form>
  );
}

Reset Password Form:

function ResetPasswordForm() {
  const [searchParams] = useSearchParams();
  const navigate = useNavigate();
  const token = searchParams.get("token");

  const [password, setPassword] = useState("");
  const [confirmPassword, setConfirmPassword] = useState("");
  const [error, setError] = useState("");

  if (!token) return <p>Invalid reset link.</p>;

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    if (password !== confirmPassword) {
      setError("Passwords do not match");
      return;
    }

    const res = await fetch("/api/password-reset/confirm", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ token, password }),
    });

    if (res.ok) {
      navigate("/login");
    } else {
      const data = await res.json();
      setError(data.message || "Reset failed");
    }
  }

  return (
    <form onSubmit={handleSubmit}>
      {error && <p className="error">{error}</p>}
      <input
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        placeholder="New Password"
        minLength={8}
        required
      />
      <input
        type="password"
        value={confirmPassword}
        onChange={(e) => setConfirmPassword(e.target.value)}
        placeholder="Confirm Password"
        required
      />
      <button type="submit">Reset Password</button>
    </form>
  );
}

Authenticated Password Change

For logged-in users changing their own password:

async function changePassword(currentPassword: string, newPassword: string) {
  const api = new Api({ host: "http://localhost:7654", storage: localStorage });

  // Verify current password by re-authenticating
  const { data: userData } = await api.auth.me();
  if (!userData?.user) throw new Error("Not authenticated");

  const { ok } = await api.auth.login("password", {
    email: userData.user.email,
    password: currentPassword,
  });

  if (!ok) throw new Error("Current password is incorrect");

  // Call custom password change endpoint
  const res = await fetch("/api/password-change", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ newPassword }),
  });

  if (!res.ok) throw new Error("Failed to change password");
}

Security Considerations

Token Security

// Good: Cryptographically secure token
import { randomBytes } from "crypto";
const token = randomBytes(32).toString("hex"); // 64 chars

// Bad: Predictable token
const token = Math.random().toString(36); // NOT secure!

Rate Limiting

const resetAttempts = new Map<string, { count: number; lastAttempt: Date }>();

function checkRateLimit(email: string): boolean {
  const record = resetAttempts.get(email);
  const now = new Date();

  if (!record || record.lastAttempt < new Date(now.getTime() - 3600000)) {
    resetAttempts.set(email, { count: 1, lastAttempt: now });
    return true;
  }

  if (record.count >= 3) return false; // Max 3 per hour

  record.count++;
  return true;
}

Common Pitfalls

Not Hashing Password

// Wrong - bypasses hashing
await api.data.updateOne("users", userId, {
  strategy_value: "plainPassword123",
});

// Correct - uses configured hashing
await ctx.app.module.auth.changePassword(userId, "plainPassword123");

Email Enumeration

// Wrong - reveals email existence
if (!user) return { error: "Email not found" };

// Correct - doesn't reveal
return { success: true, message: "If email exists, reset link sent" };

OAuth User Password Reset

const { data: user } = await api.data.readOneBy("users", { email });
if (user?.strategy !== "password") {
  return { error: "This account uses social login" };
}

Verification

# 1. Request reset
curl -X POST http://localhost:7654/api/password-reset/request \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'

# 2. Reset password (use token from email/DB)
curl -X POST http://localhost:7654/api/password-reset/confirm \
  -H "Content-Type: application/json" \
  -d '{"token": "<token>", "password": "newPassword123"}'

# 3. Login with new password
curl -X POST http://localhost:7654/api/auth/password/login \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "password": "newPassword123"}'

DOs and DON'Ts

DO:

  • Use changePassword() method for proper hashing
  • Generate cryptographically secure tokens
  • Set short expiration (1 hour max)
  • Mark tokens as used immediately
  • Return consistent responses (don't reveal email existence)
  • Rate limit reset requests

DON'T:

  • Store/transmit passwords in plain text
  • Use predictable tokens (Math.random)
  • Allow unlimited reset attempts
  • Keep tokens valid indefinitely
  • Allow password reset for OAuth users

Related Skills

  • bknd-setup-auth - Configure authentication system
  • bknd-login-flow - Login/logout functionality
  • bknd-registration - User registration setup
  • bknd-session-handling - Manage user sessions
  • bknd-custom-endpoint - Create custom API endpoints

平台分布

Codex

33.32%
按下载量换算35

Claude

32.99%
按下载量换算35

Cursor

19.91%
按下载量换算21

Gemini CLI

10.09%
按下载量换算11

安全审计

Gen Agent Trust Hub

未通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在提醒或未通过项,安装前请自行复核。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills