{"id":25428950,"url":"https://github.com/kidgodzilla/bluesky-oauth-kit","last_synced_at":"2025-06-20T18:35:34.613Z","repository":{"id":276921417,"uuid":"930497172","full_name":"kidGodzilla/bluesky-oauth-kit","owner":"kidGodzilla","description":"A drop-in, ready-to-use, Bluesky OAuth login solution for Node.js and Javascript (any client).","archived":false,"fork":false,"pushed_at":"2025-04-17T15:00:24.000Z","size":140,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-10T11:24:09.865Z","etag":null,"topics":["authentication","bluesky","express","fastify","oauth","oauth2"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/bluesky-oauth-kit","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kidGodzilla.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-02-10T18:18:21.000Z","updated_at":"2025-04-17T15:00:28.000Z","dependencies_parsed_at":"2025-04-17T14:54:40.380Z","dependency_job_id":"70ed7d3d-f245-4210-84db-ba9dfe6d6d90","html_url":"https://github.com/kidGodzilla/bluesky-oauth-kit","commit_stats":null,"previous_names":["kidgodzilla/bluesky-oauth-kit"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/kidGodzilla/bluesky-oauth-kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fbluesky-oauth-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fbluesky-oauth-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fbluesky-oauth-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fbluesky-oauth-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kidGodzilla","download_url":"https://codeload.github.com/kidGodzilla/bluesky-oauth-kit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kidGodzilla%2Fbluesky-oauth-kit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260062662,"owners_count":22953406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","bluesky","express","fastify","oauth","oauth2"],"created_at":"2025-02-17T01:49:34.259Z","updated_at":"2025-06-20T18:35:29.602Z","avatar_url":"https://github.com/kidGodzilla.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Bluesky OAuth (2.0) Kit\n\nA drop-in, ready-to-use, Bluesky OAuth login solution for Node.js and Javascript (any client).\n\nAccelerate the migration of third-party Bluesky apps and integrations from insecure authentication methods (password stored in plaintext), to modern OAuth.\n\nThis package aims to adhere to OAuth 2.0 norms, while providing a simple to understand and ready-to-use Node.js backend \nthat can be used with any sort of frontend client (Javascript, Vue, React, React Native, Ionic/Capacitor, Android, Swift, Electron, PWA, etc.)\n\nExamples provided for Express (with hopefully more to come.) Testing an PRs welcome!\n\n\n# Installation\n\n```bash\nnpm i -s bluesky-oauth-kit\n```\n\n# Usage\n\nSee `examples` directory.\n\n## Express (Default Options)\n\n```js\nconst express = require('express');\nconst { setupExpressAuth } = require('bluesky-oauth-kit');\n\nconst app = express();\n\n// Basic setup\nawait setupExpressAuth(app);\n\n// With additional options\nawait setupExpressAuth(app, {\n    baseUrl: 'http://localhost:5001',\n    redirectUrl: '/dashboard',\n    clientName: 'My OAuth App',\n    // Optional: Custom storage implementations\n    stateStore: customStateStore,\n    sessionStore: customSessionStore\n});\n```\n\n## Express (composable)\n\n```js\nconst express = require('express');\nconst { initializeOAuth, authenticateToken, setupOauthRoutes } = require('bluesky-oauth-kit');\n\nconst app = express();\n\n(async function() {\n    const { client, sessionStore, stateStore } = await initializeOAuth(options);\n    setupOauthRoutes(app, sessionStore);\n})();\n```\n\n## Framework Support\n\nThe library works with multiple frameworks:\n- Express (primary support)\n\nOther frameworks can be supported by PR.\n\n## Environment Variables\n\n```env\n# Required\nOAUTH_JWT_SECRET=your-jwt-secret\nOAUTH_BASE_URL=http://localhost:5001\nOAUTH_PRIVATE_KEY_1=your-private-key-1\nOAUTH_PRIVATE_KEY_2=your-private-key-2\nOAUTH_PRIVATE_KEY_3=your-private-key-3\n\n# Optional\nOAUTH_CLIENT_NAME=My OAuth App\nOAUTH_USE_COOKIES=true\nOAUTH_REDIRECT_URL=/dashboard\nNODE_ENV=development\n```\n\n## Custom Storage\n\nThe library uses in-memory storage by default, but you can implement your own storage:\n\n```js\nclass CustomStore {\n    async get(key) { /* ... */ }\n    async set(key, value) { /* ... */ }\n    async del(key) { /* ... */ }\n}\n\n// Redis example\nclass RedisStore {\n    constructor(redis) {\n        this.redis = redis;\n    }\n    async get(key) { return JSON.parse(await this.redis.get(key)); }\n    async set(key, value) { await this.redis.set(key, JSON.stringify(value)); }\n    async del(key) { await this.redis.del(key); }\n}\n```\n\n## Available Endpoints\n\nThe library sets up the following endpoints:\n- `/login` - Serves a login form (optional, can be disabled)\n- `/oauth/login` - Initiates the OAuth flow\n- `/oauth/callback` - Handles the OAuth callback\n- `/oauth/userinfo` - Returns info about the authenticated user\n- `/oauth/revoke` - Revokes the current session\n- `/oauth/client-metadata.json` - Serves OAuth client metadata\n- `/oauth/jwks.json` - Serves the JSON Web Key Set\n\n## Configuration\n\n```js\nawait setupExpressAuth(app, {\n    baseUrl: 'http://localhost:5001',\n    serveLoginPage: true,  // Set to false to disable built-in login page\n    serveErrorPage: true,  // Set to false to disable built-in error page\n    loginPageTitle: 'Login with Bluesky',  // Customize login page\n    display: 'page',  // 'page', 'popup', or 'touch' for mobile\n    maxAge: 48 * 60 * 60 * 1000,  // Cookie lifetime\n    cookieDomain: '.yourdomain.com',\n    cookiePath: '/',\n    cookieSecret: 'your-secret',\n    addHeaders: true,\n    forceHTTPS: true,\n    // ... other options\n});\n```\n\n# Development\n\n## Running the Example\n\n1. Clone the repository\n2. Install dependencies:\n   ```bash\n   npm install\n   ```\n3. Copy .env.example to .env and fill in your values:\n   ```bash\n   cp .env.example .env\n   ```\n4. Run the example:\n   ```bash\n   node examples/express.js\n   ```\n\nThe example server will start on http://localhost:5001\n\n## Generating Keys\n\nYou can generate OAuth keys in two ways:\n\n1. Using npx (recommended):\n```bash\nnpx bluesky-oauth-kit generate-oauth-keys\n```\n\n2. After installing as a dependency:\n```bash\nnpm run generate-keys\n```\n\nThis will either create a new .env file or append OAuth keys to your existing one.\n\n## Authentication Flow\n\nThe library implements standard OAuth 2.0 authentication, providing:\n\n1. A JWT containing:\n   - `sub`: The user's DID (standard OpenID Connect subject identifier)\n   - `did`: The user's DID (AT Protocol identifier)\n   - `iss`: The issuer ('bsky.social')\n   - `iat`: Token issue timestamp\n\n2. The `/oauth/userinfo` endpoint returns this basic profile information.\n\nNote: For richer profile data (handle, displayName, avatar, etc.), you'll need to:\n1. Install `@atproto/api`\n2. Use the session to create an Agent\n3. Call `agent.getProfile()`\n\nExample:\n```js\nconst { Agent } = require('@atproto/api');\n\n// Get rich profile data\nconst agent = new Agent(session);\nconst profile = await agent.getProfile({ actor: agent.did });\nconsole.log(profile.data);  // Contains handle, displayName, avatar, etc.\n```\n\n## Security Configuration\n\nThe library includes several security features that can be configured:\n\n### Cookie Options\nWhen using `OAUTH_USE_COOKIES=true`, you can configure cookie security:\n\n```js\nawait setupExpressAuth(app, {\n    maxAge: 7 * 24 * 60 * 60 * 1000,  // Cookie lifetime (default 48h)\n    cookieDomain: '.yourdomain.com',   // Cookie domain\n    cookiePath: '/',                   // Cookie path\n    cookieSecret: 'your-secret',       // Enable signed cookies\n});\n```\n\n### Security Headers\nThe library automatically sets security headers:\n- `X-Content-Type-Options: nosniff`\n- `X-Frame-Options: DENY`\n- `X-XSS-Protection: 1; mode=block`\n\n### CORS\nConfigure CORS in your Express app:\n```js\napp.use(cors({\n    origin: process.env.OAUTH_BASE_URL,\n    methods: ['GET', 'POST'],\n    allowedHeaders: ['Content-Type', 'Authorization'],\n}));\n```\n\n### HTTPS\nIn production (`NODE_ENV=production`):\n- Cookies are automatically set as `Secure`\n- HTTP requests are redirected to HTTPS\n- Cookies use `SameSite=Strict`\n\n### Rate Limiting\nThe example includes rate limiting. You should include this (or something similar) in your app.\n\n```js\nconst rateLimit = require('express-rate-limit');\napp.use(['/login', '/oauth/*'], rateLimit({\n    windowMs: 15 * 60 * 1000,  // 15 minutes\n    max: 100                    // Limit each IP to 100 requests per window\n}));\n```\n\n## Available Scopes\n\nThe Bluesky OAuth server supports these scopes:\n- `atproto` - Standard AT Protocol access\n- `transition:generic` - Generic transition scope\n- `transition:chat.bsky` - Chat transition scope (future use)\n\n## OAuth Implementation Details\n\nThis library implements the AT Protocol OAuth specification via `@atproto/oauth-client-node`:\n- Secure OAuth 2.0 flow with PAR, DPoP, and PKCE\n- Session management\n- Token handling and refresh\n- Framework integrations (Express)\n- Configurable storage backends\n\n# Using the Bluesky API (ATProto) with this package\n\nThis kit provides a helper function, `getClient()`, to retrieve your authenticated client instance, \nwhich can be passed to `@atproto/api` to make authenticated API requests. \n\nSee `examples/express.js`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidgodzilla%2Fbluesky-oauth-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkidgodzilla%2Fbluesky-oauth-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkidgodzilla%2Fbluesky-oauth-kit/lists"}