feat(qoder): 弄清国际版每日 100 Credits 的「按设备下发」规则 + 一键设备授权登录
排查结论(本机对真实接口做了 30+ 组对照实验)
- GET /sash/api/v1/me/campaigns 只返回一条常驻 VIEW_DETAILS 广告
(act-20260901-493,BOGO 订阅推广,claimStatus=CLAIMED 与签到无关)
- 无论 Cosy-MachineToken/Code/Type 用 env 0/3/4/prod、裸调用/带 stdin、
是否附 Cosy-MachineId/OS/Hostname/Origin/Referer/X-*、是否带 clientType,
都拿不到 CLAIM_BEFIT 轮次;账号本人 balances/achievements 正常
- 三个社区实现(qoder2api-hub、dsh-connect-qoder、CreditDaddy)一致:
每日轮次按「登录过官方客户端的那台设备」下发,NAS 侧另造的设备看不到它
修复
- _benefits() 改为只认 actionType=CLAIM_BEFIT(不再把 VIEW_DETAILS 当签到),
窗口过期也排除;claimStatus 未知按可领处理(领取接口幂等)
- 两段式取活动:先裸取拿 uid → 按 uid 生成风控身份 → 再带设备身份重取
- 状态文案改为「未下发每日签到活动」而不是误导性的「今日已领取」
新功能
- Qoder 一键登录(OAuth 设备授权 / PKCE S256):应用内点按钮 → 浏览器确认一次,
Token 直接绑定本机设备;同 uid 已存在则更新凭证而不是新增重复账号
- 手工导入桌面端设备身份接口 /api/qoder/import_device
- 诊断接口:/api/qoder/{probe,experiment,growth,matrix,desktop}
测试:39 后端 + 25 E2E + 9 前端全绿
This commit is contained in:
@@ -47,7 +47,7 @@
|
||||
fail: { label: "签到失败", cls: "fail", icon: "❌" },
|
||||
no_session: { label: "需重新授权", cls: "no_session", icon: "🔒" },
|
||||
no_auth: { label: "缺少凭据", cls: "no_auth", icon: "🔒" },
|
||||
retry_later: { label: "风控冷却", cls: "retry_later", icon: "⏳" }
|
||||
retry_later: { label: "活动未下发·待重试", cls: "retry_later", icon: "⏳" }
|
||||
};
|
||||
|
||||
function platformName(p) { return p === "trae" ? "TRAE" : (p === "qoder" ? "Qoder" : "WorkBuddy"); }
|
||||
@@ -256,7 +256,7 @@
|
||||
|
||||
// ---------------------------------------------------------------- add modal
|
||||
function openModal() { $("modal-add").classList.remove("hidden"); }
|
||||
function closeModal(id) { $(id).classList.add("hidden"); stopOauth(); $("add-msg").textContent = ""; }
|
||||
function closeModal(id) { $(id).classList.add("hidden"); stopOauth(); stopQdLogin(); $("add-msg").textContent = ""; }
|
||||
|
||||
document.querySelectorAll("[data-close]").forEach(function (b) {
|
||||
b.addEventListener("click", function () { closeModal(b.dataset.close); });
|
||||
@@ -310,6 +310,65 @@
|
||||
});
|
||||
|
||||
|
||||
// ---- qoder 一键登录(OAuth 设备授权,绑定本机设备)
|
||||
var qdState = null, qdTimer = null;
|
||||
|
||||
function stopQdLogin() {
|
||||
if (qdTimer) { clearInterval(qdTimer); qdTimer = null; }
|
||||
qdState = null;
|
||||
}
|
||||
|
||||
$("btn-qoder-login").addEventListener("click", function () {
|
||||
var realm = $("qoder-domain").value.indexOf("com.cn") >= 0 ? "cn" : "intl";
|
||||
var btn = this;
|
||||
stopQdLogin();
|
||||
btn.disabled = true;
|
||||
$("qoder-login-link").innerHTML = "";
|
||||
$("qoder-login-status").textContent = "正在申请授权链接…";
|
||||
api("POST", "/qoder/login/start", { realm: realm })
|
||||
.then(function (d) {
|
||||
qdState = d.state;
|
||||
var box = $("qoder-login-link");
|
||||
box.innerHTML = "";
|
||||
var a = document.createElement("a");
|
||||
a.href = d.auth_url;
|
||||
a.target = "_blank";
|
||||
a.rel = "noopener";
|
||||
a.textContent = "👉 点这里打开 Qoder 授权页";
|
||||
box.appendChild(a);
|
||||
var p = document.createElement("div");
|
||||
p.className = "muted";
|
||||
p.textContent = "(或在浏览器打开:" + d.auth_url + ")";
|
||||
box.appendChild(p);
|
||||
$("qoder-login-status").textContent =
|
||||
"等待浏览器里确认授权…(" + Math.round(d.ttl / 60) + " 分钟内有效)";
|
||||
qdTimer = setInterval(pollQdLogin, 3000);
|
||||
})
|
||||
.catch(function (e) { $("qoder-login-status").textContent = e.message; })
|
||||
.finally(function () { btn.disabled = false; });
|
||||
});
|
||||
|
||||
function pollQdLogin() {
|
||||
if (!qdState) return;
|
||||
api("GET", "/qoder/login/poll?state=" + encodeURIComponent(qdState))
|
||||
.then(function (d) {
|
||||
if (d.status === "ok") {
|
||||
stopQdLogin();
|
||||
$("qoder-login-status").textContent = "登录成功";
|
||||
toast(d.message || "Qoder 账号已添加", "ok");
|
||||
closeModal("modal-add");
|
||||
refreshState();
|
||||
} else if (d.status === "error") {
|
||||
stopQdLogin();
|
||||
$("qoder-login-status").textContent = d.message || "登录失败";
|
||||
}
|
||||
})
|
||||
.catch(function (e) {
|
||||
stopQdLogin();
|
||||
$("qoder-login-status").textContent = e.message;
|
||||
});
|
||||
}
|
||||
|
||||
$("btn-qoder-add").addEventListener("click", function () {
|
||||
var token = $("qoder-token").value.trim();
|
||||
if (!token) return addMsg("请填写 Access Token", false);
|
||||
|
||||
Reference in New Issue
Block a user