this repo has no description
1# PDS Implementation TODOs
2
3Lewis' corrected big boy todofile
4
5## Server Infrastructure & Proxying
6- [x] Health Check
7 - [x] Implement `GET /health` endpoint (returns "OK").
8 - [x] Implement `GET /xrpc/_health` endpoint (returns "OK").
9- [x] Server Description
10 - [x] Implement `com.atproto.server.describeServer` (returns available user domains).
11- [x] XRPC Proxying
12 - [x] Implement strict forwarding for all `app.bsky.*` and `chat.bsky.*` requests to an appview.
13 - [x] Forward auth headers correctly.
14 - [x] Handle appview errors/timeouts gracefully.
15
16## Authentication & Account Management (`com.atproto.server`)
17- [x] Account Creation
18 - [x] Implement `com.atproto.server.createAccount`.
19 - [x] Validate handle format (reject invalid characters).
20 - [x] Create DID for new user (PLC directory).
21 - [x] Initialize user repository (Root commit).
22 - [x] Return access JWT and DID.
23 - [x] Create DID for new user (did:web).
24- [x] Session Management
25 - [x] Implement `com.atproto.server.createSession` (Login).
26 - [x] Implement `com.atproto.server.getSession`.
27 - [x] Implement `com.atproto.server.refreshSession`.
28 - [x] Implement `com.atproto.server.deleteSession` (Logout).
29 - [x] Implement `com.atproto.server.activateAccount`.
30 - [x] Implement `com.atproto.server.checkAccountStatus`.
31 - [x] Implement `com.atproto.server.createAppPassword`.
32 - [x] Implement `com.atproto.server.createInviteCode`.
33 - [x] Implement `com.atproto.server.createInviteCodes`.
34 - [x] Implement `com.atproto.server.deactivateAccount`.
35 - [x] Implement `com.atproto.server.deleteAccount` (user-initiated, requires password + email token).
36 - [x] Implement `com.atproto.server.getAccountInviteCodes`.
37 - [x] Implement `com.atproto.server.getServiceAuth` (Cross-service auth).
38 - [x] Implement `com.atproto.server.listAppPasswords`.
39 - [x] Implement `com.atproto.server.requestAccountDelete`.
40 - [x] Implement `com.atproto.server.requestEmailConfirmation` / `requestEmailUpdate`.
41 - [x] Implement `com.atproto.server.requestPasswordReset` / `resetPassword`.
42 - [x] Implement `com.atproto.server.reserveSigningKey`.
43 - [x] Implement `com.atproto.server.revokeAppPassword`.
44 - [x] Implement `com.atproto.server.updateEmail`.
45 - [x] Implement `com.atproto.server.confirmEmail`.
46
47## Repository Operations (`com.atproto.repo`)
48- [x] Record CRUD
49 - [x] Implement `com.atproto.repo.createRecord`.
50 - [x] Generate `rkey` (TID) if not provided.
51 - [x] Handle MST (Merkle Search Tree) insertion.
52 - [x] **Trigger Firehose Event**.
53 - [x] Implement `com.atproto.repo.putRecord`.
54 - [x] Implement `com.atproto.repo.getRecord`.
55 - [x] Implement `com.atproto.repo.deleteRecord`.
56 - [x] Implement `com.atproto.repo.listRecords`.
57 - [x] Implement `com.atproto.repo.describeRepo`.
58 - [x] Implement `com.atproto.repo.applyWrites` (Batch writes).
59 - [x] Implement `com.atproto.repo.importRepo` (Migration).
60 - [x] Implement `com.atproto.repo.listMissingBlobs`.
61- [x] Blob Management
62 - [x] Implement `com.atproto.repo.uploadBlob`.
63 - [x] Store blob (S3).
64 - [x] return `blob` ref (CID + MimeType).
65
66## Sync & Federation (`com.atproto.sync`)
67- [x] The Firehose (WebSocket)
68 - [x] Implement `com.atproto.sync.subscribeRepos`.
69 - [x] Broadcast real-time commit events.
70 - [x] Handle cursor replay (backfill).
71- [x] Bulk Export
72 - [x] Implement `com.atproto.sync.getRepo` (Return full CAR file of repo).
73 - [x] Implement `com.atproto.sync.getBlocks` (Return specific blocks via CIDs).
74 - [x] Implement `com.atproto.sync.getLatestCommit`.
75 - [x] Implement `com.atproto.sync.getRecord` (Sync version, distinct from repo.getRecord).
76 - [x] Implement `com.atproto.sync.getRepoStatus`.
77 - [x] Implement `com.atproto.sync.listRepos`.
78 - [x] Implement `com.atproto.sync.notifyOfUpdate`.
79- [x] Blob Sync
80 - [x] Implement `com.atproto.sync.getBlob`.
81 - [x] Implement `com.atproto.sync.listBlobs`.
82- [x] Crawler Interaction
83 - [x] Implement `com.atproto.sync.requestCrawl` (Notify relays to index us).
84- [x] Deprecated Sync Endpoints (for compatibility)
85 - [x] Implement `com.atproto.sync.getCheckout` (deprecated).
86 - [x] Implement `com.atproto.sync.getHead` (deprecated).
87
88## Identity (`com.atproto.identity`)
89- [x] Resolution
90 - [x] Implement `com.atproto.identity.resolveHandle` (Can be internal or proxy to PLC).
91 - [x] Implement `com.atproto.identity.updateHandle`.
92 - [x] Implement `com.atproto.identity.submitPlcOperation` / `signPlcOperation` / `requestPlcOperationSignature`.
93 - [x] Implement `com.atproto.identity.getRecommendedDidCredentials`.
94 - [x] Implement `/.well-known/did.json` (Depends on supporting did:web).
95
96## Admin Management (`com.atproto.admin`)
97- [x] Implement `com.atproto.admin.deleteAccount`.
98- [x] Implement `com.atproto.admin.disableAccountInvites`.
99- [x] Implement `com.atproto.admin.disableInviteCodes`.
100- [x] Implement `com.atproto.admin.enableAccountInvites`.
101- [x] Implement `com.atproto.admin.getAccountInfo` / `getAccountInfos`.
102- [x] Implement `com.atproto.admin.getInviteCodes`.
103- [x] Implement `com.atproto.admin.getSubjectStatus`.
104- [x] Implement `com.atproto.admin.sendEmail`.
105- [x] Implement `com.atproto.admin.updateAccountEmail`.
106- [x] Implement `com.atproto.admin.updateAccountHandle`.
107- [x] Implement `com.atproto.admin.updateAccountPassword`.
108- [x] Implement `com.atproto.admin.updateSubjectStatus`.
109
110## Moderation (`com.atproto.moderation`)
111- [x] Implement `com.atproto.moderation.createReport`.
112
113## Temp Namespace (`com.atproto.temp`)
114- [x] Implement `com.atproto.temp.checkSignupQueue` (signup queue status for gated signups).
115
116## Misc HTTP Endpoints
117- [x] Implement `/robots.txt` endpoint.
118
119## OAuth 2.1 Support
120Full OAuth 2.1 provider for ATProto native app authentication.
121- [x] OAuth Provider Core
122 - [x] Implement `/.well-known/oauth-protected-resource` metadata endpoint.
123 - [x] Implement `/.well-known/oauth-authorization-server` metadata endpoint.
124 - [x] Implement `/oauth/authorize` authorization endpoint (with login UI).
125 - [x] Implement `/oauth/par` Pushed Authorization Request endpoint.
126 - [x] Implement `/oauth/token` token endpoint (authorization_code + refresh_token grants).
127 - [x] Implement `/oauth/jwks` JSON Web Key Set endpoint.
128 - [x] Implement `/oauth/revoke` token revocation endpoint.
129 - [x] Implement `/oauth/introspect` token introspection endpoint.
130- [x] OAuth Database Tables
131 - [x] Device table for tracking authorized devices.
132 - [x] Authorization request table.
133 - [x] Authorized client table.
134 - [x] Token table for OAuth tokens.
135 - [x] Used refresh token table (replay protection).
136 - [x] DPoP JTI tracking table.
137- [x] DPoP (Demonstrating Proof-of-Possession) support.
138- [x] Client metadata fetching and validation.
139- [x] PKCE (S256) enforcement.
140- [x] OAuth token verification extractor for protected resources.
141- [x] Authorization UI templates (HTML login form).
142- [x] Implement `private_key_jwt` signature verification with async JWKS fetching.
143- [x] HS256 JWT support (matches reference PDS).
144
145## OAuth Security Notes
146
147Security measures implemented:
148
149- Constant-time comparison for signature verification (prevents timing attacks)
150- HMAC-SHA256 for access token signing with configurable secret
151- Production secrets require 32+ character minimum
152- DPoP JTI replay protection via database
153- DPoP nonce validation with HMAC-based timestamps (5 min validity)
154- Refresh token rotation with reuse detection (revokes token family on reuse)
155- PKCE S256 enforced (plain not allowed)
156- Authorization code single-use enforcement
157- URL encoding for redirect parameters (prevents injection)
158- All database queries use parameterized statements (no SQL injection)
159- Deactivated/taken-down accounts blocked from OAuth authorization
160- Client ID validation on token exchange (defense-in-depth against cross-client attacks)
161- HTML escaping in OAuth templates (XSS prevention)
162
163### Auth Notes
164- Dual algorithm support: ES256K (secp256k1 ECDSA) with per-user keys AND HS256 (HMAC) for compatibility with reference PDS.
165- Token storage: Storing only token JTIs in session_tokens table (defense in depth against DB breaches). Refresh token family tracking enables detection of token reuse attacks.
166- Key encryption: User signing keys encrypted at rest using AES-256-GCM with keys derived via HKDF from KEY_ENCRYPTION_KEY environment variable.
167
168## PDS-Level App Endpoints
169These endpoints need to be implemented at the PDS level (not just proxied to appview).
170
171### Actor (`app.bsky.actor`)
172- [x] Implement `app.bsky.actor.getPreferences` (user preferences storage).
173- [x] Implement `app.bsky.actor.putPreferences` (update user preferences).
174- [x] Implement `app.bsky.actor.getProfile` (PDS-level with proxy fallback).
175- [x] Implement `app.bsky.actor.getProfiles` (PDS-level with proxy fallback).
176
177### Feed (`app.bsky.feed`)
178These are implemented at PDS level to enable local-first reads (read-after-write pattern):
179- [x] Implement `app.bsky.feed.getTimeline` (PDS-level with proxy + RAW).
180- [x] Implement `app.bsky.feed.getAuthorFeed` (PDS-level with proxy + RAW).
181- [x] Implement `app.bsky.feed.getActorLikes` (PDS-level with proxy + RAW).
182- [x] Implement `app.bsky.feed.getPostThread` (PDS-level with proxy + RAW + NotFound handling).
183- [x] Implement `app.bsky.feed.getFeed` (proxy to feed generator).
184
185### Notification (`app.bsky.notification`)
186- [x] Implement `app.bsky.notification.registerPush` (push notification registration, proxied).
187
188## Infrastructure & Core Components
189- [x] Sequencer (Event Log)
190 - [x] Implement a `Sequencer` (backed by `repo_seq` table).
191 - [x] Implement event formatting (`commit`, `handle`, `identity`, `account`).
192 - [x] Implement database polling / event emission mechanism.
193 - [x] Implement cursor-based event replay (`requestSeqRange`).
194- [x] Repo Storage & Consistency (in postgres)
195 - [x] Implement `RepoStorage` for postgres (replaces per-user SQLite).
196 - [x] Read/Write IPLD blocks to `blocks` table (global deduplication).
197 - [x] Manage Repo Root in `repos` table.
198 - [x] Implement Atomic Repo Transactions.
199 - [x] Ensure `blocks` write, `repo_root` update, `records` index update, and `sequencer` event are committed in a single transaction.
200 - [x] Implement concurrency control (row-level locking via FOR UPDATE).
201- [ ] DID Cache
202 - [ ] Implement caching layer for DID resolution (Redis or in-memory).
203 - [ ] Handle cache invalidation/expiry.
204- [x] Crawlers Service
205 - [x] Implement `Crawlers` service (debounce notifications to relays).
206 - [x] 20-minute notification debounce.
207 - [x] Circuit breaker for relay failures.
208- [x] Notification Service
209 - [x] Queue-based notification system with database table
210 - [x] Background worker polling for pending notifications
211 - [x] Extensible sender trait for multiple channels
212 - [x] Email sender via OS sendmail/msmtp
213 - [x] Discord webhook sender
214 - [x] Telegram bot sender
215 - [x] Signal CLI sender
216 - [x] Helper functions for common notification types (welcome, password reset, email verification, etc.)
217 - [x] Respect user's `preferred_notification_channel` setting for non-email-specific notifications
218- [x] Image Processing
219 - [x] Implement image resize/formatting pipeline (for blob uploads).
220 - [x] WebP conversion for thumbnails.
221 - [x] EXIF stripping.
222 - [x] File size limits (10MB default).
223- [x] IPLD & MST
224 - [x] Implement Merkle Search Tree logic for repo signing.
225 - [x] Implement CAR (Content Addressable Archive) encoding/decoding.
226 - [x] Cycle detection in CAR export.
227- [x] Rate Limiting
228 - [x] Per-IP rate limiting on login (10/min).
229 - [x] Per-IP rate limiting on OAuth token endpoint (30/min).
230 - [x] Per-IP rate limiting on password reset (5/hour).
231 - [x] Per-IP rate limiting on account creation (10/hour).
232- [x] Circuit Breakers
233 - [x] PLC directory circuit breaker (5 failures → open, 60s timeout).
234 - [x] Relay notification circuit breaker (10 failures → open, 30s timeout).
235- [x] Security Hardening
236 - [x] Email header injection prevention (CRLF sanitization).
237 - [x] Signal command injection prevention (phone number validation).
238 - [x] Constant-time signature comparison.
239 - [x] SSRF protection for outbound requests.
240
241## Lewis' fabulous mini-list of remaining TODOs
242- [ ] DID resolution caching (valkey).
243- [ ] Record schema validation (generic validation framework).
244- [ ] Fix any remaining TODOs in the code.
245
246## Future: Web Management UI
247A single-page web app for account management. The frontend (JS framework) calls existing ATProto XRPC endpoints - no server-side rendering or bespoke HTML form handlers.
248
249### Architecture
250- [ ] Static SPA served from PDS (or separate static host)
251- [ ] Frontend authenticates via OAuth 2.1 flow (same as any ATProto client)
252- [ ] All operations use standard XRPC endpoints (existing + new PDS-specific ones below)
253- [ ] No server-side sessions or CSRF - pure API client
254
255### PDS-Specific XRPC Endpoints (new)
256Absolutely subject to change, "bspds" isn't even the real name of this pds thus far :D
257Anyway... endpoints for PDS settings not covered by standard ATProto:
258- [ ] `com.bspds.account.getNotificationPrefs` - get preferred channel, verified channels
259- [ ] `com.bspds.account.updateNotificationPrefs` - set preferred channel
260- [ ] `com.bspds.account.getNotificationHistory` - list past notifications
261- [ ] `com.bspds.account.verifyChannel` - initiate verification for Discord/Telegram/Signal
262- [ ] `com.bspds.account.confirmChannelVerification` - confirm with code
263- [ ] `com.bspds.admin.getServerStats` - user count, storage usage, etc.
264
265### Frontend Views
266Uses existing ATProto endpoints where possible:
267
268User Dashboard
269- [ ] Account overview (uses `com.atproto.server.getSession`, `com.atproto.admin.getAccountInfo`)
270- [ ] Active sessions view (needs new endpoint or extend existing)
271- [ ] App passwords (uses `com.atproto.server.listAppPasswords`, `createAppPassword`, `revokeAppPassword`)
272- [ ] Invite codes (uses `com.atproto.server.getAccountInviteCodes`, `createInviteCode`)
273
274Notification Preferences
275- [ ] Channel selector (uses `com.bspds.account.*` endpoints above)
276- [ ] Verification flows for Discord/Telegram/Signal
277- [ ] Notification history view
278
279Account Settings
280- [ ] Email change (uses `com.atproto.server.requestEmailUpdate`, `updateEmail`)
281- [ ] Password change (uses `com.atproto.server.requestPasswordReset`, `resetPassword`)
282- [ ] Handle change (uses `com.atproto.identity.updateHandle`)
283- [ ] Account deletion (uses `com.atproto.server.requestAccountDelete`, `deleteAccount`)
284- [ ] Data export (uses `com.atproto.sync.getRepo`)
285
286Admin Dashboard (privileged users only)
287- [ ] User list (uses `com.atproto.admin.getAccountInfos` with pagination)
288- [ ] User detail/actions (uses `com.atproto.admin.*` endpoints)
289- [ ] Invite management (uses `com.atproto.admin.getInviteCodes`, `disableInviteCodes`)
290- [ ] Server stats (uses `com.bspds.admin.getServerStats`)
291