diff --git a/.changeset/config.json b/.changeset/config.json index a97ddc48..6a796e1f 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -3,7 +3,7 @@ "changelog": [ "@changesets/changelog-github", { - "repo": "ascorbic/atproto-worker" + "repo": "ascorbic/cirrus" } ], "commit": false, diff --git a/.changeset/pretty-vans-bathe.md b/.changeset/pretty-vans-bathe.md new file mode 100644 index 00000000..cc0b6fb9 --- /dev/null +++ b/.changeset/pretty-vans-bathe.md @@ -0,0 +1,7 @@ +--- +"@getcirrus/oauth-provider": patch +"create-pds": patch +"@getcirrus/pds": patch +--- + +Rename to Cirrus diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 7669ce59..d272b198 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -25,4 +25,4 @@ jobs: - name: Build run: pnpm build - name: E2E Tests - run: pnpm --filter @ascorbic/pds test:e2e + run: pnpm --filter @getcirrus/pds test:e2e diff --git a/CLAUDE.md b/CLAUDE.md index bd34c6d2..05843481 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,7 @@ This file provides guidance to agentic coding tools when working with code in th **ALWAYS verify your current working directory before operating on files:** -- Repository root is `atproto-worker` not `packages/pds/` +- Repository root is `cirrus` not `packages/pds/` - Use `pwd` or check `process.cwd()` to confirm location - Many project files (CLAUDE.md, plans/) are at repository root - Package-specific files are in `packages/pds/` @@ -27,8 +27,10 @@ This file provides guidance to agentic coding tools when working with code in th This is a monorepo using pnpm workspaces with the following structure: -- **Root** (`atproto-worker`): Workspace configuration, shared tooling, plan documents -- **packages/pds**: The main PDS library (`@ascorbic/pds`) +- **Root** (`cirrus`): Workspace configuration, shared tooling, plan documents +- **packages/pds**: The main PDS library (`@getcirrus/pds`) +- **packages/oauth-provider**: OAuth 2.1 Provider (`@getcirrus/oauth-provider`) +- **packages/create-pds**: CLI scaffolding tool (`create-pds`) - **demos/pds**: Demo PDS deployment ## Commands diff --git a/README.md b/README.md index cb151da8..a23ae068 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ -# AT Protocol PDS on Cloudflare Workers +
+

☁️ Cirrus

+

The lightest PDS in the Atmosphere

