Skip to content

fix(synchronizer-feishu): 用户同步 NPE 因 status 字段缺失,需判空保护 #271

Description

@float0108

问题描述

MaxKey 管理端「同步器 → 飞书」点击“同步”时:

  • 部门能正常同步,但成员(用户)全部同步失败
  • 前端提示“操作失败”,控制台报 Cannot read properties of undefined (reading 'refresh')
  • 后端日志:
java.lang.NullPointerException: Cannot invoke "org.dromara.maxkey.synchronizer.feishu.entity.FeishuUserStatus.isIs_activated()"
because the return value of "org.dromara.maxkey.synchronizer.feishu.entity.FeishuUsers.getStatus()" is null
    at org.dromara.maxkey.synchronizer.feishu.FeishuUsersService.buildUserInfoByFieldMapper(FeishuUsersService.java:153)
    at org.dromara.maxkey.synchronizer.feishu.FeishuUsersService.sync(FeishuUsersService.java:70)

复现步骤

  1. 飞书开放平台创建应用,配置 contact:user.base:readonly(及所需通讯录权限)并发布上线
  2. 在 MaxKey 飞书同步器中填写 App ID / Secret;
  3. 执行“立即同步”。Token 获取正常,部门可拉到,执行到用户同步时 NPE。

根因

MaxKey 4.1.12 同步用户调用的是:

GET https://open.feishu.cn/open-apis/contact/v3/users/find_by_department?department_id=<open_department_id>&page_size=50

该 v3 接口当前返回的用户对象不包含 status 字段,实际返回形如:

{
  "code": 0,
  "data": {
    "items": [
      {
        "name": "...",
        "email": "...",
        "employee_no": "...",
        "open_id": "...",
        "union_id": "...",
        "user_id": "..."
      }
    ]
  }
}

FeishuUsersService.buildUserInfoByFieldMapper(第 153 行)直接解引用了 status,未判空:

if (user.getStatus().isIs_activated()) {
    userInfo.setStatus(1);   // 在职
} else {
    userInfo.setStatus(2);   // 离职/未激活
}

getStatus() 返回 null → isIs_activated() NPE → 用户同步中断。

建议修复

请官方对用户对象做空值保护,例如:

FeishuUserStatus status = user.getStatus();
boolean activated = (status != null && status.isIs_activated());
userInfo.setStatus(activated ? 1 : 2);

并明确 status 缺失(该接口不返回)时的默认值——当前我们按“未激活”(status=2)处理。

影响范围 / 备注

  • 版本:maxkey-mgt + maxkey-synchronizer-feishu 4.1.12maxkeytop/maxkey-mgt:latest);
  • 仅在 users/find_by_department 这种“精简字段”接口下触发;若改用含 status 的完整用户接口(如 users/{user_id})则不会 NPE;
  • 因为要验证能否仅依赖该接口配置,是否应同步该精简接口回归更多字段(status)也可一并评估。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions