commits
When concurrent requests trigger token refresh simultaneously across
different isolates (e.g., Val Town, Deno Deploy), the second request
would fail with 'Refresh token replayed' error.
Now gracefully handles this by:
- Detecting the 'replayed' error from OAuth servers
- Waiting briefly for the other process to save
- Re-reading the session from storage to get fresh tokens
Also adds:
- errorDescription field on TokenExchangeError
- Proper JSON parsing of OAuth error responses
- @panva/jose: ^6.1.0 → 6.1.0
- @std/assert: 1 → 1.0.13
Improves reproducibility by locking to exact dependency versions.
Breaking Changes:
- restore() now throws errors instead of returning null
- Removed unused API parameters (signal, CallbackOptions)
New Features:
- Configurable logging system (Logger interface, NoOpLogger, ConsoleLogger)
- Dual concurrency locks (restore + refresh operations)
- New modules: pkce.ts, token-exchange.ts, logger.ts
Improvements:
- Removed all type assertions, added runtime validation
- Deduplicated DPoP retry logic
- Better code organization (all files <700 lines)
- Enhanced error handling with typed errors
See CHANGELOG.md for migration guide.
- Move all external dependencies to imports section in deno.json
- Update all import statements to use import map aliases
- Regenerate deno.lock with new dependency configuration
- Improves dependency management for JSR package
- BREAKING: restore() now throws typed errors instead of returning null
- Add SessionNotFoundError, RefreshTokenExpiredError, RefreshTokenRevokedError, NetworkError
- Add comprehensive error logging throughout session restoration and token refresh
- Improve error visibility and classification for better debugging
Changes the GitHub workflow to use git ls-files to only check tracked
files during formatting, linting, and type checking. This prevents
untracked or ignored files from causing CI failures.
Prevents race conditions when multiple concurrent requests try to restore
the same session during token refresh. Concurrent requests now wait for and
share the result of the first refresh operation instead of triggering
multiple simultaneous refreshes.
- Add per-session lock manager to OAuthClient
- Locks are per-DID, preventing cross-user blocking
- Automatic lock cleanup when restore completes
- Enhanced JSDoc documentation
- Zero breaking changes
Fixes intermittent "OAuth session not found" errors in multi-endpoint
applications when sessions expire.
- Add Ko-fi badge at top of README
- Add Support Development section with Ko-fi link
- Create .claude/CLAUDE.md with architecture and development guidance
BREAKING CHANGES:
- Add required `pdsUrl` property to `OAuthSession` interface for consistency with hono-oauth-sessions v0.3.0
This enhances type compatibility across the AT Protocol OAuth ecosystem but requires
existing implementations to provide the pdsUrl property. The Session class already
includes this property via its getter, so no implementation changes are needed.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
ECDSA private keys should only have "sign" capability, not "verify".
The "verify" operation is only valid for public keys. This fixes the
persistent "Invalid key usage" error in Web Crypto API.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The jose library's exportJWK function adds key_ops fields that can conflict
with Web Crypto API's strict key usage validation. This fix creates a clean
JWK containing only the essential fields before import.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
Ensures compatibility with hono-oauth-sessions SessionInterface
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add detailed JSDoc comments to all error classes with examples
- Enhance resolver class documentation with usage patterns
- Improve client method documentation with comprehensive examples
- Add JSDoc to all exported functions with parameter descriptions
- Follow JSR documentation best practices for symbol documentation
- Improve developer experience with rich IDE support
This should significantly improve the JSR documentation score by providing
comprehensive documentation for all public symbols.
- Auto-format table alignment to meet linting standards
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Document breaking API changes for @atproto compatibility
- Note documentation improvements and Bun compatibility
- Clarify positioning as handle-focused alternative
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Moved design choices to single prominent section at top
- Removed repetitive messaging throughout document
- Clarified positioning as handle-focused alternative
- Simplified comparison table
- Removed redundant choose-this-package messaging
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated README to clearly state handle-focused design
- Added comparison table with @atproto/oauth-client-node
- Clarified input limitations (handles only, not DIDs/URLs)
- Updated package description to be honest about scope
- This prevents confusion about compatibility expectations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
BREAKING CHANGES:
- authorize() now returns URL instead of string
- callback() now takes URLSearchParams instead of object
- callback() return format changed to { session: OAuthSession, state: string | null }
- Session class now implements OAuthSession interface with sub/aud properties
- Removed legacy interfaces (AuthorizationUrlOptions, CallbackParams, CallbackResult)
- Added AuthorizeOptions, CallbackOptions to match @atproto exactly
This makes @tijs/oauth-client-deno a 100% drop-in replacement for @atproto/oauth-client-node
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix token exchange to check for 400 status instead of 401
- Fix refresh token to check for 400 status instead of 401
- Use correct DPoP-Nonce header name (case sensitive)
- Follows AT Protocol OAuth specification correctly
- Resolves "use_dpop_nonce" error in token exchange
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove "for now" commented code
- Make auth server discovery errors explicit
- Add proper fallback behavior in PDS discovery
- Cleaner error propagation with better user experience
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix authentication server discovery endpoint
- Add proper OAuth metadata discovery flow
- Improve error messages for custom domain setups
- Bump version to 0.1.1
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
When concurrent requests trigger token refresh simultaneously across
different isolates (e.g., Val Town, Deno Deploy), the second request
would fail with 'Refresh token replayed' error.
Now gracefully handles this by:
- Detecting the 'replayed' error from OAuth servers
- Waiting briefly for the other process to save
- Re-reading the session from storage to get fresh tokens
Also adds:
- errorDescription field on TokenExchangeError
- Proper JSON parsing of OAuth error responses
Breaking Changes:
- restore() now throws errors instead of returning null
- Removed unused API parameters (signal, CallbackOptions)
New Features:
- Configurable logging system (Logger interface, NoOpLogger, ConsoleLogger)
- Dual concurrency locks (restore + refresh operations)
- New modules: pkce.ts, token-exchange.ts, logger.ts
Improvements:
- Removed all type assertions, added runtime validation
- Deduplicated DPoP retry logic
- Better code organization (all files <700 lines)
- Enhanced error handling with typed errors
See CHANGELOG.md for migration guide.
- BREAKING: restore() now throws typed errors instead of returning null
- Add SessionNotFoundError, RefreshTokenExpiredError, RefreshTokenRevokedError, NetworkError
- Add comprehensive error logging throughout session restoration and token refresh
- Improve error visibility and classification for better debugging
Prevents race conditions when multiple concurrent requests try to restore
the same session during token refresh. Concurrent requests now wait for and
share the result of the first refresh operation instead of triggering
multiple simultaneous refreshes.
- Add per-session lock manager to OAuthClient
- Locks are per-DID, preventing cross-user blocking
- Automatic lock cleanup when restore completes
- Enhanced JSDoc documentation
- Zero breaking changes
Fixes intermittent "OAuth session not found" errors in multi-endpoint
applications when sessions expire.
BREAKING CHANGES:
- Add required `pdsUrl` property to `OAuthSession` interface for consistency with hono-oauth-sessions v0.3.0
This enhances type compatibility across the AT Protocol OAuth ecosystem but requires
existing implementations to provide the pdsUrl property. The Session class already
includes this property via its getter, so no implementation changes are needed.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
The jose library's exportJWK function adds key_ops fields that can conflict
with Web Crypto API's strict key usage validation. This fix creates a clean
JWK containing only the essential fields before import.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add detailed JSDoc comments to all error classes with examples
- Enhance resolver class documentation with usage patterns
- Improve client method documentation with comprehensive examples
- Add JSDoc to all exported functions with parameter descriptions
- Follow JSR documentation best practices for symbol documentation
- Improve developer experience with rich IDE support
This should significantly improve the JSR documentation score by providing
comprehensive documentation for all public symbols.
- Document breaking API changes for @atproto compatibility
- Note documentation improvements and Bun compatibility
- Clarify positioning as handle-focused alternative
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Moved design choices to single prominent section at top
- Removed repetitive messaging throughout document
- Clarified positioning as handle-focused alternative
- Simplified comparison table
- Removed redundant choose-this-package messaging
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Updated README to clearly state handle-focused design
- Added comparison table with @atproto/oauth-client-node
- Clarified input limitations (handles only, not DIDs/URLs)
- Updated package description to be honest about scope
- This prevents confusion about compatibility expectations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
BREAKING CHANGES:
- authorize() now returns URL instead of string
- callback() now takes URLSearchParams instead of object
- callback() return format changed to { session: OAuthSession, state: string | null }
- Session class now implements OAuthSession interface with sub/aud properties
- Removed legacy interfaces (AuthorizationUrlOptions, CallbackParams, CallbackResult)
- Added AuthorizeOptions, CallbackOptions to match @atproto exactly
This makes @tijs/oauth-client-deno a 100% drop-in replacement for @atproto/oauth-client-node
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Fix token exchange to check for 400 status instead of 401
- Fix refresh token to check for 400 status instead of 401
- Use correct DPoP-Nonce header name (case sensitive)
- Follows AT Protocol OAuth specification correctly
- Resolves "use_dpop_nonce" error in token exchange
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>