+
-A single-user [AT Protocol](https://atproto.com) Personal Data Server (PDS) that runs entirely on Cloudflare's edge infrastructure. Host your Bluesky identity on your own domain with minimal operational overhead. +A single-user [AT Protocol](https://atproto.com) Personal Data Server (PDS) that runs on a Cloudflare Worker. ## Why run your own PDS? @@ -31,11 +34,11 @@ This scaffolds a new project, installs dependencies, and runs the setup wizard. ## Packages -| Package | Description | -|---------|-------------| -| [`@ascorbic/pds`](./packages/pds/) | The PDS implementation – handles repository operations, federation, OAuth, and the CLI | -| [`@ascorbic/atproto-oauth-provider`](./packages/oauth-provider/) | OAuth 2.1 provider for "Login with Bluesky" | -| [`create-pds`](./packages/create-pds/) | Scaffolding CLI to create new PDS projects | +| Package | Description | +| --------------------------------------------------------- | -------------------------------------------------------------------------------------- | +| [`@getcirrus/pds`](./packages/pds/) | The PDS implementation – handles repository operations, federation, OAuth, and the CLI | +| [`@getcirrus/oauth-provider`](./packages/oauth-provider/) | OAuth 2.1 provider for "Login with Bluesky" | +| [`create-pds`](./packages/create-pds/) | Scaffolding CLI to create new PDS projects | ## Status diff --git a/demos/pds/README.md b/demos/pds/README.md index f8c50a55..ae6ce577 100644 --- a/demos/pds/README.md +++ b/demos/pds/README.md @@ -1,6 +1,6 @@ # Personal PDS on Cloudflare Workers -This is an example deployment of `@ascorbic/pds` - a single-user AT Protocol Personal Data Server on Cloudflare Workers. +This is an example deployment of `@getcirrus/pds` - a single-user AT Protocol Personal Data Server on Cloudflare Workers. > **⚠️ Experimental Software** > @@ -76,11 +76,11 @@ Configuration is via environment variables: vars in the `wrangler.jsonc` and sec ## Architecture -This deployment simply re-exports the `@ascorbic/pds` package: +This deployment simply re-exports the `@getcirrus/pds` package: ```typescript // src/index.ts -export { default, AccountDurableObject } from "@ascorbic/pds"; +export { default, AccountDurableObject } from "@getcirrus/pds"; ``` No additional code needed! diff --git a/demos/pds/package.json b/demos/pds/package.json index 9c8ed860..b316b96e 100644 --- a/demos/pds/package.json +++ b/demos/pds/package.json @@ -5,7 +5,7 @@ "type": "module", "private": true, "dependencies": { - "@ascorbic/pds": "workspace:*" + "@getcirrus/pds": "workspace:*" }, "devDependencies": { "@cloudflare/vite-plugin": "^1.17.0", diff --git a/demos/pds/src/index.ts b/demos/pds/src/index.ts index d05e9a4f..a1ff2405 100644 --- a/demos/pds/src/index.ts +++ b/demos/pds/src/index.ts @@ -1,2 +1,2 @@ // Re-export the PDS worker - that's all you need! -export { default, AccountDurableObject } from "@ascorbic/pds"; +export { default, AccountDurableObject } from "@getcirrus/pds"; diff --git a/package.json b/package.json index c52be3e8..4ebc28c2 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { - "name": "atproto-worker", + "name": "cirrus", "private": true, "version": "1.0.0", - "description": "AT Protocol PDS on Cloudflare Workers", + "description": "Cirrus – A single-user AT Protocol PDS on Cloudflare Workers", "scripts": { - "check": "pnpm run --filter '@ascorbic/*' --filter 'create-pds' check", - "test": "pnpm run --filter '@ascorbic/*' --filter 'create-pds' test", - "build": "pnpm run --filter '@ascorbic/*' --filter 'create-pds' build", + "check": "pnpm run --filter '@getcirrus/*' --filter 'create-pds' check", + "test": "pnpm run --filter '@getcirrus/*' --filter 'create-pds' test", + "build": "pnpm run --filter '@getcirrus/*' --filter 'create-pds' build", "format": "prettier --write .", "knip": "knip" }, diff --git a/packages/create-pds/README.md b/packages/create-pds/README.md index 9b2dc0f0..1ffae4f7 100644 --- a/packages/create-pds/README.md +++ b/packages/create-pds/README.md @@ -1,6 +1,6 @@ # create-pds -Scaffold a new [AT Protocol](https://atproto.com) Personal Data Server (PDS) on Cloudflare Workers. +Scaffold a new [AT Protocol](https://atproto.com) Personal Data Server (PDS) on Cloudflare Workers. Creates a Cirrus PDS project. ## Usage @@ -24,7 +24,7 @@ This will: create-pds [name] Arguments: - name Project name (default: pds-worker) + name Project name (default: my-pds) Options: --package-manager Package manager to use (npm, yarn, pnpm, bun) @@ -45,4 +45,4 @@ npm run dev Your PDS will be running at http://localhost:5173 -See the [@ascorbic/pds documentation](https://github.com/ascorbic/atproto-worker/tree/main/packages/pds) for configuration and deployment instructions. +See the [@getcirrus/pds documentation](https://github.com/ascorbic/cirrus/tree/main/packages/pds) for configuration and deployment instructions. diff --git a/packages/create-pds/package.json b/packages/create-pds/package.json index fecfb8ef..3552a1b6 100644 --- a/packages/create-pds/package.json +++ b/packages/create-pds/package.json @@ -1,7 +1,7 @@ { "name": "create-pds", "version": "0.0.6", - "description": "Create a new AT Protocol PDS on Cloudflare Workers", + "description": "Create a new Cirrus AT Protocol PDS on Cloudflare Workers", "type": "module", "bin": { "create-pds": "./dist/index.js" diff --git a/packages/create-pds/src/index.ts b/packages/create-pds/src/index.ts index e8d794d5..6e1d4cb9 100644 --- a/packages/create-pds/src/index.ts +++ b/packages/create-pds/src/index.ts @@ -100,7 +100,7 @@ async function replaceInFile( async function getLatestPdsVersion(): Promise { try { const response = await fetch( - "https://registry.npmjs.org/@ascorbic/pds/latest", + "https://registry.npmjs.org/@getcirrus/pds/latest", ); if (!response.ok) { throw new Error(`Failed to fetch: ${response.status}`); @@ -242,9 +242,9 @@ const main = defineCommand({ // Copy template const spinner = p.spinner(); - spinner.start("Fetching latest @ascorbic/pds version..."); + spinner.start("Fetching latest @getcirrus/pds version..."); const pdsVersion = await getLatestPdsVersion(); - spinner.stop(`Using @ascorbic/pds ${pdsVersion}`); + spinner.stop(`Using @getcirrus/pds ${pdsVersion}`); spinner.start("Copying template..."); diff --git a/packages/create-pds/templates/pds-worker/README.md b/packages/create-pds/templates/pds-worker/README.md index a5342e41..a065e5dc 100644 --- a/packages/create-pds/templates/pds-worker/README.md +++ b/packages/create-pds/templates/pds-worker/README.md @@ -180,7 +180,7 @@ If migration fails partway through: - [AT Protocol Documentation](https://atproto.com) - [Cloudflare Workers Docs](https://developers.cloudflare.com/workers/) -- [@ascorbic/pds Documentation](https://github.com/ascorbic/atproto-worker/tree/main/packages/pds) +- [@getcirrus/pds Documentation](https://github.com/ascorbic/cirrus/tree/main/packages/pds) - [Account Migration Guide](https://atproto.com/guides/account-migration) ## License diff --git a/packages/create-pds/templates/pds-worker/package.json.tmpl b/packages/create-pds/templates/pds-worker/package.json.tmpl index c299759a..9a63f01c 100644 --- a/packages/create-pds/templates/pds-worker/package.json.tmpl +++ b/packages/create-pds/templates/pds-worker/package.json.tmpl @@ -1,11 +1,11 @@ { "name": "{{name}}", "version": "1.0.0", - "description": "AT Protocol PDS on Cloudflare Workers", + "description": "Cirrus – AT Protocol PDS on Cloudflare Workers", "type": "module", "private": true, "dependencies": { - "@ascorbic/pds": "{{pdsVersion}}" + "@getcirrus/pds": "{{pdsVersion}}" }, "devDependencies": { "@cloudflare/vite-plugin": "^1.17.0", diff --git a/packages/create-pds/templates/pds-worker/src/index.ts b/packages/create-pds/templates/pds-worker/src/index.ts index d05e9a4f..a1ff2405 100644 --- a/packages/create-pds/templates/pds-worker/src/index.ts +++ b/packages/create-pds/templates/pds-worker/src/index.ts @@ -1,2 +1,2 @@ // Re-export the PDS worker - that's all you need! -export { default, AccountDurableObject } from "@ascorbic/pds"; +export { default, AccountDurableObject } from "@getcirrus/pds"; diff --git a/packages/create-pds/test/e2e.test.ts b/packages/create-pds/test/e2e.test.ts index 9c19b2f5..8afe9cde 100644 --- a/packages/create-pds/test/e2e.test.ts +++ b/packages/create-pds/test/e2e.test.ts @@ -59,13 +59,13 @@ describe("create-pds e2e", () => { ); expect(packageJson.name).toBe(PROJECT_NAME); - expect(packageJson.dependencies["@ascorbic/pds"]).toBeDefined(); + expect(packageJson.dependencies["@getcirrus/pds"]).toBeDefined(); }); it("includes correct worker entry point", () => { const indexTs = readFileSync(join(PROJECT_DIR, "src/index.ts"), "utf-8"); - expect(indexTs).toContain("@ascorbic/pds"); + expect(indexTs).toContain("@getcirrus/pds"); expect(indexTs).toContain("AccountDurableObject"); }); diff --git a/packages/oauth-provider/CHANGELOG.md b/packages/oauth-provider/CHANGELOG.md index 9ae56f2a..41246c4d 100644 --- a/packages/oauth-provider/CHANGELOG.md +++ b/packages/oauth-provider/CHANGELOG.md @@ -1,4 +1,4 @@ -# @ascorbic/atproto-oauth-provider +# @getcirrus/oauth-provider ## 0.1.1 diff --git a/packages/oauth-provider/README.md b/packages/oauth-provider/README.md index 2e1cda03..4386a22f 100644 --- a/packages/oauth-provider/README.md +++ b/packages/oauth-provider/README.md @@ -1,4 +1,4 @@ -# @ascorbic/atproto-oauth-provider +# @getcirrus/oauth-provider > **🚨 This package has been renamed to `@getcirrus/oauth-provider`** > @@ -20,15 +20,15 @@ A complete OAuth 2.1 provider implementation that enables "Login with Bluesky" f ## Installation ```bash -npm install @ascorbic/atproto-oauth-provider +npm install @getcirrus/oauth-provider # or -pnpm add @ascorbic/atproto-oauth-provider +pnpm add @getcirrus/oauth-provider ``` ## Quick Start ```typescript -import { OAuthProvider } from "@ascorbic/atproto-oauth-provider"; +import { OAuthProvider } from "@getcirrus/oauth-provider"; import { OAuthStorage } from "./your-storage-implementation"; // Initialize the provider @@ -102,7 +102,7 @@ export interface OAuthProviderStorage { } ``` -A SQLite implementation for Durable Objects is included in the `@ascorbic/pds` package. +A SQLite implementation for Durable Objects is included in the `@getcirrus/pds` package. ## OAuth 2.1 Flow @@ -283,6 +283,6 @@ MIT ## Related Packages -- `@ascorbic/pds` - AT Protocol PDS implementation using this OAuth provider +- `@getcirrus/pds` - AT Protocol PDS implementation using this OAuth provider - `@atproto/oauth-client` - Official AT Protocol OAuth client - `@atproto/oauth-types` - TypeScript types for AT Protocol OAuth diff --git a/packages/oauth-provider/package.json b/packages/oauth-provider/package.json index 4eaab5de..06943015 100644 --- a/packages/oauth-provider/package.json +++ b/packages/oauth-provider/package.json @@ -1,5 +1,5 @@ { - "name": "@ascorbic/atproto-oauth-provider", + "name": "@getcirrus/oauth-provider", "version": "0.1.1", "description": "OAuth 2.1 Provider with AT Protocol extensions for Cloudflare Workers", "type": "module", diff --git a/packages/oauth-provider/src/index.ts b/packages/oauth-provider/src/index.ts index abc2ed83..2055abe4 100644 --- a/packages/oauth-provider/src/index.ts +++ b/packages/oauth-provider/src/index.ts @@ -1,5 +1,5 @@ /** - * @ascorbic/atproto-oauth-provider + * @getcirrus/oauth-provider * OAuth 2.1 Provider with AT Protocol extensions for Cloudflare Workers */ diff --git a/packages/pds/CHANGELOG.md b/packages/pds/CHANGELOG.md index 4d1e6160..c19ba375 100644 --- a/packages/pds/CHANGELOG.md +++ b/packages/pds/CHANGELOG.md @@ -1,4 +1,4 @@ -# @ascorbic/pds +# @getcirrus/pds ## 0.2.3 diff --git a/packages/pds/README.md b/packages/pds/README.md index 4ed9c67c..3bb7429b 100644 --- a/packages/pds/README.md +++ b/packages/pds/README.md @@ -1,10 +1,11 @@ -# @ascorbic/pds +
+

☁️ Cirrus

+

The lightest PDS in the Atmosphere

+
-> **🚨 This package has been renamed to `@getcirrus/pds`** -> -> This package is deprecated and will no longer receive updates. Please migrate to [`@getcirrus/pds`](https://www.npmjs.com/package/@getcirrus/pds) for the latest features and bug fixes. +Cirrus is a single-user [AT Protocol](https://atproto.com) Personal Data Server (PDS) that runs on Cloudflare Workers. Named for the highest, lightest clouds in a blue sky – fitting for a Bluesky server running on Cloudflare. -A single-user [AT Protocol](https://atproto.com) Personal Data Server (PDS) that runs on Cloudflare Workers. Host your own Bluesky identity with minimal infrastructure. +Host your own Bluesky identity with minimal infrastructure. > **⚠️ Experimental Software** > @@ -25,6 +26,8 @@ Key benefits: ## Quick Start ```bash +pnpm create pds +# or npm create pds ``` @@ -40,36 +43,38 @@ npm run dev ### 1. Install the package ```bash -npm install @ascorbic/pds +npm install @getcirrus/pds ``` ### 2. Create a worker entry point ```typescript // src/index.ts -export { default, AccountDurableObject } from "@ascorbic/pds"; +export { default, AccountDurableObject } from "@getcirrus/pds"; ``` ### 3. Configure wrangler.jsonc ```jsonc { - "name": "my-pds", - "main": "src/index.ts", - "compatibility_date": "2024-12-01", - "compatibility_flags": ["nodejs_compat"], - "durable_objects": { - "bindings": [{ "name": "ACCOUNT", "class_name": "AccountDurableObject" }] - }, - "migrations": [{ "tag": "v1", "new_sqlite_classes": ["AccountDurableObject"] }], - "r2_buckets": [{ "binding": "BLOBS", "bucket_name": "pds-blobs" }] + "name": "my-pds", + "main": "src/index.ts", + "compatibility_date": "2024-12-01", + "compatibility_flags": ["nodejs_compat"], + "durable_objects": { + "bindings": [{ "name": "ACCOUNT", "class_name": "AccountDurableObject" }], + }, + "migrations": [ + { "tag": "v1", "new_sqlite_classes": ["AccountDurableObject"] }, + ], + "r2_buckets": [{ "binding": "BLOBS", "bucket_name": "pds-blobs" }], } ``` ### 4. Run the setup wizard ```bash -npx pds init +pnpm pds init ``` This prompts for your hostname, handle, and password, then generates signing keys and writes configuration. @@ -185,31 +190,31 @@ The PDS runs as a Cloudflare Worker with a Durable Object for state: ``` ┌─────────────────────────────────────────────────────────────┐ │ Cloudflare Worker │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ Hono Router │ │ -│ │ • Authentication middleware │ │ -│ │ • CORS handling │ │ -│ │ • DID document serving │ │ -│ │ • XRPC endpoint routing │ │ -│ │ • OAuth 2.1 provider │ │ -│ │ • Proxy to AppView for read endpoints │ │ -│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ Hono Router │ │ +│ │ • Authentication middleware │ │ +│ │ • CORS handling │ │ +│ │ • DID document serving │ │ +│ │ • XRPC endpoint routing │ │ +│ │ • OAuth 2.1 provider │ │ +│ │ • Proxy to AppView for read endpoints │ │ +│ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ AccountDurableObject │ │ -│ │ • SQLite repository storage │ │ -│ │ • Merkle tree for commits │ │ -│ │ • Record indexing │ │ -│ │ • WebSocket firehose │ │ -│ │ • OAuth token storage │ │ -│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ AccountDurableObject │ │ +│ │ • SQLite repository storage │ │ +│ │ • Merkle tree for commits │ │ +│ │ • Record indexing │ │ +│ │ • WebSocket firehose │ │ +│ │ • OAuth token storage │ │ +│ └─────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ R2 Bucket │ │ -│ │ • Blob storage (images, videos) │ │ -│ └─────────────────────────────────────────────────────┘ │ +│ ┌─────────────────────────────────────────────────────┐ │ +│ │ R2 Bucket │ │ +│ │ • Blob storage (images, videos) │ │ +│ └─────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘ ``` @@ -267,12 +272,12 @@ The PDS uses environment variables for configuration. Public values go in `wrang ### Public Variables (wrangler.jsonc) -| Variable | Description | -| -------------------- | ---------------------------------------- | -| `PDS_HOSTNAME` | Public hostname (e.g., pds.example.com) | -| `DID` | Account DID (did:web:... or did:plc:...) | -| `HANDLE` | Account handle | -| `SIGNING_KEY_PUBLIC` | Public key for DID document (multibase) | +| Variable | Description | +| -------------------- | ------------------------------------------ | +| `PDS_HOSTNAME` | Public hostname (e.g., pds.example.com) | +| `DID` | Account DID (did:web:... or did:plc:...) | +| `HANDLE` | Account handle | +| `SIGNING_KEY_PUBLIC` | Public key for DID document (multibase) | | `INITIAL_ACTIVE` | Whether account starts active (true/false) | ### Secrets @@ -288,11 +293,11 @@ The PDS uses environment variables for configuration. Public values go in `wrang ### Identity -| Endpoint | Description | -| ------------------------------ | ---------------------------------------------------- | -| `GET /.well-known/did.json` | DID document for did:web resolution | +| Endpoint | Description | +| ------------------------------ | ----------------------------------------------------- | +| `GET /.well-known/did.json` | DID document for did:web resolution | | `GET /.well-known/atproto-did` | Handle verification (only if handle matches hostname) | -| `GET /health` | Health check with version info | +| `GET /health` | Health check with version info | ### Federation (Sync) @@ -323,45 +328,45 @@ The PDS uses environment variables for configuration. Public values go in `wrang ### Server & Session -| Endpoint | Auth | Description | -| ----------------------------------------------- | ---- | --------------------------------- | -| `GET /xrpc/com.atproto.server.describeServer` | No | Server capabilities and info | -| `POST /xrpc/com.atproto.server.createSession` | No | Login with password, get JWT | -| `POST /xrpc/com.atproto.server.refreshSession` | Yes | Refresh JWT tokens | -| `GET /xrpc/com.atproto.server.getSession` | Yes | Get current session info | -| `POST /xrpc/com.atproto.server.deleteSession` | Yes | Logout | -| `GET /xrpc/com.atproto.server.getServiceAuth` | Yes | Get JWT for external services | -| `GET /xrpc/com.atproto.server.getAccountStatus` | Yes | Account status (active/deactivated) | -| `POST /xrpc/com.atproto.server.activateAccount` | Yes | Enable writes | -| `POST /xrpc/com.atproto.server.deactivateAccount` | Yes | Disable writes | +| Endpoint | Auth | Description | +| ------------------------------------------------- | ---- | ----------------------------------- | +| `GET /xrpc/com.atproto.server.describeServer` | No | Server capabilities and info | +| `POST /xrpc/com.atproto.server.createSession` | No | Login with password, get JWT | +| `POST /xrpc/com.atproto.server.refreshSession` | Yes | Refresh JWT tokens | +| `GET /xrpc/com.atproto.server.getSession` | Yes | Get current session info | +| `POST /xrpc/com.atproto.server.deleteSession` | Yes | Logout | +| `GET /xrpc/com.atproto.server.getServiceAuth` | Yes | Get JWT for external services | +| `GET /xrpc/com.atproto.server.getAccountStatus` | Yes | Account status (active/deactivated) | +| `POST /xrpc/com.atproto.server.activateAccount` | Yes | Enable writes | +| `POST /xrpc/com.atproto.server.deactivateAccount` | Yes | Disable writes | ### Handle Resolution -| Endpoint | Description | -| --------------------------------------------- | ----------------------------------------- | +| Endpoint | Description | +| ---------------------------------------------- | ---------------------------------------- | | `GET /xrpc/com.atproto.identity.resolveHandle` | Resolve handle to DID (local or proxied) | ### Actor Preferences -| Endpoint | Auth | Description | -| ----------------------------------------- | ---- | -------------------- | -| `GET /xrpc/app.bsky.actor.getPreferences` | Yes | Get user preferences | -| `POST /xrpc/app.bsky.actor.putPreferences` | Yes | Set user preferences | +| Endpoint | Auth | Description | +| ------------------------------------------ | ---- | -------------------- | +| `GET /xrpc/app.bsky.actor.getPreferences` | Yes | Get user preferences | +| `POST /xrpc/app.bsky.actor.putPreferences` | Yes | Set user preferences | ### OAuth 2.1 The PDS includes a complete OAuth 2.1 provider for "Login with Bluesky": -| Endpoint | Description | -| --------------------------------------------- | ------------------------------------ | -| `GET /.well-known/oauth-authorization-server` | OAuth server metadata | -| `POST /oauth/par` | Pushed Authorization Request | -| `GET /oauth/authorize` | Authorization endpoint | -| `POST /oauth/authorize` | Process authorization decision | -| `POST /oauth/token` | Token exchange | -| `POST /oauth/revoke` | Token revocation | +| Endpoint | Description | +| --------------------------------------------- | ------------------------------ | +| `GET /.well-known/oauth-authorization-server` | OAuth server metadata | +| `POST /oauth/par` | Pushed Authorization Request | +| `GET /oauth/authorize` | Authorization endpoint | +| `POST /oauth/authorize` | Process authorization decision | +| `POST /oauth/token` | Token exchange | +| `POST /oauth/revoke` | Token revocation | -See the [@ascorbic/atproto-oauth-provider](../oauth-provider/) package for implementation details. +See the [@getcirrus/oauth-provider](../oauth-provider/) package for implementation details. ## Deploying to Production diff --git a/packages/pds/e2e/fixture/package.json b/packages/pds/e2e/fixture/package.json index e22271c3..3f6900ac 100644 --- a/packages/pds/e2e/fixture/package.json +++ b/packages/pds/e2e/fixture/package.json @@ -7,7 +7,7 @@ "dev": "vite" }, "dependencies": { - "@ascorbic/pds": "{{PDS_PACKAGE_PATH}}" + "@getcirrus/pds": "{{PDS_PACKAGE_PATH}}" }, "devDependencies": { "@cloudflare/vite-plugin": "^1.17.0", diff --git a/packages/pds/e2e/fixture/src/index.ts b/packages/pds/e2e/fixture/src/index.ts index 615f56cc..4dae3ead 100644 --- a/packages/pds/e2e/fixture/src/index.ts +++ b/packages/pds/e2e/fixture/src/index.ts @@ -1 +1 @@ -export { default, AccountDurableObject } from "@ascorbic/pds"; +export { default, AccountDurableObject } from "@getcirrus/pds"; diff --git a/packages/pds/package.json b/packages/pds/package.json index 1d2d6c8c..efaaf9c0 100644 --- a/packages/pds/package.json +++ b/packages/pds/package.json @@ -1,7 +1,7 @@ { - "name": "@ascorbic/pds", + "name": "@getcirrus/pds", "version": "0.2.3", - "description": "AT Protocol PDS on Cloudflare Workers", + "description": "Cirrus – A single-user AT Protocol PDS on Cloudflare Workers", "type": "module", "main": "dist/index.js", "bin": { @@ -22,7 +22,7 @@ "check": "publint && attw --pack --ignore-rules=cjs-resolves-to-esm" }, "dependencies": { - "@ascorbic/atproto-oauth-provider": "workspace:*", + "@getcirrus/oauth-provider": "workspace:*", "@atproto-labs/handle-resolver": "^0.3.4", "@atproto/common-web": "^0.4.7", "@atproto/crypto": "^0.4.5", diff --git a/packages/pds/src/account-do.ts b/packages/pds/src/account-do.ts index 96a70668..22c6e37b 100644 --- a/packages/pds/src/account-do.ts +++ b/packages/pds/src/account-do.ts @@ -1190,7 +1190,7 @@ export class AccountDurableObject extends DurableObject { /** Save an authorization code */ async rpcSaveAuthCode( code: string, - data: import("@ascorbic/atproto-oauth-provider").AuthCodeData, + data: import("@getcirrus/oauth-provider").AuthCodeData, ): Promise { const storage = await this.getOAuthStorage(); await storage.saveAuthCode(code, data); @@ -1199,7 +1199,7 @@ export class AccountDurableObject extends DurableObject { /** Get authorization code data */ async rpcGetAuthCode( code: string, - ): Promise { + ): Promise { const storage = await this.getOAuthStorage(); return storage.getAuthCode(code); } @@ -1212,7 +1212,7 @@ export class AccountDurableObject extends DurableObject { /** Save token data */ async rpcSaveTokens( - data: import("@ascorbic/atproto-oauth-provider").TokenData, + data: import("@getcirrus/oauth-provider").TokenData, ): Promise { const storage = await this.getOAuthStorage(); await storage.saveTokens(data); @@ -1221,7 +1221,7 @@ export class AccountDurableObject extends DurableObject { /** Get token data by access token */ async rpcGetTokenByAccess( accessToken: string, - ): Promise { + ): Promise { const storage = await this.getOAuthStorage(); return storage.getTokenByAccess(accessToken); } @@ -1229,7 +1229,7 @@ export class AccountDurableObject extends DurableObject { /** Get token data by refresh token */ async rpcGetTokenByRefresh( refreshToken: string, - ): Promise { + ): Promise { const storage = await this.getOAuthStorage(); return storage.getTokenByRefresh(refreshToken); } @@ -1249,7 +1249,7 @@ export class AccountDurableObject extends DurableObject { /** Save client metadata */ async rpcSaveClient( clientId: string, - metadata: import("@ascorbic/atproto-oauth-provider").ClientMetadata, + metadata: import("@getcirrus/oauth-provider").ClientMetadata, ): Promise { const storage = await this.getOAuthStorage(); await storage.saveClient(clientId, metadata); @@ -1258,7 +1258,7 @@ export class AccountDurableObject extends DurableObject { /** Get client metadata */ async rpcGetClient( clientId: string, - ): Promise { + ): Promise { const storage = await this.getOAuthStorage(); return storage.getClient(clientId); } @@ -1266,7 +1266,7 @@ export class AccountDurableObject extends DurableObject { /** Save PAR data */ async rpcSavePAR( requestUri: string, - data: import("@ascorbic/atproto-oauth-provider").PARData, + data: import("@getcirrus/oauth-provider").PARData, ): Promise { const storage = await this.getOAuthStorage(); await storage.savePAR(requestUri, data); @@ -1275,7 +1275,7 @@ export class AccountDurableObject extends DurableObject { /** Get PAR data */ async rpcGetPAR( requestUri: string, - ): Promise { + ): Promise { const storage = await this.getOAuthStorage(); return storage.getPAR(requestUri); } diff --git a/packages/pds/src/oauth-storage.ts b/packages/pds/src/oauth-storage.ts index 095b2f30..72063c65 100644 --- a/packages/pds/src/oauth-storage.ts +++ b/packages/pds/src/oauth-storage.ts @@ -4,12 +4,12 @@ import type { OAuthStorage, PARData, TokenData, -} from "@ascorbic/atproto-oauth-provider"; +} from "@getcirrus/oauth-provider"; /** * SQLite-backed OAuth storage for Cloudflare Durable Objects. * - * Implements the OAuthStorage interface from @ascorbic/atproto-oauth-provider, + * Implements the OAuthStorage interface from @getcirrus/oauth-provider, * storing OAuth data in SQLite tables within a Durable Object. */ export class SqliteOAuthStorage implements OAuthStorage { diff --git a/packages/pds/src/oauth.ts b/packages/pds/src/oauth.ts index 6cf6c2f3..917b174c 100644 --- a/packages/pds/src/oauth.ts +++ b/packages/pds/src/oauth.ts @@ -1,20 +1,20 @@ /** * OAuth 2.1 integration for the PDS * - * Connects the @ascorbic/atproto-oauth-provider package with the PDS + * Connects the @getcirrus/oauth-provider package with the PDS * by providing storage through Durable Objects and user authentication * through the existing session system. */ import { Hono } from "hono"; -import { ATProtoOAuthProvider } from "@ascorbic/atproto-oauth-provider"; +import { ATProtoOAuthProvider } from "@getcirrus/oauth-provider"; import type { OAuthStorage, AuthCodeData, TokenData, ClientMetadata, PARData, -} from "@ascorbic/atproto-oauth-provider"; +} from "@getcirrus/oauth-provider"; import { compare } from "bcryptjs"; import type { PDSEnv } from "./types"; import type { AccountDurableObject } from "./account-do"; diff --git a/plans/complete/oauth-provider.md b/plans/complete/oauth-provider.md index 1ef0cb29..bf05daba 100644 --- a/plans/complete/oauth-provider.md +++ b/plans/complete/oauth-provider.md @@ -1,7 +1,7 @@ # OAuth Provider Implementation **Status:** ✅ Complete -**Package:** `@ascorbic/atproto-oauth-provider` +**Package:** `@getcirrus/oauth-provider` ## Overview @@ -9,7 +9,7 @@ OAuth 2.1 provider with AT Protocol extensions enabling "Login with Bluesky" eco ## What Was Built -### Package: `@ascorbic/atproto-oauth-provider` +### Package: `@getcirrus/oauth-provider` A purpose-built OAuth 2.1 provider (not extending Cloudflare's OAuth provider) with: @@ -117,7 +117,7 @@ packages/pds/src/ ## Usage ```typescript -import { ATProtoOAuthProvider } from "@ascorbic/atproto-oauth-provider"; +import { ATProtoOAuthProvider } from "@getcirrus/oauth-provider"; const provider = new ATProtoOAuthProvider({ issuer: "https://your-pds.com", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 846cf773..179e71f4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -32,7 +32,7 @@ importers: demos/pds: dependencies: - '@ascorbic/pds': + '@getcirrus/pds': specifier: workspace:* version: link:../../packages/pds devDependencies: @@ -100,9 +100,6 @@ importers: packages/pds: dependencies: - '@ascorbic/atproto-oauth-provider': - specifier: workspace:* - version: link:../oauth-provider '@atproto-labs/handle-resolver': specifier: ^0.3.4 version: 0.3.4 @@ -133,6 +130,9 @@ importers: '@clack/prompts': specifier: ^0.11.0 version: 0.11.0 + '@getcirrus/oauth-provider': + specifier: workspace:* + version: link:../oauth-provider bcryptjs: specifier: ^3.0.3 version: 3.0.3 @@ -376,7 +376,7 @@ packages: engines: {node: '>=18.0.0'} '@cloudflare/kv-asset-handler@https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/kv-asset-handler@64982d4': - resolution: {tarball: https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/kv-asset-handler@64982d4} + resolution: {integrity: sha512-A1qPBLIb6J9iKy2M8X/ywh4e9jyHsAucJZVPNqCHdHrkeJIUntVfozazCZj9Sdm+rr4om20toCQgoxRPQtlWLQ==, tarball: https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/kv-asset-handler@64982d4} version: 0.4.1 engines: {node: '>=18.0.0'} @@ -390,7 +390,7 @@ packages: optional: true '@cloudflare/unenv-preset@https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/unenv-preset@64982d4': - resolution: {tarball: https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/unenv-preset@64982d4} + resolution: {integrity: sha512-WXbktS8e26BzZjbqQL2syj9UTC4+8zdEIbRQ8hsVxsAp6bES9q9lkyGnreX9Ax/2ENWpc0VFidwq/k3M9MNkqA==, tarball: https://pkg.pr.new/cloudflare/workers-sdk/@cloudflare/unenv-preset@64982d4} version: 2.7.13 peerDependencies: unenv: 2.0.0-rc.24 @@ -406,7 +406,7 @@ packages: wrangler: ^4.53.0 '@cloudflare/vitest-pool-workers@https://pkg.pr.new/@cloudflare/vitest-pool-workers@11632': - resolution: {tarball: https://pkg.pr.new/@cloudflare/vitest-pool-workers@11632} + resolution: {integrity: sha512-bUcBi9IflGaKQGFyxjyluNfZ4Wi+0jJzz2SMwWpHGqTPtfLJqfGv3VhfpecEE2Dir6Vohtn7Frs8uiIVThM9JA==, tarball: https://pkg.pr.new/@cloudflare/vitest-pool-workers@11632} version: 0.11.1 peerDependencies: '@vitest/runner': 4.0.16 @@ -1948,7 +1948,7 @@ packages: hasBin: true miniflare@https://pkg.pr.new/cloudflare/workers-sdk/miniflare@64982d4: - resolution: {tarball: https://pkg.pr.new/cloudflare/workers-sdk/miniflare@64982d4} + resolution: {integrity: sha512-HygCuVJoQbUVyHBGRtvF3LorrbqWavL1R1gXhYJqaenbPYuP2d//2zp3zmYPF2yRkaTzVg/NDqN9BlaU6/btoA==, tarball: https://pkg.pr.new/cloudflare/workers-sdk/miniflare@64982d4} version: 4.20251217.0 engines: {node: '>=18.0.0'} hasBin: true @@ -2613,7 +2613,7 @@ packages: optional: true wrangler@https://pkg.pr.new/cloudflare/workers-sdk/wrangler@64982d4: - resolution: {tarball: https://pkg.pr.new/cloudflare/workers-sdk/wrangler@64982d4} + resolution: {integrity: sha512-x/FjewjH8KL8s4w09157cJOPpY/ovh9fPJQ8VTFA6ncxsi1BZrk/N2aRZqh8l6M2x58z+w4J6VbDtgBkE7pXnA==, tarball: https://pkg.pr.new/cloudflare/workers-sdk/wrangler@64982d4} version: 4.56.0 engines: {node: '>=20.0.0'} hasBin: true