From 06a4189ce268467a88e049038993b48004def660 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Sat, 6 Sep 2025 11:31:29 +0100 Subject: [PATCH 1/3] client: Add WhoIs func --- client.go | 9 +++++++++ responses.go | 18 ++++++++++++++++++ 2 files changed, 27 insertions(+) diff --git a/client.go b/client.go index 85b27923..05e7a296 100644 --- a/client.go +++ b/client.go @@ -2562,6 +2562,15 @@ func (cli *Client) ReportRoom(ctx context.Context, roomID id.RoomID, reason stri return err } +// WhoIs fetches session information belonging to a specific user. Typically requires being a server admin. +// +// https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv3adminwhoisuserid +func (cli *Client) WhoIs(ctx context.Context, userID id.UserID) (resp RespWhoIs, err error) { + urlPath := cli.BuildClientURL("v3", "admin", "whois", userID) + _, err = cli.MakeRequest(ctx, http.MethodGet, urlPath, nil, &resp) + return +} + // UnstableGetSuspendedStatus uses MSC4323 to check if a user is suspended. func (cli *Client) UnstableGetSuspendedStatus(ctx context.Context, userID id.UserID) (res *RespSuspended, err error) { urlPath := cli.BuildClientURL("unstable", "uk.timedout.msc4323", "admin", "suspend", userID) diff --git a/responses.go b/responses.go index 8ab78373..8cdb44f1 100644 --- a/responses.go +++ b/responses.go @@ -715,3 +715,21 @@ type RespSuspended struct { type RespLocked struct { Locked bool `json:"locked"` } + +type ConnectionInfo struct { + IP string `json:"ip"` + LastSeen int64 `json:"last_seen"` + UserAgent string `json:"user_agent"` +} +type SessionInfo struct { + Connections []ConnectionInfo `json:"connections"` +} +type DeviceInfo struct { + Sessions []SessionInfo `json:"sessions"` +} + +// RespWhoIs is the response body for https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv3adminwhoisuserid +type RespWhoIs struct { + UserID id.UserID `json:"user_id"` + Devices map[string]DeviceInfo `json:"devices"` +} From 5123ed8c54c5166dc72f6e6480d58fc7c3f3a1a9 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Wed, 10 Sep 2025 16:36:21 +0100 Subject: [PATCH 2/3] client: Apply suggested changes --- responses.go | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/responses.go b/responses.go index 8cdb44f1..ae41084e 100644 --- a/responses.go +++ b/responses.go @@ -717,19 +717,21 @@ type RespLocked struct { } type ConnectionInfo struct { - IP string `json:"ip"` - LastSeen int64 `json:"last_seen"` - UserAgent string `json:"user_agent"` + IP string `json:"ip,omitempty"` + LastSeen jsontime.UnixMilli `json:"last_seen,omitempty"` + UserAgent string `json:"user_agent,omitempty"` } + type SessionInfo struct { - Connections []ConnectionInfo `json:"connections"` + Connections []ConnectionInfo `json:"connections,omitempty"` } + type DeviceInfo struct { - Sessions []SessionInfo `json:"sessions"` + Sessions []SessionInfo `json:"sessions,omitempty"` } // RespWhoIs is the response body for https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv3adminwhoisuserid type RespWhoIs struct { - UserID id.UserID `json:"user_id"` - Devices map[string]DeviceInfo `json:"devices"` + UserID id.UserID `json:"user_id,omitempty"` + Devices map[id.Device]DeviceInfo `json:"devices,omitempty"` } From b2f80c3870b0a931c1062efb476cc4171b05da99 Mon Sep 17 00:00:00 2001 From: nexy7574 Date: Thu, 11 Sep 2025 19:06:06 +0100 Subject: [PATCH 3/3] client: WhoIs -> AdminWhoIs --- client.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client.go b/client.go index 05e7a296..034b1bc3 100644 --- a/client.go +++ b/client.go @@ -2562,10 +2562,10 @@ func (cli *Client) ReportRoom(ctx context.Context, roomID id.RoomID, reason stri return err } -// WhoIs fetches session information belonging to a specific user. Typically requires being a server admin. +// AdminWhoIs fetches session information belonging to a specific user. Typically requires being a server admin. // // https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv3adminwhoisuserid -func (cli *Client) WhoIs(ctx context.Context, userID id.UserID) (resp RespWhoIs, err error) { +func (cli *Client) AdminWhoIs(ctx context.Context, userID id.UserID) (resp RespWhoIs, err error) { urlPath := cli.BuildClientURL("v3", "admin", "whois", userID) _, err = cli.MakeRequest(ctx, http.MethodGet, urlPath, nil, &resp) return