Metadata-Version: 2.4
Name: account-kit
Version: 0.1.1
Summary: Shared async account service for FastAPI apps
Author: kqstone
License-Expression: MIT
Keywords: fastapi,authentication,account,jwt,totp,2fa,sqlalchemy,asyncpg,postgresql
Classifier: Development Status :: 3 - Alpha
Classifier: Framework :: FastAPI
Classifier: Framework :: AsyncIO
Classifier: Intended Audience :: Developers
Classifier: Natural Language :: Chinese (Simplified)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
Classifier: Topic :: Security
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: fastapi>=0.110
Requires-Dist: sqlalchemy[asyncio]>=2.0
Requires-Dist: asyncpg>=0.29
Requires-Dist: pydantic[email]>=2.0
Requires-Dist: python-jose[cryptography]>=3.3
Requires-Dist: bcrypt>=4.0
Requires-Dist: python-multipart
Requires-Dist: jinja2>=3.1
Requires-Dist: pyotp>=2.9
Requires-Dist: cryptography
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
Requires-Dist: httpx>=0.27; extra == "dev"
Dynamic: license-file

# account-kit

dedd-online 与 dental-case-pro 共用的异步账号包。PostgreSQL + SQLAlchemy + asyncpg，表在 `auth` schema，用户主键是 UUID。

账号能力：注册、登录、邮件验证码、审批、单设备会话、自定义角色、后台权限（`is_admin`，不是角色）、等级目录、两步验证。限额、限流、积分留在宿主。

```python
from account_kit import init_db, mount_account, seed_defaults
from account_kit.config import AccountKitConfig

await init_db(engine)
await seed_defaults(session)
mount_account(app, get_db, AccountKitConfig(jwt_secret="..."))
```

### 可选：邮箱两步验证、登录图形验证码

两项默认关闭，由宿主在 `AccountKitConfig` 里打开：

- `two_factor_email_enabled=True`：两步验证可用邮箱验证码代替验证器（"跳过 2FA"）。登录时 `POST /login/2fa/email/send`（`challenge_token`、`language`）发码，再把 `email_code` 提交到 `POST /login/2fa`；设置里 `POST /2fa/disable/email-code` 发码，`POST /2fa/disable` 带 `email_code` 关闭。`MFA_REQUIRED` 的 `detail` 里 `email_available` 为真，`methods` 含 `email`。
- `captcha_verifier=fn(captcha_id, captcha_code) -> bool`（可为 async）：同一 IP 或用户名在 `captcha_fail_window_seconds` 内失败 `captcha_fail_threshold` 次后，`POST /login` 必须带 `captcha_id`、`captcha_code`，否则 428 `CAPTCHA_REQUIRED`，错了 400 `CAPTCHA_INVALID`；密码错误返回 401 `INVALID_CREDENTIALS`（带 `captcha_required`）。验证码图片由宿主提供（界面包从 `GET {api_prefix}/captcha` 取 `captcha_id`、`image_base64`）。反向代理后用 `client_ip=fn(request)` 取真实 IP。
- `before_two_factor=async fn(request, user)`：每次校验第二因素、发邮箱码前调用，宿主可在这里限流。

## 安装

Python 包从 [PyPI](https://pypi.org/project/account-kit/) 安装：

```bash
pip install account-kit
```

界面包发在 GitHub Packages（不是 npmjs.com）。安装前在项目根写 `.npmrc`：

```
@kqstone:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}
```

`NPM_TOKEN` 需要带 `read:packages` 的 classic PAT（或等价权限）。CI 里可以用 `GITHUB_TOKEN`，但要先在包的 **Manage Actions access** 里给消费仓库（如 `kqstone/dedd-online`、`kqstone/dental-case-pro`）Read 权限。从 private 仓库首次发布的包默认为 private；可在包设置里改成 public，但无论可见性如何，安装都仍需要 token。

```bash
npm install @kqstone/account-ui-vue    # Vue 3
npm install @kqstone/account-ui-react  # React 18 / 19
```

不单独发布 client 包，请求客户端打进这两个界面包：

- `@kqstone/account-ui-vue`：`LoginForm`、`RegisterForm`、`ResetPasswordForm`、`TierBadge`、`createAccountClient`
- `@kqstone/account-ui-react`：同上

界面包发布的是构建后的 `dist/`（ESM + `.d.ts`），样式在组件首次渲染时注入，不需要单独引入 CSS。

## 本地开发

宿主仓库用 `file:` 路径引用界面包时，先在 account-kit 里构建一次（`npm ci` 会通过 `prepare` 自动构建）：

```bash
cd packages/account-ui-vue && npm ci     # 或 packages/account-ui-react
```

改了界面包源码后，重新 `npm run build`，再在宿主里重新安装依赖。

## 发布

版本号写在 `pyproject.toml` 和两个 `packages/*/package.json` 里，三处保持一致。推送 `v<版本号>` tag（如 `v0.1.0`）后，GitHub Action 先校验 tag 与三处版本一致、跑测试和构建，然后：

- Python 包发布到 [PyPI](https://pypi.org/project/account-kit/)（Trusted Publishing，不用 token）
- 两个界面包发布到 [GitHub Packages](https://github.com/kqstone?tab=packages)（`GITHUB_TOKEN`，`packages: write`）

日后若改发 npmjs.com：把 `publishConfig.registry` 改回默认、workflow 改为 `registry.npmjs.org` + `NPM_TOKEN`（或 npm trusted publishing），并更新本节安装说明。

## 许可证

MIT
