{"_id":"@aoctech/auth-client","_rev":"6-42f7f9dfc5bbde99e751fcef0ffaa982","name":"@aoctech/auth-client","dist-tags":{"latest":"1.3.0"},"versions":{"0.1.0":{"name":"@aoctech/auth-client","version":"0.1.0","keywords":["oauth2","oidc","pkce","ctech"],"author":{"name":"Artur Oliveira"},"license":"MIT","_id":"@aoctech/auth-client@0.1.0","maintainers":[{"name":"aoctech","email":"dev@aoctech.app"}],"dist":{"shasum":"334fe7e8888bb56db9087c7f17e2a45075a6c4a4","tarball":"https://registry.npmjs.org/@aoctech/auth-client/-/auth-client-0.1.0.tgz","fileCount":15,"integrity":"sha512-KHv5wHE/jeAqJou8hxRNGqXkVfpM4/VEXtPV7C/+qFeQZ0cJlAoKyZ6/PYFQ9dxrt2L2bYRBckmVZ8jUNw6G2A==","signatures":[{"sig":"MEYCIQCHwobBw8vS6Bt8M+9eZoUeltgecOEnb8Yew5L2Tkyh2QIhAMiynQ+QYuKZIIW0nEfb+k5Y4smKunERwkdIDrwpdlDm","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":19488},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"9bb3ac702373a08550814ffe6fb60da2ff044486","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"aoctech","email":"dev@aoctech.app"},"_npmVersion":"11.16.0","description":"Shared browser OAuth 2.0 / PKCE client for apps built on the ctech-account identity provider.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.0"},"_npmOperationalInternal":{"tmp":"tmp/auth-client_0.1.0_1784293180009_0.947897516550227","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@aoctech/auth-client","version":"1.0.0","keywords":["oauth2","oidc","pkce","ctech"],"author":{"name":"Artur Oliveira"},"license":"MIT","_id":"@aoctech/auth-client@1.0.0","maintainers":[{"name":"aoctech","email":"dev@aoctech.app"}],"homepage":"https://github.com/artur-oliveira/ctech-oauth-client#readme","bugs":{"url":"https://github.com/artur-oliveira/ctech-oauth-client/issues"},"dist":{"shasum":"d535f096726969fc77fe24f654e508538fed3a20","tarball":"https://registry.npmjs.org/@aoctech/auth-client/-/auth-client-1.0.0.tgz","fileCount":15,"integrity":"sha512-zIUSHPhr2raaM33eb3ynKHwRhnOjqfzHi5OORT23G3ce/5TcD3TxJg34VUqB5bxPEm+sg9SqwtNXDsgUBi5bpA==","signatures":[{"sig":"MEUCIGnAodSQWHiP/Y384gzONs4ACUaxYQt0fEuDsjzOH9p/AiEAy7FVO+AN86sJs+BuA1aoPTKvKUa/+4Q+5vJ/BOvKm9A=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aoctech%2fauth-client@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":20475},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"8f347a02f9bc5bfea5a2101cb1331322d0ab2c93","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:20b4f3b7-1b33-4f15-9bfe-8deba5117fbd"}},"repository":{"url":"git+https://github.com/artur-oliveira/ctech-oauth-client.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared browser OAuth 2.0 / PKCE client for apps built on the ctech-account identity provider.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.0"},"_npmOperationalInternal":{"tmp":"tmp/auth-client_1.0.0_1784295523597_0.7108357188240331","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@aoctech/auth-client","version":"1.0.1","keywords":["oauth2","oidc","pkce","ctech"],"author":{"name":"Artur Oliveira"},"license":"MIT","_id":"@aoctech/auth-client@1.0.1","maintainers":[{"name":"aoctech","email":"dev@aoctech.app"}],"homepage":"https://github.com/artur-oliveira/ctech-oauth-client#readme","bugs":{"url":"https://github.com/artur-oliveira/ctech-oauth-client/issues"},"dist":{"shasum":"c4f81c1174b84f1c91ef33015742d1d923ef382e","tarball":"https://registry.npmjs.org/@aoctech/auth-client/-/auth-client-1.0.1.tgz","fileCount":15,"integrity":"sha512-OpneiMd1nxHw38iLk/h2YIOiAJIVYyj3RYbKeqR8kCDTwtUgYfKzQWVK2RsVt5dV4HEB70hH63kZfiGdgMtAvQ==","signatures":[{"sig":"MEUCIGiL3crpgivPc1cSltUFTPZZiMCL1A9CU6z8IdR96UBPAiEAvNCGW445B08uCItPWDJgmQM/xr4gTdBG8qIfErrz7DU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aoctech%2fauth-client@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":21420},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"fcc62018bfb9ae45b7264ad0968660e3627fa654","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:20b4f3b7-1b33-4f15-9bfe-8deba5117fbd"}},"repository":{"url":"git+https://github.com/artur-oliveira/ctech-oauth-client.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared browser OAuth 2.0 / PKCE client for apps built on the ctech-account identity provider.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.0"},"_npmOperationalInternal":{"tmp":"tmp/auth-client_1.0.1_1784303261488_0.4896433549421746","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@aoctech/auth-client","version":"1.1.0","keywords":["oauth2","oidc","pkce","ctech"],"author":{"name":"Artur Oliveira"},"license":"MIT","_id":"@aoctech/auth-client@1.1.0","maintainers":[{"name":"aoctech","email":"dev@aoctech.app"}],"homepage":"https://github.com/artur-oliveira/ctech-oauth-client#readme","bugs":{"url":"https://github.com/artur-oliveira/ctech-oauth-client/issues"},"dist":{"shasum":"b1b4ae04305727e4b7e2f2822594b5b3c92bc940","tarball":"https://registry.npmjs.org/@aoctech/auth-client/-/auth-client-1.1.0.tgz","fileCount":15,"integrity":"sha512-laq8/iUUkUW0hIE5+79s5wAA32Eu3JxeF4CPF98hDiytKHuCwG9AgRHKv3oHC7Tdi/mbgVLc1IQqXQpqJwbZ/w==","signatures":[{"sig":"MEUCIQD3AHRehap5R5Fdy/SDz6M6zs5fiqKHmR+SayWoV91lxwIgNZK553+5WbbfUg/lKdRBl2HgjAOPKAW5d0Xq8nH3AjU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aoctech%2fauth-client@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":25301},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"747f68a2726e9274b4c69becf2ec435e69e21dee","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:20b4f3b7-1b33-4f15-9bfe-8deba5117fbd"}},"repository":{"url":"git+https://github.com/artur-oliveira/ctech-oauth-client.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared browser OAuth 2.0 / PKCE client for apps built on the ctech-account identity provider.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.0"},"_npmOperationalInternal":{"tmp":"tmp/auth-client_1.1.0_1784382982623_0.5579632937043142","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@aoctech/auth-client","version":"1.2.0","keywords":["oauth2","oidc","pkce","ctech"],"author":{"name":"Artur Oliveira"},"license":"MIT","_id":"@aoctech/auth-client@1.2.0","maintainers":[{"name":"aoctech","email":"dev@aoctech.app"}],"homepage":"https://github.com/artur-oliveira/ctech-oauth-client#readme","bugs":{"url":"https://github.com/artur-oliveira/ctech-oauth-client/issues"},"dist":{"shasum":"0d6b9d3fcf35e232c903634aadb43cb6a02ab61b","tarball":"https://registry.npmjs.org/@aoctech/auth-client/-/auth-client-1.2.0.tgz","fileCount":15,"integrity":"sha512-hD0VsHy/puHi5/iy5NCDuLHZjrpa1QiGGdu1IbUxC+mHHwdStJq6VUjpyo6pubq13OrKAVhEMZ90hlx/BuFCoA==","signatures":[{"sig":"MEUCIGgDbHwv1WjX0eEEFMu+F//8GUhdxJt7TxRWE4EvMjEqAiEAhRzc0FpqJES+Ggo92lkQlgsyyQMLYvM/yQS+/pd+D5k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aoctech%2fauth-client@1.2.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":28324},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"9a5ecff9425d8137906d635786d114ee0d62c8f3","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:20b4f3b7-1b33-4f15-9bfe-8deba5117fbd"}},"repository":{"url":"git+https://github.com/artur-oliveira/ctech-oauth-client.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared browser OAuth 2.0 / PKCE client for apps built on the ctech-account identity provider.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.0"},"_npmOperationalInternal":{"tmp":"tmp/auth-client_1.2.0_1788438975391_0.1770318309002501","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"_id":"@aoctech/auth-client@1.3.0","bugs":{"url":"https://github.com/artur-oliveira/ctech-oauth-client/issues"},"dist":{"shasum":"112d64d671864fe4134dea17e9750e3e1ef8f477","tarball":"https://registry.npmjs.org/@aoctech/auth-client/-/auth-client-1.3.0.tgz","fileCount":15,"integrity":"sha512-slCbvb7Dto7hTevDEIdfUwvzToQNw0An6CF4iGYrqNog0XwYd1roZd45A4W/6/NcmlPXvh2GP66b0r0Un9KfnA==","signatures":[{"sig":"MEYCIQDsu2gQV0lundlMcNGVtpqjh8IEw/8EkvWk4y2z57Iu6AIhAPf18vSW4AGdMHhLJ4rZPU+NgGEzlMzGrH1f0310G8Wt","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCuyJJzspqrV7x3IPOb8DyQQUVqShmY3hTlMA+OKJy/GwIhAPs7kE1K6UQqFbUtVYg2v1LYWmEon+BOpvAvKKE0jiTn"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@aoctech%2fauth-client@1.3.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":30687},"main":"./dist/index.js","name":"@aoctech/auth-client","type":"module","types":"./dist/index.d.ts","author":{"name":"Artur Oliveira"},"engines":{"node":">=24"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"f9d19d5a9d151ce09d2fff6ad657ab1327ab8c27","license":"MIT","scripts":{"test":"npm run build && node --test","build":"tsc -p tsconfig.json"},"version":"1.3.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:20b4f3b7-1b33-4f15-9bfe-8deba5117fbd"}},"homepage":"https://github.com/artur-oliveira/ctech-oauth-client#readme","keywords":["oauth2","oidc","pkce","ctech"],"repository":{"url":"git+https://github.com/artur-oliveira/ctech-oauth-client.git","type":"git"},"_npmVersion":"11.16.0","description":"Shared browser OAuth 2.0 / PKCE client for apps built on the ctech-account identity provider.","directories":{},"maintainers":[{"name":"aoctech","email":"dev@aoctech.app"}],"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/auth-client_1.3.0_1788719737544_0.21563976200838164"}}},"time":{"created":"2026-07-17T12:59:39.818Z","modified":"2026-09-06T18:35:37.938Z","0.1.0":"2026-07-17T12:59:40.148Z","1.0.0":"2026-07-17T13:38:43.741Z","1.0.1":"2026-07-17T15:47:41.619Z","1.1.0":"2026-07-18T13:56:22.765Z","1.2.0":"2026-09-03T12:36:15.554Z","1.3.0":"2026-09-06T18:35:37.629Z"},"bugs":{"url":"https://github.com/artur-oliveira/ctech-oauth-client/issues"},"author":{"name":"Artur Oliveira"},"license":"MIT","homepage":"https://github.com/artur-oliveira/ctech-oauth-client#readme","keywords":["oauth2","oidc","pkce","ctech"],"repository":{"url":"git+https://github.com/artur-oliveira/ctech-oauth-client.git","type":"git"},"description":"Shared browser OAuth 2.0 / PKCE client for apps built on the ctech-account identity provider.","maintainers":[{"name":"aoctech","email":"dev@aoctech.app"}],"readme":"# @aoctech/auth-client\n\n[![CI](https://github.com/artur-oliveira/ctech-oauth-client/actions/workflows/ci.yml/badge.svg)](https://github.com/artur-oliveira/ctech-oauth-client/actions/workflows/ci.yml)\n[![npm](https://img.shields.io/npm/v/@aoctech/auth-client)](https://www.npmjs.com/package/@aoctech/auth-client)\n\nShared browser OAuth 2.0 + PKCE client for apps built on the [ctech-account](https://accounts.aoctech.app)\nidentity provider. One `OAuthClient` instance per app, config-only — no server, no framework dependency.\n\n> Repo name is `ctech-oauth-client` on GitHub; published to npm as `@aoctech/auth-client`.\n> Searching by either name should land here.\n\n## Why this exists\n\nThree SPAs (accounts, ctech-dfe, ctech-wallet) each carried their own ~200-line copy of the same OAuth\nflow. They drifted: two of the three checked whether a session could plausibly exist (via the `ctech_auth`\nhint cookie or a local revoked-flag) before firing a silent refresh — the third fired unconditionally on\nevery mount, including the very first visit of a browser that never had a session. That's a guaranteed\n`POST /v1.0/token` failure on every cold visit, and it burns the same shared brute-force rate limit that\nprotects login and client-secret guessing on the IdP.\n\nThis package is the single implementation. `OAuthClient.refresh()` always checks the hint cookie and a\nlocal revoked-state before touching the network, and de-duplicates concurrent calls (boot-time init and a\n401 retry interceptor calling `refresh()` at the same instant share one request instead of firing two).\n\n## Install\n\n```bash\nnpm install @aoctech/auth-client\n```\n\n## Usage\n\n```ts\nimport { OAuthClient } from \"@aoctech/auth-client\";\n\nexport const oauth = new OAuthClient({\n  baseUrl: process.env.NEXT_PUBLIC_CTECH_URL!,\n  clientId: process.env.NEXT_PUBLIC_CTECH_CLIENT_ID!,\n  redirectUri: `${window.location.origin}/callback`,\n  scope: \"openid profile\",\n});\n\n// Kick off login\nawait oauth.startOAuthFlow(\"/dashboard\");\n\n// On the /callback page\nconst { accessToken, idToken, returnTo } = await oauth.exchangeCode(code, state);\n\n// Silent refresh — safe to call from app boot AND a 401 interceptor at once\nconst result = await oauth.refresh(); // null only when there is no usable session\n\n// Logout\nawait oauth.revoke();\noauth.endSessionRedirect(\"/login\");\n```\n\n## API\n\n- `hasAuthHint(cookieString?)` / `clearAuthHint()` — read/clear the `ctech_auth` marker cookie.\n- `startOAuthFlow(returnTo?)` — redirects to `/v1.0/authorize` with a fresh PKCE pair.\n- `exchangeCode(code, state)` — `authorization_code` grant.\n- `refresh()` — guarded, single-flight `refresh_token` grant. Retries a transient\n  transport/server failure a few times with backoff before giving up; throws\n  `OAuthTransientError` only once that's exhausted. `null` means the credential\n  is absent or definitively rejected — never retried.\n- `revoke()` — best-effort `POST /v1.0/revoke`.\n- `endSessionRedirect(returnTo?)` — RP-initiated logout via `/v1.0/auth/end-session`.\n- `decodeIdToken(idToken)` — unverified payload decode, for display-only name claims.\n\nAlso exported standalone: `generatePKCE()`, `generateState()`, `decodeIdToken()`.\n\n## Development\n\n```bash\nnpm run build   # tsc -> dist/\nnpm test        # build + node's built-in test runner\n```\n\n## Releasing\n\n`publish.yml` only fires on a published GitHub Release — a push to `main` alone never publishes\n(it only runs `ci.yml`, which tests). Publishing uses npm's OIDC trusted publishing, so there's no\n`NPM_TOKEN` secret to manage; provenance is generated automatically.\n\n```bash\n# 1. Bump \"version\" in package.json, then commit and push as usual\ngit commit -am \"chore: release vX.Y.Z\"\ngit push\n\n# 2. Tag it and push the tag\ngit tag vX.Y.Z\ngit push --tags\n\n# 3. Cut the release — this is what actually triggers the publish workflow\ngh release create vX.Y.Z --generate-notes\n```\n\n## License\n\nMIT\n\n## Implementation reference (file:line) — audited\n\nAnchors into `src/` (the dist is built from these; `src/index.ts:1-5` is the export surface):\n\n- `OAuthClient` — `src/client.ts:25`. `startOAuthFlow(returnTo?, opts?)` `:122`; **step-up is the\n  `opts.maxAge` seconds option** `:142-144` (there is no `startStepUpFlow` symbol). `exchangeCode`\n  `:151`, `refresh()` `:190` (single-flight, throws `OAuthTransientError` `:14` for retryable\n  failures), `revoke()` `:256`, `endSessionRedirect` `:274`, `hasAuthHint` `:84` / `clearAuthHint`\n  `:90`, `decodeIdToken` `:282`, `close()` `:46`.\n- PKCE/state — `generatePKCE` `src/pkce.ts:14`, `generateState` `:22`.\n- id_token decode — `decodeIdToken` `src/jwt.ts:17` → `UnverifiedIdTokenClaims` `src/jwt.ts:1`\n  (`IdTokenClaims` `:10` is a deprecated alias; **no signature/nonce check**).\n- Storage — `NamespacedStorage` `src/storage.ts:3` is **sessionStorage** (PKCE/ephemeral state only).\n  Tokens are held by the IdP in **HttpOnly cookies** (`credentials:\"include\"` `src/client.ts:173`);\n  this client is stateless w.r.t. tokens. Hypothesis that it \"stores tokens in HttpOnly cookies\" is\n  inaccurate — the cookies are the IdP's.\n- Config types — `OAuthClientConfig` `src/types.ts:1`, `TokenResult` `:14`.\n","readmeFilename":"README.md"}