diff --git a/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs b/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs
index 593f5b0..46c3062 100644
--- a/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs
+++ b/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs
@@ -101,6 +101,8 @@ public class RoomStateController(ILogger<RoomStateController> logger, TokenServi
var evt = room.SetStateInternal(request.ToStateEvent(user, room));
evt.Type = eventType;
evt.StateKey = stateKey;
- return new EventIdResponse(evt);
+ return new EventIdResponse(){
+ EventId = evt.EventId
+ };
}
}
\ No newline at end of file
diff --git a/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomTimelineController.cs b/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomTimelineController.cs
new file mode 100644
index 0000000..c9bdb57
--- /dev/null
+++ b/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomTimelineController.cs
@@ -0,0 +1,52 @@
+using System.Collections.Frozen;
+using System.Text.Json.Nodes;
+using LibMatrix.HomeserverEmulator.Extensions;
+using LibMatrix.HomeserverEmulator.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.Rooms;
+
+[ApiController]
+[Route("/_matrix/client/{version}/rooms/{roomId}")]
+public class RoomTimelineController(ILogger<RoomTimelineController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+ [HttpPut("send/{eventType}/{txnId}")]
+ public async Task<EventIdResponse> SendMessage(string roomId, string eventType, string txnId, [FromBody] JsonObject content) {
+ var token = tokenService.GetAccessToken(HttpContext);
+ if (token == null)
+ throw new MatrixException() {
+ ErrorCode = "M_MISSING_TOKEN",
+ Error = "Missing token"
+ };
+
+ var user = await userStore.GetUserByToken(token);
+ if (user == null)
+ throw new MatrixException() {
+ ErrorCode = "M_UNKNOWN_TOKEN",
+ Error = "No such user"
+ };
+
+ var room = roomStore.GetRoomById(roomId);
+ if (room == null)
+ throw new MatrixException() {
+ ErrorCode = "M_NOT_FOUND",
+ Error = "Room not found"
+ };
+
+ if (!room.JoinedMembers.Any(x=>x.StateKey == user.UserId))
+ throw new MatrixException() {
+ ErrorCode = "M_FORBIDDEN",
+ Error = "User is not in the room"
+ };
+
+ var evt = new StateEvent() {
+ RawContent = content,
+ Type = eventType
+ }.ToStateEvent(user, room);
+
+ room.Timeline.Add(evt);
+
+ return new() {
+ EventId = evt.EventId
+ };
+ }
+}
\ No newline at end of file
diff --git a/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomsController.cs b/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomsController.cs
index e9f52dc..b0f5014 100644
--- a/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomsController.cs
+++ b/Tests/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomsController.cs
@@ -112,7 +112,7 @@ public class RoomsController(ILogger<RoomsController> logger, TokenService token
["creator"] = user.UserId
}
});
-
+
oldRoom.State.Where(x => eventTypesToTransfer.Contains(x.Type)).ToList().ForEach(x => room.SetStateInternal(x));
room.AddUser(user.UserId);
@@ -122,6 +122,38 @@ public class RoomsController(ILogger<RoomsController> logger, TokenService token
replacement_room = room.RoomId
};
}
+
+ [HttpPost("rooms/{roomId}/leave")] // TODO: implement
+ public async Task<object> LeaveRoom(string roomId) {
+ var token = tokenService.GetAccessToken(HttpContext);
+ if (token == null)
+ throw new MatrixException() {
+ ErrorCode = "M_MISSING_TOKEN",
+ Error = "Missing token"
+ };
+
+ var user = await userStore.GetUserByToken(token);
+ if (user == null)
+ throw new MatrixException() {
+ ErrorCode = "M_UNKNOWN_TOKEN",
+ Error = "No such user"
+ };
+
+ var room = roomStore.GetRoomById(roomId);
+ if (room == null)
+ throw new MatrixException() {
+ ErrorCode = "M_NOT_FOUND",
+ Error = "Room not found"
+ };
+
+ // room.RemoveUser(user.UserId);
+
+ // room.SetStateInternal(new StateEventResponse() { });
+
+ return new {
+ room_id = room.RoomId
+ };
+ }
}
public class UpgradeRoomRequest {
diff --git a/Tests/LibMatrix.HomeserverEmulator/Controllers/SyncController.cs b/Tests/LibMatrix.HomeserverEmulator/Controllers/SyncController.cs
index 1653110..afcf711 100644
--- a/Tests/LibMatrix.HomeserverEmulator/Controllers/SyncController.cs
+++ b/Tests/LibMatrix.HomeserverEmulator/Controllers/SyncController.cs
@@ -1,11 +1,8 @@
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
-using System.Security.Cryptography;
-using System.Text.Json.Nodes;
using ArcaneLibs.Extensions;
using LibMatrix.HomeserverEmulator.Services;
using LibMatrix.Responses;
-using LibMatrix.Services;
using Microsoft.AspNetCore.Mvc;
namespace LibMatrix.HomeserverEmulator.Controllers;
@@ -51,7 +48,6 @@ public class SyncController(ILogger<SyncController> logger, TokenService tokenSe
session.SyncStates.Add(response.NextBatch, new() {
RoomPositions = syncState.RoomPositions.ToDictionary(x => x.Key, x => new UserStore.User.SessionInfo.UserSyncState.SyncRoomPosition() {
- StatePosition = roomStore._rooms.First(y => y.RoomId == x.Key).State.Count,
TimelinePosition = roomStore._rooms.First(y => y.RoomId == x.Key).Timeline.Count,
AccountDataPosition = roomStore._rooms.First(y => y.RoomId == x.Key).AccountData[user.UserId].Count
})
@@ -67,19 +63,19 @@ public class SyncController(ILogger<SyncController> logger, TokenService tokenSe
response.Rooms ??= new();
response.Rooms.Join ??= new();
response.Rooms.Join[room.RoomId] = new() {
- State = new(room.State.Skip(roomPositions.StatePosition).ToList()),
Timeline = new(events: room.Timeline.Skip(roomPositions.TimelinePosition).ToList(), limited: false),
AccountData = new(room.AccountData.GetOrCreate(user.UserId, _ => []).Skip(roomPositions.AccountDataPosition).ToList())
};
+ if (response.Rooms.Join[room.RoomId].Timeline?.Events?.Count > 0)
+ response.Rooms.Join[room.RoomId].State = new(response.Rooms.Join[room.RoomId].Timeline!.Events.Where(x => x.StateKey != null).ToList());
session.SyncStates[response.NextBatch].RoomPositions[room.RoomId] = new() {
- StatePosition = room.State.Count,
TimelinePosition = room.Timeline.Count,
AccountDataPosition = room.AccountData[user.UserId].Count
};
- if (response.Rooms.Join[room.RoomId].State.Events.Count == 0 &&
- response.Rooms.Join[room.RoomId].Timeline.Events.Count == 0 &&
- response.Rooms.Join[room.RoomId].AccountData.Events.Count == 0
+ if (response.Rooms.Join[room.RoomId].State?.Events?.Count == 0 &&
+ response.Rooms.Join[room.RoomId].Timeline?.Events?.Count == 0 &&
+ response.Rooms.Join[room.RoomId].AccountData?.Events?.Count == 0
)
response.Rooms.Join.Remove(room.RoomId);
}
@@ -108,7 +104,6 @@ public class SyncController(ILogger<SyncController> logger, TokenService tokenSe
AccountData = new(room.AccountData.GetOrCreate(user.UserId, _ => []).ToList())
};
session.SyncStates[response.NextBatch].RoomPositions[room.RoomId] = new() {
- StatePosition = room.State.Count,
TimelinePosition = room.Timeline.Count,
AccountDataPosition = room.AccountData[user.UserId].Count
};
diff --git a/Tests/LibMatrix.HomeserverEmulator/Controllers/Users/UserController.cs b/Tests/LibMatrix.HomeserverEmulator/Controllers/Users/UserController.cs
index eb2b879..e886d46 100644
--- a/Tests/LibMatrix.HomeserverEmulator/Controllers/Users/UserController.cs
+++ b/Tests/LibMatrix.HomeserverEmulator/Controllers/Users/UserController.cs
@@ -1,4 +1,5 @@
using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
using ArcaneLibs.Extensions;
using LibMatrix.EventTypes.Spec.State;
using LibMatrix.Filters;
@@ -55,4 +56,43 @@ public class UserController(ILogger<UserController> logger, TokenService tokenSe
).Select(r => r.RoomId).ToList()
};
}
+
+ [HttpGet("devices")]
+ public async Task<DevicesResponse> GetDevices() {
+ var token = tokenService.GetAccessToken(HttpContext);
+ if (token is null)
+ throw new MatrixException() {
+ ErrorCode = "M_UNAUTHORIZED",
+ Error = "No token passed."
+ };
+
+ var user = await userStore.GetUserByToken(token, false);
+ if (user is null)
+ throw new MatrixException() {
+ ErrorCode = "M_UNAUTHORIZED",
+ Error = "Invalid token."
+ };
+ return new() {
+ Devices = user.AccessTokens.Select(x=>new DevicesResponse.Device() {
+ DeviceId = x.Value.DeviceId,
+ DisplayName = x.Value.DeviceId
+ }).ToList()
+ };
+ }
+
+ public class DevicesResponse {
+ [JsonPropertyName("devices")]
+ public List<Device> Devices { get; set; }
+
+ public class Device {
+ [JsonPropertyName("device_id")]
+ public string DeviceId { get; set; }
+ [JsonPropertyName("display_name")]
+ public string DisplayName { get; set; }
+ [JsonPropertyName("last_seen_ip")]
+ public string LastSeenIp { get; set; }
+ [JsonPropertyName("last_seen_ts")]
+ public long LastSeenTs { get; set; }
+ }
+ }
}
\ No newline at end of file
|