{"record":{"id":"b77173cff4424293","repo":"jackwener/OpenCLI","slug":"jianyu360-cn","errorCode":null,"errorMessage":"jianyu360.cn","messagePattern":"jianyu360\\.cn","errorType":"exception","errorClass":"AuthRequiredError","httpStatus":null,"severity":"error","filePath":"clis/jianyu/auth.js","lineNumber":11,"sourceCode":"import { AuthRequiredError, CommandExecutionError } from '@jackwener/opencli/errors';\nimport { registerSiteAuthCommands } from '../_shared/site-auth.js';\n\nasync function hasJianyuUserCookie(page) {\n  const cookies = await page.getCookies({ url: 'https://www.jianyu360.cn' });\n  return cookies.some(c => c.name === 'userid_secure' && c.value);\n}\n\nasync function verifyJianyuIdentity(page) {\n  if (!await hasJianyuUserCookie(page)) {\n    throw new AuthRequiredError('jianyu360.cn', 'Jianyu userid_secure cookie missing — anonymous');\n  }\n  await page.goto('https://www.jianyu360.cn/');\n  await page.wait(2);\n  const probe = await page.evaluate(`(async () => {\n    try {\n      const r = await fetch('/swordfish/frontPage/customer/sess/index', { credentials: 'include' });\n      const text = await r.text();\n      if (/<title>\\\\s*登录\\\\s*[-—]\\\\s*剑鱼标讯/.test(text)) {\n        return { kind: 'auth', detail: 'Jianyu protected page returned login page — anonymous' };\n      }\n      const userIdMeta = text.match(/<meta[^>]+name=[\\\"'](?:user-id|userId)[\\\"'][^>]+content=[\\\"']([^\\\"']+)[\\\"']/)?.[1] || '';\n      const userScript = text.match(/window\\\\.__USER__\\\\s*=\\\\s*(\\\\{[^}]+\\\\})/)?.[1] || '';\n      let userId = userIdMeta;\n      let name = '';\n      if (userScript) {\n        try {\n          const u = JSON.parse(userScript);\n          userId = userId || String(u.id || u.userId || '');","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/jianyu/auth.js#L1-L29","documentation":"verifyJianyuIdentity throws AuthRequiredError('jianyu360.cn', 'Jianyu userid_secure cookie missing — anonymous') when the browser has no non-empty 'userid_secure' cookie for jianyu360.cn, meaning the session is anonymous. The check runs before probing the user's identity endpoint.","triggerScenarios":"Any jianyu auth verify / whoami / login poll where page.getCookies({ url: 'https://www.jianyu360.cn' }) contains no 'userid_secure' cookie or its value is empty.","commonSituations":"Never logged in to Jianyu360 in the automation profile; session expired and the cookie was cleared; user logged out; wrong browser profile attached.","solutions":["Log in to https://www.jianyu360.cn in the connected Chrome profile","Run the jianyu auth login flow and complete it in the browser","Confirm the CLI is attached to the profile holding the Jianyu cookies","Re-run the verify command after login"],"exampleFix":"// before\nconst me = await jianyuWhoami();\n// after\ntry {\n  const me = await jianyuWhoami();\n} catch (e) {\n  if (e.code === 'AUTH_REQUIRED') {\n    await jianyuAuthLogin();\n    const me = await jianyuWhoami();\n  }\n}","handlingStrategy":"try-catch","validationCode":"const cookies = await page.getCookies({ url: 'https://www.jianyu360.cn' });\nconst authed = cookies.some(c => c.name === 'userid_secure' && c.value);\nif (!authed) await jianyuAuthLogin();","typeGuard":"function hasJianyuSession(cookies) {\n  return cookies.some(c => c.name === 'userid_secure' && c.value);\n}","tryCatchPattern":"try {\n  const me = await jianyuVerify();\n} catch (e) {\n  if (e.code === 'AUTH_REQUIRED') {\n    await jianyuAuthLogin();\n    return jianyuVerify();\n  }\n  throw e;\n}","preventionTips":["Check the userid_secure cookie before Jianyu API calls","Complete the jianyu auth login flow before scripted usage","Re-login when the session expires rather than retrying anonymously","Confirm the CLI is attached to the correct browser profile"],"tags":["auth","jianyu360","cookies","login-required"],"backgroundTag":"site-session-not-logged-in","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}