From 33e2a713626371a48fb9a38a653190087cd0d95e Mon Sep 17 00:00:00 2001 From: hawklin2017 <32898629+hawklin2017@users.noreply.github.com> Date: Sun, 12 Apr 2026 19:57:17 +0800 Subject: [PATCH] =?UTF-8?q?=E5=89=94=E9=99=A4=E8=AE=BE=E5=A4=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/api/auth.go | 8 +++++++ internal/api/router.go | 3 ++- internal/rpc/auth/auth.go | 47 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/internal/api/auth.go b/internal/api/auth.go index 92d911b71..3892b140e 100644 --- a/internal/api/auth.go +++ b/internal/api/auth.go @@ -43,3 +43,11 @@ func (o *AuthApi) ParseToken(c *gin.Context) { func (o *AuthApi) ForceLogout(c *gin.Context) { a2r.Call(c, auth.AuthClient.ForceLogout, o.Client) } + +func (o *AuthApi) GetActiveDevices(c *gin.Context) { + a2r.Call(c, auth.AuthClient.GetActiveDevices, o.Client) +} + +func (o *AuthApi) KickDevice(c *gin.Context) { + a2r.Call(c, auth.AuthClient.KickDevice, o.Client) +} diff --git a/internal/api/router.go b/internal/api/router.go index 06e08dde3..b71be4ba6 100644 --- a/internal/api/router.go +++ b/internal/api/router.go @@ -238,7 +238,8 @@ func newGinRouter(ctx context.Context, client discovery.SvcDiscoveryRegistry, co authRouterGroup.POST("/get_user_token", a.GetUserToken) authRouterGroup.POST("/parse_token", a.ParseToken) authRouterGroup.POST("/force_logout", a.ForceLogout) - + authRouterGroup.POST("/get_active_devices", a.GetActiveDevices) + authRouterGroup.POST("/kick_device", a.KickDevice) } // Third service { diff --git a/internal/rpc/auth/auth.go b/internal/rpc/auth/auth.go index 9a909c520..bb7a95ce1 100644 --- a/internal/rpc/auth/auth.go +++ b/internal/rpc/auth/auth.go @@ -294,3 +294,50 @@ func (s *authServer) KickTokens(ctx context.Context, req *pbauth.KickTokensReq) } return &pbauth.KickTokensResp{}, nil } + +// GetActiveDevices returns all platforms that have at least one valid (non-kicked) token for the user. +// Only the user themselves or an admin can call this. +func (s *authServer) GetActiveDevices(ctx context.Context, req *pbauth.GetActiveDevicesReq) (*pbauth.GetActiveDevicesResp, error) { + if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } + + var devices []*pbauth.DeviceInfo + for platformID, platformName := range constant.PlatformID2Name { + if int32(platformID) == constant.AdminPlatformID { + continue + } + m, err := s.authDatabase.GetTokensWithoutError(ctx, req.UserID, platformID) + if err != nil { + return nil, err + } + for _, state := range m { + if state == constant.NormalToken { + devices = append(devices, &pbauth.DeviceInfo{ + PlatformID: int32(platformID), + PlatformName: platformName, + }) + break + } + } + } + return &pbauth.GetActiveDevicesResp{Devices: devices}, nil +} + +// KickDevice kicks the specified platform device offline for the given user. +// Only the user themselves or an admin can call this. +func (s *authServer) KickDevice(ctx context.Context, req *pbauth.KickDeviceReq) (*pbauth.KickDeviceResp, error) { + if err := authverify.CheckAccessV3(ctx, req.UserID, s.config.Share.IMAdminUserID); err != nil { + return nil, err + } + if req.PlatformID == constant.AdminPlatformID { + return nil, errs.ErrArgs.WrapMsg("cannot kick admin platform") + } + if _, ok := constant.PlatformID2Name[int(req.PlatformID)]; !ok { + return nil, errs.ErrArgs.WrapMsg("invalid platformID", "platformID", req.PlatformID) + } + if err := s.forceKickOff(ctx, req.UserID, req.PlatformID); err != nil { + return nil, err + } + return &pbauth.KickDeviceResp{}, nil +}