{"record":{"id":"c40845086c545153","repo":"jackwener/OpenCLI","slug":"auth-c40845","errorCode":null,"errorMessage":"auth","messagePattern":"auth","errorType":"error_code","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/zsxq/auth.js","lineNumber":36,"sourceCode":"          credentials: 'include',\n          headers: { Accept: 'application/json' },\n        });\n        if (r.status === 401 || r.status === 403) {\n          return { kind: 'auth', detail: 'zsxq /v2/users/self returned HTTP ' + r.status };\n        }\n        if (!r.ok) return { kind: 'http', httpStatus: r.status };\n        const d = await r.json();\n        if (d?.succeeded === false || !d?.resp_data?.user) {\n          return { kind: 'auth', detail: 'zsxq /v2/users/self returned succeeded=false — anonymous' };\n        }\n        const u = d.resp_data.user;\n        return { ok: true, user_id: String(u.user_id || u.id || ''), name: String(u.name || u.nickname || '') };\n      } catch (e) {\n        return { kind: 'exception', detail: String(e && e.message || e) };\n      }\n    })()\n  `);\n  if (probe?.kind === 'auth') throw new AuthRequiredError('zsxq.com', probe.detail);\n  if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from zsxq /v2/users/self`);\n  if (probe?.kind === 'exception') throw new CommandExecutionError(`zsxq whoami failed: ${probe.detail}`);\n  if (!probe?.ok) throw new CommandExecutionError(`Unexpected zsxq probe: ${JSON.stringify(probe)}`);\n  if (!probe.user_id) {\n    throw new AuthRequiredError('zsxq.com', 'zsxq /v2/users/self 200 but user_id missing — incomplete session');\n  }\n  return { user_id: probe.user_id, name: probe.name };\n}\n\nregisterSiteAuthCommands({\n  site: 'zsxq',\n  domain: 'zsxq.com',\n  loginUrl: 'https://wx.zsxq.com/login',\n  columns: ['user_id', 'name'],\n  verify: verifyZsxqIdentity,\n  // No-navigation poll: probe the API from the current page so the login-page\n  // QR code isn't reset by a goto on every interval.\n  poll: async (page) => {","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/zsxq/auth.js#L18-L54","documentation":"verifyZsxqIdentity probes the zsxq.com /v2/users/self endpoint using the browser session; when the probe detects an authentication problem (typically a 401 or login redirect) it throws AuthRequiredError('zsxq.com', detail). This is the library's way of signaling that the user's zsxq cookie/session is missing or no longer valid before any authenticated command can proceed.","triggerScenarios":"Calling any zsxq command that requires identity verification while the browser session lacks valid zsxq.com login cookies, or after cookies expired / were cleared, so /v2/users/self responds with an auth-rejecting status.","commonSituations":"Developers running headless browser automation after session expiry; machine without a logged-in zsxq account; cookies wiped by browser profile reset; zsxq rotating session tokens server-side.","solutions":["Run the library's zsxq login flow (registerSiteAuthCommands 'zsxq' wait-for-login) to establish a valid session, then retry.","Verify the browser profile used actually contains zsxq.com cookies (visit zsxq.com manually and confirm you are logged in).","Clear and re-create the browser session/profile if stale cookies cause repeated auth rejection.","Check probe.detail in the error message for the specific auth failure reason (e.g. 401 body) and address accordingly."],"exampleFix":"// before\nconst identity = await verifyZsxqIdentity(page);\n// after\ntry {\n  const identity = await verifyZsxqIdentity(page);\n} catch (e) {\n  if (e instanceof AuthRequiredError) {\n    await performZsxqLogin(page); // interactive login flow\n    return verifyZsxqIdentity(page);\n  }\n  throw e;\n}","handlingStrategy":"try-catch","validationCode":"// before calling commands, probe login state\nconst r = await page.request.get('https://api.zsxq.com/v2/users/self');\nif (r.status() === 401) await runZsxqLogin(page);","typeGuard":"const isAuthRequired = (e) => e instanceof AuthRequiredError || e?.name === 'AuthRequiredError';","tryCatchPattern":"try {\n  const identity = await verifyZsxqIdentity(page);\n} catch (e) {\n  if (isAuthRequired(e)) {\n    await loginZsxq(page);\n    return verifyZsxqIdentity(page);\n  }\n  throw e;\n}","preventionTips":["Use a persistent browser profile so zsxq cookies survive restarts.","Re-login proactively when sessions are older than the known cookie lifetime.","Check AuthRequiredError before treating failures as bugs in your pipeline."],"tags":["auth","http","session-expired"],"backgroundTag":"missing-or-expired-session-auth","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}