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(<< $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(<< $roomId, "user_id" => $user->getId(), "state" => MembershipState::JOIN->value, ]); return new JsonResponse([ "room_id" => $roomId, ]); } /** * GET /_matrix/client/v3/directory/room/{roomAlias} * * @see https://spec.matrix.org/v1.15/client-server-api/#get_matrixclientv3directoryroomroomalias */ public function resolveAlias(Request $request): Response { $alias = $request->attributes->get("roomAlias"); $roomAlias = Parser::parseRoomAlias($alias); # TODO: on parse error => 400 $roomId = null; if ($roomAlias["server"] != $_ENV["DOMAIN"]) { # TODO: federation API resolve $roomId = -1; } else { $room = Database::getInstance()->query(<< $roomAlias["name"], ])->fetch(); $roomId = $room["id"] ?? null; } if (empty($roomId)) { throw new AppException( ErrorCode::NOT_FOUND, "Room alias $alias not found.", Response::HTTP_NOT_FOUND ); } return new JsonResponse([ "room_id" => $roomId, "servers" => [], ]); } 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} * * @see https://spec.matrix.org/v1.15/client-server-api/#put_matrixclientv3roomsroomidsendeventtypetxnid */ public function send(Request $request): Response { $accessToken = str_replace("Bearer ", "", $request->headers->get("authorization") ?: ""); $user = User::fetchWithAccessToken($accessToken); if (empty($user)) { throw new UnauthorizedError(); } $roomId = $request->attributes->get("roomId"); $eventType = EventType::from($request->attributes->get("eventType")); $transactionId = $request->attributes->get("txnId"); $body = json_decode($request->getContent(), true); RequestValidator::validateJson(); $message = $body["body"]; $messageType = MessageType::from($body["msgtype"]); $eventId = "\$" . md5(random_bytes(512)) . ":" . $_ENV["DOMAIN"]; $event = new RoomMessageEvent( id: $eventId, sender: $user->getId(), originServerTimestamp: new \DateTime("now"), content: [ "body" => $message, "msgtype" => $messageType->value, ], unsigned: [ "age" => 1234, "membership" => MembershipState::JOIN->value, ], roomId: $roomId, ); $event->insert(); return new JsonResponse([ "event_id" => $eventId, ]); } }