A zero-dependency AT Protocol Personal Data Server written in JavaScript
atproto
pds
1# Changelog
2
3All notable changes to this project will be documented in this file.
4
5The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
7## [Unreleased]
8
9## [0.5.0] - 2026-01-08
10
11### Added
12
13- **Direct OAuth authorization** without requiring Pushed Authorization Requests (PAR)
14 - `/oauth/authorize` now accepts direct query parameters (client_id, redirect_uri, code_challenge, etc.)
15 - Creates authorization request record on-the-fly, same as PAR flow
16 - DPoP binding deferred to token exchange time for direct auth flows
17 - Matches official AT Protocol PDS behavior
18
19### Changed
20
21- AS metadata: `require_pushed_authorization_requests` now `false`
22- Extracted `validateAuthorizationParameters()` helper shared between PAR and direct auth
23
24## [0.4.0] - 2026-01-08
25
26### Added
27
28- **Foreign DID proxying** via `atproto-proxy` header
29 - `parseAtprotoProxyHeader()` parses `did:web:api.bsky.app#bsky_appview` format
30 - `getKnownServiceUrl()` maps known service DIDs to URLs
31 - `proxyToService()` generic proxy utility with header forwarding
32 - Repo endpoints (getRecord, listRecords, describeRepo) support explicit proxying
33 - Returns appropriate errors for malformed headers or unknown services
34- Unit tests for proxy utilities
35- E2E tests for foreign DID proxying behavior
36
37### Changed
38
39- Refactored `handleAppViewProxy` to use shared `proxyToService` utility
40
41## [0.3.0] - 2026-01-08
42
43### Added
44
45- **Granular OAuth scope enforcement** on repo and blob endpoints
46 - `parseRepoScope()` parses `repo:collection?action=create&action=update` format
47 - `parseBlobScope()` parses `blob:image/*` format with MIME wildcards
48 - `ScopePermissions` class for checking repo/blob permissions
49 - Enforced on createRecord, putRecord, deleteRecord, applyWrites, uploadBlob
50- **Consent page permissions table** displaying scopes in human-readable format
51 - Identity-only: "wants to uniquely identify you" message
52 - Granular scopes: Table with Collection + Create/Update/Delete columns
53 - Full access: Warning banner for `transition:generic`
54- `parseScopesForDisplay()` helper for consent page rendering
55- E2E tests for scope enforcement and consent page display
56
57## [0.2.0] - 2026-01-07
58
59### Added
60
61- **OAuth 2.0 authorization server** with full AT Protocol support
62 - Discovery endpoints (AS metadata, protected resource, JWKS)
63 - Pushed Authorization Requests (PAR)
64 - Authorization endpoint with dark-themed consent UI
65 - Token endpoint (authorization_code + refresh_token grants)
66 - Token revocation (RFC 7009)
67 - DPoP proof validation and token binding
68 - PKCE with S256 code challenge
69 - Client metadata fetching and validation
70 - Loopback client support for development
71- DPoP JTI tracking to prevent replay attacks
72- Comprehensive OAuth e2e tests
73
74### Changed
75
76- **BREAKING:** Normalized SQL schema to snake_case convention
77 - Tables: `blob` → `blobs`, `record_blob` → `record_blobs`
78 - Columns: `mimeType` → `mime_type`, `createdAt` → `created_at`, `blobCid` → `blob_cid`, `recordUri` → `record_uri`
79 - Existing Durable Objects require storage reset
80- Consolidated error responses to use `errorResponse` helper
81- Moved OAuth types to TYPES & CONSTANTS section
82
83## [0.1.0] - 2025-01-07
84
85Initial experimental release.
86
87### Added
88
89- **Repo operations:** createRecord, getRecord, putRecord, deleteRecord, applyWrites, listRecords
90- **Sync endpoints:** getRepo (CAR export), subscribeRepos (WebSocket firehose), getLatestCommit
91- **Authentication:** createSession, getSession, refreshSession with JWT tokens
92- **Blob storage:** uploadBlob, getBlob, listBlobs with R2 backend
93 - MIME type sniffing (JPEG, PNG, GIF, WebP, MP4, AVIF, HEIC)
94 - Automatic orphaned blob cleanup via DO alarms
95 - Blob-record association tracking
96- **Identity:** Handle resolution, PLC directory registration
97- **Federation:** Relay notification (requestCrawl), AppView proxy for app.bsky.* endpoints
98- **Infrastructure:**
99 - Merkle Search Tree (MST) for repo structure
100 - DAG-CBOR encoding with CID generation
101 - P-256 ECDSA signing via Web Crypto
102 - TypeScript checking via JSDoc annotations
103 - Setup script for key generation and PLC registration