{"_id":"@autonomous-ai/auth-sdk","_rev":"5-645e202ada0af66ee878718e71abf7fe","name":"@autonomous-ai/auth-sdk","dist-tags":{"latest":"1.0.11"},"versions":{"1.0.7":{"name":"@autonomous-ai/auth-sdk","version":"1.0.7","keywords":["auth","sso","oauth2","pkce","react","authentication"],"author":{"name":"Autonomous"},"license":"MIT","_id":"@autonomous-ai/auth-sdk@1.0.7","maintainers":[{"name":"autonomous2026","email":"dev@autonomous.ai"},{"name":"autonomousai","email":"webqa@autonomous.ai"}],"homepage":"https://github.com/autonomousdotai/auth-sdk#readme","bugs":{"url":"https://github.com/autonomousdotai/auth-sdk/issues"},"dist":{"shasum":"41ca70ad71fdff4eab19158569ef6250c17e15ba","tarball":"https://registry.npmjs.org/@autonomous-ai/auth-sdk/-/auth-sdk-1.0.7.tgz","fileCount":46,"integrity":"sha512-ywbwUIjmTXjpgFObxL4eC9E5qcIwhovcsyir28IZfx6kpHiYMVB5AXcTbWtJ0XfcITlt+4IelQof1iFYdz6twA==","signatures":[{"sig":"MEQCIEZXh7UWGW9cqst6V/xMlyp2lwsCu0yKanBypOMfE+Q+AiAcC3g6YudRs/jhORQ+6iOSDIapbk3ZHVHDGTtrpy+JNg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":73471},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"4a44334378d1479cb7396998fe4ac6e2bdd2d08f","scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"autonomous2026","email":"dev@autonomous.ai"},"repository":{"url":"git+https://github.com/autonomousdotai/auth-sdk.git","type":"git"},"_npmVersion":"11.6.2","description":"Client SDK for auth-service SSO flow with OAuth2 PKCE","directories":{},"_nodeVersion":"24.13.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.0.0","typescript":"^5.0.0","@types/react":"^19.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/auth-sdk_1.0.7_1786610359155_0.6681639654315814","host":"s3://npm-registry-packages-npm-production"}},"1.0.8":{"name":"@autonomous-ai/auth-sdk","version":"1.0.8","keywords":["auth","sso","oauth2","pkce","react","authentication"],"author":{"name":"Autonomous"},"license":"MIT","_id":"@autonomous-ai/auth-sdk@1.0.8","maintainers":[{"name":"autonomous2026","email":"dev@autonomous.ai"},{"name":"autonomousai","email":"webqa@autonomous.ai"}],"homepage":"https://github.com/autonomousdotai/auth-sdk#readme","bugs":{"url":"https://github.com/autonomousdotai/auth-sdk/issues"},"dist":{"shasum":"a8ff92cbebdcbc86a458295833388eee891b47bc","tarball":"https://registry.npmjs.org/@autonomous-ai/auth-sdk/-/auth-sdk-1.0.8.tgz","fileCount":46,"integrity":"sha512-5PYuaBkKHIXaUqjkM0alYOnqSgEe/gYT4v/td10JGf6LGMDPD/JB+P3zn8Bg4FkBFaHAk9YDi9uSRd/kAtwm2g==","signatures":[{"sig":"MEUCIGHrht7vuyCluDDGJ0NrDl7gKFHfwSvAz4lAkGAm4WRrAiEAtEw7MSAyFk/1YPKjmqiLlxIu1c2UY2J6F7rMlKNbAhI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIFCJnLUIW6s7pftDquHS5Ca8Q1m4pOnStigsNCYXEzkCAiAyw6G9tgK55Hbm2XPY1DfFIo7sY6dYOADnOfhSDQC8Og==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":74397},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"d9e0ee2ff163d38f86b01a253d9b9ba349bd3baf","scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"autonomous2026","email":"dev@autonomous.ai"},"repository":{"url":"git+https://github.com/autonomousdotai/auth-sdk.git","type":"git"},"_npmVersion":"11.6.2","description":"Client SDK for auth-service SSO flow with OAuth2 PKCE","directories":{},"_nodeVersion":"24.13.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.0.0","typescript":"^5.0.0","@types/react":"^19.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/auth-sdk_1.0.8_1789107915527_0.6721523735328698","host":"s3://npm-registry-packages-npm-production"}},"1.0.9":{"name":"@autonomous-ai/auth-sdk","version":"1.0.9","keywords":["auth","sso","oauth2","pkce","react","authentication"],"author":{"name":"Autonomous"},"license":"MIT","_id":"@autonomous-ai/auth-sdk@1.0.9","maintainers":[{"name":"autonomous2026","email":"dev@autonomous.ai"},{"name":"autonomousai","email":"webqa@autonomous.ai"}],"homepage":"https://github.com/autonomousdotai/auth-sdk#readme","bugs":{"url":"https://github.com/autonomousdotai/auth-sdk/issues"},"dist":{"shasum":"af7c0b3f4affea632a8705e09f3f2abf13a2477a","tarball":"https://registry.npmjs.org/@autonomous-ai/auth-sdk/-/auth-sdk-1.0.9.tgz","fileCount":46,"integrity":"sha512-JkuB8pf7HjEMFtLsAX7vGCE3VKxBTWwIbpA8PDVFGSl3rTJEVtiJPz2LyEb/nBtJcmw/dbvbij+I1WjnMmHcPw==","signatures":[{"sig":"MEQCIGk4pCUOkc3Njh3S6ryo1ruxxNBVOuwutgWevXD0djRIAiBUQ8caZY8OzcWZjMW9VGvroIrTox36HNSt3bsoBcSF3w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIEYHtMDIrxIO9qV5Bi9WmQjGqsus7W73F8TRrZY0CCAwAiEA0AQGQjs5oqaRBTKUlyVU0rC34LlqFLjfnLsdOmMYdwY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76782},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"1bbabb570ab6d24bdbc43a8024c2dd212b2dd102","scripts":{"dev":"tsc --watch","build":"tsc","clean":"rm -rf dist","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"autonomous2026","email":"dev@autonomous.ai"},"repository":{"url":"git+https://github.com/autonomousdotai/auth-sdk.git","type":"git"},"_npmVersion":"11.6.2","description":"Client SDK for auth-service SSO flow with OAuth2 PKCE","directories":{},"_nodeVersion":"24.13.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.0.0","typescript":"^5.0.0","@types/react":"^19.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/auth-sdk_1.0.9_1789697133508_0.4743900710067279","host":"s3://npm-registry-packages-npm-production"}},"1.0.10":{"name":"@autonomous-ai/auth-sdk","version":"1.0.10","keywords":["auth","sso","oauth2","pkce","react","authentication"],"author":{"name":"Autonomous"},"license":"MIT","_id":"@autonomous-ai/auth-sdk@1.0.10","maintainers":[{"name":"autonomous2026","email":"dev@autonomous.ai"},{"name":"autonomousai","email":"webqa@autonomous.ai"}],"homepage":"https://github.com/autonomousdotai/auth-sdk#readme","bugs":{"url":"https://github.com/autonomousdotai/auth-sdk/issues"},"dist":{"shasum":"e699acd46d90a84ab1fe10dfe093ca6a64cf64f1","tarball":"https://registry.npmjs.org/@autonomous-ai/auth-sdk/-/auth-sdk-1.0.10.tgz","fileCount":82,"integrity":"sha512-VxufeZszFtmRcZsTC8l/Or6F+RWzp1l1X8GayoLdaC+Y0vlbnK0IvaGZNIqA1aoD+F06BEp3xoiBsFDAzRNnZg==","signatures":[{"sig":"MEQCIGA84RSjd1DLAxCSSrQjO6qoJD30iqE+XfPVhgEozH4TAiBQ3scXe+e8r5qtJbyY/fGQCJqvqesrd0neDfgAB+r1JQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCID61T97murPvnGZ/gjCjAVShADICyzkVdSwSefp2VIb0AiEAmOR246XcduQk4+PrjOqmP3bbm/6WK6gsnUJI11aKD1g=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":149115},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.js","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./node":{"types":"./dist/node/index.d.ts","import":"./dist/node/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"}},"gitHead":"c6dac687bb93220536cb027f43690df09f0bad85","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","clean":"rm -rf dist","test:watch":"vitest","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"autonomous2026","email":"dev@autonomous.ai"},"repository":{"url":"git+https://github.com/autonomousdotai/auth-sdk.git","type":"git"},"_npmVersion":"11.6.2","description":"Client SDK for auth-service SSO flow with OAuth2 PKCE","directories":{},"_nodeVersion":"24.13.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.0.0","vitest":"^2.1.0","typescript":"^5.0.0","@types/node":"^20.19.43","@types/react":"^19.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/auth-sdk_1.0.10_1789976774343_0.36736732787105275","host":"s3://npm-registry-packages-npm-production"}},"1.0.11":{"_id":"@autonomous-ai/auth-sdk@1.0.11","bugs":{"url":"https://github.com/autonomousdotai/auth-sdk/issues"},"dist":{"shasum":"30f990fe0af27bb0efcd278691b079d276521eb4","tarball":"https://registry.npmjs.org/@autonomous-ai/auth-sdk/-/auth-sdk-1.0.11.tgz","fileCount":108,"integrity":"sha512-l4YVBMT2/5VGGRo0d1GpS+PeZJnsCqF7O1Ygt7swOOVk1dIxDCVPOQU46nI/s+oqXgDBedlqcEvQnV/HL4j9eA==","signatures":[{"sig":"MEUCIF7oI5qAPvIMSDim0+kVy4adluv5fxd6KSncjtan1pAFAiEAvfmmiT9IGqWkK1xy3U7OuQ1gd51YRNBi1WkJUeJAENw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIEREksDY4tI9SDcaZk+Tz75sYxPczote8mqJme+8/dCtAiBsCs9wYbbgQXIrJwEIBon/uDbpHOOCjSvcvLdPdrrdJQ=="}],"unpackedSize":243097},"main":"dist/index.js","name":"@autonomous-ai/auth-sdk","type":"module","types":"dist/index.d.ts","author":{"name":"Autonomous"},"module":"dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./node":{"types":"./dist/node/index.d.ts","import":"./dist/node/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.js"},"./package.json":"./package.json"},"gitHead":"90935bc1ce7b462b640266c8581073d47b50c0e2","license":"MIT","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc","clean":"rm -rf dist","typecheck":"tsc --noEmit -p tsconfig.test.json","test:watch":"vitest","prepublishOnly":"npm run clean && npm run build"},"version":"1.0.11","_npmUser":{"name":"autonomous2026","email":"dev@autonomous.ai"},"homepage":"https://github.com/autonomousdotai/auth-sdk#readme","keywords":["auth","sso","oauth2","pkce","react","authentication"],"repository":{"url":"git+https://github.com/autonomousdotai/auth-sdk.git","type":"git"},"_npmVersion":"11.6.2","description":"Client SDK for auth-service SSO flow with OAuth2 PKCE","directories":{},"maintainers":[{"name":"autonomous2026","email":"dev@autonomous.ai"},{"name":"autonomousai","email":"webqa@autonomous.ai"}],"_nodeVersion":"24.13.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.0.0","vitest":"^2.1.0","typescript":"^5.0.0","@types/node":"^20.19.43","@types/react":"^19.0.0"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/auth-sdk_1.0.11_1789980893055_0.4930136798587952"}}},"time":{"created":"2026-08-13T08:39:18.802Z","modified":"2026-09-21T08:54:53.301Z","1.0.7":"2026-08-13T08:39:19.304Z","1.0.8":"2026-09-11T06:25:15.602Z","1.0.9":"2026-09-18T02:05:33.589Z","1.0.10":"2026-09-21T07:46:14.439Z","1.0.11":"2026-09-21T08:54:53.144Z"},"bugs":{"url":"https://github.com/autonomousdotai/auth-sdk/issues"},"author":{"name":"Autonomous"},"license":"MIT","homepage":"https://github.com/autonomousdotai/auth-sdk#readme","keywords":["auth","sso","oauth2","pkce","react","authentication"],"repository":{"url":"git+https://github.com/autonomousdotai/auth-sdk.git","type":"git"},"description":"Client SDK for auth-service SSO flow with OAuth2 PKCE","maintainers":[{"name":"autonomous2026","email":"dev@autonomous.ai"},{"name":"autonomousai","email":"webqa@autonomous.ai"}],"readme":"# @autonomous-ai/auth-sdk\n\nClient SDK for the auth-service SSO flow — OAuth2 Authorization Code + PKCE (S256), with first-class React bindings.\n\n- **Zero runtime dependencies** — React is an optional peer dependency\n- **ESM only**, ships TypeScript types\n- Automatic token refresh before expiry\n- Post-login redirect via `nextUrl`, no server-side changes needed\n\n## Installation\n\n```bash\nnpm install @autonomous-ai/auth-sdk\n```\n\nReact is optional — only needed if you import `@autonomous-ai/auth-sdk/react`:\n\n```bash\nnpm install react   # >= 18\n```\n\n### Local development\n\n```bash\nnpm install && npm run build\nnpm link                       # in this repo\nnpm link @autonomous-ai/auth-sdk   # in the consuming app\n```\n\n## Entry points\n\n| Import path                     | Contents                                             |\n| ------------------------------- | ---------------------------------------------------- |\n| `@autonomous-ai/auth-sdk`       | `AuthClient`, `TokenManager`, PKCE helpers, all types |\n| `@autonomous-ai/auth-sdk/react` | `AuthProvider`, `useAuth`, `useUser`, `useAuthCallback` |\n\n## Quick Start (React)\n\n### 1. Wrap your app with AuthProvider\n\nDefine `authConfig` outside the component (or memoize it) — a new object identity on every render re-triggers the provider's effects.\n\n```tsx\nimport { AuthProvider } from \"@autonomous-ai/auth-sdk/react\";\n\nconst authConfig = {\n  ssoUrl: \"https://sso.example.com\",\n  clientId: \"my-app\",\n  redirectUri: \"https://app.example.com/callback\",\n  scope: \"openid profile email\",\n};\n\nfunction App() {\n  return (\n    <AuthProvider config={authConfig}>\n      <YourApp />\n    </AuthProvider>\n  );\n}\n```\n\n### 2. Use the hooks\n\n```tsx\nimport { useAuth, useUser } from \"@autonomous-ai/auth-sdk/react\";\n\nfunction LoginButton() {\n  const { isAuthenticated, login, logout, isLoading } = useAuth();\n\n  if (isLoading) return <div>Loading...</div>;\n\n  if (isAuthenticated) {\n    return <button onClick={() => logout()}>Logout</button>;\n  }\n\n  return <button onClick={() => login()}>Login with SSO</button>;\n}\n\nfunction UserProfile() {\n  const user = useUser();\n\n  if (!user) return null;\n\n  return <p>Welcome, {user.fullName || user.email}!</p>;\n}\n```\n\n### 3. Handle the OAuth2 callback\n\nMount this on the route you registered as `redirectUri`. The hook reads `code` / `state` from the URL, exchanges them for tokens, and is guarded against React StrictMode double-invocation.\n\n```tsx\nimport { useEffect } from \"react\";\nimport { useAuthCallback, useAuth } from \"@autonomous-ai/auth-sdk/react\";\nimport { useNavigate } from \"react-router-dom\";\n\nfunction CallbackPage() {\n  const navigate = useNavigate();\n  const { refreshAuthState } = useAuth();\n  const { isLoading, error, success, nextUrl } = useAuthCallback(authConfig);\n\n  useEffect(() => {\n    if (success) {\n      refreshAuthState(); // re-read tokens written by the callback\n      navigate(nextUrl || \"/\");\n    }\n  }, [success, nextUrl, navigate, refreshAuthState]);\n\n  if (isLoading) return <div>Processing login...</div>;\n  if (error) return <div>Login failed: {error}</div>;\n\n  return null;\n}\n```\n\n### 4. Post-login redirect (`nextUrl`)\n\nPass `nextUrl` to `login()` to send the user back to the page they started from. It is stored in `sessionStorage` before the SSO redirect and returned by `useAuthCallback` after a successful exchange.\n\n```tsx\nimport { useEffect } from \"react\";\nimport { useAuth } from \"@autonomous-ai/auth-sdk/react\";\nimport { useLocation } from \"react-router-dom\";\n\nfunction ProtectedPage() {\n  const location = useLocation();\n  const { isAuthenticated, isLoading, login } = useAuth();\n\n  useEffect(() => {\n    if (!isLoading && !isAuthenticated) {\n      login({\n        nextUrl: `${location.pathname}${location.search}${location.hash}`,\n      });\n    }\n  }, [isAuthenticated, isLoading, login, location]);\n\n  if (isLoading || !isAuthenticated) {\n    return <div>Redirecting to login...</div>;\n  }\n\n  return <div>Protected content</div>;\n}\n```\n\n## Vanilla JavaScript / TypeScript\n\n```typescript\nimport { AuthClient } from \"@autonomous-ai/auth-sdk\";\n\nconst client = new AuthClient({\n  ssoUrl: \"https://sso.example.com\",\n  clientId: \"my-app\",\n  redirectUri: \"https://app.example.com/callback\",\n  scope: \"openid profile email\",\n});\n\n// Start login (redirects the browser to SSO)\nawait client.authorize({ nextUrl: \"/dashboard\" });\n\n// On the callback page\nconst params = new URLSearchParams(window.location.search);\nconst result = await client.handleCallback(\n  params.get(\"code\")!,\n  params.get(\"state\")!\n);\n\nif (result.success) {\n  if (result.nextUrl) window.location.href = result.nextUrl;\n} else {\n  console.error(result.error);\n}\n\n// Auth status\nif (client.isAuthenticated()) {\n  console.log(\"User:\", client.getUser());\n}\n\n// Access token for API calls — refreshes automatically if expired\nconst token = await client.getValidAccessToken();\nawait fetch(\"/api/me\", { headers: { Authorization: `Bearer ${token}` } });\n\n// Logout (clears tokens and redirects to SSO logout)\nclient.logout();\n```\n\n## API Reference\n\n### AuthClient\n\n| Method                          | Returns                    | Description                              |\n| ------------------------------- | -------------------------- | ---------------------------------------- |\n| `authorize(options?)`           | `Promise<void>`            | Start OAuth2 login flow (redirects away)  |\n| `handleCallback(code, state)`   | `Promise<CallbackResult>`  | Exchange authorization code for tokens    |\n| `refreshToken()`                | `Promise<TokenResponse>`   | Refresh the access token                  |\n| `logout(redirectUri?)`          | `Promise<void>`            | Revoke this sign-in, clear tokens and redirect to SSO logout |\n| `isAuthenticated()`             | `boolean`                  | Whether a valid session exists            |\n| `getAccessToken()`              | `string \\| null`           | Current access token                      |\n| `getRefreshToken()`             | `string \\| null`           | Current refresh token                     |\n| `getUser()`                     | `User \\| null`             | User decoded from the JWT                 |\n| `isTokenExpired(buffer = 60)`   | `boolean`                  | Expiry check with a seconds buffer        |\n| `getValidAccessToken()`         | `Promise<string>`          | Token, refreshed if expired               |\n| `clearTokens()`                 | `void`                     | Clear tokens without an SSO logout        |\n\n`createAuthClient(config)` is a factory shorthand for `new AuthClient(config)`.\n\n### Login source tracking\n\n- `login({ entryPoint: 'header' })` / `authorize({ entryPoint })` tells auth-service which UI placement started the sign-in.\n- After the callback, `result.tokens.first_time_in_app` is `true` the first time this user gets a session in your app (use it for onboarding). `result.tokens.first_time` is `true` for their first sign-in anywhere in the Autonomous ecosystem.\n\n### AuthConfig\n\n| Option        | Type           | Default          | Description                          |\n| ------------- | -------------- | ---------------- | ------------------------------------ |\n| `ssoUrl`      | `string`       | required         | SSO server base URL                  |\n| `clientId`    | `string`       | required         | OAuth2 client ID                     |\n| `redirectUri` | `string`       | required         | Callback URL registered with the SSO |\n| `scope`       | `string?`      | -                | Space-separated scopes               |\n| `storage`     | `TokenStorage?` | `localStorage`  | Custom token storage                 |\n\n### AuthorizeOptions\n\n| Option      | Type                                    | Description                               |\n| ----------- | --------------------------------------- | ----------------------------------------- |\n| `prompt`    | `'select_account' \\| 'none' \\| 'login'` | Force account selection or silent auth    |\n| `loginHint` | `string`                                | Pre-fill email for login                  |\n| `nextUrl`   | `string`                                | URL to redirect to after successful login |\n\n### User\n\nParsed from the JWT's `ext_info` claim.\n\n| Field                | Type        | Description               |\n| -------------------- | ----------- | ------------------------- |\n| `id`                 | `string`    | User ID                   |\n| `email`              | `string`    | User email                |\n| `fullName`           | `string?`   | Full name                 |\n| `code`               | `string?`   | User code                 |\n| `roles`              | `string[]?` | User roles                |\n| `scope`              | `string?`   | Granted scope             |\n| `companyDomain`      | `string?`   | Company domain            |\n| `companyDomainType`  | `string?`   | Company domain type       |\n| `isEppUser`          | `boolean?`  | Employee Purchase Program |\n| `vendorId`           | `string?`   | Vendor ID                 |\n| `vendorCode`         | `string?`   | Vendor code               |\n| `vendorName`         | `string?`   | Vendor name               |\n| `referralCode`       | `string?`   | Referral code             |\n\n### CallbackResult\n\n| Field     | Type              | Description                            |\n| --------- | ----------------- | -------------------------------------- |\n| `success` | `boolean`         | Whether the code exchange succeeded    |\n| `tokens`  | `TokenResponse?`  | Tokens returned by auth-service        |\n| `error`   | `string?`         | Error message when `success` is false  |\n| `nextUrl` | `string?`         | Post-login redirect target             |\n\n### React hooks\n\n| Hook                      | Returns                                                     | Description            |\n| ------------------------- | ----------------------------------------------------------- | ---------------------- |\n| `useAuth()`               | `AuthContextValue`                                           | Auth state and actions |\n| `useUser()`               | `User \\| null`                                               | Current user           |\n| `useAuthCallback(config)` | `{ isLoading, error, success, result, nextUrl }`             | Handle OAuth2 callback |\n\n`useAuth()` returns `isAuthenticated`, `isLoading`, `user`, `error`, plus `login()`, `logout()`, `getAccessToken()`, `refreshToken()` and `refreshAuthState()`.\n\n`useAuthCallback` creates its own `AuthClient` and works outside `AuthProvider` — but call `refreshAuthState()` afterwards so the provider picks up the new tokens.\n\n### AuthProvider props\n\n| Prop            | Type         | Default  | Description                      |\n| --------------- | ------------ | -------- | -------------------------------- |\n| `config`        | `AuthConfig` | required | Auth configuration               |\n| `autoRefresh`   | `boolean`    | `true`   | Auto-refresh tokens              |\n| `refreshBuffer` | `number`     | `60`     | Seconds before expiry to refresh |\n| `onAuthChange`  | `function`   | -        | Called on auth state change      |\n\n## Custom storage\n\nTokens go to `localStorage` by default. Supply any object implementing `TokenStorage` to change that — e.g. `sessionStorage` so the session dies with the tab:\n\n```typescript\nconst client = new AuthClient({\n  ...config,\n  storage: {\n    getItem: (key) => sessionStorage.getItem(key),\n    setItem: (key, value) => sessionStorage.setItem(key, value),\n    removeItem: (key) => sessionStorage.removeItem(key),\n  },\n});\n```\n\nThe PKCE verifier and `state` always use `sessionStorage`, regardless of this setting.\n\n## Node (CLIs)\n\n```bash\nnpm install @autonomous-ai/auth-sdk\n```\n\n```ts\nimport { createNodeAuthClient } from '@autonomous-ai/auth-sdk/node'\n\nconst auth = createNodeAuthClient({\n  ssoUrl: 'https://auth.autonomous.ai',\n  clientId: 'my-cli',\n  appName: 'my-cli', // ~/.config/my-cli/auth.json\n})\n\nawait auth.signIn()                 // browser + 127.0.0.1, or pasted code over SSH\nconst token = await auth.getAccessToken() // refreshes when it is about to expire\nawait auth.logout()                 // revokes the sign-in and forgets it\n```\n\n`signIn({ mode })` forces a flow: `'loopback'` (browser on this machine) or `'manual'` (paste the code\nthe page shows). The default, `'auto'`, uses the pasted code over SSH, on a machine with no browser, or\nwhenever the browser could not be opened.\n\nRegister both redirect URIs for the client: `http://127.0.0.1/callback` and\n`https://<sso-domain>/oauth2/code`.\n\n`getAccessToken()` throws `AuthSessionError`: `SIGNED_OUT` means the sign-in was revoked or expired and\nthe session has been cleared — run your login command again; `UNAVAILABLE` means the service could not\nbe reached (or the local session file could not be read/locked) and the session was kept; `NO_SESSION`\nmeans nobody has signed in yet.\n\n`getSession()` and `isSignedIn()` are synchronous and read only from memory, so they return `null`/`false`\nuntil the on-disk session has actually been loaded. `signIn()` and `getAccessToken()` both load it as a\nside effect, but if you need the answer before calling either of those — e.g. to decide whether to show a\n\"sign in\" prompt — call `await auth.loadSession()` first.\n\nRequires Node 20 or newer. The session file is created `0600` in `~/.config/<appName>/`\n(`%APPDATA%\\<appName>\\` on Windows).\n\n## Security\n\n- PKCE (S256) prevents authorization code interception\n- `state` parameter for CSRF protection, validated on callback\n- PKCE verifier kept in `sessionStorage`, never in `localStorage`\n- Tokens refreshed automatically before expiry (`refreshBuffer`)\n\n## License\n\nMIT\n","readmeFilename":"README.md"}