feat: 新增修改密码和注销账号功能

新增修改密码和注销账号的API接口,实现用户通过验证旧密码修改密码,以及通过短信验证流程注销账号的功能,同时补充相关常量和文档说明。
This commit is contained in:
Austin
2026-09-29 16:13:32 +08:00
parent cf9d559944
commit ab73b69870
5 changed files with 205 additions and 10 deletions
+23 -3
View File
@@ -943,7 +943,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
**状态:新增。**
- 敏感操作先调用 `POST /v1/im/security/challenges`;开启青少年模式设置独立密码时 Body 为 `{"scene":"set_independent_password","channel":"sms"}`,关闭青少年模式时 Body 为 `{"scene":"close_youth_mode","channel":"sms"}`;群主转让使用 `{"scene":"group_owner_transfer","channel":"sms"}`;解散群聊使用 `{"scene":"group_dissolve","channel":"sms"}`。手机号由登录身份读取,客户端不提交目标手机号。
- 敏感操作先调用 `POST /v1/im/security/challenges`;开启青少年模式设置独立密码时 Body 为 `{"scene":"set_independent_password","channel":"sms"}`,关闭青少年模式时 Body 为 `{"scene":"close_youth_mode","channel":"sms"}`;群主转让使用 `{"scene":"group_owner_transfer","channel":"sms"}`;解散群聊使用 `{"scene":"group_dissolve","channel":"sms"}`;注销账号使用 `{"scene":"delete_account","channel":"sms"}`。手机号由登录身份读取,客户端不提交目标手机号。
- 发码/校验:服务端返回 `challenge_id` 和脱敏手机号;提交 `POST /v1/im/security/challenges/{id}/verify`,Body `{"code":"..."}`。
- 重复发码:同一用户、同一手机号、同一敏感场景存在未过期 challenge 且仍在 `resend_after_seconds` 冷却期内时,服务端返回 HTTP `429 VERIFICATION_RATE_LIMITED`,`details` 带 `challenge_id` 和 `retry_after_seconds`。客户端应复用该 `challenge_id` 继续倒计时,不要当成接口不可达或重新登录。
- 小时限流:超过一小时创建次数上限时同样返回 HTTP `429 VERIFICATION_RATE_LIMITED`,`details.retry_after_seconds` 可能大于 60 秒且不一定带 `challenge_id`。客户端只展示倒计时,倒计时结束后允许用户重新获取验证码。
@@ -969,7 +969,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
- 页面只调用 `GET /v1/im/security/realname`。`verified` 时返回如 `masked_name:"张*"`、`masked_id_number:"110***********1234"`、`verified_at`。
- 前端只读展示,不缓存原始证件信息,不提供直接修改接口。
- 更正信息使用独立申诉 `POST /v1/im/security/realname/appeals`,需二次身份验证;不复用本页保存按钮。
- 更正信息使用独立申诉 `POST /v1/im/security/realname/appeals`,Body `{"reason":"...","attachments":[]}`(`reason` 必填、≤500 字;`attachments` 最多 9 个 file_id),Bearer 即可,当前无需二次身份验证;不复用本页保存按钮。
### 1.10 实名认证(安卓).png
@@ -3179,9 +3179,29 @@ GET /v1/im/topics/{topic}/message-mutations?since_version={localMutationVersion}
| `POST /v1/im/security/challenges/{id}/verify` 关闭青少年模式 | `{"code":"123456"}` | `{"action_token":"close_token","action":"close_youth_mode","expires_at":"2026-08-20T09:05:00Z"}` |
| `GET /v1/im/security/realname` | Query only | `{"status":"unverified","can_submit":true}` |
| `POST /v1/im/security/realname/submissions` | `{"name":"张三","id_type":"cn_id","id_number":"110101199001011234"}` | `{"submission_id":"rn_1","status":"pending","can_submit":false}` |
| `POST /v1/im/security/realname/appeals` 待实现 | `{"reason":"证件变更","description":"需要更正实名信息","action_token":"action_token"}` | `{"appeal_id":"rna_1","status":"pending","submitted_at":"2026-08-20T09:00:00Z"}` |
| `POST /v1/im/security/realname/appeals` | `{"reason":"证件变更需要更正实名信息","attachments":["file_1"]}` | `{"appeal_id":"rna_1","reason":"...","attachments":["file_1"],"status":"pending"}`;当前无需二次身份验证(如后续启用,将复用 1.7 的 action_token 机制并在此处更新) |
| `PUT /v1/im/devices/{device_id}/push-token` | `{"provider":"jpush","token":"registration_id","platform":"android","app_version":"1.0.0","push_env":"test","sdk_version":"5.0.0","notification_permission":"granted"}` | `{"device_id":"device_1","provider":"jpush","platform":"android","app_version":"1.0.0","updated_at":"2026-08-20T09:00:00Z"}` |
| `DELETE /v1/im/security/sessions/{session_id}` 待实现 | Header `X-Action-Token: action_token` | `{"session_id":"sess_1","revoked":true}` |
| `POST /v1/im/me/password` | `{"old_password":"OldPass123","new_password":"NewPass123"}` | `{"status":"ok"}`;旧密码错误返回 HTTP `401`:`{"code":30001,"reason":"AUTH_REQUIRED","message":"invalid credentials"}`;新密码不满足策略返回 HTTP `400`:`{"code":30040,"reason":"PASSWORD_POLICY_VIOLATION"}` |
| `POST /v1/im/security/challenges` 注销账号发码 | Header `Idempotency-Key`;Body `{"scene":"delete_account","channel":"sms"}` | `{"challenge_id":"sec_chg_9","phone_mask":"+861****000","expires_in_seconds":300,"resend_after_seconds":60}` |
| `POST /v1/im/security/challenges/{id}/verify` 注销账号验证 | `{"code":"123456"}` | `{"action_token":"del_token","action":"delete_account","expires_at":"2026-08-20T09:05:00Z"}` |
| `POST /v1/im/me/deletion` | Header `X-Action-Token: del_token`;Body `{}` | `{"status":"ok"}` |
#### 10.22.2 账号安全:修改密码与注销账号
**修改密码 `POST /v1/im/me/password`(已实现):**
- 已登录(Bearer)用户提交 `old_password`、`new_password`;两者必填,缺一返回 `400 MALFORMED_REQUEST`。
- 服务端先用旧密码走 `basic` 认证校验,失败返回 HTTP `401`:`{"code":30001,"reason":"AUTH_REQUIRED","message":"invalid credentials"}`,不泄露账号状态。
- 新密码不满足密码策略返回 HTTP `400`:`{"code":30040,"reason":"PASSWORD_POLICY_VIOLATION"}`。
- 成功后服务端递增 `auth_version` 并撤销该用户全部在线 Session(广播 `password_changed`);包括当前请求在内的所有旧 Token 全部失效,客户端收到成功响应后必须清理本租户凭证并跳转登录页。
**注销账号 `POST /v1/im/me/deletion`(已实现):**
- 两步挑战复用 1.7 敏感操作基建:`POST /v1/im/security/challenges`(Body `{"scene":"delete_account","channel":"sms"}`,发码到账号绑定手机号)→ `POST /v1/im/security/challenges/{id}/verify`(返回一次性 `action_token`)→ `POST /v1/im/me/deletion`(Header `X-Action-Token` 携带)。
- 服务端配置 `permanent_accounts=true` 时拒绝注销:HTTP `403` `{"code":30040,"reason":"FORBIDDEN","message":"account deletion is disabled"}`。
- 执行成功为**软删除**:撤销全部认证记录(含登录密码)、踢出所有在线 Session(`reason=user_deleted`)、退出并停用其拥有的群与 P2P 会话、向关注该用户的好友下发 `gone` 在线状态;账号不再可登录。客户端收到成功响应后清理本地数据并返回企业入口。
- 挑战阶段限流与错误码同 1.7(`VERIFICATION_RATE_LIMITED`、`CHALLENGE_EXPIRED`、`CODE_INVALID`、`TOO_MANY_ATTEMPTS`);action token 缺失/无效返回 HTTP `403` `{"code":30042,"reason":"ACTION_TOKEN_INVALID"}`。
## 11. 反诈安全、举报与意见反馈
@@ -909,7 +909,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
**状态:新增。**
- 敏感操作先调用 `POST /v1/im/security/challenges`;开启青少年模式设置独立密码时 Body 为 `{"scene":"set_independent_password","channel":"sms"}`,关闭青少年模式时 Body 为 `{"scene":"close_youth_mode","channel":"sms"}`。手机号由登录身份读取,客户端不提交目标手机号。
- 敏感操作先调用 `POST /v1/im/security/challenges`;开启青少年模式设置独立密码时 Body 为 `{"scene":"set_independent_password","channel":"sms"}`,关闭青少年模式时 Body 为 `{"scene":"close_youth_mode","channel":"sms"}`;群主转让使用 `{"scene":"group_owner_transfer","channel":"sms"}`;解散群聊使用 `{"scene":"group_dissolve","channel":"sms"}`;注销账号使用 `{"scene":"delete_account","channel":"sms"}`。手机号由登录身份读取,客户端不提交目标手机号。
- 发码/校验:服务端返回 `challenge_id` 和脱敏手机号;提交 `POST /v1/im/security/challenges/{id}/verify`,Body `{"code":"..."}`。
- 重复发码:同一用户、同一手机号、同一敏感场景存在未过期 challenge 且仍在 `resend_after_seconds` 冷却期内时,服务端返回 HTTP `429 VERIFICATION_RATE_LIMITED`,`details` 带 `challenge_id` 和 `retry_after_seconds`。客户端应复用该 `challenge_id` 继续倒计时,不要当成接口不可达或重新登录。
- 小时限流:超过一小时创建次数上限时同样返回 HTTP `429 VERIFICATION_RATE_LIMITED`,`details.retry_after_seconds` 可能大于 60 秒且不一定带 `challenge_id`。客户端只展示倒计时,倒计时结束后允许用户重新获取验证码。
@@ -935,7 +935,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
- 页面只调用 `GET /v1/im/security/realname`。`verified` 时返回如 `masked_name:"张*"`、`masked_id_number:"110***********1234"`、`verified_at`。
- 前端只读展示,不缓存原始证件信息,不提供直接修改接口。
- 更正信息使用独立申诉 `POST /v1/im/security/realname/appeals`,需二次身份验证;不复用本页保存按钮。
- 更正信息使用独立申诉 `POST /v1/im/security/realname/appeals`,Body `{"reason":"...","attachments":[]}`(`reason` 必填、≤500 字;`attachments` 最多 9 个 file_id),Bearer 即可,当前无需二次身份验证;不复用本页保存按钮。
### 1.10 实名认证(安卓).png
@@ -983,7 +983,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
| `POST /v1/im/auth/password-reset/challenges/{challenge_id}/verify` | `{"code":"123456"}` | `{"reset_token":"reset_token_123","expires_in_seconds":300}` |
| `POST /v1/im/auth/password-reset/confirm` | `{"reset_token":"reset_token_123","new_password":"NewPass123"}` | `{"status":"ok"}` |
| `POST /admin/v1/tenant/users/{user_id}/reset-password` 管理后台 | `{"new_password":"AdminReset123","reason":"用户无手机号无法自助找回"}` | `{"user_id":"usr...","status":"reset","auth_version":2}` |
| `POST /v1/im/auth/logout` 待实现 | `{}` | `{"status":"ok"}` |
| `POST /v1/im/auth/logout` | `{}`(可选 `device_id`;或 Header `X-Device-ID`/`X-IM-Device-ID`) | `{"status":"ok","device_id":"...","push_unbound":true}`;当前 Token 写入 Redis 撤销集合(TTL=剩余有效期),仅当前设备失效,不影响其他设备;带 `device_id` 时同步解绑该设备推送 |
| `GET /v1/im/app/releases/latest?platform=ios\|android\|web&current_version=1.0.0&channel=stable` | Query only | `{"platform":"web","channel":"stable","latest_version":"1.0.0","min_supported_version":"1.0.0","update_type":"none","package_url":"","store_url":"","release_notes":"当前已是最新版本。","remind_after_seconds":0}` |
## 2. 消息首页、全局导航与系统通知
@@ -2928,7 +2928,7 @@ GET /v1/im/topics/{topic}/message-mutations?since_version={localMutationVersion}
**状态:菜单纯客户端;数据接口部分新增。**
- 菜单来自 `bootstrap.settings_menu`,安全、通知、隐私、通用、关于按权限展示。系统通知权限状态由 iOS API 读取,不由服务端伪造。
- 退出:`POST /v1/im/auth/logout` 撤销当前登录 Token 对应的设备会话,成功或 Token 已失效后关闭 WS、清安全存储和本租户用户缓存。
- 退出:`POST /v1/im/auth/logout` 将当前登录 Token 的 SHA-256 摘要写入 Redis 撤销集合,TTL 与 Token 剩余有效期一致,不影响同账号其他设备。成功后关闭 WS、清安全存储和本租户用户缓存;请求须带 `Authorization: Bearer <token>` 和 `Idempotency-Key`。
- 多设备退出使用 `DELETE /v1/im/security/sessions/{session_id}`,需二次验证。
### 10.8 设置(安卓).png
@@ -3096,9 +3096,29 @@ GET /v1/im/topics/{topic}/message-mutations?since_version={localMutationVersion}
| `POST /v1/im/security/challenges/{id}/verify` 关闭青少年模式 | `{"code":"123456"}` | `{"action_token":"close_token","action":"close_youth_mode","expires_at":"2026-08-20T09:05:00Z"}` |
| `GET /v1/im/security/realname` | Query only | `{"status":"unverified","can_submit":true}` |
| `POST /v1/im/security/realname/submissions` | `{"name":"张三","id_type":"cn_id","id_number":"110101199001011234"}` | `{"submission_id":"rn_1","status":"pending","can_submit":false}` |
| `POST /v1/im/security/realname/appeals` 待实现 | `{"reason":"证件变更","description":"需要更正实名信息","action_token":"action_token"}` | `{"appeal_id":"rna_1","status":"pending","submitted_at":"2026-08-20T09:00:00Z"}` |
| `POST /v1/im/security/realname/appeals` | `{"reason":"证件变更需要更正实名信息","attachments":["file_1"]}` | `{"appeal_id":"rna_1","reason":"...","attachments":["file_1"],"status":"pending"}`;当前无需二次身份验证(如后续启用,将复用 1.7 的 action_token 机制并在此处更新) |
| `PUT /v1/im/devices/{device_id}/push-token` | `{"provider":"jpush","token":"registration_id","platform":"android","app_version":"1.0.0","push_env":"test","sdk_version":"5.0.0","notification_permission":"granted"}` | `{"device_id":"device_1","provider":"jpush","platform":"android","app_version":"1.0.0","updated_at":"2026-08-20T09:00:00Z"}` |
| `DELETE /v1/im/security/sessions/{session_id}` 待实现 | Header `X-Action-Token: action_token` | `{"session_id":"sess_1","revoked":true}` |
| `POST /v1/im/me/password` | `{"old_password":"OldPass123","new_password":"NewPass123"}` | `{"status":"ok"}`;旧密码错误返回 HTTP `401`:`{"code":30001,"reason":"AUTH_REQUIRED","message":"invalid credentials"}`;新密码不满足策略返回 HTTP `400`:`{"code":30040,"reason":"PASSWORD_POLICY_VIOLATION"}` |
| `POST /v1/im/security/challenges` 注销账号发码 | Header `Idempotency-Key`;Body `{"scene":"delete_account","channel":"sms"}` | `{"challenge_id":"sec_chg_9","phone_mask":"+861****000","expires_in_seconds":300,"resend_after_seconds":60}` |
| `POST /v1/im/security/challenges/{id}/verify` 注销账号验证 | `{"code":"123456"}` | `{"action_token":"del_token","action":"delete_account","expires_at":"2026-08-20T09:05:00Z"}` |
| `POST /v1/im/me/deletion` | Header `X-Action-Token: del_token`;Body `{}` | `{"status":"ok"}` |
#### 10.22.2 账号安全:修改密码与注销账号
**修改密码 `POST /v1/im/me/password`(已实现):**
- 已登录(Bearer)用户提交 `old_password`、`new_password`;两者必填,缺一返回 `400 MALFORMED_REQUEST`。
- 服务端先用旧密码走 `basic` 认证校验,失败返回 HTTP `401`:`{"code":30001,"reason":"AUTH_REQUIRED","message":"invalid credentials"}`,不泄露账号状态。
- 新密码不满足密码策略返回 HTTP `400`:`{"code":30040,"reason":"PASSWORD_POLICY_VIOLATION"}`。
- 成功后服务端递增 `auth_version` 并撤销该用户全部在线 Session(广播 `password_changed`);包括当前请求在内的所有旧 Token 全部失效,客户端收到成功响应后必须清理本租户凭证并跳转登录页。
**注销账号 `POST /v1/im/me/deletion`(已实现):**
- 两步挑战复用 1.7 敏感操作基建:`POST /v1/im/security/challenges`(Body `{"scene":"delete_account","channel":"sms"}`,发码到账号绑定手机号)→ `POST /v1/im/security/challenges/{id}/verify`(返回一次性 `action_token`)→ `POST /v1/im/me/deletion`(Header `X-Action-Token` 携带)。
- 服务端配置 `permanent_accounts=true` 时拒绝注销:HTTP `403` `{"code":30040,"reason":"FORBIDDEN","message":"account deletion is disabled"}`。
- 执行成功为**软删除**:撤销全部认证记录(含登录密码)、踢出所有在线 Session(`reason=user_deleted`)、退出并停用其拥有的群与 P2P 会话、向关注该用户的好友下发 `gone` 在线状态;账号不再可登录。客户端收到成功响应后清理本地数据并返回企业入口。
- 挑战阶段限流与错误码同 1.7(`VERIFICATION_RATE_LIMITED`、`CHALLENGE_EXPIRED`、`CODE_INVALID`、`TOO_MANY_ATTEMPTS`);action token 缺失/无效返回 HTTP `403` `{"code":30042,"reason":"ACTION_TOKEN_INVALID"}`。
## 11. 反诈安全、举报与意见反馈