{"_id":"@codefox-inc/oauth-provider","_rev":"11-df3d79ebef0ec7ada4c393a50b8532fa","name":"@codefox-inc/oauth-provider","dist-tags":{"latest":"0.4.2"},"versions":{"0.2.0":{"name":"@codefox-inc/oauth-provider","version":"0.2.0","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.2.0","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"2ce2674d9db87a01003534e8ad08807212fdf498","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.2.0.tgz","fileCount":113,"integrity":"sha512-cHQvww6FyajGLCA+6DGynxxBSa4jyZnnmCt4qjUpWQpyAuqmxfKpDRlO11wbyAcRT+nMm+OIc06nM8YhECwjRA==","signatures":[{"sig":"MEYCIQDEY+VuIFfSkTGkhIgBcY/r1gDSLMrBifRkwAu/p79KKgIhAIamIi1u80KcQ3kYS1FPdaj3pio9QAt/jp+W2sgsiMgQ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":653189},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"bf7ad9c7d303af639175236d853d8c1ad71ba252","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.0","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.5","vite":"7.3.1","react":"^19.2.3","convex":"1.31.6","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.15.2","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.62","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.25.3","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.2.0_1769181405966_0.471970689142033","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@codefox-inc/oauth-provider","version":"0.2.1","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.2.1","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"f8be204db2d5f02f34ec3299429179132410f94f","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.2.1.tgz","fileCount":113,"integrity":"sha512-yawtip7mm3I861bu/FECh43lv3w5T0HNuzaZ7YTZEHPNpAMmGBW42Ax9n6F9diiaCV/SndxFzVed2wXtRmtCQw==","signatures":[{"sig":"MEQCICXY9Uh3YIFc1v1O26F/a/cWPB4Eo1fwSBAf3y7ac0koAiBSHtlV3d66BGWLGGe0WHPdYmWTqPY+VzEgn32NRqxZNA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":653241},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"2ed40f7101adf806f61664edf6f4245824f197b4","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.0","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.5","vite":"7.3.1","react":"^19.2.3","convex":"1.31.6","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.15.2","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.62","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.25.3","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.2.1_1769201628984_0.92100516821445","host":"s3://npm-registry-packages-npm-production"}},"0.2.2":{"name":"@codefox-inc/oauth-provider","version":"0.2.2","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.2.2","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"0a2e49e068b74f1cc26032a4ffebef28ea7f4412","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.2.2.tgz","fileCount":113,"integrity":"sha512-RSj5mmZEKCwE3CkoiV8QGgDdTDCif8KkoGoP3BdqBoijNAoLbfhXJ8v/JBC+76w29xjn67A1oKRGkHOAXsjXCQ==","signatures":[{"sig":"MEUCIQDjgVZN3N6z/THLlQAM0bcaOJbwGCXzSsohAZA81qmo1gIgLtyVOijeoBH+Hger1vD5je/gCe67qweVdMxn5aNBYFY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":653177},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"fb095d97862f31768345df79dee3d79eab1f5d1d","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.0","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.5","vite":"7.3.1","react":"^19.2.3","convex":"1.31.6","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.15.2","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.62","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.25.3","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.2.2_1769204841046_0.9506564111140305","host":"s3://npm-registry-packages-npm-production"}},"0.2.3":{"name":"@codefox-inc/oauth-provider","version":"0.2.3","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.2.3","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"c56c5870e6e58c677f26c737c67b845b1fdab067","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.2.3.tgz","fileCount":113,"integrity":"sha512-zYOX5Jx1kAWYr8GXwHZlqj7xcjFdfeh1DW/HyXmw10TF2EjRIx434sNEwZsXTs4RBbYDKI59PQBLVFgnT9IJpQ==","signatures":[{"sig":"MEYCIQD4JkBhQ1EC/ZUSuGQOXvVncz5HUrWn0P6WQCz9cD+CCgIhAItweCRlPJ79gHgQ97D1/OtHoAF+X+4HSgOPEcU+zJp5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":652479},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"92407bde5558ab994b7d505e33ff0f1346caaac4","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.0","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.5","vite":"7.3.1","react":"^19.2.3","convex":"1.31.6","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.15.2","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.62","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.25.3","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.2.3_1769274463189_0.9529057068778242","host":"s3://npm-registry-packages-npm-production"}},"0.2.4":{"name":"@codefox-inc/oauth-provider","version":"0.2.4","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.2.4","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"3cd907d1572aa326cb83a4f5f82488e570e4f06b","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.2.4.tgz","fileCount":113,"integrity":"sha512-bY56hIJ5LPOiNvUQhyTTcrwWBGbsdOHJghRUPFuwBoV5/TX9RaT8Dcls7T9GiqsyltPCYe3uvQfEj2dIUw3v2Q==","signatures":[{"sig":"MEUCIQDuMGsNjbmV3woxwJ0wm1KdB3WQW5jaBPn9IhflPPaW/QIgcYdTc2RqhOumKC4mI0sE97SBHr6zUSOVCK3Zcs8+wvk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":652479},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"2305b92142b58f31aafd2486bbbd3b1a5cc52899","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.0","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.7","vite":"7.3.1","react":"^19.2.3","convex":"1.31.6","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.15.2","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.62","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.25.3","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.2.4_1769583875579_0.5361234532041188","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@codefox-inc/oauth-provider","version":"0.3.0","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.3.0","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"f327d1a0acbad1cdd7697d45d80c216544cc610b","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.3.0.tgz","fileCount":113,"integrity":"sha512-Gx5P21e1Gkyq6UMrFQeuERcNIMM5LUCDeHss94Xgqd5O3gd+fo/0jbwm9TUtTOI1ozG+xptKWpYAZgp1yqKUzg==","signatures":[{"sig":"MEQCIDwgCCgGKnOiHwscXIGDGbtJ962bU1yyVgj3VqFpHuvbAiBODvzjFWc7CVBraSviyJOPU9FrLZ7aejpj5L0DQACZxA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":658257},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"175e8d3f287975d3a7553486772c42a655af5eb7","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.0","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.11.7","vite":"7.3.1","react":"^19.2.3","convex":"1.31.6","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.15.2","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.62","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.25.3","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.3.0_1769881626773_0.2687586725970277","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@codefox-inc/oauth-provider","version":"0.3.1","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.3.1","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"c1516ad6883520bf5e8a192e54a94c2645731cfe","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.3.1.tgz","fileCount":113,"integrity":"sha512-vCO5s66+w0sFkcUopFkDyr4sEctgOcymAoG0L3KC4l5WO/LKf/NaNek/WuKLwDtMPwyJLMWDTpM6QiJ3s3PmDQ==","signatures":[{"sig":"MEQCICQfRdzSWTWtdxV35NlmgEvEPZkpW5J3YfubkcdJQTEIAiAgnN9BB90ppxLnTOcFpEahchV2nBhxdLFv4V50WjKQmQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":658257},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"2833ffc2ce8825a81ad2d1b62005ddd19e472905","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.1","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.12.8","vite":"7.3.1","react":"^19.2.3","convex":"1.34.0","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.75.0","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.66","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.27.1","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.3.1_1773991805757_0.5218457967037964","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@codefox-inc/oauth-provider","version":"0.3.2","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.3.2","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"88b1a23a774481164e692358e09d63f34d4bcd94","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.3.2.tgz","fileCount":113,"integrity":"sha512-OTtQEborw1yBneP7q3HSqpt8ajqOerK1NqooL1GAsP7JzPnexQ3REwmJp5IiItaCG02Bg1f27XKevPbm9nIOeQ==","signatures":[{"sig":"MEQCIErUD04GI6r5iOlkmhjNvk0VwxVqrRmG0Se369lX7wkAAiAuzmuF/NDLzLZegsO3+YRLfhMzhQchCycySGHmiQ5RMA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":658239},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"a9cd4896f440c5d6583fd7d7d2a19930e879f1c1","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (npm run build && convex dev --once)","release":"npm run build && changeset publish","version":"changeset version && npm install --package-lock-only","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'npm run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && npm run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"npx convex codegen --component-dir ./src/component && npm run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"fshindo","email":"f.shindo@codefox.co.jp"},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"10.8.2","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"20.20.1","dependencies":{"jose":"^5.9.6","bcryptjs":"^2.4.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"hono":"^4.12.8","vite":"7.3.1","react":"^19.2.3","convex":"1.34.0","eslint":"9.39.2","vitest":"4.0.17","cpy-cli":"^6.0.0","globals":"^17.0.0","prettier":"3.8.1","wrangler":"^4.75.0","react-dom":"^19.2.3","@eslint/js":"9.39.2","pkg-pr-new":"^0.0.66","typescript":"5.9.3","@types/node":"^24.10.9","convex-test":"0.0.41","@types/react":"^19.2.9","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.27.1","@types/bcryptjs":"^2.4.6","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.88","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.3","@types/react-dom":"^19.2.3","react-router-dom":"^7.6.2","typescript-eslint":"8.53.1","@vitest/coverage-v8":"^4.0.17","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^5.1.2","@cloudflare/workers-types":"^4.20260123.0","@convex-dev/eslint-plugin":"^1.1.1","@modelcontextprotocol/sdk":"^1.27.1","eslint-plugin-react-hooks":"^7.0.1","eslint-plugin-react-refresh":"^0.4.26"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.3.2_1774416157239_0.19167385481464394","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@codefox-inc/oauth-provider","version":"0.4.0","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.4.0","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"3041bb95c84799074d87bb2d747ab9faed2149f5","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.4.0.tgz","fileCount":115,"integrity":"sha512-XRtq0h6jC1Ol2dhSP0QAJeZ9DwijnI5MsUQWqVppNTwgQf5zVxWVpA1Bfy3fpGPCSbvSUAg0ehklK5OfBFRUXQ==","signatures":[{"sig":"MEQCIElluZC4mPGXAAFYmE1jktjyaUc4hH6K540hJ6YCSeeLAiAmLSXGI+pbXdq82DK7UeLgEbToACO2+9Yy1W5dp+DI4Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codefox-inc%2foauth-provider@0.4.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":767843},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"f6fa47aa6be5745b27dfa54a98739b28bb0f2f78","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (bun run build && convex dev --once)","release":"bun run build && changeset publish","version":"changeset version && bun install","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'bun run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && bun run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"bunx convex codegen --component-dir ./src/component && bun run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e8a75388-6c57-42c2-a49a-5d02af11fe41"}},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"11.11.0","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"24.14.1","dependencies":{"jose":"^6.2.3","bcryptjs":"^3.0.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.13","devDependencies":{"hono":"^4.12.16","vite":"8.0.10","react":"^19.2.5","convex":"1.37.0","eslint":"9.39.4","vitest":"4.1.5","cpy-cli":"^7.0.0","globals":"^17.6.0","prettier":"3.8.3","wrangler":"^4.87.0","react-dom":"^19.2.5","@eslint/js":"9.39.4","pkg-pr-new":"^0.0.70","typescript":"6.0.3","@types/node":"^25.6.0","convex-test":"0.0.51","@types/react":"^19.2.14","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.31.0","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.92","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.5","@types/react-dom":"^19.2.3","react-router-dom":"^7.14.2","typescript-eslint":"8.59.2","@vitest/coverage-v8":"^4.1.5","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^6.0.1","@cloudflare/workers-types":"^4.20260505.1","@convex-dev/eslint-plugin":"^2.0.0","@modelcontextprotocol/sdk":"^1.29.0","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-react-refresh":"^0.5.2"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.4.0_1777975114994_0.8441551090334125","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@codefox-inc/oauth-provider","version":"0.4.1","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"license":"Apache-2.0","_id":"@codefox-inc/oauth-provider@0.4.1","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"dist":{"shasum":"6713698c4a4fb66a49a9ebf61a9aaead20d581dd","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.4.1.tgz","fileCount":115,"integrity":"sha512-AKCWqUSgxK9rGkZvpps+4wQr5IktiwDIG75LPZNYT81C/ETt+vy3MA7xmci9GmOdLHNNq4hQudWfQMYEWsWMDw==","signatures":[{"sig":"MEUCIQDGi3/3qmoXw3+0no65gHqM8XRtb72DrqQ4ksgeeZSOqQIgT3zNFm5o7ZXNtfqw6Ks0lr/ivuV1UuJxTb1Q4zF+tyM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codefox-inc%2foauth-provider@0.4.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":769557},"type":"module","types":"./dist/client/index.d.ts","module":"./dist/client/index.js","exports":{".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./test":"./src/test.ts","./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./package.json":"./package.json","./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"}},"gitHead":"80babf03d395d21c52cd47ab01ffa560d05abd1b","scripts":{"all":"run-p -r 'dev:*' 'test:watch'","dev":"run-p -r 'dev:*'","lint":"eslint .","test":"vitest run --typecheck","build":"tsc --project ./tsconfig.build.json","predev":"path-exists .env.local dist || (bun run build && convex dev --once)","release":"bun run build && changeset publish","version":"changeset version && bun install","changeset":"changeset","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'bun run build:codegen' --initial","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","test:debug":"vitest --inspect-brk --no-file-parallelism","test:watch":"vitest --typecheck --clearScreen false","build:clean":"rm -rf dist *.tsbuildinfo && bun run build:codegen","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","build:codegen":"bunx convex codegen --component-dir ./src/component && bun run build","test:coverage":"vitest run --coverage --coverage.reporter=text"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e8a75388-6c57-42c2-a49a-5d02af11fe41"}},"repository":{"url":"git+https://github.com/codefox-inc/convex-oauth-provider.git","type":"git"},"_npmVersion":"11.11.0","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","directories":{},"_nodeVersion":"24.14.1","dependencies":{"jose":"^6.2.3","bcryptjs":"^3.0.3"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"bun@1.3.13","devDependencies":{"hono":"^4.12.16","vite":"8.0.10","react":"^19.2.5","convex":"1.37.0","eslint":"9.39.4","vitest":"4.1.5","cpy-cli":"^7.0.0","globals":"^17.6.0","prettier":"3.8.3","wrangler":"^4.87.0","react-dom":"^19.2.5","@eslint/js":"9.39.4","pkg-pr-new":"^0.0.70","typescript":"6.0.3","@types/node":"^25.6.0","convex-test":"0.0.51","@types/react":"^19.2.14","chokidar-cli":"3.0.0","npm-run-all2":"8.0.4","@changesets/cli":"^2.31.0","path-exists-cli":"2.0.0","@convex-dev/auth":"^0.0.92","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.5","@types/react-dom":"^19.2.3","react-router-dom":"^7.14.2","typescript-eslint":"8.59.2","@vitest/coverage-v8":"^4.1.5","eslint-plugin-react":"^7.37.5","@vitejs/plugin-react":"^6.0.1","@cloudflare/workers-types":"^4.20260505.1","@convex-dev/eslint-plugin":"^2.0.0","@modelcontextprotocol/sdk":"^1.29.0","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-react-refresh":"^0.5.2"},"peerDependencies":{"react":"^18.2.0 || ^19.0.0","convex":"^1.31.6"},"_npmOperationalInternal":{"tmp":"tmp/oauth-provider_0.4.1_1777980080895_0.41541326266112044","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@codefox-inc/oauth-provider","description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","repository":{"type":"git","url":"git+https://github.com/codefox-inc/convex-oauth-provider.git"},"homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"version":"0.4.2","packageManager":"bun@1.3.13","license":"Apache-2.0","publishConfig":{"access":"public"},"keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"type":"module","scripts":{"dev":"run-p -r 'dev:*'","dev:backend":"convex dev --typecheck-components","dev:frontend":"cd example && vite --clearScreen false","dev:build":"chokidar 'tsconfig*.json' 'src/**/*.ts' -i '**/*.test.ts' -c 'bun run build:codegen' --initial","dev:worker":"cd example && wrangler dev --port 8787 2>&1 | cat","predev":"path-exists .env.local dist || (bun run build && convex dev --once)","build":"tsc --project ./tsconfig.build.json","build:codegen":"bunx convex codegen --component-dir ./src/component && bun run build","build:clean":"rm -rf dist *.tsbuildinfo && bun run build:codegen","typecheck":"tsc --noEmit && tsc -p example && tsc -p example/convex","lint":"eslint .","all":"run-p -r 'dev:*' 'test:watch'","test":"vitest run --typecheck","test:watch":"vitest --typecheck --clearScreen false","test:debug":"vitest --inspect-brk --no-file-parallelism","test:coverage":"vitest run --coverage --coverage.reporter=text","changeset":"changeset","version":"changeset version && bun install","release":"bun run build && changeset publish"},"exports":{"./package.json":"./package.json",".":{"types":"./dist/client/index.d.ts","default":"./dist/client/index.js"},"./react":{"types":"./dist/react/index.d.ts","default":"./dist/react/index.js"},"./test":"./src/test.ts","./_generated/component.js":{"types":"./dist/component/_generated/component.d.ts"},"./convex.config":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"},"./convex.config.js":{"types":"./dist/component/convex.config.d.ts","default":"./dist/component/convex.config.js"}},"peerDependencies":{"convex":"^1.31.6","react":"^18.2.0 || ^19.0.0"},"dependencies":{"bcryptjs":"^3.0.3","jose":"^6.2.3"},"devDependencies":{"@changesets/cli":"^2.31.0","@cloudflare/workers-types":"^4.20260505.1","@convex-dev/auth":"^0.0.92","@convex-dev/eslint-plugin":"^2.0.0","@edge-runtime/vm":"^5.0.0","@eslint/eslintrc":"^3.3.5","@eslint/js":"9.39.4","@modelcontextprotocol/sdk":"^1.29.0","@types/node":"^25.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.1","@vitest/coverage-v8":"^4.1.5","chokidar-cli":"3.0.0","convex":"1.37.0","convex-test":"0.0.51","cpy-cli":"^7.0.0","eslint":"9.39.4","eslint-plugin-react":"^7.37.5","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-react-refresh":"^0.5.2","globals":"^17.6.0","hono":"^4.12.16","npm-run-all2":"8.0.4","path-exists-cli":"2.0.0","pkg-pr-new":"^0.0.70","prettier":"3.8.3","react":"^19.2.5","react-dom":"^19.2.5","react-router-dom":"^7.14.2","typescript":"6.0.3","typescript-eslint":"8.59.2","vite":"8.0.10","vitest":"4.1.5","wrangler":"^4.87.0"},"types":"./dist/client/index.d.ts","module":"./dist/client/index.js","gitHead":"50d547117d2dc0ce3d051b187508d8238c5cc7d2","_id":"@codefox-inc/oauth-provider@0.4.2","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-QIznih/uD/2e7GDUXfvKNr4U+LacW+GqD4LLkmlU9FxsjFKyUk+LXuSVApxk9Cmr4/430soAUmMKZ8HXy7BHgw==","shasum":"36ba75f2659bebe556fa64514868cf1775c604be","tarball":"https://registry.npmjs.org/@codefox-inc/oauth-provider/-/oauth-provider-0.4.2.tgz","fileCount":116,"unpackedSize":864879,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@codefox-inc%2foauth-provider@0.4.2","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDg+PbJHh91euKrFOrZI5SIQx4vH7+Ghyz7unj43Z17zAiEAt4AVXI1XkW7/8DmDL1DUcvfa483Z/UQmwIM+phL94T0="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:e8a75388-6c57-42c2-a49a-5d02af11fe41"}},"directories":{},"maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/oauth-provider_0.4.2_1779009548996_0.7489438332495142"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-23T15:16:45.879Z","modified":"2026-05-17T09:19:09.537Z","0.2.0":"2026-01-23T15:16:46.147Z","0.2.1":"2026-01-23T20:53:49.150Z","0.2.2":"2026-01-23T21:47:21.195Z","0.2.3":"2026-01-24T17:07:43.428Z","0.2.4":"2026-01-28T07:04:35.730Z","0.3.0":"2026-01-31T17:47:06.955Z","0.3.1":"2026-03-20T07:30:05.913Z","0.3.2":"2026-03-25T05:22:37.380Z","0.4.0":"2026-05-05T09:58:35.145Z","0.4.1":"2026-05-05T11:21:21.058Z","0.4.2":"2026-05-17T09:19:09.221Z"},"bugs":{"url":"https://github.com/codefox-inc/convex-oauth-provider/issues"},"license":"Apache-2.0","homepage":"https://github.com/codefox-inc/convex-oauth-provider#readme","keywords":["convex","component","oauth","oauth2","openid-connect","oidc","authentication","authorization"],"repository":{"type":"git","url":"git+https://github.com/codefox-inc/convex-oauth-provider.git"},"description":"OAuth 2.1 / OpenID Connect Provider for Convex Auth (Beta).","maintainers":[{"name":"fshindo","email":"f.shindo@codefox.co.jp"}],"readme":"# @codefox-inc/oauth-provider\n\nOAuth 2.1 / OpenID Connect Provider implemented as a Convex component.\n\n> **⚠️ Beta Software** - Production use at your own risk.\n\nTested with [Convex Auth](https://labs.convex.dev/auth) and [@convex-dev/better-auth](https://labs.convex.dev/better-auth).\n\n## Why?\n\nMost MCP clients (like Claude Code or ChatGPT) require your app to be an OAuth provider. If you want to connect your Convex app to MCP clients, you need to implement OAuth 2.1.\n\nThis component turns your Convex app into a fully compliant OAuth 2.1 provider, so you can:\n- Connect to MCP clients out of the box\n- Let clients register automatically via Dynamic Client Registration\n- Let users control what permissions each app gets\n- Focus on your app, not OAuth complexity\n\n## Installation\n\n```bash\nbun add @codefox-inc/oauth-provider\n```\n\n## Features\n\n- **OAuth 2.1 compliant** authorization and token endpoints\n- **OpenID Connect Discovery** for automatic client configuration\n- **PKCE required** for all authorization code flows (S256 only)\n- **RFC 8707 resource indicators** for audience-bound access tokens\n- **RFC 9068 JWT access tokens** (`typ: at+jwt`, `client_id`, `scope`, `jti`)\n- **Secure token storage** using SHA-256 hashing for tokens and authorization codes\n- **JWT access tokens** with RS256 signing\n- **Refresh token rotation** for enhanced security\n- **Dynamic client registration** (opt-in)\n- **Authorization management** for user consent tracking\n- **JWKS endpoint** for token verification\n\n<details>\n<summary><strong>OAuth 2.1 Compliance</strong></summary>\n\nThis implementation follows [OAuth 2.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1) and related OAuth/OIDC specifications:\n\n### Supported Grant Types\n- ✅ **Authorization Code with PKCE** (public and confidential clients)\n- ✅ **Refresh Token** (with token rotation)\n\n### Unsupported Features (OAuth 2.0 Legacy)\n- ❌ **Implicit Grant** (removed in OAuth 2.1 for security reasons)\n- ❌ **Resource Owner Password Credentials Grant** (removed in OAuth 2.1)\n- ❌ **PKCE Plain Method** (only S256 is supported per OAuth 2.1 best practices)\n\n### Key Security Requirements\n- **PKCE Enforcement**: All authorization code flows require PKCE with S256 method\n- **Redirect URI Validation**: Exact string matching (with RFC 8252 loopback variable port exception only)\n- **Resource Binding**: `resource` values are bound to the authorization grant and refresh token\n- **Access Token Audience**: Access token `aud` is the authorized `resource`, or the configured default audience\n- **Authorization Code**: Single-use, expires in 10 minutes\n- **Token Hashing**: All tokens stored as SHA-256 hashes\n- **Refresh Token Rotation**: New refresh token issued on each use, old token invalidated\n\n</details>\n\n<details>\n<summary><strong>Security Features</strong></summary>\n\n### Built-in Security Controls\n\n- **PKCE Enforcement**: All authorization code flows require PKCE (code_challenge/code_verifier)\n- **Redirect URI Validation**: Strict checking against registered URIs\n- **Scope Validation**: Only registered scopes are allowed per client\n- **Token Hashing**: Access and refresh tokens are stored as SHA-256 hashes\n- **Client Secret Hashing**: Confidential client secrets use bcrypt\n- **Client Secret Compatibility**: Newly issued confidential client secrets fit within bcrypt's 72-byte input limit; existing longer secrets remain valid for patch-release compatibility and should be rotated when practical\n- **Internal Mutations**: Critical operations like `issueAuthorizationCode` are not directly accessible\n- **DCR Disabled by Default**: Dynamic Client Registration must be explicitly enabled\n\n### Authorization Flow Security\n\nThe `/oauth/authorize` endpoint performs comprehensive validation:\n1. Client ID verification\n2. Redirect URI matching against registered URIs\n3. Scope validation against client's allowed scopes\n4. PKCE requirement (code_challenge with S256 method)\n5. User authentication via `getUserId` hook\n\n</details>\n\n<details>\n<summary><strong>Scopes and Token Types</strong></summary>\n\n### Supported Scopes\n\n- **`openid`**: Required for OpenID Connect authentication and ID tokens\n- **`profile`**: Grants access to user profile information (name, picture)\n- **`email`**: Grants access to user email address\n- **`offline_access`**: Enables refresh token issuance for long-lived access\n\n### Refresh Token Requirements\n\nRefresh tokens are **only issued** when the `offline_access` scope is requested and granted during the initial authorization. For OpenID Connect requests, `offline_access` requires `prompt=consent` (or a space-delimited prompt value that includes `consent`):\n\n- ✅ **With `offline_access`**: Client receives both access token and refresh token\n- ❌ **Without `offline_access`**: Client receives only access token (no refresh token)\n\n**Refresh Token Grant Flow:**\n- Use the `refresh_token` grant type to obtain new access tokens\n- The original authorization must have included the `offline_access` scope\n- Refresh tokens are automatically rotated on each use (old token is invalidated)\n- The new refresh token maintains the same scope as the original\n- Reuse of a rotated refresh token revokes the active refresh-token family and its authorization record\n\nThis follows OAuth 2.1 and OpenID Connect specifications, ensuring that long-lived refresh tokens are only issued with explicit user consent.\n\n</details>\n\n<details>\n<summary><strong>Resource Indicators and Audience Binding</strong></summary>\n\nThis provider supports RFC 8707 `resource` indicators for MCP and other resource-server flows.\n\n- `resource` is optional on the authorization request.\n- If present, it must be an absolute URI without a fragment.\n- The authorization code stores the approved `resource`.\n- The token request may repeat the same `resource`, but cannot add a new one that was not approved.\n- Refresh tokens preserve the same resource/audience binding during rotation.\n- Access tokens use the authorized `resource` as `aud`; otherwise they use `applicationID` or the default `convex` audience.\n\nFor custom consent UIs, preserve the incoming `resource` parameter and pass it to `issueAuthorizationCode`.\n\n</details>\n\n## OAuth Token Detection Helper\n\nProvides helper functions to distinguish between OAuth tokens and session tokens:\n\n```typescript\nimport { isOAuthToken, getOAuthClientId } from \"@codefox-inc/oauth-provider\";\n\nconst identity = await ctx.auth.getUserIdentity();\n\nif (isOAuthToken(identity)) {\n    // Handle OAuth token (MCP client, third-party apps, etc.)\n    const clientId = getOAuthClientId(identity);\n    console.log(\"OAuth client:\", clientId);\n} else {\n    // Handle Convex Auth session (first-party user)\n}\n```\n\n## Setup\n\n### 1. Set Environment Variables\n\nThis component works with any authentication system. Choose the setup that matches your stack:\n\n#### Option A: With Convex Auth\n\nIf you're using [Convex Auth](https://labs.convex.dev/auth), you already have the required environment variables configured (`JWT_PRIVATE_KEY`, `JWKS`, `SITE_URL`).\n\n#### Option B: With Better Auth\n\nIf you're using [@convex-dev/better-auth](https://labs.convex.dev/better-auth), you can share the same keys:\n\n```bash\nbunx convex env set OAUTH_PRIVATE_KEY \"$(cat private.pem)\"  # Or use JWT_PRIVATE_KEY\nbunx convex env set OAUTH_JWKS '{\"keys\":[...]}'             # Or use JWKS\nbunx convex env set SITE_URL \"https://your-app.example.com\"\n```\n\n**Important:** When using Better Auth, set `applicationID: \"oauth-provider\"` in your OAuthProvider config to distinguish OAuth tokens from Better Auth session tokens.\n\n<details>\n<summary><strong>Option C: Manual Setup</strong></summary>\n\nGenerate RSA keys manually:\n\n```bash\n# Generate private key\nopenssl genrsa -out private.pem 2048\n\n# Generate JWKS (use https://mkjwk.org or this script)\nnode -e \"\nconst jose = require('jose');\nconst fs = require('fs');\nconst privateKey = fs.readFileSync('private.pem', 'utf8');\n(async () => {\n  const key = await jose.importPKCS8(privateKey, 'RS256');\n  const jwk = await jose.exportJWK(key);\n  console.log(JSON.stringify({ keys: [{ ...jwk, use: 'sig', alg: 'RS256', kid: 'default-key' }] }));\n})();\n\"\n```\n\nSet environment variables:\n\n```bash\nbunx convex env set JWT_PRIVATE_KEY \"-----BEGIN RSA PRIVATE KEY-----\\n...\"\nbunx convex env set JWKS '{\"keys\":[...]}'\nbunx convex env set SITE_URL \"https://your-app.example.com\"\n```\n\n</details>\n\n### 2. Register Component\n\n```typescript\n// convex/convex.config.ts\nimport { defineApp } from \"convex/server\";\nimport oauthProvider from \"@codefox-inc/oauth-provider/convex.config\";\n\nconst app = defineApp();\napp.use(oauthProvider, { name: \"oauthProvider\" });\n\nexport default app;\n```\n\n### 3. Configure HTTP Routes\n\n#### Option A: Using the Helper Function (Recommended)\n\n```typescript\n// convex/http.ts\nimport { httpAction } from \"./_generated/server\";\nimport { httpRouter } from \"convex/server\";\nimport { OAuthProvider, registerOAuthRoutes } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\nimport { api } from \"./_generated/api\";\n\nconst http = httpRouter();\n\nconst oauthProvider = new OAuthProvider(components.oauthProvider, {\n    privateKey: process.env.JWT_PRIVATE_KEY!,\n    jwks: process.env.JWKS!,\n    siteUrl: process.env.SITE_URL!,\n\n    // REQUIRED: Authenticate user for authorization endpoint\n    getUserId: async (ctx, request) => {\n        const identity = await ctx.auth.getUserIdentity();\n        return identity?.subject ?? null;\n    },\n});\n\n// Register all OAuth routes automatically\nregisterOAuthRoutes(http, httpAction, oauthProvider, {\n    siteUrl: process.env.SITE_URL!,\n    // OPTIONAL: Override the prefix used for route registration.\n    // By default, this uses oauthProvider's config prefix.\n    // prefix: \"/oauth\",\n    getUserProfile: async (ctx, userId) => {\n        // Return user profile for /oauth/userinfo endpoint\n        const user = await ctx.runQuery(api.users.get, { userId });\n        return user ? {\n            sub: userId,\n            name: user.name,\n            email: user.email,\n            picture: user.pictureUrl\n        } : null;\n    },\n});\n\nexport default http;\n```\n\n#### Option B: With Better Auth\n\n```typescript\n// convex/http.ts\nimport { httpAction } from \"./_generated/server\";\nimport { httpRouter } from \"convex/server\";\nimport { OAuthProvider, registerOAuthRoutes } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\nimport { api } from \"./_generated/api\";\n\nconst http = httpRouter();\n\nconst oauthProvider = new OAuthProvider(components.oauthProvider, {\n    privateKey: process.env.OAUTH_PRIVATE_KEY ?? process.env.JWT_PRIVATE_KEY!,\n    jwks: process.env.OAUTH_JWKS ?? process.env.JWKS!,\n    siteUrl: process.env.SITE_URL!,\n\n    // IMPORTANT: Set applicationID to distinguish from Better Auth tokens\n    applicationID: \"oauth-provider\",\n\n    getUserId: async (ctx, request) => {\n        const identity = await ctx.auth.getUserIdentity();\n        return identity?.subject ?? null;\n    },\n});\n\n// Register Better Auth routes first (if using @convex-dev/better-auth)\n// authComponent.registerRoutes(http, createAuth, { cors: true });\n\n// Then register OAuth routes\nregisterOAuthRoutes(http, httpAction, oauthProvider, {\n    siteUrl: process.env.SITE_URL!,\n    getUserProfile: async (ctx, userId) => {\n        const user = await ctx.runQuery(api.users.get, { userId });\n        return user ? {\n            sub: userId,\n            name: user.name,\n            email: user.email,\n            picture: user.pictureUrl\n        } : null;\n    },\n});\n\nexport default http;\n```\n\n<details>\n<summary><strong>Option C: Manual Route Registration</strong></summary>\n\n```typescript\n// convex/http.ts\nimport { httpAction } from \"./_generated/server\";\nimport { httpRouter } from \"convex/server\";\nimport { OAuthProvider } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\n\nconst http = httpRouter();\n\nconst oauthProvider = new OAuthProvider(components.oauthProvider, {\n    privateKey: process.env.JWT_PRIVATE_KEY!,\n    jwks: process.env.JWKS!,\n    siteUrl: process.env.SITE_URL!,\n\n    // REQUIRED: Authenticate user for authorization endpoint\n    getUserId: async (ctx, request) => {\n        const identity = await ctx.auth.getUserIdentity();\n        return identity?.subject ?? null;\n    },\n});\n\n// OpenID Connect Discovery\nhttp.route({\n    path: \"/oauth/.well-known/openid-configuration\",\n    method: \"GET\",\n    handler: httpAction((ctx, req) =>\n        oauthProvider.handlers.openIdConfiguration(ctx, req)\n    ),\n});\n\n// JWKS endpoint\nhttp.route({\n    path: \"/oauth/.well-known/jwks.json\",\n    method: \"GET\",\n    handler: httpAction((ctx, req) =>\n        oauthProvider.handlers.jwks(ctx, req)\n    ),\n});\n\n// Authorization endpoint (validates and issues auth codes)\nhttp.route({\n    path: \"/oauth/authorize\",\n    method: \"GET\",\n    handler: httpAction((ctx, req) =>\n        oauthProvider.handlers.authorize(ctx, req)\n    ),\n});\n\n// Token endpoint\nhttp.route({\n    path: \"/oauth/token\",\n    method: \"POST\",\n    handler: httpAction((ctx, req) =>\n        oauthProvider.handlers.token(ctx, req)\n    ),\n});\n\n// UserInfo endpoint\nhttp.route({\n    path: \"/oauth/userinfo\",\n    method: \"GET\",\n    handler: httpAction((ctx, req) =>\n        oauthProvider.handlers.userInfo(ctx, req, async (userId) => {\n            const user = await ctx.runQuery(api.users.get, { userId });\n            return user ? { sub: userId, name: user.name, email: user.email } : null;\n        })\n    ),\n});\n\n// Dynamic Client Registration (optional)\nhttp.route({\n    path: \"/oauth/register\",\n    method: \"POST\",\n    handler: httpAction((ctx, req) =>\n        oauthProvider.handlers.register(ctx, req)\n    ),\n});\n\nexport default http;\n```\n\n</details>\n\n## UserInfo Endpoint\n\nRequires `openid` scope. Returns claims based on scopes:\n- `openid`: Always returns `sub`\n- `profile`: Adds `name`, `picture`\n- `email`: Adds `email` (and `email_verified` if available)\n\n<details>\n<summary><strong>Client Registration</strong></summary>\n\n### Register OAuth Client (Admin)\n\n```typescript\n// convex/oauthAdmin.ts\nimport { mutation } from \"./_generated/server\";\nimport { OAuthProvider } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\n\nexport const registerOAuthClient = mutation({\n    handler: async (ctx, args: {\n        name: string;\n        redirectUris: string[];\n        scopes: string[];\n        type: \"confidential\" | \"public\";\n    }) => {\n        // Check admin permissions\n        const identity = await ctx.auth.getUserIdentity();\n        if (!identity) throw new Error(\"Unauthorized\");\n\n        const oauthProvider = new OAuthProvider(components.oauthProvider, {\n            privateKey: process.env.JWT_PRIVATE_KEY!,\n            jwks: process.env.JWKS!,\n            siteUrl: process.env.SITE_URL!,\n        });\n\n        const result = await oauthProvider.registerClient(ctx, {\n            name: args.name,\n            redirectUris: args.redirectUris,\n            scopes: args.scopes,\n            type: args.type,\n        });\n\n        // IMPORTANT: Save clientSecret securely - it's only returned once!\n        return result;\n    },\n});\n```\n\n</details>\n\n## Authorization Flow\n\n### Automatic Authorization Handler\n\nThe `/oauth/authorize` endpoint handles the complete authorization flow automatically:\n\n```\nGET /oauth/authorize?\n  response_type=code\n  &client_id=CLIENT_ID\n  &redirect_uri=REDIRECT_URI\n  &scope=openid+profile+email\n  &resource=https://api.example.com/mcp\n  &state=STATE\n  &code_challenge=CHALLENGE\n  &code_challenge_method=S256\n  &nonce=NONCE\n```\n\nThe handler:\n1. Validates the client ID\n2. Checks redirect_uri against registered URIs\n3. Validates requested scopes\n4. Requires PKCE (code_challenge)\n5. Validates and binds `resource` when provided\n6. Authenticates the user via `getUserId`\n7. Issues authorization code\n8. Redirects back to the client with the code\n\n<details>\n<summary><strong>Custom Authorization Flow (Advanced)</strong></summary>\n\nIf you need custom consent UI, you can use the SDK methods directly:\n\n```typescript\n// convex/oauth.ts\nimport { mutation } from \"./_generated/server\";\nimport { OAuthProvider } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\n\nexport const approveAuthorization = mutation({\n    handler: async (ctx, args: {\n        clientId: string;\n        scopes: string[];\n        redirectUri: string;\n        codeChallenge: string;\n        codeChallengeMethod: string;\n        nonce?: string;\n        resource?: string;\n    }) => {\n        // Verify user is authenticated\n        const identity = await ctx.auth.getUserIdentity();\n        if (!identity) throw new Error(\"Not authenticated\");\n\n        const oauthProvider = new OAuthProvider(components.oauthProvider, {\n            privateKey: process.env.JWT_PRIVATE_KEY!,\n            jwks: process.env.JWKS!,\n            siteUrl: process.env.SITE_URL!,\n        });\n\n        // Issue authorization code (automatically creates authorization record)\n        const authCode = await oauthProvider.issueAuthorizationCode(ctx, {\n            userId: identity.subject,\n            clientId: args.clientId,\n            scopes: args.scopes,\n            redirectUri: args.redirectUri,\n            codeChallenge: args.codeChallenge,\n            codeChallengeMethod: args.codeChallengeMethod,\n            nonce: args.nonce,\n            resource: args.resource,\n        });\n\n        return authCode;\n    },\n});\n```\n\nWhen the authorization request contains `resource`, show it in the consent UI and pass it through unchanged. If the token request asks for a `resource` that was not stored on the authorization code, the token endpoint returns `invalid_target`.\n\n</details>\n\n<details>\n<summary><strong>Authorization Management</strong></summary>\n\n### List User's Authorized Apps\n\n```typescript\nimport { query } from \"./_generated/server\";\nimport { OAuthProvider } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\n\nexport const listAuthorizedApps = query({\n    handler: async (ctx) => {\n        const identity = await ctx.auth.getUserIdentity();\n        if (!identity) return [];\n\n        const oauthProvider = new OAuthProvider(components.oauthProvider, {\n            privateKey: process.env.JWT_PRIVATE_KEY!,\n            jwks: process.env.JWKS!,\n            siteUrl: process.env.SITE_URL!,\n        });\n\n        return await oauthProvider.listUserAuthorizations(ctx, identity.subject);\n    },\n});\n```\n\n### Revoke Authorization\n\n```typescript\nimport { mutation } from \"./_generated/server\";\nimport { OAuthProvider } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\n\nexport const revokeApp = mutation({\n    handler: async (ctx, args: { clientId: string }) => {\n        const identity = await ctx.auth.getUserIdentity();\n        if (!identity) throw new Error(\"Not authenticated\");\n\n        const oauthProvider = new OAuthProvider(components.oauthProvider, {\n            privateKey: process.env.JWT_PRIVATE_KEY!,\n            jwks: process.env.JWKS!,\n            siteUrl: process.env.SITE_URL!,\n        });\n\n        // Deletes authorization and all associated tokens\n        await oauthProvider.revokeAuthorization(ctx, identity.subject, args.clientId);\n    },\n});\n```\n\n</details>\n\n<details>\n<summary><strong>Configuration Options (OAuthConfig)</strong></summary>\n\n```typescript\ninterface OAuthConfig {\n    // REQUIRED: RSA private key in PEM format\n    privateKey: string;\n\n    // REQUIRED: JWKS for token verification (public keys only)\n    jwks: string;\n\n    // REQUIRED: Your application URL\n    siteUrl: string;\n\n    // OPTIONAL: Convex deployment URL (if different from siteUrl)\n    convexSiteUrl?: string;\n\n    // OPTIONAL: OAuth endpoint prefix (default: \"/oauth\")\n    // Normalized to a leading slash, trailing slash removed; \"/\" means root.\n    // Must match the route prefix you register in http.ts.\n    prefix?: string;\n\n    // OPTIONAL: Comma-separated list of allowed CORS origins\n    allowedOrigins?: string;\n\n    // OPTIONAL: Allowed scopes for dynamic client registration\n    allowedScopes?: string[];\n\n    // OPTIONAL: JWT audience claim (default: \"convex\")\n    // Set to \"oauth-provider\" when using Better Auth to distinguish tokens\n    applicationID?: string;\n\n    // REQUIRED: Function to get authenticated user ID\n    // Must return a Convex users table Id (string)\n    // Returns null if user is not authenticated\n    getUserId?: (ctx: ActionCtx, request: Request) => Promise<string | null> | string | null;\n\n    // OPTIONAL: Enable dynamic client registration (default: false)\n    allowDynamicClientRegistration?: boolean;\n}\n```\n\n</details>\n\n## Token Verification\n\n### Revocation and Access Token Lifetime\n\nAccess tokens are JWTs and can be verified statelessly with the JWKS. Stateless verification alone cannot observe authorization revocation, authorization-code replay detection, or refresh-token family revocation until the access token expires.\n\nFor Convex resource servers, wire `createAuthorizationChecker()` into `createAuthHelper()` so bearer-token requests check the current authorization record:\n\n```typescript\nimport { createAuthHelper, OAuthProvider } from \"@codefox-inc/oauth-provider\";\nimport { components } from \"./_generated/api\";\n\nconst oauthProvider = new OAuthProvider(components.oauthProvider, {\n    privateKey: process.env.JWT_PRIVATE_KEY!,\n    jwks: process.env.JWKS!,\n    siteUrl: process.env.SITE_URL!,\n});\n\nexport const authHelper = createAuthHelper({\n    providers: [\"anonymous\"],\n    checkAuthorization: oauthProvider.createAuthorizationChecker(),\n});\n```\n\nIf you verify access tokens outside Convex with `verifyAccessToken()` only, revoked access tokens remain valid until their `exp` time. Use short access-token lifetimes and a resource-server authorization check if immediate revocation is required.\n\nAfter upgrading this component, rerun Convex code generation (for example `convex dev --once` or your repository's codegen script). The generated component references and schema must match the package version; `prompt=none` silent authorization also relies on the latest generated `getAuthorization` query reference.\n\n### In Convex Functions\n\n```typescript\nimport { query } from \"./_generated/server\";\n\nexport const protectedQuery = query({\n    handler: async (ctx) => {\n        const identity = await ctx.auth.getUserIdentity();\n        if (!identity) throw new Error(\"Not authenticated\");\n\n        // Token is already verified by Convex Auth\n        // Use identity.subject for user ID\n        return { userId: identity.subject };\n    },\n});\n```\n\n<details>\n<summary><strong>External Token Verification</strong></summary>\n\n```typescript\nimport { verifyAccessToken } from \"@codefox-inc/oauth-provider\";\n\nconst payload = await verifyAccessToken(\n    token,\n    {\n        jwks: process.env.JWKS!,\n        siteUrl: process.env.SITE_URL!,\n        // If using Better Auth, specify the applicationID\n        // applicationID: \"oauth-provider\",\n    },\n    issuerUrl\n);\n\nconsole.log(\"User ID:\", payload.sub);\nconsole.log(\"Scopes:\", payload.scp);\nconsole.log(\"Client ID:\", payload.cid);\n```\n\n</details>\n\n<details>\n<summary><strong>Distinguishing OAuth Tokens from Session Tokens</strong></summary>\n\nWhen using multiple auth systems (e.g., Better Auth + OAuth Provider), you can distinguish tokens by checking the issuer:\n\n```typescript\nimport { isOAuthToken, getOAuthClientId } from \"@codefox-inc/oauth-provider\";\n\n// Option 1: Using helper functions\nconst identity = await ctx.auth.getUserIdentity();\nif (isOAuthToken(identity)) {\n    const clientId = getOAuthClientId(identity);\n    // Handle OAuth token (MCP clients, third-party apps)\n} else {\n    // Handle session token (first-party users)\n}\n\n// Option 2: Check issuer directly\nif (identity?.issuer?.includes(\"/oauth\")) {\n    // This is an OAuth token\n}\n```\n\n</details>\n\n## Testing\n\n```bash\nbun run test\n```\n\n## License\n\nApache-2.0\n","readmeFilename":"README.md"}