Skip to content
This repository was archived by the owner on Apr 22, 2026. It is now read-only.

Commit e9eb0e1

Browse files
committed
release(v1.0.7): 切换 Graph 备注回写到开放接口
Graph 接口模式改为 PATCH /api/open/accounts/:id/remark,仅发送 remark;并限制备注回写仅在 graph+api 模式触发,同时在 README 标注 microsoft-account-manager 对接地址。
1 parent da3a566 commit e9eb0e1

4 files changed

Lines changed: 27 additions & 104 deletions

File tree

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,12 @@ CodeX Register 是一个本地桌面化控制台,用于统一执行注册流
1010

1111
## 0. 更新日志
1212

13+
### v1.0.7 (2026-04-06)
14+
15+
- Graph 接口模式账号备注更新切换为开放接口:`PATCH /api/open/accounts/:id/remark`
16+
- 备注更新请求体改为最小负载:`{"remark":"已注册"}`,不再依赖全量账号字段。
17+
- 保持 token 鉴权与错误提示一致,注册链路中的“已注册账号”仍会自动回写备注。
18+
1319
### v1.0.6 (2026-04-06)
1420

1521
- Issue: #7 — Graph 接口模式注册链路异常(区域限制误归因、已注册账号处理、邮箱 OTP 重试策略)。
@@ -108,6 +114,7 @@ python gui.py --mode browser --no-auto-open
108114
- MailFree / Cloudflare Temp / CloudMail 可配置域名策略(随机域名、白名单、自定义 local-part)。
109115
- Luckyous API 支持按项目编码自动下单邮箱并轮询验证码。
110116
- Graph 支持文件模式与接口模式:文件模式使用账号文件;接口模式使用项目地址 + token。
117+
- Graph 接口模式推荐对接 `microsoft-account-manager``https://github.com/Msg-Lbo/microsoft-account-manager`
111118
- Gmail 模式需使用应用专用密码(非登录密码)。
112119

113120
### 5.3 MailFree 域名配置(Cloudflare DNS)
@@ -236,7 +243,7 @@ Cloudflare Token 要求(用于域名配置页读取 Zone 和管理 CNAME):
236243
| `gmail_alias_mix_googlemail` | bool | `true` | 混用 gmail/googlemail 域名 |
237244
| `graph_accounts_mode` | string | `file` | Graph 账号来源:`file` / `api` |
238245
| `graph_accounts_file` | string | `""` | Graph 账号文件路径 |
239-
| `graph_api_base_url` | string | `""` | Graph 接口模式地址 |
246+
| `graph_api_base_url` | string | `""` | Graph 接口模式地址(推荐 `microsoft-account-manager` 项目地址) |
240247
| `graph_api_token` | string | `""` | Graph 接口模式 token |
241248
| `graph_tenant` | string | `common` | Graph tenant |
242249
| `graph_fetch_mode` | string | `graph_api` | `graph_api` / `imap_xoauth2` |

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.0.6
1+
1.0.7

codex_register/mail_services.py

Lines changed: 9 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -2772,58 +2772,6 @@ def _find_account(self, mailbox: str) -> dict[str, Any]:
27722772
raise MailServiceError(f"Graph 接口账号池中不存在该邮箱: {target}")
27732773
raise MailServiceError(f"Graph 账号文件中不存在该邮箱: {target}")
27742774

