commits
- Add cleanup_inactive_user_follows() function to remove follows for users who haven't accessed the feed
- Runs every 5 minutes in the cleanup task
- Removes follows for any user not in active_users table (7 day window)
- Prevents storing unnecessary follow data for the entire Bluesky network
Follows should persist until user unfollows - they don't have a TTL.
Only posts should be cleaned up after 48 hours.
This fixes the issue where the cleanup task was deleting millions of
follows every 5 minutes, causing the feed to appear empty.
- Enable WAL (Write-Ahead Logging) mode to allow concurrent reads/writes
- Set busy_timeout to 5 seconds to reduce lock errors
- This fixes database lock issues caused by backfill competing with Jetstream
- Add active_users table to track users who have accessed the feed
- Record feed requests and only verify follows for active users (last 7 days)
- Run cleanup every 5 minutes for active users instead of all users
- This prevents database locks from verifying thousands of inactive users
- Run cleanup task every 5 minutes (instead of hourly)
- Verify all follows against Bluesky API and remove stale ones
- Clean up posts and follows older than 48 hours
- Add logging for cleanup operations
This ensures unfollows are properly reflected even if Jetstream
events are missed or delayed.
Log the number of posts returned when generating feed to help debug
issues with unfollows not reflecting in the feed.
Log when posts and follows are successfully deleted from the database,
not just when deletions fail. This helps with debugging and monitoring
unfollow events.
Closes #3
Major improvements:
- Added table of contents for easy navigation
- Enhanced Features section with emojis and clearer descriptions
- Added 'How It Works' section explaining the system flow
- Comprehensive installation and configuration guide
- Detailed deployment section with systemd service and reverse proxy configs
- Complete publishing guide with both CLI and manual methods
- Architecture diagrams and code structure documentation
- Full API endpoint documentation with examples
- Performance metrics and scalability information
- Expanded troubleshooting section with solutions
- Development guidelines and contribution instructions
- Enhanced resource links and acknowledgments
The README now provides everything needed to:
- Understand the project and its architecture
- Set up and run the feed generator locally
- Deploy to production with proper configuration
- Publish feeds to Bluesky
- Troubleshoot common issues
- Contribute to the project
Bump tower from 0.4.13 to 0.5.2
Bumps [tower](https://github.com/tower-rs/tower) from 0.4.13 to 0.5.2.
- [Release notes](https://github.com/tower-rs/tower/releases)
- [Commits](https://github.com/tower-rs/tower/compare/tower-0.4.13...tower-0.5.2)
---
updated-dependencies:
- dependency-name: tower
dependency-version: 0.5.2
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Bump tower-http from 0.5.2 to 0.6.6
Bump axum from 0.7.9 to 0.8.6
Bumps [axum](https://github.com/tokio-rs/axum) from 0.7.9 to 0.8.6.
- [Release notes](https://github.com/tokio-rs/axum/releases)
- [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.7.9...axum-v0.8.6)
---
updated-dependencies:
- dependency-name: axum
dependency-version: 0.8.6
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps [tower-http](https://github.com/tower-rs/tower-http) from 0.5.2 to 0.6.6.
- [Release notes](https://github.com/tower-rs/tower-http/releases)
- [Commits](https://github.com/tower-rs/tower-http/compare/tower-http-0.5.2...tower-http-0.6.6)
---
updated-dependencies:
- dependency-name: tower-http
dependency-version: 0.6.6
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Bump reqwest from 0.11.27 to 0.12.23
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.11.27 to 0.12.23.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.11.27...v0.12.23)
---
updated-dependencies:
- dependency-name: reqwest
dependency-version: 0.12.23
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Potential fix for code scanning alert no. 1: Workflow does not contain permissions
Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com>
Fixes CVE-2023-43669 (GHSA-9mcr-873m-xcxp) - HIGH severity
The vulnerability in tungstenite <= 0.20.0 allows remote attackers to
cause denial of service via excessive HTTP header length during client
handshake, causing minutes of CPU consumption.
Changes:
- Updated tokio-tungstenite from 0.18 to 0.28
- Updated tungstenite from 0.18.0 to 0.28.0
- Removed unnecessary url::Url import and parsing
- API change: connect_async now accepts &str directly
For binary applications, Cargo.lock should be committed to ensure
reproducible builds and allow dependency scanning tools like Dependabot
to detect the exact versions in use.
Fixes GHSA-xmrp-424f-vfpx (CVE for protocol-level SQL injection)
The vulnerability affects sqlx <= 0.8.0 where encoding values larger
than 4GiB can cause the length prefix in the protocol to overflow.
Updated from 0.7.4 to 0.8.6 which includes the fix.
Closes #2
- Add full GPLv3 license text
- Update README.md to reference GPLv3 instead of MIT
- Ensures code remains free and open source
Closes #1
- Add full ES256K signature verification using atrium-crypto
- Resolve issuer DID documents via atrium-identity
- Extract and verify publicKeyMultibase from #atproto verification method
- Convert keys to did:key format for signature verification
- Update atrium-xrpc-client to v0.5 for compatibility
- Remove explicit atrium-api dependency (pulled transitively)
Security impact: Prevents JWT forgery attacks by cryptographically
verifying that tokens are signed by the issuer's private key.
- Add .pre-commit-config.yaml with fmt and clippy hooks
- Fix all clippy warnings (use first().copied(), allow dead_code)
- Remove unused imports
- Format all code with rustfmt
The atproto-jetstream library was connecting but not receiving any events.
Replaced with simpler, proven approach using tokio-tungstenite directly
based on the rsky implementation.
- Created admin_socket module with command interface
- Commands: backfill <did>, stats, help, quit
- Socket path configurable via ADMIN_SOCKET env var
- Default socket: /var/run/noreposts-feed.sock
- Added admin.sh helper script for easy connection
- Allows manual backfill triggering and stats monitoring
- Wrap Jetstream consumer in retry loop
- Automatically reconnect after 5 seconds on error
- Log reconnection attempts for monitoring
- Fixes issue where feed stops updating after connection timeout
- Changed ORDER BY from indexed_at to created_at for chronological order
- Updated cursor to use created_at for pagination consistency
- Posts now appear in reverse chronological order (newest first)
- created_at is the original post timestamp from Bluesky
- Fetch recent posts from each followed account (10 posts per user)
- Skip reposts during backfill (check for 'reason' and 'subject' fields)
- Backfill posts after follows are fetched
- Add 100ms delay between requests to avoid rate limiting
- Use public.api.bsky.app getAuthorFeed endpoint
- Created backfill module to fetch existing follows from Bluesky API
- Automatically backfill follows when user has none in database
- Uses public.api.bsky.app to fetch follow list
- Runs backfill in background task to not block feed response
- Make database pool public for backfill access
- Add step to copy systemd service file to /etc/systemd/system/
- Run daemon-reload after updating service file
- Ensures RUST_LOG and other service changes are deployed
- Set RUST_LOG=info to enable application logging
- Logs will now appear in journalctl output
- Deserialize claims as JSON Value to inspect structure
- Extract iss, aud, exp from custom claims or standard fields
- Add debug logging to see actual JWT structure
- Handle both custom and standard claim locations
- Replaced jsonwebtoken with jwt-compact crate
- Added ES256K algorithm support for Bluesky JWT tokens
- Parse and validate JWT claims (iss, aud, exp)
- Verify audience matches service DID
- Validate expiration timestamp
- Note: Signature verification still TODO (needs DID doc fetching)
- validate_jwt now expects token without Bearer prefix
- Added debug logging for JWT validation steps
- Log token length, expected audience, and decode errors
- Added ErrorResponse type with error and message fields
- Changed get_feed_skeleton to return Response for flexible error handling
- Return AuthenticationRequired error with descriptive message
- Follows ATProto error response format for proper client handling
- Changed get_feed_skeleton to extract JWT from HTTP Authorization header instead of query params
- Added HeaderMap extractor to read headers properly
- Strip 'Bearer ' prefix from token before validation
- Added comprehensive logging for feed requests and JWT validation
- Removed auth field from FeedSkeletonParams (was incorrectly reading from query params)
Closes #3
Major improvements:
- Added table of contents for easy navigation
- Enhanced Features section with emojis and clearer descriptions
- Added 'How It Works' section explaining the system flow
- Comprehensive installation and configuration guide
- Detailed deployment section with systemd service and reverse proxy configs
- Complete publishing guide with both CLI and manual methods
- Architecture diagrams and code structure documentation
- Full API endpoint documentation with examples
- Performance metrics and scalability information
- Expanded troubleshooting section with solutions
- Development guidelines and contribution instructions
- Enhanced resource links and acknowledgments
The README now provides everything needed to:
- Understand the project and its architecture
- Set up and run the feed generator locally
- Deploy to production with proper configuration
- Publish feeds to Bluesky
- Troubleshoot common issues
- Contribute to the project
Bumps [tower](https://github.com/tower-rs/tower) from 0.4.13 to 0.5.2.
- [Release notes](https://github.com/tower-rs/tower/releases)
- [Commits](https://github.com/tower-rs/tower/compare/tower-0.4.13...tower-0.5.2)
---
updated-dependencies:
- dependency-name: tower
dependency-version: 0.5.2
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps [axum](https://github.com/tokio-rs/axum) from 0.7.9 to 0.8.6.
- [Release notes](https://github.com/tokio-rs/axum/releases)
- [Changelog](https://github.com/tokio-rs/axum/blob/main/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/axum/compare/axum-v0.7.9...axum-v0.8.6)
---
updated-dependencies:
- dependency-name: axum
dependency-version: 0.8.6
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps [tower-http](https://github.com/tower-rs/tower-http) from 0.5.2 to 0.6.6.
- [Release notes](https://github.com/tower-rs/tower-http/releases)
- [Commits](https://github.com/tower-rs/tower-http/compare/tower-http-0.5.2...tower-http-0.6.6)
---
updated-dependencies:
- dependency-name: tower-http
dependency-version: 0.6.6
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Bumps [reqwest](https://github.com/seanmonstar/reqwest) from 0.11.27 to 0.12.23.
- [Release notes](https://github.com/seanmonstar/reqwest/releases)
- [Changelog](https://github.com/seanmonstar/reqwest/blob/master/CHANGELOG.md)
- [Commits](https://github.com/seanmonstar/reqwest/compare/v0.11.27...v0.12.23)
---
updated-dependencies:
- dependency-name: reqwest
dependency-version: 0.12.23
dependency-type: direct:production
update-type: version-update:semver-minor
...
Signed-off-by: dependabot[bot] <support@github.com>
Fixes CVE-2023-43669 (GHSA-9mcr-873m-xcxp) - HIGH severity
The vulnerability in tungstenite <= 0.20.0 allows remote attackers to
cause denial of service via excessive HTTP header length during client
handshake, causing minutes of CPU consumption.
Changes:
- Updated tokio-tungstenite from 0.18 to 0.28
- Updated tungstenite from 0.18.0 to 0.28.0
- Removed unnecessary url::Url import and parsing
- API change: connect_async now accepts &str directly
Closes #1
- Add full ES256K signature verification using atrium-crypto
- Resolve issuer DID documents via atrium-identity
- Extract and verify publicKeyMultibase from #atproto verification method
- Convert keys to did:key format for signature verification
- Update atrium-xrpc-client to v0.5 for compatibility
- Remove explicit atrium-api dependency (pulled transitively)
Security impact: Prevents JWT forgery attacks by cryptographically
verifying that tokens are signed by the issuer's private key.
- Created admin_socket module with command interface
- Commands: backfill <did>, stats, help, quit
- Socket path configurable via ADMIN_SOCKET env var
- Default socket: /var/run/noreposts-feed.sock
- Added admin.sh helper script for easy connection
- Allows manual backfill triggering and stats monitoring
- Changed get_feed_skeleton to extract JWT from HTTP Authorization header instead of query params
- Added HeaderMap extractor to read headers properly
- Strip 'Bearer ' prefix from token before validation
- Added comprehensive logging for feed requests and JWT validation
- Removed auth field from FeedSkeletonParams (was incorrectly reading from query params)