Skip to content

[Bug] #7

Description

@best-orange

[Bug] 纯本地认证模式下首次注册仍强制要求邀请码,且 /admin 未登录时会跳转到已关闭的 LINUX DO 登录

问题描述

神墨佬,看一下这里有两个小问题。
在纯本地部署场景中,我使用以下配置关闭 LINUX DO OAuth,仅启用本地用户名密码登录:

LINUXDO_AUTH_ENABLED=false
LOCAL_AUTH_ENABLED=true
FIRST_USER_IS_ADMIN=true
LINUXDO_ADMIN_IDS=
INVITE_REQUIRED_FOR_LOCAL=true

按照 .env.example 中的说明:

纯本地部署:LINUXDO_ADMIN_IDS 留空 + FIRST_USER_IS_ADMIN=true 时,第一个本地注册用户自动成为管理员(首个用户无需邀请码)。

后端目前也已经实现了这一 bootstrap 逻辑,但前端仍存在两个问题,导致纯本地首次部署无法正常完成初始化。


问题 1:首次本地注册仍被前端强制要求邀请码

实际表现

首次部署后访问:

/app

进入本地账号注册页面时,必须填写邀请码,否则前端直接提示:

请填写邀请码

无法提交注册请求。

当前 apps/api/public/app.html 中存在类似逻辑:

const inviteCode = ($("#regInvite")?.value || "").trim();

if (!inviteCode) {
  showAuthError("请填写邀请码");
  return;
}

因此即使这是数据库中的第一个用户,也无法在不填写邀请码的情况下提交。

但后端已经支持首次免邀请码

/api/v1/auth/register 中已经存在 bootstrap 判断:

const bootstrap =
  totalUsers === 0 &&
  ctx.cfg.firstUserIsAdmin &&
  ctx.cfg.adminIds.size === 0;

if (needInvite && !bootstrap) {
  // validate invite code
}

也就是说,当:

totalUsers === 0
FIRST_USER_IS_ADMIN=true
LINUXDO_ADMIN_IDS 为空

时,后端本来允许首个本地用户不提供邀请码,并自动成为管理员。

目前前端的必填检查导致这一后端逻辑实际上无法从 Web UI 正常使用。

临时绕过方法

目前可以在邀请码字段随便填写一个非空字符串,例如:

bootstrap

前端即可提交请求,而后端因为处于 bootstrap 状态不会验证该邀请码。

也可以直接调用:

POST /api/v1/auth/register

并省略 inviteCode

但这显然不应该成为正常部署流程的一部分。

期望行为

当后端处于首次用户 bootstrap 状态时:

  • 注册页面不应强制要求邀请码;
  • 最好将邀请码输入框标记为“首个管理员无需邀请码”;
  • 首个本地用户注册成功后自动成为管理员。

问题 2:关闭 LINUX DO 后,直接访问 /admin 会跳转到已关闭的 OAuth 接口

实际表现

配置:

LINUXDO_AUTH_ENABLED=false
LOCAL_AUTH_ENABLED=true

后直接访问:

/admin

如果当前浏览器尚未登录,页面调用:

GET /api/v1/auth/me

返回 401 后,admin.html 中的公共 api() 逻辑会自动执行:

if (res.status === 401) {
  location.href =
    "/api/v1/auth/login?redirect=" +
    encodeURIComponent("/admin" + (location.hash || ""));
}

于是浏览器被跳转到:

/api/v1/auth/login?redirect=/admin

但因为:

LINUXDO_AUTH_ENABLED=false

最终只会得到:

{
  "error": "LINUX DO 登录已关闭(LINUXDO_AUTH_ENABLED=false)"
}

当前 admin 页面实际上已经支持密码登录

admin.html 本身已经包含:

  • 用户名输入框
  • 密码输入框
  • “密码登录”按钮

并且会调用:

POST /api/v1/auth/password-login

同时代码里也已经有根据:

/api/v1/auth/config

返回的 oauthEnabled 隐藏 LINUX DO 登录按钮的逻辑。

因此这里的问题主要是旧的 401 → 强制 OAuth redirect 行为没有适配新的本地认证模式。

期望行为

当:

LINUXDO_AUTH_ENABLED=false
LOCAL_AUTH_ENABLED=true

时,如果访问 /admin 尚未登录:

/admin
  ↓
GET /api/v1/auth/me → 401
  ↓
停留在 /admin
  ↓
显示用户名/密码登录表单

而不是:

401
  ↓
跳转 /api/v1/auth/login
  ↓
LINUX DO disabled
  ↓
返回 JSON error

如果 OAuth 开启,则仍可以保留当前 OAuth 登录按钮。


建议修复方向

这两个问题看起来主要都是前端状态处理与当前后端认证逻辑没有完全同步。

建议:

  1. /app 注册页面不要无条件要求 inviteCode,应根据后端返回的认证/注册配置决定是否必填;

  2. 最好由 /api/v1/auth/config 返回类似:

    • localAuthEnabled
    • oauthEnabled
    • inviteRequired
    • bootstrapAvailable
  3. bootstrapAvailable=true 时允许邀请码为空;

  4. /admin 的公共 api() 在收到 401 时,不应无条件跳转 /api/v1/auth/login

  5. 当本地认证启用时,401 应优先显示 admin 页面已有的密码登录 Gate;

  6. 仅在 OAuth 启用且需要 OAuth 登录时再跳转 /api/v1/auth/login


部署环境

  • Docker 部署
  • 单节点
  • Redis
  • Cloudflare Tunnel
  • LINUX DO OAuth:关闭
  • 本地用户名密码认证:开启

核心认证配置:

LINUXDO_AUTH_ENABLED=false
LOCAL_AUTH_ENABLED=true
FIRST_USER_IS_ADMIN=true
LINUXDO_ADMIN_IDS=
INVITE_REQUIRED_FOR_LOCAL=true

这两个问题在纯本地、自托管部署场景下会直接影响首次初始化流程,希望可以考虑修复,谢谢。

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions