* Unified NetBird combined server (Management, Signal, Relay, STUN) as a single executable with richer YAML configuration, validation, and defaults.
* Official Dockerfile/image for single-container deployment.
* Optional in-process profiling endpoint for diagnostics.
* Multiplexing to route HTTP/gRPC/WebSocket traffic via one port; runtime hooks to inject custom handlers.
* **Chores**
* Updated deployment scripts, compose files, and reverse-proxy templates to target the combined server; added example configs and getting-started updates.
- Add ValidateSession gRPC method for proxy-side user validation
- Move group access validation from REST callback to gRPC layer
- Capture user info in access logs via CapturedData mutable pointer
- Create validate_session_test.go for gRPC validation tests
- Simplify auth_callback_integration_test.go to create accounts
programmatically instead of using SQL file
- SQL test data file now only used by validate_session_test.go
Implement user group validation during OAuth callback to ensure users
belong to allowed distribution groups before granting access to reverse
proxies. This provides account isolation and fine-grained access control.
Key changes:
- Add ValidateUserGroupAccess to ProxyServiceServer for group membership checks
- Redirect denied users to error page with access_denied parameter
- Handle OAuth error responses in proxy middleware
- Add comprehensive integration tests for auth callback flow
* Add gRPC update debouncing mechanism
Implements backpressure handling for peer network map updates to
efficiently handle rapid changes. First update is sent immediately,
subsequent rapid updates are coalesced, ensuring only the latest
update is sent after a 1-second quiet period.
* Enhance unit test to verify peer count synchronization with debouncing and timeout handling
* Debounce based on type
* Refactor test to validate timer restart after pending update dispatch
* Simplify timer reset for Go 1.23+ automatic channel draining
Remove manual channel drain in resetTimer() since Go 1.23+ automatically
drains the timer channel when Stop() returns false, making the
select-case pattern unnecessary.