code
Clone this repository
https://tangled.org/chadtmiller.com/pds.js
git@tangled.org:chadtmiller.com/pds.js
For self-hosted knots, clone URLs may differ based on your setup.
Implement full authentication system for ATProto PDS:
- JWT helpers: base64url encode/decode, HMAC-SHA256 signing
- Access tokens (2hr) and refresh tokens (90 days)
- createSession endpoint with password validation
- getSession endpoint with token verification
- Auth middleware protecting write endpoints (createRecord, deleteRecord, putRecord, applyWrites)
- AppView proxy with ES256 service auth for app.bsky.* endpoints
- Local storage for user preferences (getPreferences, putPreferences)
- resolveHandle XRPC endpoint
Refactoring:
- Consolidated 4 CBOR encoders into 2
- Added errorResponse() helper for consistent ATProto error format
- Extracted handleAuthenticatedRepoWrite() to reduce duplication
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements record deletion with proper ATProto event emission:
- Removes record from database and rebuilds MST
- Creates signed commit with updated repo state
- Emits delete event to firehose for relay/indexer propagation
- Routes POST requests with repo in body to correct Durable Object
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
ATProto MST spec: "Layers are counted from the bottom of the tree,
starting with zero." This means:
- Layer 0 is at the BOTTOM
- Root is at the HIGHEST layer (max depth of any key)
- Subtrees go DOWN to lower layers
Previous implementation had this inverted, causing "depths are out of
order" validation errors in pdsls.
Also includes:
- MST nodes must include l and t fields (even when null) per ATProto schema
- handleGetRepo now only includes blocks reachable from current commit
馃 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>