summaryrefslogtreecommitdiff
path: root/src/Controllers
diff options
context:
space:
mode:
Diffstat (limited to 'src/Controllers')
-rw-r--r--src/Controllers/LoginController.php12
-rwxr-xr-xsrc/Controllers/RoomController.php154
-rw-r--r--src/Controllers/ServerDiscoveryController.php2
-rwxr-xr-xsrc/Controllers/SyncController.php168
-rwxr-xr-xsrc/Controllers/UserController.php27
5 files changed, 274 insertions, 89 deletions
diff --git a/src/Controllers/LoginController.php b/src/Controllers/LoginController.php
index c520e25..9ae3a48 100644
--- a/src/Controllers/LoginController.php
+++ b/src/Controllers/LoginController.php
@@ -9,10 +9,12 @@ use App\Errors\UnknownError;
use App\Models\Device;
use App\Models\Tokens;
use App\Models\User;
+use App\Support\Logger;
+use App\Support\Parser;
use App\Support\RequestValidator;
-use App\Types\UserRegistrationKind;
use Matrix\Data\LoginFlow;
use Matrix\Enums\LoginType;
+use Matrix\Enums\UserRegistrationKind;
use Matrix\Responses\ClientLoginGetResponse;
use Matrix\Responses\ClientLoginPostResponse;
use Matrix\Responses\ClientRegisterPostResponse;
@@ -37,6 +39,8 @@ class LoginController
*/
public function login(Request $request): Response
{
+ Logger::logRequestToFile($request);
+
$body = json_decode($request->getContent(), true);
RequestValidator::validateJson();
@@ -49,7 +53,11 @@ class LoginController
}
// get user id
- $userId = $body["identifier"]["user"];
+ $userId = Parser::parseUser($body["identifier"]["user"]);
+ if (empty($userId["server"])) {
+ #$userId = "@$userId[username]:$_ENV[DOMAIN]";
+ $userId = "@$userId[username]:localhost";
+ }
#if ($loginType == LoginType::PASSWORD) {}
diff --git a/src/Controllers/RoomController.php b/src/Controllers/RoomController.php
index c02d5ce..dcc0415 100755
--- a/src/Controllers/RoomController.php
+++ b/src/Controllers/RoomController.php
@@ -7,18 +7,155 @@ use App\Errors\AppException;
use App\Errors\ErrorCode;
use App\Errors\UnauthorizedError;
use App\Events\RoomMessageEvent;
+use App\Models\RoomEvent;
use App\Models\User;
+use App\Support\Id;
use App\Support\Parser;
use App\Support\RequestValidator;
-use App\Types\EventType;
-use App\Types\MembershipState;
-use App\Types\MessageType;
+use Matrix\Enums\EventType;
+use Matrix\Enums\MembershipState;
+use Matrix\Enums\MessageType;
+use Matrix\Enums\RoomGuestAccess;
+use Matrix\Enums\RoomHistoryVisibility;
+use Matrix\Enums\RoomJoinRule;
+use Matrix\Enums\RoomVisibility;
+use Matrix\Events\Room\CreateEvent;
+use Matrix\Events\Room\GuestAccessEvent;
+use Matrix\Events\Room\HistoryVisibilityEvent;
+use Matrix\Events\Room\JoinRulesEvent;
+use Matrix\Events\Room\MemberEvent;
+use Matrix\Events\Room\NameEvent;
+use Matrix\Events\Room\PowerLevelsEvent;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
class RoomController
{
+ public function createRoom(Request $request): Response
+ {
+ $user = User::authenticateWithRequest($request);
+ $body = json_decode($request->getContent(), true);
+ RequestValidator::validateJson();
+
+ $creationContent = $body["creation_content"] ?? [];
+ $initialState = $body["initial_state"] ?? [];
+ $invite = $body["invite"] ?? [];
+ $body["invite_3pid"] ?? [];
+ $body["is_direct"] ?? false;
+ $name = $body["name"] ?? "";
+ $body["power_level_content_override"] ?? [];
+ $preset = $body["preset"] ?? "";
+ $roomAliasName = $body["room_alias_name"] ?? "";
+ $roomVersion = $body["room_version"] ?? "DEFAULT_ROOM_VERSION";
+ $topic = $body["topic"] ?? "";
+ $visibility = RoomVisibility::tryFrom($body["visibility"] ?? "private");
+
+ if (! $preset) {
+ $preset = $visibility->value . "_chat";
+ }
+
+ # TODO: get events for preset
+ # TODO: override preset events with initial state
+ # TODO: override events with name and topic if applicable
+ $state = [];
+
+ if ($name) {
+ $state[EventType::ROOM_NAME->value] = $name;
+ }
+
+ if ($topic) {
+ $state[EventType::ROOM_TOPIC->value] = $topic;
+ }
+
+ // create room
+ $roomId = Id::generateRoomId();
+ Database::getInstance()->query(<<<SQL
+ insert into rooms (id, name) values (:id, :name)
+ SQL, [
+ "id" => $roomId,
+ "name" => $roomAliasName, # "#$roomAliasName:$_ENV[DOMAIN]",
+ ]);
+
+ $roomCreateEvent = new RoomEvent(new CreateEvent(
+ eventId: Id::generateEventId(),
+ originServerTimestamp: time(),
+ roomId: $roomId,
+ sender: $user->getId(),
+ roomVersion: "12",
+ ));
+ $roomCreateEvent->insert();
+
+ $roomMemberEvent = new RoomEvent(new MemberEvent(
+ eventId: Id::generateEventId(),
+ originServerTimestamp: time(),
+ roomId: $roomId,
+ sender: $user->getId(),
+ stateKey: $user->getId(),
+ isDirect: false,
+ membership: MembershipState::JOIN,
+ displayName: $user->getName(),
+ ));
+ $roomMemberEvent->insert();
+
+ $roomPowerLevelsEvent = new RoomEvent(new PowerLevelsEvent(
+ eventId: Id::generateEventId(),
+ originServerTimestamp: time(),
+ roomId: $roomId,
+ sender: $user->getId(),
+ ));
+ $roomPowerLevelsEvent->insert();
+
+ $roomJoinRulesEvent = new RoomEvent(new JoinRulesEvent(
+ eventId: Id::generateEventId(),
+ originServerTimestamp: time(),
+ roomId: $roomId,
+ sender: $user->getId(),
+ joinRule: RoomJoinRule::INVITE,
+ ));
+ $roomJoinRulesEvent->insert();
+
+ $roomHistoryVisibilityEvent = new RoomEvent(new HistoryVisibilityEvent(
+ eventId: Id::generateEventId(),
+ originServerTimestamp: time(),
+ roomId: $roomId,
+ sender: $user->getId(),
+ historyVisibility: RoomHistoryVisibility::SHARED,
+ ));
+ $roomHistoryVisibilityEvent->insert();
+
+ $roomGuestAccessEvent = new RoomEvent(new GuestAccessEvent(
+ eventId: Id::generateEventId(),
+ originServerTimestamp: time(),
+ roomId: $roomId,
+ sender: $user->getId(),
+ guestAccess: RoomGuestAccess::CAN_JOIN,
+ ));
+ $roomGuestAccessEvent->insert();
+
+ $roomNameEvent = new RoomEvent(new NameEvent(
+ eventId: Id::generateEventId(),
+ originServerTimestamp: time(),
+ roomId: $roomId,
+ sender: $user->getId(),
+ name: $roomAliasName,
+ ));
+ $roomNameEvent->insert();
+
+ Database::getInstance()->query(<<<SQL
+ insert into room_memberships (room_id, user_id, state)
+ values (:room_id, :user_id, :state)
+ SQL, [
+ "room_id" => $roomId,
+ "user_id" => $user->getId(),
+ "state" => MembershipState::JOIN->value,
+ ]);
+
+ return new JsonResponse([
+ "room_id" => $roomId,
+ ]);
+ }
+
/**
* GET /_matrix/client/v3/directory/room/{roomAlias}
*
@@ -59,6 +196,17 @@ class RoomController
]);
}
+ public function readMarkers(Request $request): Response
+ {
+ $user = User::authenticateWithRequest($request);
+ $body = json_decode($request->getContent(), true);
+ RequestValidator::validateJson();
+
+ $roomId = $request->attributes->get("roomId");
+
+ return new JsonResponse();
+ }
+
/**
* PUT /_matrix/client/v3/rooms/{roomId}/send/{eventType}/{txnId}
*
diff --git a/src/Controllers/ServerDiscoveryController.php b/src/Controllers/ServerDiscoveryController.php
index f3b96b2..917df14 100644
--- a/src/Controllers/ServerDiscoveryController.php
+++ b/src/Controllers/ServerDiscoveryController.php
@@ -19,7 +19,7 @@ class ServerDiscoveryController
{
return new JsonResponse([
"m.homeserver" => [
- "base_url" => "https://$_ENV[DOMAIN]",
+ "base_url" => "http://$_ENV[DOMAIN]",
],
]);
}
diff --git a/src/Controllers/SyncController.php b/src/Controllers/SyncController.php
index 243fab5..acebb11 100755
--- a/src/Controllers/SyncController.php
+++ b/src/Controllers/SyncController.php
@@ -3,13 +3,23 @@
namespace App\Controllers;
use App\Database;
-use App\Errors\UnauthorizedError;
-use App\Events\PresenceEvent;
-use App\Events\RoomMemberEvent;
-use App\Events\RoomMessageEvent;
+use App\Models\RoomEvent;
use App\Models\User;
-use App\Types\MembershipState;
-use App\Types\PresenceState;
+use Matrix\Data\AccountData;
+use Matrix\Data\DeviceLists;
+use Matrix\Data\Presence;
+use Matrix\Data\Room\Ephemeral;
+use Matrix\Data\Room\JoinedRoom;
+use Matrix\Data\Room\RoomSummary;
+use Matrix\Data\Room\Rooms;
+use Matrix\Data\Room\State;
+use Matrix\Data\Room\Timeline;
+use Matrix\Data\Room\UnreadNotificationCounts;
+use Matrix\Data\ToDevice;
+use Matrix\Enums\MembershipState;
+use Matrix\Enums\PresenceState;
+use Matrix\Events\PresenceEvent;
+use Matrix\Responses\ClientSyncGetResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -24,99 +34,93 @@ class SyncController
*/
public function sync(Request $request): Response
{
- $accessToken = str_replace("Bearer ", "", $request->headers->get("authorization") ?: "");
- $user = User::fetchWithAccessToken($accessToken);
-
- if (empty($user)) {
- throw new UnauthorizedError();
- }
+ $user = User::authenticateWithRequest($request);
$filter = $request->query->get("filter", "");
$syncFullState = $request->query->get("full_state", false);
$setPresence = PresenceState::tryFrom($request->query->get("set_presence") ?? "") ?? PresenceState::ONLINE;
$since = $request->query->get("since", "");
$timeout = $request->query->get("timeout", 0);
+ $useStateAfter = $request->query->get("use_state_after", false);
+
+ if (! empty($filter)) {
+ if (str_starts_with($filter, "{")) {
+ $filter = json_decode($filter, true);
+ } else {
+ $filter = Database::getInstance()->query("select * from filters where id=:id", ["id" => $filter])->fetch();
+ }
+ }
$rooms = Database::getInstance()->query(<<<SQL
select * from rooms
- SQL)->fetchAll();
-
- $joinedRooms = new \stdClass();
- if (! empty($rooms)) {
- $joinedRooms = [];
- foreach ($rooms as $room) {
- $joinedRooms[$room["id"]] = [
- "account_data" => [
- "events" => [],
- ],
-
- "ephemeral" => [
- "events" => [],
- ],
-
- "state" => [
- "events" => [],
- ],
-
- "summary" => [
- "m.heroes" => [],
- "m.invited_member_count" => 0,
- "m.joined_member_count" => 1,
- ],
-
- "timeline" => [
- "events" => [
- (new RoomMemberEvent($user->getId(), $user->getId(), MembershipState::JOIN))->toJsonEncodeable(),
- (new RoomMessageEvent($user->getId(), "Hallo Test Nachricht"))->toJsonEncodeable(),
- ],
- "limited" => false,
- "prev_batch" => "",
- ],
-
- "unread_notifications" => [
- "highlight_count" => random_int(0, 1),
- "notification_count" => random_int(0, 10),
- ],
-
- "unread_thread_notifications" => new \stdClass(),
- ];
+ left join room_memberships
+ on rooms.id = room_memberships.room_id
+ where room_memberships.user_id = :user_id
+ SQL, [
+ "user_id" => $user->getId(),
+ ])->fetchAll();
+
+ $invitedRooms = [];
+ $joinedRooms = [];
+ $knockedRooms = [];
+ $leftRooms = [];
+
+ foreach ($rooms as $room) {
+ $events = Database::getInstance()->query(<<<SQL
+ select * from room_events
+ where room_id = :room_id
+ SQL, [
+ "room_id" => $room["room_id"],
+ #"limit" => ($filter["room"]["timeline"]["limit"] ?? false) ? "limit " . $filter["room"]["timeline"]["limit"] : "",
+ ])->fetchAll();
+
+ if ($since === "" && MembershipState::tryFrom($room["state"]) === MembershipState::JOIN) {
+ $joinedRooms[$room["room_id"]] = new JoinedRoom(
+ accountData: new AccountData([]),
+ ephemeral: new Ephemeral([]),
+ state: new State([]),
+ summary: new RoomSummary(
+ heroes: [],
+ invitedMemberCount: 0,
+ joinedMemberCount: 1,
+ ),
+ timeline: new Timeline(
+ events: array_map([RoomEvent::class, "transformEvent"], $events),
+ limited: false,# $filter["room"]["timeline"]["limit"] ?? false,
+ previousBatch: null,
+ ),
+ unreadNotifications: new UnreadNotificationCounts(0, 0),
+ unreadThreadNotifications: [],
+ );
}
}
- return new JsonResponse([
- "account_data" => [
- "events" => [
+ return new JsonResponse(new ClientSyncGetResponse(
+ nextBatch: "1",
- ],
- ],
+ accountData: new AccountData([]),
- "device_lists" => [
- "changed" => [],
- "left" => [],
- ],
+ deviceLists: new DeviceLists([], []),
- "device_one_time_keys_count" => [
+ deviceOneTimeKeysCount: [
"signed_curve25519" => 10,
],
- "next_batch" => "next_batch_id",
-
- "presence" => [
- "events" => [
- (new PresenceEvent(sender: $user->getId()))->toJsonEncodeable(),
- ],
- ],
-
- "rooms" => [
- "invite" => new \stdClass(),
- "join" => $joinedRooms,
- "knock" => new \stdClass(),
- "leave" => new \stdClass(),
- ],
-
- "to_device" => [
- "events" => [],
- ],
- ]);
+ presence: new Presence([
+ new PresenceEvent(
+ sender: $user->getId(),
+ presence: $setPresence,
+ ),
+ ]),
+
+ rooms: new Rooms(
+ $invitedRooms,
+ $joinedRooms,
+ $knockedRooms,
+ $leftRooms,
+ ),
+
+ toDevice: new ToDevice([]),
+ ));
}
}
diff --git a/src/Controllers/UserController.php b/src/Controllers/UserController.php
index a056e1d..d102160 100755
--- a/src/Controllers/UserController.php
+++ b/src/Controllers/UserController.php
@@ -2,8 +2,10 @@
namespace App\Controllers;
+use App\Database;
use App\Errors\UnauthorizedError;
use App\Models\User;
+use App\Support\RequestValidator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -25,8 +27,31 @@ class UserController
throw new UnauthorizedError();
}
+ $userId = $request->get("userId");
+ if ($user->getId() !== $userId) {
+ throw new UnauthorizedError();
+ }
+
+ $body = json_decode($request->getContent(), true);
+ RequestValidator::validateJson();
+
+ $filterId = md5($userId . random_bytes(512));
+
+ Database::getInstance()->query(<<<SQL
+ insert into filters (id, account_data, event_fields, event_format, presence, room, user_id)
+ values (:id, :account_data, :event_fields, :event_format, :presence, :room, :user_id)
+ SQL, [
+ "id" => $filterId,
+ "account_data" => isset($body["account_data"]) ? json_encode($body["account_data"]) : null,
+ "event_fields" => isset($body["event_fields"]) ? json_encode($body["event_fields"]) : null,
+ "event_format" => isset($body["event_format"]) ? json_encode($body["event_format"]) : null,
+ "presence" => isset($body["presence"]) ? json_encode($body["presence"]) : null,
+ "room" => isset($body["room"]) ? json_encode($body["room"]) : null,
+ "user_id" => $userId,
+ ]);
+
return new JsonResponse([
- "filter_id" => "1234",
+ "filter_id" => $filterId,
]);
}
}