diff options
author | Daniel Weipert <git@mail.dweipert.de> | 2025-08-20 14:58:10 +0200 |
---|---|---|
committer | Daniel Weipert <git@mail.dweipert.de> | 2025-08-20 14:58:10 +0200 |
commit | 6dc0447320272aaae51a98eb6606597019f986d3 (patch) | |
tree | 0acb527801a1d9eac943b5e0b0ccb33e610cd755 /src/Controllers | |
parent | d08f4c83470c25d35d24594bd73e4effdac191a0 (diff) |
login produces devices and tokens
Diffstat (limited to 'src/Controllers')
-rw-r--r-- | src/Controllers/KeyController.php | 34 | ||||
-rw-r--r-- | src/Controllers/LoginController.php | 54 |
2 files changed, 77 insertions, 11 deletions
diff --git a/src/Controllers/KeyController.php b/src/Controllers/KeyController.php index a999e40..5050d9b 100644 --- a/src/Controllers/KeyController.php +++ b/src/Controllers/KeyController.php @@ -2,6 +2,10 @@ namespace App\Controllers; +use App\Errors\AppException; +use App\Errors\ErrorCode; +use App\Models\Tokens; +use App\Support\RequestValidator; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\JsonResponse; @@ -29,4 +33,34 @@ class KeyController public function query(string $serverName): Response {} + + /** + * POST /_matrix/client/v3/refresh + */ + public function refresh(): Response + { + $request = Request::createFromGlobals(); + RequestValidator::validateJson(); + $body = json_decode($request->getContent(), true); + + $tokens = Tokens::fetchWithRefreshToken($body["refresh_token"]); + + if (empty($tokens)) { + throw new AppException( + ErrorCode::UNKNOWN_TOKEN, + "Soft logged out", + Response::HTTP_UNAUTHORIZED, + ["soft_logout" => true], + ); + } + + $newTokens = Tokens::new($tokens->getUserId(), $tokens->getDeviceId()); + $newTokens->insert(); + + return new JsonResponse([ + "access_token" => $newTokens->getAccessToken(), + "expires_in" => $newTokens->getExpiresIn(), + "refresh_token" => $newTokens->getRefreshToken(), + ]); + } } diff --git a/src/Controllers/LoginController.php b/src/Controllers/LoginController.php index 1ff234c..fd48f25 100644 --- a/src/Controllers/LoginController.php +++ b/src/Controllers/LoginController.php @@ -7,7 +7,9 @@ use App\Errors\AppException; use App\Errors\ErrorCode; use App\Errors\UnknownError; use App\Models\Device; +use App\Models\Tokens; use App\Models\User; +use App\Support\RequestValidator; use App\Types\LoginFlow; use App\Types\LoginType; use App\Types\UserRegistrationKind; @@ -36,6 +38,7 @@ class LoginController { $request = Request::createFromGlobals(); $body = json_decode($request->getContent(), true); + RequestValidator::validateJson(); // validate login type $loginType = null; @@ -53,24 +56,43 @@ class LoginController $user = User::fetchWithPassword($userId, $body["password"]); if (! $user) { - throw new AppException(ErrorCode::FORBIDDEN, "Invalid credentials.", Response::HTTP_FORBIDDEN); + throw new AppException(ErrorCode::FORBIDDEN, "Invalid credentials", Response::HTTP_FORBIDDEN); } $deviceId = $body["device_id"] ?? ""; - $device = $user->fetchDevice($deviceId); - if (! $device) { + $device = null; + $tokens = null; + + // create new device with tokens + if (empty($deviceId)) { $device = Device::new( $user->getId(), initialDisplayName: $body["initial_device_display_name"] ?? "", ); + $device->insert(); + + $tokens = Tokens::new($userId, $device->getId()); + $tokens->insert(); + } else { // fetch existing device and tokens + $device = $user->fetchDevice($deviceId); + $tokens = Tokens::fetch($userId, $device->getId()); + + if (empty($tokens)) { + throw new AppException( + ErrorCode::UNKNOWN_TOKEN, + "Soft logged out", + Response::HTTP_UNAUTHORIZED, + ["soft_logout" => true], + ); + } } return new JsonResponse([ - "access_token" => $device->getAccessToken(), + "access_token" => $tokens->getAccessToken(), "device_id" => $device->getId(), - "expires_in_ms" => 60000, - "refresh_token" => $device->getRefreshToken(), + "expires_in_ms" => $tokens->getExpiresIn(), + "refresh_token" => $tokens->getRefreshToken(), "user_id" => $user->getId(), #"well_known" => [], ]); @@ -83,8 +105,15 @@ class LoginController { $request = Request::createFromGlobals(); $body = json_decode($request->getContent(), true); + RequestValidator::validateJson(); - $kind = UserRegistrationKind::from($request->query->get("kind") ?? "user"); + // validate kind + $kind = null; + try { + $kind = UserRegistrationKind::from($request->query->get("kind") ?? "user"); + } catch (\ValueError $error) { + throw new UnknownError("Bad registration kind.", Response::HTTP_BAD_REQUEST); + } $username = $body["username"]; $userId = "@$username:$_ENV[DOMAIN]"; @@ -95,16 +124,19 @@ class LoginController ]); $device_id = $body["device_id"] ?? ""; - $initialDeviceDisplayName = $body["initialDeviceDisplayName"] ?? ""; + $initialDeviceDisplayName = $body["initial_device_display_name"] ?? ""; $device = Device::new($userId, $device_id, $initialDeviceDisplayName); $device->insert(); + $tokens = Tokens::new($userId, $device->getId()); + $tokens->insert(); + return new JsonResponse([ - "access_token" => $device->getAccessToken(), + "access_token" => $tokens->getAccessToken(), "device_id" => $device->getId(), - "expires_in_ms" => 60000, - "refresh_token" => $device->getRefreshToken(), + "expires_in_ms" => $tokens->getExpiresIn(), + "refresh_token" => $tokens->getRefreshToken(), "user_id" => $userId, ]); } |