@gengchenchina/chrome-media-publish-extension 1.0.8 → 1.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -509,6 +509,10 @@ Manager 发布菜单会自动递增 patch;工具包若首发为 `1.0.9`,则
509
509
 
510
510
  ## Adapter 开发规范
511
511
 
512
+ 百家号编辑页跳到 STOKEN 中间页时,内核会自动执行 Passport 获取 STOKEN、`dealtoken` 和一次编辑页重试。
513
+ 真实账号验证步骤与失败诊断见 `docs/integration-guide.md` 的“百家号 STOKEN 补全与修复验证”。
514
+ 已发布的 `1.0.8` 不会包含本地新修复;发布前查询版本并递增,然后更新下游依赖、重建并重新加载扩展。
515
+
512
516
  真实平台 adapter 放在:
513
517
 
514
518
  ```text
package/dist/index.js CHANGED
@@ -4126,6 +4126,9 @@ var BAIJIAHAO_PLATFORM = Platform.Baijiahao;
4126
4126
  var BAIJIAHAO_ORIGIN = "https://baijiahao.baidu.com";
4127
4127
  var BAIJIAHAO_APPINFO_URL = `${BAIJIAHAO_ORIGIN}/builder/app/appinfo`;
4128
4128
  var BAIJIAHAO_EDIT_URL = `${BAIJIAHAO_ORIGIN}/builder/rc/edit`;
4129
+ var BAIJIAHAO_STOKEN_URL = `${BAIJIAHAO_ORIGIN}/builder/fe-react/stoken.html`;
4130
+ var BAIJIAHAO_PASSPORT_AUTH_URL = "https://passport.baidu.com/v3/login/api/auth/";
4131
+ var BAIJIAHAO_DEALTOKEN_URL = `${BAIJIAHAO_ORIGIN}/pcui/home/dealtoken`;
4129
4132
  var BAIJIAHAO_ARTICLE_PUBLISH_URL = `${BAIJIAHAO_ORIGIN}/pcui/article/publish`;
4130
4133
  var BAIJIAHAO_ARTICLE_LIST_URL = `${BAIJIAHAO_ORIGIN}/pcui/article/lists`;
4131
4134
  var BAIJIAHAO_IMAGE_UPLOAD_URL = `${BAIJIAHAO_ORIGIN}/pcui/picture/uploadproxy`;
@@ -4154,7 +4157,9 @@ async function fetchText(ctx, url, init = {}, options = {}) {
4154
4157
  Accept: "application/json, text/plain, */*",
4155
4158
  ...init.headers || {}
4156
4159
  },
4157
- body: init.body
4160
+ body: init.body,
4161
+ ...init.cache ? { cache: init.cache } : {},
4162
+ ...init.redirect ? { redirect: init.redirect } : {}
4158
4163
  }, { timeoutMs: options.timeoutMs });
4159
4164
  const text = await response.text();
4160
4165
  options.onResponse?.(response, text);
@@ -4616,14 +4621,7 @@ function createArticleDependencies(ctx, input) {
4616
4621
  async function fetchBaijiahaoAuthToken(ctx, input = {}) {
4617
4622
  const startedAt = Date.now();
4618
4623
  let httpErrorCode;
4619
- const diagnostics = {
4620
- schemaVersion: 1,
4621
- stage: "baijiahao.auth-token",
4622
- failure: "REQUEST_FAILED",
4623
- requestedAt: new Date(startedAt).toISOString(),
4624
- requestUrl: BAIJIAHAO_EDIT_URL,
4625
- requestAccept: "application/json, text/plain, */*",
4626
- credentials: "include",
4624
+ const emptyResponse = {
4627
4625
  status: null,
4628
4626
  finalUrl: null,
4629
4627
  redirected: null,
@@ -4633,13 +4631,26 @@ async function fetchBaijiahaoAuthToken(ctx, input = {}) {
4633
4631
  tokenMatched: null,
4634
4632
  hasHtmlMarkers: null,
4635
4633
  hasLoginMarkers: null,
4636
- hasChallengeMarkers: null,
4634
+ hasChallengeMarkers: null
4635
+ };
4636
+ const diagnostics = {
4637
+ schemaVersion: 1,
4638
+ stage: "baijiahao.auth-token",
4639
+ failure: "REQUEST_FAILED",
4640
+ requestedAt: new Date(startedAt).toISOString(),
4641
+ requestUrl: BAIJIAHAO_EDIT_URL,
4642
+ requestAccept: "application/json, text/plain, */*",
4643
+ credentials: "include",
4644
+ ...emptyResponse,
4637
4645
  elapsedMs: 0
4638
4646
  };
4639
- try {
4640
- const html = await fetchText(ctx, BAIJIAHAO_EDIT_URL, {
4641
- credentials: "include"
4642
- }, {
4647
+ const requestText = (url, init = {}) => {
4648
+ httpErrorCode = void 0;
4649
+ Object.assign(diagnostics, emptyResponse, {
4650
+ requestUrl: url.split("?")[0],
4651
+ failure: "REQUEST_FAILED"
4652
+ });
4653
+ return fetchText(ctx, url, { credentials: "include", ...init }, {
4643
4654
  timeoutMs: input.timeoutMs,
4644
4655
  includeErrorBody: false,
4645
4656
  onResponse(response, text) {
@@ -4650,8 +4661,8 @@ async function fetchBaijiahaoAuthToken(ctx, input = {}) {
4650
4661
  }
4651
4662
  let finalUrl = null;
4652
4663
  try {
4653
- const url = new URL(response.url);
4654
- finalUrl = `${url.origin}${url.pathname}`;
4664
+ const url2 = new URL(response.url);
4665
+ finalUrl = `${url2.origin}${url2.pathname}`;
4655
4666
  } catch {
4656
4667
  }
4657
4668
  Object.assign(diagnostics, {
@@ -4667,9 +4678,71 @@ async function fetchBaijiahaoAuthToken(ctx, input = {}) {
4667
4678
  hasLoginMarkers: /passport\.baidu\.com|登录|\blogin\b/i.test(text),
4668
4679
  hasChallengeMarkers: /验证码|安全验证|安全校验|\bcaptcha\b/i.test(text)
4669
4680
  });
4681
+ if (diagnostics.sessionRefresh?.phase === "passport") {
4682
+ diagnostics.sessionRefresh.authStatus = response.status;
4683
+ } else if (diagnostics.sessionRefresh?.phase === "dealtoken") {
4684
+ diagnostics.sessionRefresh.dealtokenStatus = response.status;
4685
+ }
4670
4686
  }
4671
4687
  });
4672
- const match = html.match(/window\.__BJH__INIT__AUTH__\s*=\s*['"]([^'"]+)['"]/);
4688
+ };
4689
+ const matchToken = (html) => html.match(/window\.__BJH__INIT__AUTH__\s*=\s*['"]([^'"]+)['"]/);
4690
+ try {
4691
+ let html = await requestText(BAIJIAHAO_EDIT_URL);
4692
+ let match = matchToken(html);
4693
+ if (!match && diagnostics.finalUrl === BAIJIAHAO_STOKEN_URL) {
4694
+ diagnostics.sessionRefresh = {
4695
+ attempted: true,
4696
+ completed: false,
4697
+ phase: "passport",
4698
+ authStatus: null,
4699
+ authErrno: null,
4700
+ dealtokenStatus: null
4701
+ };
4702
+ const callback = `json_callback_${Date.now()}`;
4703
+ const params = new URLSearchParams({ callback, return_type: "2", tpl: "bjh" });
4704
+ const authText = await requestText(`${BAIJIAHAO_PASSPORT_AUTH_URL}?${params}`, { cache: "no-store" });
4705
+ let auth;
4706
+ try {
4707
+ const jsonp = authText.trim().match(new RegExp(`^${callback}\\s*\\(([\\s\\S]*)\\)\\s*;?$`));
4708
+ auth = JSON.parse(jsonp ? jsonp[1] : authText);
4709
+ if (!auth || typeof auth !== "object" || Array.isArray(auth)) throw new Error();
4710
+ } catch {
4711
+ diagnostics.failure = "STOKEN_RESPONSE_INVALID";
4712
+ throw new Error("\u767E\u5BB6\u53F7 Passport STOKEN \u54CD\u5E94\u683C\u5F0F\u5F02\u5E38");
4713
+ }
4714
+ const errno = typeof auth.errno === "number" || typeof auth.errno === "string" && /^-?\d+$/.test(auth.errno) ? Number(auth.errno) : NaN;
4715
+ diagnostics.sessionRefresh.authErrno = Number.isFinite(errno) ? errno : null;
4716
+ const stoken = typeof auth.stoken === "string" ? auth.stoken.trim() : "";
4717
+ if (errno !== 0 || !/^[\x21-\x7e]+$/.test(stoken)) {
4718
+ diagnostics.failure = "STOKEN_AUTH_FAILED";
4719
+ throw new Error(`\u767E\u5BB6\u53F7 STOKEN \u83B7\u53D6\u5931\u8D25\uFF08Passport errno=${diagnostics.sessionRefresh.authErrno ?? "\u672A\u77E5"}\uFF09\uFF0C\u8BF7\u5728\u5E73\u53F0\u9875\u9762\u5B8C\u6210\u767B\u5F55\u6216\u9A8C\u8BC1\u540E\u91CD\u8BD5`);
4720
+ }
4721
+ diagnostics.sessionRefresh.phase = "dealtoken";
4722
+ await requestText(BAIJIAHAO_DEALTOKEN_URL, {
4723
+ headers: { bjh: stoken },
4724
+ cache: "no-store",
4725
+ redirect: "error"
4726
+ });
4727
+ if (diagnostics.sessionRefresh.dealtokenStatus !== 200 || diagnostics.redirected === true || diagnostics.finalUrl !== null && diagnostics.finalUrl !== BAIJIAHAO_DEALTOKEN_URL) {
4728
+ diagnostics.failure = "STOKEN_REFRESH_FAILED";
4729
+ throw new Error("\u767E\u5BB6\u53F7 STOKEN \u4F1A\u8BDD\u8865\u5168\u672A\u6210\u529F");
4730
+ }
4731
+ diagnostics.sessionRefresh.completed = true;
4732
+ diagnostics.sessionRefresh.phase = "retry-edit";
4733
+ html = await requestText(BAIJIAHAO_EDIT_URL, { cache: "no-store" });
4734
+ match = matchToken(html);
4735
+ if (!match) {
4736
+ const repeatedRedirect = diagnostics.finalUrl === BAIJIAHAO_STOKEN_URL;
4737
+ diagnostics.failure = repeatedRedirect ? "STOKEN_REDIRECT_LOOP" : "TOKEN_NOT_FOUND";
4738
+ throw new Error(repeatedRedirect ? "\u767E\u5BB6\u53F7 STOKEN \u8865\u5168\u540E\u4ECD\u8DF3\u8F6C\u5230\u4F1A\u8BDD\u521D\u59CB\u5316\u9875\uFF0C\u8BF7\u5728\u5E73\u53F0\u9875\u9762\u5B8C\u6210\u767B\u5F55\u6216\u9A8C\u8BC1\u540E\u91CD\u8BD5" : "\u767E\u5BB6\u53F7\u4F1A\u8BDD\u8865\u5168\u540E\u672A\u80FD\u83B7\u53D6\u7F16\u8F91\u9875\u53D1\u5E03 token");
4739
+ }
4740
+ ctx.Logger?.info?.("\u767E\u5BB6\u53F7 STOKEN \u4F1A\u8BDD\u8865\u5168\u6210\u529F", {
4741
+ stage: "baijiahao.auth-token",
4742
+ ...diagnostics.sessionRefresh,
4743
+ elapsedMs: Date.now() - startedAt
4744
+ });
4745
+ }
4673
4746
  if (!match) throw new Error("\u767B\u5F55\u5931\u6548\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55\u767E\u5BB6\u53F7");
4674
4747
  return match[1];
4675
4748
  } catch (error) {