mirror of
https://github.com/J3vb/OwnCord.git
synced 2026-09-03 03:50:00 +03:00
feat: broadcast username changes to all connected clients via WebSocket
Add user_update event so other clients see profile changes in real-time without needing to reconnect. Also updates saved credentials in Windows Credential Manager when the current user changes their username. Fixes: livekit-session test mock missing unpublishTrack property.
This commit is contained in:
@@ -748,7 +748,7 @@ func buildCombinedRouter(t *testing.T) (http.Handler, *auth.RateLimiter, string)
|
||||
|
||||
r := chi.NewRouter()
|
||||
api.MountAuthRoutes(r, database, limiter, nil, testTOTPKey)
|
||||
api.MountProfileRoutes(r, database, limiter, nil)
|
||||
api.MountProfileRoutes(r, database, limiter, nil, nil)
|
||||
api.MountInviteRoutes(r, database)
|
||||
|
||||
token := loginAndGetToken(t, r, database, "combined1", 2)
|
||||
|
||||
@@ -45,13 +45,19 @@ type sessionsListResponse struct {
|
||||
|
||||
// ─── Route mounting ──────────────────────────────────────────────────────────
|
||||
|
||||
// ProfileBroadcaster is the interface the profile handler uses to notify
|
||||
// connected WebSocket clients about profile changes.
|
||||
type ProfileBroadcaster interface {
|
||||
BroadcastUserUpdate(userID int64, username string, avatar *string)
|
||||
}
|
||||
|
||||
// MountProfileRoutes registers user profile management endpoints.
|
||||
// All routes require authentication. trustedProxies is used for rate limiting.
|
||||
func MountProfileRoutes(r chi.Router, database *db.DB, limiter *auth.RateLimiter, trustedProxies []string) {
|
||||
func MountProfileRoutes(r chi.Router, database *db.DB, limiter *auth.RateLimiter, trustedProxies []string, broadcaster ProfileBroadcaster) {
|
||||
r.Route("/api/v1/users/me", func(r chi.Router) {
|
||||
r.Use(AuthMiddleware(database))
|
||||
|
||||
r.Patch("/", handleUpdateProfile(database))
|
||||
r.Patch("/", handleUpdateProfile(database, broadcaster))
|
||||
|
||||
r.With(RateLimitMiddleware(limiter, profilePasswordRateLimitPerMinute, time.Minute, trustedProxies)).
|
||||
Put("/password", handleChangePassword(database, limiter))
|
||||
@@ -64,7 +70,7 @@ func MountProfileRoutes(r chi.Router, database *db.DB, limiter *auth.RateLimiter
|
||||
// ─── Handlers ────────────────────────────────────────────────────────────────
|
||||
|
||||
// handleUpdateProfile processes PATCH /api/v1/users/me.
|
||||
func handleUpdateProfile(database *db.DB) http.HandlerFunc {
|
||||
func handleUpdateProfile(database *db.DB, broadcaster ProfileBroadcaster) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
user, ok := r.Context().Value(UserKey).(*db.User)
|
||||
if !ok || user == nil {
|
||||
@@ -138,6 +144,11 @@ func handleUpdateProfile(database *db.DB) http.HandlerFunc {
|
||||
slog.Info("profile updated", "user_id", user.ID, "new_username", req.Username)
|
||||
_ = database.LogAudit(user.ID, "profile_update", "user", user.ID, "profile updated")
|
||||
|
||||
// Broadcast profile change to all connected WebSocket clients.
|
||||
if broadcaster != nil {
|
||||
broadcaster.BroadcastUserUpdate(updated.ID, updated.Username, updated.Avatar)
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, toUserResponse(updated))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import (
|
||||
func buildProfileRouter(database *db.DB) http.Handler {
|
||||
r := chi.NewRouter()
|
||||
limiter := auth.NewRateLimiter()
|
||||
api.MountProfileRoutes(r, database, limiter, nil)
|
||||
api.MountProfileRoutes(r, database, limiter, nil, nil)
|
||||
return r
|
||||
}
|
||||
|
||||
|
||||
@@ -83,8 +83,8 @@ func NewRouter(cfg *config.Config, database *db.DB, ver string, logBuf *admin.Ri
|
||||
// Auth routes: register, login, logout, me.
|
||||
MountAuthRoutes(r, database, limiter, cfg.Server.TrustedProxies, totpKey)
|
||||
|
||||
// Profile routes: update profile, change password, session management.
|
||||
MountProfileRoutes(r, database, limiter, cfg.Server.TrustedProxies)
|
||||
// Profile routes are mounted after hub creation (below) so the hub can
|
||||
// broadcast user_update events for real-time profile changes.
|
||||
|
||||
// Invite management routes (require MANAGE_INVITES permission).
|
||||
MountInviteRoutes(r, database)
|
||||
@@ -167,6 +167,10 @@ func NewRouter(cfg *config.Config, database *db.DB, ver string, logBuf *admin.Ri
|
||||
Handle("/livekit/*", http.StripPrefix("/livekit", NewLiveKitProxy(cfg.Voice.LiveKitURL, cfg.Server.AllowedOrigins)))
|
||||
}
|
||||
|
||||
// Profile routes: update profile, change password, session management.
|
||||
// Mounted after hub creation so the hub can broadcast user_update events.
|
||||
MountProfileRoutes(r, database, limiter, cfg.Server.TrustedProxies, hub)
|
||||
|
||||
// DM (direct message) REST routes — mounted after hub creation so the
|
||||
// hub can send real-time dm_channel_close events to WebSocket clients.
|
||||
MountDMRoutes(r, database, hub)
|
||||
|
||||
Reference in New Issue
Block a user