{"_id":"@auth0/auth0-cloudflare-agents-api","_rev":"43-e2ffd5d6726eb64a46aa4bd62f966bb5","name":"@auth0/auth0-cloudflare-agents-api","dist-tags":{"latest":"2.0.1"},"versions":{"1.0.0":{"name":"@auth0/auth0-cloudflare-agents-api","version":"1.0.0","author":{"url":"https://auth0.com","name":"Auth0 Inc."},"license":"Apache-2.0","_id":"@auth0/auth0-cloudflare-agents-api@1.0.0","maintainers":[{"name":"auth0-oss","email":"oss.sdks@auth0.com"},{"name":"ziluvatar","email":"eduardo.diaz@okta.com"},{"name":"iaco","email":"sebastian.iacomuzzi@gmail.com"},{"name":"pubalokta","email":"pablo.ubal@okta.com"},{"name":"auth0npm","email":"devops+npm@auth0.com"},{"name":"auth0brokkr","email":"support@auth0.com"},{"name":"hzalaz","email":"hernan@auth0.com"},{"name":"aaguiarz","email":"andres.aguiar@gmail.com"},{"name":"charlesrea","email":"charles.rea@auth0.com"},{"name":"ncluer","email":"natalie.cluer@gmail.com"},{"name":"julien.wollscheid","email":"julien.wollscheid@auth0.com"},{"name":"cristiandouce","email":"cristiandouce@gmail.com"},{"name":"sambego","email":"sambellen@gmail.com"},{"name":"sandrinodimattia","email":"sandrino@dimattia.be"},{"name":"lzychowski","email":"les.zychowski@auth0.com"},{"name":"davidpatrick0","email":"david.patrick@auth0.com"},{"name":"sergii.biienko","email":"sergii.biienko@auth0.com"},{"name":"jpadilla","email":"hello@jpadilla.com"},{"name":"jessele","email":"jesse.le@auth0.com"},{"name":"rhamzeh_auth0","email":"raghd.hamzeh@auth0.com"},{"name":"oktajeffoktajeff","email":"jeff.shuman@okta.com"},{"name":"david.renaud.okta","email":"david.renaud@okta.com"},{"name":"madhuri.rm23","email":"madhuri.ravindramohan@okta.com"},{"name":"npirani_okta","email":"neil.pirani@auth0.com"},{"name":"soumya.bodavula","email":"soumya.bodavula@auth0.com"},{"name":"jamescgarrett-okta","email":"james.garrett@auth0.com"},{"name":"stheller","email":"stefan.heller@auth0.com"},{"name":"jfromaniello","email":"jfromaniello@gmail.com"},{"name":"edgarchirivella-okta","email":"edgar.chirivella@okta.com"},{"name":"sanjay.manikandhan","email":"sanjay.manikandhan@okta.com"},{"name":"rithuc23","email":"rithu.chandrasekar@auth0.com"},{"name":"ece-okta","email":"ece.tavasli@auth0.com"},{"name":"enriquepina","email":"enrique.pina@auth0.com"},{"name":"dougmiller-okta","email":"douglas.miller@auth0.com"},{"name":"sgarcia-atko","email":"sergio.garciaramos@okta.com"},{"name":"roger.chan","email":"roger.chan@auth0.com"},{"name":"joshbetz_auth0","email":"josh.betz@auth0.com"},{"name":"andriy0k","email":"andriy.kharchuk@auth0.com"},{"name":"maaantone","email":"michael.antone@auth0.com"},{"name":"jason.gervais","email":"jason.gervais@okta.com"},{"name":"shafatkhan","email":"shafat.khan@okta.com"},{"name":"psychoticbrat","email":"merisa.lee@okta.com"}],"dist":{"shasum":"263c9506d6886b40edf7e3e687af7b262d85d7ee","tarball":"https://registry.npmjs.org/@auth0/auth0-cloudflare-agents-api/-/auth0-cloudflare-agents-api-1.0.0.tgz","fileCount":18,"integrity":"sha512-QizxyzQ7yJoCvAw1CW8hbI1e+s0G1JWBcRPhu3Ya6ARKZ1PhxtOQY3wcjIyXYdrd/FVldAmgYM91SUSNBJmhQg==","signatures":[{"sig":"MEUCID+NWHJnQ2Puj2HWK/Uy0wV8aPCICA+PCaEmHrlz7+TlAiEAyN53N3PiTtDrnwLilIdsshPImc6cQ4WUpXuK2gMRmJI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":103615},"type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"4c761860c2a04faef179a0e27b02a9ca80e68bfe","scripts":{"lint":"eslint . --ext .ts","test":"vitest run","build":"tsc","prepare":"npm run build && husky","test:ui":"vitest --ui","lint:fix":"eslint . --ext .ts --fix","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"auth0npm","email":"devops+npm@auth0.com"},"_npmVersion":"10.9.2","description":"A PartyServer mixin for adding Auth0 API authentication to your PartyServer applications.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@auth0/auth0-api-js":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","eslint":"^9.24.0","vitest":"^3.1.1","globals":"^16.0.0","prettier":"3.5.3","@eslint/js":"^9.24.0","@vitest/ui":"^3.1.1","typescript":"^5.8.3","@types/node":"^20.11.26","@eslint/compat":"^1.2.8","@commitlint/cli":"^19.3.0","semantic-release":"^24.2.5","typescript-eslint":"^8.30.1","@vitest/coverage-v8":"^3.1.1","eslint-config-prettier":"^10.1.2","@typescript-eslint/parser":"^8.29.1","@commitlint/config-conventional":"^19.2.2","@typescript-eslint/eslint-plugin":"^8.29.1"},"peerDependencies":{"partyserver":">=0.0.67 <0.0.72"},"_npmOperationalInternal":{"tmp":"tmp/auth0-cloudflare-agents-api_1.0.0_1749833656071_0.19392188656098708","host":"s3://npm-registry-packages-npm-production"}},"2.0.0":{"name":"@auth0/auth0-cloudflare-agents-api","version":"2.0.0","author":{"url":"https://auth0.com","name":"Auth0 Inc."},"license":"Apache-2.0","_id":"@auth0/auth0-cloudflare-agents-api@2.0.0","maintainers":[{"name":"auth0-oss","email":"oss.sdks@auth0.com"},{"name":"ziluvatar","email":"eduardo.diaz@okta.com"},{"name":"iaco","email":"sebastian.iacomuzzi@gmail.com"},{"name":"pubalokta","email":"pablo.ubal@okta.com"},{"name":"auth0npm","email":"devops+npm@auth0.com"},{"name":"auth0brokkr","email":"support@auth0.com"},{"name":"hzalaz","email":"hernan@auth0.com"},{"name":"aaguiarz","email":"andres.aguiar@gmail.com"},{"name":"charlesrea","email":"charles.rea@auth0.com"},{"name":"ncluer","email":"natalie.cluer@gmail.com"},{"name":"julien.wollscheid","email":"julien.wollscheid@auth0.com"},{"name":"cristiandouce","email":"cristiandouce@gmail.com"},{"name":"sambego","email":"sambellen@gmail.com"},{"name":"sandrinodimattia","email":"sandrino@dimattia.be"},{"name":"lzychowski","email":"les.zychowski@auth0.com"},{"name":"davidpatrick0","email":"david.patrick@auth0.com"},{"name":"sergii.biienko","email":"sergii.biienko@auth0.com"},{"name":"jpadilla","email":"hello@jpadilla.com"},{"name":"jessele","email":"jesse.le@auth0.com"},{"name":"rhamzeh_auth0","email":"raghd.hamzeh@auth0.com"},{"name":"oktajeffoktajeff","email":"jeff.shuman@okta.com"},{"name":"david.renaud.okta","email":"david.renaud@okta.com"},{"name":"bsmith-auth0","email":"brian.s.smith@okta.com"},{"name":"madhuri.rm23","email":"madhuri.ravindramohan@okta.com"},{"name":"npirani_okta","email":"neil.pirani@auth0.com"},{"name":"soumya.bodavula","email":"soumya.bodavula@auth0.com"},{"name":"jamescgarrett-okta","email":"james.garrett@auth0.com"},{"name":"stheller","email":"stefan.heller@auth0.com"},{"name":"jfromaniello","email":"jfromaniello@gmail.com"},{"name":"edgarchirivella-okta","email":"edgar.chirivella@okta.com"},{"name":"sanjay.manikandhan","email":"sanjay.manikandhan@okta.com"},{"name":"rithuc23","email":"rithu.chandrasekar@auth0.com"},{"name":"enriquepina","email":"enrique.pina@auth0.com"},{"name":"sgarcia-atko","email":"sergio.garciaramos@okta.com"},{"name":"roger.chan","email":"roger.chan@auth0.com"},{"name":"joshbetz_auth0","email":"josh.betz@auth0.com"},{"name":"andriy0k","email":"andriy.kharchuk@auth0.com"},{"name":"maaantone","email":"michael.antone@auth0.com"},{"name":"jason.gervais","email":"jason.gervais@okta.com"},{"name":"shafatkhan","email":"shafat.khan@okta.com"},{"name":"psychoticbrat","email":"merisa.lee@okta.com"},{"name":"brohowismynamealreadytaken","email":"ijlal.khan@okta.com"},{"name":"lewisbyrne-okta","email":"lewis.byrne@okta.com"},{"name":"tarunpreet.kaur","email":"tarunpreet.kaur@okta.com"},{"name":"harish.sundar","email":"harish.sundar@auth0.com"},{"name":"dannyturcotte","email":"danny.turcotte@okta.com"},{"name":"auth0-werner","email":"tommy.werner@okta.com"},{"name":"safder.areepattamannil","email":"safder.areepattamannil@okta.com"}],"dist":{"shasum":"c82285b9c6ec02d5ad9ed67aeed0763df3bc2a73","tarball":"https://registry.npmjs.org/@auth0/auth0-cloudflare-agents-api/-/auth0-cloudflare-agents-api-2.0.0.tgz","fileCount":18,"integrity":"sha512-95Ea1HC3JPF+F4kVz9PBzgMQai7BQpAmwYm4y80a2IMchiPbRc0wTygSEd6eKU1BA9tEfv5erVLv5qZ2/+fX+w==","signatures":[{"sig":"MEUCIQDdsh1AHe86wEfPPxLSVLAdVgT2U3l72LuyBpyu0HaLjwIgNLIjTq6bjgbgKmizcvBb5wq/D/XW4rAaRtSDxEI5aWY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98446},"type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"2bc32679c0d61e40f4c75ca3990d816268b123a5","scripts":{"lint":"eslint . --ext .ts","test":"vitest run","build":"tsc","prepare":"npm run build && husky","test:ui":"vitest --ui","lint:fix":"eslint . --ext .ts --fix","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"auth0npm","email":"devops+npm@auth0.com"},"_npmVersion":"10.9.2","description":"A PartyServer mixin for adding Auth0 API authentication to your PartyServer applications.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"@auth0/auth0-api-js":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","agents":"^0.2.11","eslint":"^9.24.0","flumix":"^1.0.0","vitest":"^3.1.1","globals":"^16.0.0","prettier":"3.5.3","@eslint/js":"^9.24.0","@vitest/ui":"^3.1.1","typescript":"^5.8.3","@types/node":"^20.11.26","@eslint/compat":"^1.2.8","@commitlint/cli":"^19.3.0","semantic-release":"^24.2.5","typescript-eslint":"^8.30.1","@vitest/coverage-v8":"^3.1.1","eslint-config-prettier":"^10.1.2","@typescript-eslint/parser":"^8.29.1","@commitlint/config-conventional":"^19.2.2","@typescript-eslint/eslint-plugin":"^8.29.1"},"peerDependencies":{"partyserver":">=0.0.67 <0.0.72"},"_npmOperationalInternal":{"tmp":"tmp/auth0-cloudflare-agents-api_2.0.0_1762521909242_0.9358164256469135","host":"s3://npm-registry-packages-npm-production"}},"2.0.1":{"name":"@auth0/auth0-cloudflare-agents-api","version":"2.0.1","author":{"url":"https://auth0.com","name":"Auth0 Inc."},"license":"Apache-2.0","_id":"@auth0/auth0-cloudflare-agents-api@2.0.1","maintainers":[{"name":"auth0-oss","email":"oss.sdks@auth0.com"},{"name":"ziluvatar","email":"eduardo.diaz@okta.com"},{"name":"iaco","email":"sebastian.iacomuzzi@gmail.com"},{"name":"pubalokta","email":"pablo.ubal@okta.com"},{"name":"auth0npm","email":"devops+npm@auth0.com"},{"name":"auth0brokkr","email":"support@auth0.com"},{"name":"hzalaz","email":"hernan@auth0.com"},{"name":"aaguiarz","email":"andres.aguiar@gmail.com"},{"name":"charlesrea","email":"charles.rea@auth0.com"},{"name":"ncluer","email":"natalie.cluer@gmail.com"},{"name":"julien.wollscheid","email":"julien.wollscheid@auth0.com"},{"name":"cristiandouce","email":"cristiandouce@gmail.com"},{"name":"sambego","email":"sambellen@gmail.com"},{"name":"sandrinodimattia","email":"sandrino@dimattia.be"},{"name":"lzychowski","email":"les.zychowski@auth0.com"},{"name":"davidpatrick0","email":"david.patrick@auth0.com"},{"name":"sergii.biienko","email":"sergii.biienko@auth0.com"},{"name":"jpadilla","email":"hello@jpadilla.com"},{"name":"jessele","email":"jesse.le@auth0.com"},{"name":"rhamzeh_auth0","email":"raghd.hamzeh@auth0.com"},{"name":"oktajeffoktajeff","email":"jeff.shuman@okta.com"},{"name":"david.renaud.okta","email":"david.renaud@okta.com"},{"name":"bsmith-auth0","email":"brian.s.smith@okta.com"},{"name":"madhuri.rm23","email":"madhuri.ravindramohan@okta.com"},{"name":"npirani_okta","email":"neil.pirani@auth0.com"},{"name":"soumya.bodavula","email":"soumya.bodavula@auth0.com"},{"name":"jamescgarrett-okta","email":"james.garrett@auth0.com"},{"name":"stheller","email":"stefan.heller@auth0.com"},{"name":"jfromaniello","email":"jfromaniello@gmail.com"},{"name":"edgarchirivella-okta","email":"edgar.chirivella@okta.com"},{"name":"sanjay.manikandhan","email":"sanjay.manikandhan@okta.com"},{"name":"rithuc23","email":"rithu.chandrasekar@auth0.com"},{"name":"enriquepina","email":"enrique.pina@auth0.com"},{"name":"josecarlos-chavez_atko","email":"josecarlos.chavez@okta.com"},{"name":"sgarcia-atko","email":"sergio.garciaramos@okta.com"},{"name":"roger.chan","email":"roger.chan@auth0.com"},{"name":"joshbetz_auth0","email":"josh.betz@auth0.com"},{"name":"andriy0k","email":"andriy.kharchuk@auth0.com"},{"name":"maaantone","email":"michael.antone@auth0.com"},{"name":"jason.gervais","email":"jason.gervais@okta.com"},{"name":"shafatkhan","email":"shafat.khan@okta.com"},{"name":"psychoticbrat","email":"merisa.lee@okta.com"},{"name":"brohowismynamealreadytaken","email":"ijlal.khan@okta.com"},{"name":"lewisbyrne-okta","email":"lewis.byrne@okta.com"},{"name":"tarunpreet.kaur","email":"tarunpreet.kaur@okta.com"},{"name":"harish.sundar","email":"harish.sundar@auth0.com"},{"name":"dannyturcotte","email":"danny.turcotte@okta.com"},{"name":"auth0-werner","email":"tommy.werner@okta.com"},{"name":"safder.areepattamannil","email":"safder.areepattamannil@okta.com"}],"dist":{"shasum":"33f07fa482b37737ad8053b3ffbc7f849e395295","tarball":"https://registry.npmjs.org/@auth0/auth0-cloudflare-agents-api/-/auth0-cloudflare-agents-api-2.0.1.tgz","fileCount":18,"integrity":"sha512-82094QkUfRcFkvnnYDeLJO3IzZKV38w+v5/uBOxsCati8NXzvP8vtzPCp4HrAHM4ku+IIrZgCHkV8tpin05Zjg==","signatures":[{"sig":"MEQCIE0TZGwxhlaMR58ua4c0D+4yC6IWAps0rbp4GoqTlJplAiBMwxhcBaO4xALXAIJrJKo/Hrd87hbzJo+nL33nwpAJkA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":98470},"type":"module","types":"dist/index.d.ts","module":"dist/index.js","gitHead":"d2c1d3b0867dcbd5984ac645698f01d11d953ccd","scripts":{"lint":"eslint . --ext .ts","test":"vitest run","build":"tsc","prepare":"npm run build && husky","test:ui":"vitest --ui","lint:fix":"eslint . --ext .ts --fix","test:watch":"vitest","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"auth0npm","email":"devops+npm@auth0.com"},"_npmVersion":"10.9.2","description":"A PartyServer mixin for adding Auth0 API authentication to your PartyServer applications.","directories":{},"_nodeVersion":"22.12.0","dependencies":{"react":"^19.2.1","@auth0/auth0-api-js":"^1.0.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"husky":"^9.1.7","agents":"^0.2.11","eslint":"^9.24.0","flumix":"^1.0.0","vitest":"^3.1.1","globals":"^16.0.0","prettier":"3.5.3","@eslint/js":"^9.24.0","@vitest/ui":"^3.1.1","typescript":"^5.8.3","@types/node":"^20.11.26","@eslint/compat":"^1.2.8","@commitlint/cli":"^19.3.0","semantic-release":"^24.2.5","typescript-eslint":"^8.30.1","@vitest/coverage-v8":"^3.1.1","eslint-config-prettier":"^10.1.2","@typescript-eslint/parser":"^8.29.1","@commitlint/config-conventional":"^19.2.2","@typescript-eslint/eslint-plugin":"^8.29.1"},"peerDependencies":{"partyserver":">=0.0.67 <0.0.72"},"_npmOperationalInternal":{"tmp":"tmp/auth0-cloudflare-agents-api_2.0.1_1764855207710_0.7303980137457426","host":"s3://npm-registry-packages-npm-production"}}},"time":{"created":"2025-06-13T16:54:15.975Z","modified":"2026-07-14T10:25:28.266Z","1.0.0":"2025-06-13T16:54:16.245Z","2.0.0":"2025-11-07T13:25:09.415Z","2.0.1":"2025-12-04T13:33:27.853Z"},"author":{"url":"https://auth0.com","name":"Auth0 Inc."},"license":"Apache-2.0","description":"A PartyServer mixin for adding Auth0 API authentication to your PartyServer applications.","maintainers":[{"email":"oss.sdks@auth0.com","name":"auth0-oss"},{"email":"devops+npm@auth0.com","name":"auth0npm"},{"email":"support@auth0.com","name":"auth0brokkr"},{"email":"jesse.le@auth0.com","name":"jessele"},{"email":"jeff.shuman@okta.com","name":"oktajeffoktajeff"},{"email":"brian.s.smith@okta.com","name":"bsmith-auth0"},{"email":"sanjay.manikandhan@okta.com","name":"sanjay.manikandhan"},{"email":"nirmal.joishi@okta.com","name":"nirjo"},{"email":"nil.torres@okta.com","name":"niltorresatko"},{"email":"jaskirat.singh@okta.com","name":"jaskirat_atko"},{"email":"henry.mcardle@okta.com","name":"henry.mcardle"},{"email":"nicolas.villalobos@okta.com","name":"nicolas.villalobos"},{"email":"choah.jung@auth0.com","name":"choah"},{"email":"josecarlos.chavez@okta.com","name":"josecarlos-chavez_atko"},{"email":"saurabh.kumar@okta.com","name":"skatko"},{"email":"tirone.pama@auth0.com","name":"tj.okta"},{"email":"sergio.garciaramos@okta.com","name":"sgarcia-atko"},{"email":"roger.chan@auth0.com","name":"roger.chan"},{"email":"michael.antone@auth0.com","name":"maaantone"},{"email":"lewis.byrne@okta.com","name":"lewisbyrne-okta"},{"email":"tarunpreet.kaur@okta.com","name":"tarunpreet.kaur"}],"readme":"# Agents OAuth2 JWT Bearer\n\nA PartyServer mixin for adding OAuth 2.0 JWT Bearer Token authentication to your PartyServer applications, with Auth0 support.\n\nIt should work with:\n\n- PartyKit: https://docs.partykit.io/guides/authentication/\n- Cloudflare Agents: https://agents.cloudflare.com/\n\n## Overview\n\nThis package provides a mixin that adds authentication functionality to a PartyServer server using [JSON Web Token (JWT) Profile for OAuth 2.0 Access Tokens](https://datatracker.ietf.org/doc/html/rfc9068). It allows you to secure your PartyServer applications by validating access tokens from requests and connections, with built-in support for Auth0.\n\n## Installation\n\n```bash\nnpm install @auth0/auth0-cloudflare-agent-api\n# or\nyarn add @auth0/auth0-cloudflare-agent-api\n# or\npnpm add @auth0/auth0-cloudflare-agent-api\n```\n\n## Usage\n\n### Basic Example\n\n```typescript\nimport { Server } from \"partyserver\";\nimport { WithAuth } from \"@auth0/auth0-cloudflare-agent-api\";\n\n// Define your environment type\ntype MyEnv = {\n  AUTH0_DOMAIN: string;\n  AUTH0_AUDIENCE: string;\n  // ... other environment variables\n};\n\n// Create your server class with authentication\nclass MyAuthenticatedServer extends WithAuth(Server<MyEnv>) {\n  // Your server implementation\n}\n\n// Pass options as parameters to the mixin function\nclass MyAuthenticatedServer extends WithAuth(Server, {\n  // Optional: make authentication optional\n  authRequired: false,\n  // Optional: provide a debug function\n  debug: (message, ctx) => console.log(message, ctx),\n}) {\n  // Your server implementation\n}\n\n// Start the server\nconst server = new MyAuthenticatedServer({\n  env: {\n    AUTH0_DOMAIN: \"your-tenant.auth0.com\",\n    AUTH0_AUDIENCE: \"your-api-audience\",\n    // ... other environment variables\n  },\n});\n\nserver.start();\n```\n\n### Accessing User Info\n\nOnce you've added the mixin, you can access token information and claims:\n\n```typescript\nclass MyAuthenticatedServer extends WithAuth(Server<MyEnv>) {\n  //optionally override onAuthenticatedRequest\n  onAuthenticatedRequest(req: Request) {\n    // Get the JWT claims from the token\n    const claims = this.getClaims();\n    if (claims?.sub !== expectedUserId) {\n      return new Response(\"You are not welcome\", { status: 401 });\n    }\n  }\n\n  onRequest(req: Request) {\n    // Get the token set from the request\n    const tokenSet = this.getCredentials();\n\n    // Get the Access Token claims from the token\n    const claims = this.getClaims();\n\n    // Now you can use the claims to identify the user\n    console.log(`User ID: ${claims?.sub}`);\n\n    // You can also require specific scopes for certain operations\n    try {\n      await this.requireAuth({ scopes: \"read:data\" });\n      // The user has the required scope\n    } catch (error) {\n      if (error instanceof UnauthorizedError) {\n        return error.toResponse();\n      }\n      // Handle other errors\n      return new Response(\"Unknown error\", { status: 500 });\n    }\n\n    // Continue processing the request...\n    return new Response(\"Hello authenticated user!\");\n  }\n\n  //optionally override onAuthenticatedConnect\n  onAuthenticatedConnect(connection: Connection, ctx: ConnectionContext) {\n    // Get the JWT claims from the token\n    const claims = this.getClaims();\n    if (claims.sub !== expectedUserId) {\n      connection.close(1008, \"I don't like you\");\n    }\n  }\n\n  onConnect(connection: Connection, ctx: ConnectionContext) {\n    // Get the token set from the connection\n    const tokenSet = this.getCredentials();\n\n    // Get the JWT claims from the token\n    const claims = this.getClaims();\n\n    // Use the claims in your connection handling logic\n    console.log(`Connected user: ${claims?.sub}`);\n\n    // You can also require specific scopes for certain operations\n    try {\n      await this.requireAuth({ scopes: [\"read:data\", \"write:data\"] });\n      // The user has both required scopes\n    } catch (error) {\n      if (error instanceof UnauthorizedError) {\n        return error.terminateConnection(connection);\n      }\n      // Handle other errors\n      throw error;\n    }\n  }\n\n  onMessage(connection: Connection, message: unknown) {\n    // Get the token set from the connection\n    const tokenSet = this.getCredentials();\n\n    // Get the JWT claims from the token\n    const claims = this.getClaims();\n\n    // Use the claims in your message handling logic\n    console.log(`Message from user: ${claims?.sub}`);\n\n    // Process the message...\n  }\n}\n```\n\n## Authentication Flow\n\n1. When a client makes a request or connection:\n\n   - The mixin extracts the bearer token from the Authorization header or the `access_token` query parameter\n   - It validates the token using Auth0's token verification API\n   - It verifies the token's issuer and audience claims\n\n2. If validation succeeds:\n\n   - The request or connection proceeds\n   - Token information is stored for the connection\n\n3. If validation fails:\n   - A 401 Unauthorized response is returned for HTTP requests\n   - The connection attempt is rejected\n\n## Configuration\n\nThe `WithAuth` mixin requires the following environment variables:\n\n- `AUTH0_DOMAIN`: Your Auth0 tenant domain (e.g., \"your-tenant.auth0.com\")\n- `AUTH0_AUDIENCE`: The audience for the JWT, typically your API identifier\n\nYou can also configure the mixin with options:\n\n```typescript\nWithAuth(Server, {\n  // Make authentication optional (default: true)\n  authRequired: false,\n  // Optional debug function\n  debug: (message, context) => console.log(message, context),\n});\n```\n\n## API Reference\n\n### `WithAuth(BaseClass, options?)`\n\nA mixin factory function that adds authentication functionality to a PartyServer class.\n\n**Parameters:**\n\n- `BaseClass`: The base class to extend from. This should be a class that extends `Server`.\n- `options`: Optional configuration object:\n  - `authRequired`: Boolean indicating whether authentication is required (default: true)\n  - `debug`: Function for debugging (default: noop)\n\n**Returns:**\n\n- A new class that extends the base class with authentication capabilities.\n\n### Methods\n\n#### `getCredentials(): TokenSet | undefined`\n\nGets the token set associated with the current context.\n\n**Returns:**\n\n- A `TokenSet` object containing:\n  - `access_token`: The JWT bearer token\n  - `id_token`: Optional ID token (from `x-id-token` header)\n  - `refresh_token`: Optional refresh token (from `x-refresh-token` header)\n\n#### `getClaims(): Token | undefined`\n\nGets the decoded JWT claims from the access token.\n\n**Returns:**\n\n- An object containing the JWT claims or undefined if no token is available\n\n#### `requireAuth(options?: { scopes?: string | string[] }): Promise<TokenSet>`\n\nRequires authentication with optional scope checking.\n\n**Parameters:**\n\n- `options`: Optional configuration object:\n  - `scopes`: String or array of strings representing required scopes\n\n**Returns:**\n\n- A promise that resolves to the token set if authentication is successful\n\n**Throws:**\n\n- `UnauthorizedError`: If no valid token is present\n- `InvalidTokenError`: If the token is invalid\n- `InsufficientScopeError`: If the token doesn't have the required scopes\n\n## Token Format\n\nThe mixin accepts tokens in the following formats:\n\n1. Authorization header: `Authorization: Bearer <token>`\n2. Query parameter: `?access_token=<token>`\n\n## Advanced Usage: WithOwnership Mixin\n\n### Overview\n\nThe `WithOwnership` mixin adds ownership capabilities to a PartyServer that already has authentication provided by the `WithAuth` mixin. This is particularly useful for scenarios where you need to restrict access to resources based on ownership, such as private chats or user-specific data.\n\n### Key Features\n\n- Owner-based access control for connections and requests\n- Integration with Durable Objects for persistent ownership data\n- Automatic rejection of non-owner access attempts\n\n### Usage Example\n\n```typescript\n// Then add ownership with WithOwnership\nclass MyServer extends WithOwnership(WithAuth(Server<MyEnv>), {\n  // Optional: provide a debug function\n  debug: (message, ctx) => console.log(message, ctx),\n}) {\n  // Your server implementation\n\n  // Optionally override authorization methods\n  async onAuthorizedConnect(connection, ctx) {\n    console.log(\"Owner connected:\", this.getClaims()?.sub);\n    // Handle authorized connection\n  }\n\n  async onAuthorizedRequest(req) {\n    console.log(\"Owner made a request:\", this.getClaims()?.sub);\n    // Handle authorized request\n  }\n}\n```\n\n### Ownership Methods\n\n#### `setOwner(owner: string, overwrite: boolean = false): Promise<void>`\n\nSets the owner of the object. By default, it will throw an error if the owner is already set to a different user unless `overwrite` is set to `true`.\n\n**Parameters:**\n\n- `owner`: The user ID (sub from JWT claims) to set as the owner\n- `overwrite`: Optional boolean to allow overwriting an existing owner\n\n**Example:**\n\n```typescript\n// When initializing a new chat or resource\nasync onCreate() {\n  const claims = this.getClaims();\n  if (claims?.sub) {\n    await this.setOwner(claims.sub);\n  }\n}\n```\n\n#### `getOwner(): Promise<string | undefined>`\n\nGets the current owner of the object.\n\n**Returns:**\n\n- The user ID (sub) of the owner, or undefined if no owner is set\n\n**Example:**\n\n```typescript\nasync checkOwnership() {\n  const owner = await this.getOwner();\n  console.log(`This resource is owned by: ${owner}`);\n}\n```\n\n### Authorization Flow\n\n1. When a client makes a request or connection:\n\n   - First, the authentication checks are performed by the `WithAuth` mixin\n   - Then, the ownership check verifies if the authenticated user is the owner\n\n2. If the ownership check succeeds:\n\n   - The `onAuthorizedConnect` or `onAuthorizedRequest` method is called\n   - The connection or request is allowed to proceed\n\n3. If the ownership check fails:\n   - For WebSocket connections: Connection is closed with code 1008 and message \"This chat is not yours.\"\n   - For HTTP requests: A 403 Forbidden response is returned with message \"This chat is not yours.\"\n\n### DurableObject Integration\n\nThe `WithOwnership` mixin is designed to work with Cloudflare DurableObjects for storing ownership data. The mixin uses the DurableObject's storage API to persist ownership information.\n\n**Note:** If you're not using DurableObjects, you'll need to override the `setOwner` and `getOwner` methods to implement your own storage mechanism.\n\n## References\n\n- This project uses the Auth0 API Client to verify access tokens: [@auth0/auth0-api-js](https://github.com/auth0/auth0-api-js)\n- This project is similar to other Auth0 middlewares like [node-oauth2-jwt-bearer](https://github.com/auth0/node-oauth2-jwt-bearer).\n- [Authentication on PartyKit](https://docs.partykit.io/guides/authentication/).\n\n## Feedback\n\n### Contributing\n\nWe appreciate feedback and contribution to this repo! Before you get started, please see the following:\n\n- [Auth0's general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md)\n- [Auth0's code of conduct guidelines](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md)\n\n### Raise an issue\n\nTo provide feedback or report a bug, please [raise an issue on our issue tracker](https://github.com/auth0-lab/agents-oauth2-jwt-bearer/issues).\n\n### Vulnerability Reporting\n\nPlease do not report security vulnerabilities on the public GitHub issue tracker. The [Responsible Disclosure Program](https://auth0.com/responsible-disclosure-policy) details the procedure for disclosing security issues.\n\n---\n\n<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png\"   width=\"150\">\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://cdn.auth0.com/website/sdks/logos/auth0_dark_mode.png\" width=\"150\">\n    <img alt=\"Auth0 Logo\" src=\"https://cdn.auth0.com/website/sdks/logos/auth0_light_mode.png\" width=\"150\">\n  </picture>\n</p>\n<p align=\"center\">Auth0 is an easy to implement, adaptable authentication and authorization platform. To learn more checkout <a href=\"https://auth0.com/why-auth0\">Why Auth0?</a></p>\n<p align=\"center\">\nThis project is licensed under the Apache 2.0 license. See the <a href=\"/LICENSE\"> LICENSE</a> file for more info.</p>\n","readmeFilename":"README.md"}