summaryrefslogtreecommitdiff
path: root/src/Controllers/Client/KeyController.php
blob: 5e3245be4b346acf7e70f4ae3dc374fe6acc5e45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
<?php

namespace App\Controllers\Client;

use App\Database;
use App\Models\User;
use App\Support\RequestValidator;
use Matrix\Responses\ClientKeysUploadPostResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;

class KeyController
{
  #[Route(path: "/_matrix/client/r0/keys/upload", methods: ["POST"])]
  #[Route(path: "/_matrix/client/v3/keys/upload", methods: ["POST"])]
  public function upload(Request $request): Response
  {
    $user = User::authenticateWithRequest($request);
    $body = json_decode($request->getContent(), true);
    RequestValidator::validateJson();

    if (! empty($body["device_keys"])) {
      if ($body["device_keys"]["user_id"] !== $user->getId()) {}
      if ($body["device_keys"]["user_id"] !== $user->getDeviceId()) {}
      
      Database::getInstance()->query(<<<SQL
        insert into device_keys (supported_algorithms, keys, signatures, user_id, device_id)
        values (:supported_algorithms, :keys, :signatures, :user_id, :device_id)
      SQL, [
        "supported_algorithms" => json_encode($body["device_keys"]["algorithms"]),
        "keys" => json_encode($body["device_keys"]["keys"]),
        "signatures" => json_encode($body["device_keys"]["signatures"]),
        "user_id" => $user->getId(),
        "device_id" => $user->getDeviceId(),
      ]);
    }

    $oneTimeKeys = $body["one_time_keys"];
    if (! empty($body["fallback_keys"])) {
      $oneTimeKeys += $body["fallback_keys"];
    }
    
    foreach ($oneTimeKeys as $identifier => $object) {
      $identifierParts = explode(":", $identifier);

      $algorithm = $identifierParts[0];
      $id = $identifierParts[1];

      $signatures = array_values($object["signatures"])[0];
      $signatureIdentifier = array_keys($signatures)[0];
      $signatureAlgorithm = explode(":", $signatureIdentifier)[0];
      $signatureKey = array_values($signatures)[0];

      $deviceId = explode(":", $signatureIdentifier)[1];
      
      Database::getInstance()->query(<<<SQL
        insert into one_time_keys (id, key, algorithm, signature_key, signature_algorithm, is_fallback, user_id, device_id)
        values (:id, :key, :algorithm, :signature_key, :signature_algorithm, :is_fallback, :user_id, :device_id)
      SQL, [
        "id" => $id,
        "key" => $object["key"],
        "algorithm" => $algorithm,
        "signature_key" => $signatureKey,
        "signature_algorithm" => $signatureAlgorithm,
        "is_fallback" => ($object["fallback"] ?? false) ?: 0,
        "user_id" => $user->getId(),
        "device_id" => $deviceId,
      ]);
    }

    # TODO: do that per algorithm
    $currentCountOneTimeKeys = Database::getInstance()
      ->query("select count(id) from one_time_keys where user_id=:userId and is_fallback=false", [
        "userId" => $user->getId(),
      ])
      ->fetchColumn();

    return new JsonResponse(new ClientKeysUploadPostResponse([
      #"curve25519" => 0,
      "signed_curve25519" => $currentCountOneTimeKeys,
    ]));
  }
  
  #[Route(path: "/_matrix/client/v3/keys/query", methods: ["POST"])]
  public function query(Request $request): Response
  {
    $user = User::authenticateWithRequest($request);
    $body = json_decode($request->getContent(), true);
    RequestValidator::validateJson();

    $deviceKeys = $body["device_keys"];
    $timeout = $body["timeout"] ?? 10000;

    foreach ($deviceKeys as $keysUserId => $deviceIds) {}

    return new JsonResponse([
      "device_keys" => [],
    ]);
  }

  #[Route(path: "/_matrix/client/v3/keys/claim", methods: ["POST"])]
  public function claim(Request $request): Response
  {
    $user = User::authenticateWithRequest($request);
    $body = json_decode($request->getContent(), true);
    RequestValidator::validateJson();
    
    return new JsonResponse();
  }
}