diff options
Diffstat (limited to 'src/Controllers')
| -rw-r--r-- | src/Controllers/Client/ClientController.php | 332 | ||||
| -rw-r--r-- | src/Controllers/Client/KeyController.php | 34 | ||||
| -rwxr-xr-x | src/Controllers/Client/UserController.php | 61 |
3 files changed, 409 insertions, 18 deletions
diff --git a/src/Controllers/Client/ClientController.php b/src/Controllers/Client/ClientController.php index cdce91e..28aea66 100644 --- a/src/Controllers/Client/ClientController.php +++ b/src/Controllers/Client/ClientController.php @@ -18,6 +18,7 @@ use App\Support\Parser; use App\Support\RequestValidator; use Matrix\Data\AccountData; use Matrix\Data\Capabilities; +use Matrix\Data\Capability\RoomVersionsCapability; use Matrix\Data\DeviceLists; use Matrix\Data\LoginFlow; use Matrix\Data\Presence; @@ -32,6 +33,7 @@ use Matrix\Data\Room\Timeline; use Matrix\Data\Room\UnreadNotificationCounts; use Matrix\Data\Ruleset; use Matrix\Data\ToDevice; +use Matrix\Data\UserId; use Matrix\Enums\AuthenticationType; use Matrix\Enums\ErrorCode; use Matrix\Enums\LoginType; @@ -128,7 +130,7 @@ class ClientController return new JsonResponse(new ClientLoginPostResponse( accessToken: $tokens->getAccessToken(), - deviceId:$device->getId(), + deviceId: $device->getId(), userId: $user->getId(), expiresInMilliseconds: $tokens->getExpiresIn(), refreshToken: $tokens->getRefreshToken(), @@ -356,10 +358,130 @@ class ClientController { $user = User::authenticateWithRequest($request); + $notificationActionBase = [ + "notify", + ]; + $notificationActionSound = $notificationActionBase + [ + [ + "set_tweak" => "sound", + "value" => "default", + ], + ]; + $notificationActionHighlight = $notificationActionBase + [ + [ + "set_tweak" => "highlight", + ], + ]; + $notifactionActionSoundHighlight = $notificationActionSound + [ + [ + "set_tweak" => "highlight", + ], + ]; + + // @see https://spec.matrix.org/v1.16/client-server-api/#predefined-rules return new JsonResponse([ "global" => new Ruleset( content: [ new PushRule( + ruleId: ".m.rule.contains_user_name", + default: true, + enabled: false, + pattern: Parser::parseUser($user->getId())["username"], + actions: [ + ...$notifactionActionSoundHighlight, + ], + ), + ], + + override: [ + new PushRule( + ruleId: ".m.rule.master", + default: true, + enabled: false, + conditions: [], + actions: [], + ), + + new PushRule( + ruleId: ".m.rule.suppress_notices", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "content.msgtype", + pattern: "m.notice", + ), + ], + actions: [], + ), + + new PushRule( + ruleId: ".m.rule.invite_for_me", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.room.member", + ), + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "content.membership", + pattern: "invite", + ), + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "state_key", + pattern: $user->getId(), + ), + ], + actions: [ + ...$notificationActionSound, + ], + ), + + + new PushRule( + ruleId: ".m.rule.member_event", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.room.member", + ), + ], + actions: [], + ), + + new PushRule( + ruleId: ".m.rule.is_user_mention", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_PROPERTY_CONTAINS, + key: "content.m\\.mentions.user_ids", + value: $user->getId(), + ), + ], + actions: [ + ...$notifactionActionSoundHighlight, + ], + ), + + new PushRule( + ruleId: ".m.rule.contains_display_name", + default: true, + enabled: false, + conditions: [ + new PushCondition( + kind: PushConditionKind::CONTAINS_DISPLAY_NAME, + ), + ], actions: [ "notify", [ @@ -370,20 +492,117 @@ class ClientController "set_tweak" => "highlight", ], ], + ), + + new PushRule( + ruleId: ".m.rule.is_room_mention", default: true, enabled: true, - pattern: "alice", - ruleId: ".m.rule.contains_user_name", + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_PROPERTY_IS, + key: "content.m\\.mentions.room", + value: true, + ), + new PushCondition( + kind: PushConditionKind::SENDER_NOTIFICATION_PERMISSION, + key: "room", + ), + ], + actions: [ + ...$notificationActionHighlight, + ], + ), + + new PushRule( + ruleId: ".m.rule.roomnotif", + default: true, + enabled: false, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "content.body", + pattern: "@room", + ), + new PushCondition( + kind: PushConditionKind::SENDER_NOTIFICATION_PERMISSION, + key: "room", + ), + ], + actions: [ + "notify", + [ + "set_tweak" => "highlight", + ], + ], ), - ], - override: [ new PushRule( + ruleId: ".m.rule.tombstone", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.room.tombstone", + ), + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "state_key", + pattern: "", + ), + ], + actions: [ + ...$notificationActionHighlight, + ], + ), + + new PushRule( + ruleId: ".m.rule.reaction", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.reaction", + ), + ], actions: [], - conditions: [], + ), + + new PushRule( + ruleId: ".m.rule.room.server_acl", default: true, - enabled: false, - ruleId: ".m.rule.master", + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.room.server_acl", + ), + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "state_key", + pattern: "", + ), + ], + actions: [], + ), + + new PushRule( + ruleId: ".m.rule.suppress_edits", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_PROPERTY_IS, + key: "content.m\\.relates_to.rel_type", + value: "m.replace", + ), + ], + actions: [], ), ], @@ -392,27 +611,95 @@ class ClientController underride: [ new PushRule( + ruleId: ".m.rule.call", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.call.invite", + ) + ], actions: [ "notify", [ "set_tweak" => "sound", "value" => "ring", ], - [ - "set_tweak" => "highlight", - "value" => false, - ], ], + ), + + new PushRule( + ruleId: ".m.rule.encrypted_room_one_to_one", + default: true, + enabled: true, conditions: [ new PushCondition( + kind: PushConditionKind::ROOM_MEMBER_COUNT, + is: "2", + ), + new PushCondition( kind: PushConditionKind::EVENT_MATCH, key: "type", - pattern: "m.call.invite", - ) + pattern: "m.room.encrypted", + ), + ], + actions: [ + ...$notificationActionSound, ], + ), + + new PushRule( + ruleId: ".m.rule.room_one_to_one", default: true, enabled: true, - ruleId: ".m.rule.master", + conditions: [ + new PushCondition( + kind: PushConditionKind::ROOM_MEMBER_COUNT, + is: "2", + ), + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.room.message", + ), + ], + actions: [ + ...$notificationActionSound, + ], + ), + + new PushRule( + ruleId: ".m.rule.message", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.room.message", + ), + ], + actions: [ + "notify", + ], + ), + + new PushRule( + ruleId: ".m.rule.encrypted", + default: true, + enabled: true, + conditions: [ + new PushCondition( + kind: PushConditionKind::EVENT_MATCH, + key: "type", + pattern: "m.room.encrypted", + ), + ], + actions: [ + "notify", + ], ), ], ), @@ -424,7 +711,12 @@ class ClientController { $user = User::authenticateWithRequest($request); - return new JsonResponse(new Capabilities()); + return new JsonResponse(new Capabilities( + roomVersions: new RoomVersionsCapability( + available: ["1" => "stable"], + default: "1", + ), + )); } #[Route(path: "/_matrix/client/v3/voip/turnServer", methods: ["GET"])] @@ -439,4 +731,12 @@ class ClientController "username" => "", ]); } + + #[Route(path: "/_matrix/client/v3/thirdparty/protocols", methods: ["GET"])] + public function thirdPartyProtocols(Request $request): Response + { + $user = User::authenticateWithRequest($request); + + return new JsonResponse(new \stdClass()); + } } diff --git a/src/Controllers/Client/KeyController.php b/src/Controllers/Client/KeyController.php index 5e3245b..47f8933 100644 --- a/src/Controllers/Client/KeyController.php +++ b/src/Controllers/Client/KeyController.php @@ -2,7 +2,9 @@ namespace App\Controllers\Client; +use App\App; use App\Database; +use App\Models\Device; use App\Models\User; use App\Support\RequestValidator; use Matrix\Responses\ClientKeysUploadPostResponse; @@ -93,10 +95,38 @@ class KeyController $deviceKeys = $body["device_keys"]; $timeout = $body["timeout"] ?? 10000; - foreach ($deviceKeys as $keysUserId => $deviceIds) {} + $downloadedDeviceKeys = []; + foreach ($deviceKeys as $keysUserId => $deviceIds) { + foreach ($deviceIds as $deviceId) { + $result = Database::getInstance() + ->query("select * from device_keys where user_id=:user_id and device_id=:device_id", [ + "user_id" => $keysUserId, + "device_id" => $deviceId, + ]) + ->fetch(); + $device = Device::fetch($deviceId, $keysUserId); + + $downloadedDeviceKeys[$keysUserId][$deviceId] = [ + "algorithms" => $result["supported_algorithms"], + "keys" => $result["keys"], + "signatures" => $result["signatures"], + "device_id" => $result["device_id"], + "user_id" => $result["user_id"], + "unsigned" => [ + "device_display_name" => $device->getName(), + ], + ]; + } + } + + // apply timeout + if ($timeout > 0) { + sleep(intval(($timeout / 1000) - App::getExectionTime())); + } + return new JsonResponse([ - "device_keys" => [], + "device_keys" => empty($downloadedDeviceKeys) ? new \stdClass() : $downloadedDeviceKeys, ]); } diff --git a/src/Controllers/Client/UserController.php b/src/Controllers/Client/UserController.php index 277ba78..63442ec 100755 --- a/src/Controllers/Client/UserController.php +++ b/src/Controllers/Client/UserController.php @@ -4,10 +4,12 @@ namespace App\Controllers\Client; use App\Database; use App\Errors\AppException; +use App\Errors\NotFoundError; use App\Errors\UnauthorizedError; use App\Models\Device; use App\Models\User; use App\Support\RequestValidator; +use Cassandra\Exception\UnauthorizedException; use Matrix\Enums\ErrorCode; use Matrix\Responses\ClientAccountWhoamiGetResponse; use Symfony\Component\HttpFoundation\Request; @@ -120,4 +122,63 @@ class UserController return new JsonResponse(); } + + #[Route(path: "/_matrix/client/v3/user/{userId}/account_data/{type}", methods: ["GET"])] + public function getAccountData(Request $request): Response + { + $user = User::authenticateWithRequest($request); + + $userId = $request->attributes->get("userId"); + $type = $request->attributes->get("type"); + + if ($user->getId() !== $userId) { + throw new UnauthorizedError("Cannot get account data for other users."); + } + + $value = Database::getInstance() + ->query("select value from account_data where user_id=:user_id and key=:key", [ + "user_id" => $userId, + "key" => $type, + ]) + ->fetchColumn(); + + if (empty($value)) { + throw new NotFoundError("Account data not found."); + } + + return new JsonResponse([ + $type => $value, + ]); + } + + #[Route(path: "/_matrix/client/v3/user/{userId}/account_data/{type}", methods: ["PUT"])] + public function setAccountData(Request $request): Response + { + $user = User::authenticateWithRequest($request); + $body = json_decode($request->getContent(), true); + RequestValidator::validateJson(); + + $userId = $request->attributes->get("userId"); + $type = $request->attributes->get("type"); + + if ($user->getId() !== $userId) { + throw new UnauthorizedError("Cannot add account data for other users."); + } + + Database::getInstance() + ->query( + <<<SQL + insert into account_data (key, value, user_id) values (:key, :value, :user_id) + on conflict (user_id, key) do update set + value = excluded.value + SQL, + [ + "key" => $type, + "value" => $request->getContent(), + "user_id" => $userId, + ] + ); + + return new JsonResponse(); + } } |