2775-
@staticmethod
2776-
def _extract_api_account_payload(payload: Any) -> dict[str, Any]:
2777-
if isinstance(payload, dict):
2778-
for key in ("data", "item", "account", "result", "row"):
2779-
val = payload.get(key)
2780-
if isinstance(val, dict):
2781-
return val
2782-
return payload
2783-
if isinstance(payload, list):
2784-
for it in payload:
2785-
if isinstance(it, dict):
2786-
return it
2787-
return {}
2788-
2789-
@staticmethod
2790-
def _pick_str_value(*pairs: tuple[dict[str, Any], tuple[str, ...]]) -> str:
2791-
for src, keys in pairs:
2792-
if not isinstance(src, dict):
2793-
continue
2794-
for key in keys:
2795-
val = src.get(key)
2796-
if val is None:
2797-
continue
2798-
text = str(val).strip()
2799-
if text:
2800-
return text
2801-
return ""
2802-
2803-
def _load_api_account_detail(self, account_id: str, *, proxies: Any = None) -> dict[str, Any]:
2804-
aid = str(account_id or "").strip()
2805-
if not aid:
2806-
return {}
2807-
status, payload, text = self._api_request(
2808-
"GET",
2809-
f"/api/accounts/{urllib.parse.quote(aid, safe='')}",
2810-
proxies=proxies,
2811-
timeout=25,
2812-
)
2813-
if status == 404:
2814-
return {}
2815-
if not (200 <= status < 300):
2816-
if self._is_api_token_invalid(status, payload, text):
2817-
raise MailServiceError(
2818-
"Graph 接口模式鉴权失败:开放接口 token 无效。"
2819-
"请检查 graph_api_token 是否与上游 MAIL_API_TOKEN 一致。"
2820-
)
2821-
detail = self._api_error_message(payload, text)
2822-
raise MailServiceError(
2823-
f"Graph 接口读取账号详情失败: /api/accounts/{aid} HTTP {status}: {detail or text}"
2824-
)
2825-
return self._extract_api_account_payload(payload)
2826-
28272775
def mark_account_registered(
28282776
self,
28292777
mailbox: str,
@@ -2843,69 +2791,28 @@ def mark_account_registered(
28432791
if not account_id:
28442792
return False
28452793

2846-
detail = {}
2847-
try:
2848-
detail = self._load_api_account_detail(account_id, proxies=proxies)
2849-
except Exception:
2850-
detail = {}
2851-
2852-
account_val = self._pick_str_value(
2853-
(detail, ("account", "email", "address", "mailbox")),
2854-
(acc, ("email",)),
2855-
)
2856-
password_val = self._pick_str_value(
2857-
(detail, ("password",)),
2858-
(acc, ("password",)),
2859-
)
2860-
client_id_val = self._pick_str_value(
2861-
(detail, ("clientId", "client_id")),
2862-
(acc, ("client_id", "clientId")),
2863-
)
2864-
refresh_token_val = self._pick_str_value(
2865-
(detail, ("refreshToken", "refresh_token")),
2866-
(acc, ("refresh_token", "refreshToken")),
2867-
)
2868-
if not account_val or "@" not in account_val:
2869-
account_val = target
2870-
2871-
missing: list[str] = []
2872-
if not account_val:
2873-
missing.append("account")
2874-
if not password_val:
2875-
missing.append("password")
2876-
if not client_id_val:
2877-
missing.append("clientId")
2878-
if not refresh_token_val:
2879-
missing.append("refreshToken")
2880-
if missing:
2881-
raise MailServiceError(
2882-
"Graph 接口更新账号备注失败:缺少字段 "
2883-
+ ", ".join(missing)
2884-
)
2885-
28862794
body = {
2887-
"account": account_val,
2888-
"password": password_val,
2889-
"clientId": client_id_val,
2890-
"refreshToken": refresh_token_val,
28912795
"remark": str(remark or "已注册").strip() or "已注册",
28922796
}
28932797
status, payload, text = self._api_request(
2894-
"PUT",
2895-
f"/api/accounts/{urllib.parse.quote(account_id, safe='')}",
2798+
"PATCH",
2799+
f"/api/open/accounts/{urllib.parse.quote(account_id, safe='')}/remark",
28962800
json_body=body,
28972801
proxies=proxies,
28982802
timeout=25,
28992803
)
29002804
if not (200 <= status < 300):
2805+
if self._is_api_token_invalid(status, payload, text):
2806+
raise MailServiceError(
2807+
"Graph 接口模式鉴权失败:开放接口 token 无效。"
2808+
"请检查 graph_api_token 是否与上游 MAIL_API_TOKEN 一致。"
2809+
)
29012810
detail_msg = self._api_error_message(payload, text)
29022811
raise MailServiceError(
2903-
f"Graph 接口更新账号备注失败: /api/accounts/{account_id} HTTP {status}: {detail_msg or text}"
2812+
"Graph 接口更新账号备注失败: "
2813+
f"/api/open/accounts/{account_id}/remark HTTP {status}: {detail_msg or text}"
29042814
)
29052815

2906-
acc["password"] = password_val
2907-
acc["client_id"] = client_id_val
2908-
acc["refresh_token"] = refresh_token_val
29092816
acc["remark"] = body["remark"]
29102817
return True
29112818

codex_register/r_with_pwd.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,15 @@ def _mark_graph_registered_email(
295295
proxies: Any = None,
296296
remark: str = "已注册",
297297
) -> bool:
298+
provider_now = normalize_mail_provider(
299+
os.getenv("MAIL_SERVICE_PROVIDER", MAIL_SERVICE_PROVIDER)
300+
)
301+
if provider_now != "graph":
302+
return False
303+
graph_mode = str(os.getenv("GRAPH_ACCOUNTS_MODE", "file") or "file").strip().lower()
304+
if graph_mode != "api":
305+
return False
306+
298307
target = str(email or "").strip().lower()
299308
if not target or "@" not in target:
300309
return False

0 commit comments

Comments
 (0)