about summary refs log tree commit diff
path: root/LibMatrix/Homeservers
diff options
context:
space:
mode:
Diffstat (limited to 'LibMatrix/Homeservers')
-rw-r--r--LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs58
-rw-r--r--LibMatrix/Homeservers/FederationClient.cs79
2 files changed, 55 insertions, 82 deletions
diff --git a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs

index 5fd3311..4185353 100644 --- a/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs +++ b/LibMatrix/Homeservers/AuthenticatedHomeserverGeneric.cs
@@ -295,7 +295,19 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { public async Task<RoomIdResponse> JoinRoomAsync(string roomId, List<string> homeservers = null, string? reason = null) { var joinUrl = $"/_matrix/client/v3/join/{HttpUtility.UrlEncode(roomId)}"; Console.WriteLine($"Calling {joinUrl} with {homeservers?.Count ?? 0} via's..."); - if (homeservers == null || homeservers.Count == 0) homeservers = new List<string> { roomId.Split(':')[1] }; + if (homeservers is not { Count: > 0 }) { + // Legacy room IDs: !abc:server.xyz + if (roomId.Contains(':')) + homeservers = [ServerName, roomId.Split(':')[1]]; + // v12+ room IDs: !<hash> + else { + homeservers = [ServerName]; + foreach (var room in await GetJoinedRooms()) { + homeservers.Add(await room.GetOriginHomeserverAsync()); + } + } + } + var fullJoinUrl = $"{joinUrl}?server_name=" + string.Join("&server_name=", homeservers); var res = await ClientHttpClient.PostAsJsonAsync(fullJoinUrl, new { reason @@ -397,14 +409,14 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { private Dictionary<string, string>? _namedFilterCache; private Dictionary<string, SyncFilter> _filterCache = new(); - public async Task<JsonObject?> GetCapabilitiesAsync() { + public async Task<CapabilitiesResponse> GetCapabilitiesAsync() { var res = await ClientHttpClient.GetAsync("/_matrix/client/v3/capabilities"); if (!res.IsSuccessStatusCode) { Console.WriteLine($"Failed to get capabilities: {await res.Content.ReadAsStringAsync()}"); throw new InvalidDataException($"Failed to get capabilities: {await res.Content.ReadAsStringAsync()}"); } - return await res.Content.ReadFromJsonAsync<JsonObject>(); + return await res.Content.ReadFromJsonAsync<CapabilitiesResponse>(); } public class HsNamedCaches { @@ -574,9 +586,45 @@ public class AuthenticatedHomeserverGeneric : RemoteHomeserver { await SetAccountDataAsync(IgnoredUserListEventContent.EventId, ignoredUserList); } - private class CapabilitiesResponse { + public class CapabilitiesResponse { [JsonPropertyName("capabilities")] - public Dictionary<string, object>? Capabilities { get; set; } + public CapabilitiesContents Capabilities { get; set; } + + public class CapabilitiesContents { + [JsonPropertyName("m.3pid_changes")] + public BooleanCapability? ThreePidChanges { get; set; } + + [JsonPropertyName("m.change_password")] + public BooleanCapability? ChangePassword { get; set; } + + [JsonPropertyName("m.get_login_token")] + public BooleanCapability? GetLoginToken { get; set; } + + [JsonPropertyName("m.room_versions")] + public RoomVersionsCapability? RoomVersions { get; set; } + + [JsonPropertyName("m.set_avatar_url")] + public BooleanCapability? SetAvatarUrl { get; set; } + + [JsonPropertyName("m.set_displayname")] + public BooleanCapability? SetDisplayName { get; set; } + + [JsonExtensionData] + public Dictionary<string, object>? AdditionalCapabilities { get; set; } + } + + public class BooleanCapability { + [JsonPropertyName("enabled")] + public bool Enabled { get; set; } + } + + public class RoomVersionsCapability { + [JsonPropertyName("default")] + public string? Default { get; set; } + + [JsonPropertyName("available")] + public Dictionary<string, string>? Available { get; set; } + } } #region Room Directory/aliases diff --git a/LibMatrix/Homeservers/FederationClient.cs b/LibMatrix/Homeservers/FederationClient.cs
index a2cb12d..9760e20 100644 --- a/LibMatrix/Homeservers/FederationClient.cs +++ b/LibMatrix/Homeservers/FederationClient.cs
@@ -1,7 +1,6 @@ -using System.Text.Json.Serialization; using LibMatrix.Extensions; +using LibMatrix.Responses.Federation; using LibMatrix.Services; -using Microsoft.VisualBasic.CompilerServices; namespace LibMatrix.Homeservers; @@ -18,81 +17,7 @@ public class FederationClient { public HomeserverResolverService.WellKnownUris WellKnownUris { get; set; } public async Task<ServerVersionResponse> GetServerVersionAsync() => await HttpClient.GetFromJsonAsync<ServerVersionResponse>("/_matrix/federation/v1/version"); - public async Task<ServerKeysResponse> GetServerKeysAsync() => await HttpClient.GetFromJsonAsync<ServerKeysResponse>("/_matrix/key/v2/server"); + public async Task<SignedObject<ServerKeysResponse>> GetServerKeysAsync() => await HttpClient.GetFromJsonAsync<SignedObject<ServerKeysResponse>>("/_matrix/key/v2/server"); } -public class ServerKeysResponse { - [JsonPropertyName("server_name")] - public string ServerName { get; set; } - [JsonPropertyName("valid_until_ts")] - public ulong ValidUntilTs { get; set; } - - [JsonIgnore] - public DateTime ValidUntil { - get => DateTimeOffset.FromUnixTimeMilliseconds((long)ValidUntilTs).DateTime; - set => ValidUntilTs = (ulong)new DateTimeOffset(value).ToUnixTimeMilliseconds(); - } - - [JsonPropertyName("verify_keys")] - public Dictionary<string, CurrentVerifyKey> VerifyKeys { get; set; } = new(); - - [JsonIgnore] - public Dictionary<VersionedKeyId, CurrentVerifyKey> VerifyKeysById { - get => VerifyKeys.ToDictionary(key => (VersionedKeyId)key.Key, key => key.Value); - set => VerifyKeys = value.ToDictionary(key => (string)key.Key, key => key.Value); - } - - [JsonPropertyName("old_verify_keys")] - public Dictionary<string, ExpiredVerifyKey> OldVerifyKeys { get; set; } = new(); - - [JsonIgnore] - public Dictionary<VersionedKeyId, ExpiredVerifyKey> OldVerifyKeysById { - get => OldVerifyKeys.ToDictionary(key => (VersionedKeyId)key.Key, key => key.Value); - set => OldVerifyKeys = value.ToDictionary(key => (string)key.Key, key => key.Value); - } - - public class VersionedKeyId { - public required string Algorithm { get; set; } - public required string KeyId { get; set; } - - public static implicit operator VersionedKeyId(string key) { - var parts = key.Split(':', 2); - if (parts.Length != 2) throw new ArgumentException("Invalid key format. Expected 'algorithm:keyId'.", nameof(key)); - return new VersionedKeyId { Algorithm = parts[0], KeyId = parts[1] }; - } - - public static implicit operator string(VersionedKeyId key) => $"{key.Algorithm}:{key.KeyId}"; - public static implicit operator (string, string)(VersionedKeyId key) => (key.Algorithm, key.KeyId); - public static implicit operator VersionedKeyId((string algorithm, string keyId) key) => (key.algorithm, key.keyId); - } - - public class CurrentVerifyKey { - [JsonPropertyName("key")] - public string Key { get; set; } - } - - public class ExpiredVerifyKey : CurrentVerifyKey { - [JsonPropertyName("expired_ts")] - public ulong ExpiredTs { get; set; } - - [JsonIgnore] - public DateTime Expired { - get => DateTimeOffset.FromUnixTimeMilliseconds((long)ExpiredTs).DateTime; - set => ExpiredTs = (ulong)new DateTimeOffset(value).ToUnixTimeMilliseconds(); - } - } -} - -public class ServerVersionResponse { - [JsonPropertyName("server")] - public required ServerInfo Server { get; set; } - - public class ServerInfo { - [JsonPropertyName("name")] - public string Name { get; set; } - - [JsonPropertyName("version")] - public string Version { get; set; } - } -} \ No newline at end of file