%PDF- %PDF-
Direktori : /home/bitrix/www/local/php_interface/lib/vendor/kreait/firebase-php/src/Firebase/ |
Current File : //home/bitrix/www/local/php_interface/lib/vendor/kreait/firebase-php/src/Firebase/Auth.php |
<?php namespace Kreait\Firebase; use Firebase\Auth\Token\Domain\Generator as TokenGenerator; use Firebase\Auth\Token\Domain\Verifier as IdTokenVerifier; use Firebase\Auth\Token\Exception\InvalidSignature; use Firebase\Auth\Token\Exception\InvalidToken; use Firebase\Auth\Token\Exception\IssuedInTheFuture; use Kreait\Firebase\Auth\ApiClient; use Kreait\Firebase\Auth\UserRecord; use Kreait\Firebase\Exception\Auth\InvalidPassword; use Kreait\Firebase\Exception\Auth\RevokedIdToken; use Kreait\Firebase\Exception\Auth\UserNotFound; use Kreait\Firebase\Exception\InvalidArgumentException; use Kreait\Firebase\Util\DT; use Kreait\Firebase\Util\JSON; use Kreait\Firebase\Value\ClearTextPassword; use Kreait\Firebase\Value\Email; use Kreait\Firebase\Value\PhoneNumber; use Kreait\Firebase\Value\Provider; use Kreait\Firebase\Value\Uid; use Lcobucci\JWT\Parser; use Lcobucci\JWT\Token; use Psr\Http\Message\UriInterface; class Auth { /** * @var ApiClient */ private $client; /** * @var TokenGenerator */ private $tokenGenerator; /** * @var IdTokenVerifier */ private $idTokenVerifier; public function __construct(ApiClient $client, TokenGenerator $customToken, IdTokenVerifier $idTokenVerifier) { $this->client = $client; $this->tokenGenerator = $customToken; $this->idTokenVerifier = $idTokenVerifier; } public function getApiClient(): ApiClient { return $this->client; } public function getUser($uid): UserRecord { $uid = $uid instanceof Uid ? $uid : new Uid($uid); $response = $this->client->getAccountInfo((string) $uid); $data = JSON::decode((string) $response->getBody(), true); if (empty($data['users'][0])) { throw UserNotFound::withCustomMessage('No user with uid "'.$uid.'" found.'); } return UserRecord::fromResponseData($data['users'][0]); } /** * @param int $maxResults * @param int $batchSize * * @return \Generator|UserRecord[] */ public function listUsers(int $maxResults = null, int $batchSize = null): \Generator { $maxResults = $maxResults ?? 1000; $batchSize = $batchSize ?? 1000; $pageToken = null; $count = 0; do { $response = $this->client->downloadAccount($batchSize, $pageToken); $result = JSON::decode((string) $response->getBody(), true); foreach ((array) ($result['users'] ?? []) as $userData) { yield UserRecord::fromResponseData($userData); if (++$count === $maxResults) { return; } } $pageToken = $result['nextPageToken'] ?? null; } while ($pageToken); } /** * Creates a new user with the provided properties. * * @param array|Request\CreateUser $properties * * @throws InvalidArgumentException if invalid properties have been provided * * @return UserRecord */ public function createUser($properties): UserRecord { $request = $properties instanceof Request\CreateUser ? $properties : Request\CreateUser::withProperties($properties); $response = $this->client->createUser($request); $uid = JSON::decode((string) $response->getBody(), true)['localId']; return $this->getUser($uid); } /** * Updates the given user with the given properties. * * @param Uid|string $uid * @param array|Request\UpdateUser $properties * * @throws InvalidArgumentException if invalid properties have been provided * * @return UserRecord */ public function updateUser($uid, $properties): UserRecord { $request = $properties instanceof Request\UpdateUser ? $properties : Request\UpdateUser::withProperties($properties); $request = $request->withUid($uid); $response = $this->client->updateUser($request); $uid = JSON::decode((string) $response->getBody(), true)['localId']; return $this->getUser($uid); } /** * @param Email|string $email * @param ClearTextPassword|string $password * * @return UserRecord */ public function createUserWithEmailAndPassword($email, $password): UserRecord { return $this->createUser( Request\CreateUser::new() ->withUnverifiedEmail($email) ->withClearTextPassword($password) ); } public function getUserByEmail($email): UserRecord { $email = $email instanceof Email ? $email : new Email($email); $response = $this->client->getUserByEmail((string) $email); $data = JSON::decode((string) $response->getBody(), true); if (empty($data['users'][0])) { throw UserNotFound::withCustomMessage('No user with email "'.$email.'" found.'); } return UserRecord::fromResponseData($data['users'][0]); } public function getUserByPhoneNumber($phoneNumber): UserRecord { $phoneNumber = $phoneNumber instanceof PhoneNumber ? $phoneNumber : new PhoneNumber($phoneNumber); $response = $this->client->getUserByPhoneNumber((string) $phoneNumber); $data = JSON::decode((string) $response->getBody(), true); if (empty($data['users'][0])) { throw UserNotFound::withCustomMessage('No user with phone number "'.$phoneNumber.'" found.'); } return UserRecord::fromResponseData($data['users'][0]); } public function createAnonymousUser(): UserRecord { return $this->createUser(Request\CreateUser::new()); } /** * @param Uid|string $uid * @param ClearTextPassword|string $newPassword * * @return UserRecord */ public function changeUserPassword($uid, $newPassword): UserRecord { return $this->updateUser($uid, Request\UpdateUser::new()->withClearTextPassword($newPassword)); } /** * @param Uid|string $uid * @param Email|string $newEmail * * @return UserRecord */ public function changeUserEmail($uid, $newEmail): UserRecord { return $this->updateUser($uid, Request\UpdateUser::new()->withEmail($newEmail)); } /** * @param Uid|string $uid * * @return UserRecord */ public function enableUser($uid): UserRecord { return $this->updateUser($uid, Request\UpdateUser::new()->markAsEnabled()); } /** * @param Uid|string $uid * * @return UserRecord */ public function disableUser($uid): UserRecord { return $this->updateUser($uid, Request\UpdateUser::new()->markAsDisabled()); } /** * @param Uid|string $uid */ public function deleteUser($uid) { $uid = $uid instanceof Uid ? $uid : new Uid($uid); try { $this->client->deleteUser((string) $uid); } catch (UserNotFound $e) { throw UserNotFound::withCustomMessage('No user with uid "'.$uid.'" found.'); } } /** * @param Uid|string $uid * @param UriInterface|string $continueUrl */ public function sendEmailVerification($uid, $continueUrl = null, string $locale = null) { $response = $this->client->exchangeCustomTokenForIdAndRefreshToken( $this->createCustomToken($uid) ); $idToken = JSON::decode((string) $response->getBody(), true)['idToken']; $this->client->sendEmailVerification($idToken, (string) $continueUrl, $locale); } /** * @param Email|string $email * @param UriInterface|string|null $continueUrl */ public function sendPasswordResetEmail($email, $continueUrl = null, string $locale = null) { $email = $email instanceof Email ? $email : new Email($email); $this->client->sendPasswordResetEmail((string) $email, (string) $continueUrl, $locale); } /** * @param Uid|string $uid * @param array $attributes * * @return UserRecord */ public function setCustomUserAttributes($uid, array $attributes): UserRecord { return $this->updateUser($uid, Request\UpdateUser::new()->withCustomAttributes($attributes)); } /** * @param Uid|string $uid * @param array $claims * * @return Token */ public function createCustomToken($uid, array $claims = null): Token { $claims = $claims ?? []; $uid = $uid instanceof Uid ? $uid : new Uid($uid); return $this->tokenGenerator->createCustomToken($uid, $claims); } /** * Verifies a JWT auth token. Returns a Promise with the tokens claims. Rejects the promise if the token * could not be verified. If checkRevoked is set to true, verifies if the session corresponding to the * ID token was revoked. If the corresponding user's session was invalidated, a RevokedToken * exception is thrown. If not specified the check is not applied. * * NOTE: Allowing time inconsistencies might impose a security risk. Do this only when you are not able * to fix your environment's time to be consistent with Google's servers. This parameter is here * for backwards compatibility reasons, and will be removed in the next major version. You * shouldn't rely on it. * * @param Token|string $idToken the JWT to verify * @param bool $checkIfRevoked whether to check if the ID token is revoked * @param bool $allowTimeInconsistencies whether to allow tokens that have mismatching timestamps * * @throws InvalidToken * @throws IssuedInTheFuture * @throws RevokedIdToken * @throws InvalidSignature * * @return Token the verified token */ public function verifyIdToken($idToken, bool $checkIfRevoked = null, bool $allowTimeInconsistencies = null): Token { $checkIfRevoked = $checkIfRevoked ?? false; $allowTimeInconsistencies = $allowTimeInconsistencies ?? false; try { $verifiedToken = $this->idTokenVerifier->verifyIdToken($idToken); } catch (IssuedInTheFuture $e) { if (!$allowTimeInconsistencies) { throw $e; } $verifiedToken = $e->getToken(); } catch (InvalidToken $e) { $verifiedToken = $idToken instanceof Token ? $idToken : (new Parser())->parse($idToken); if (stripos($e->getMessage(), 'authentication time') !== false) { $authTime = $verifiedToken->getClaim('auth_time', false); if ($authTime && !$allowTimeInconsistencies && $authTime > time()) { throw $e; } } else { throw $e; } } if ($checkIfRevoked && $allowTimeInconsistencies) { throw new InvalidToken($verifiedToken, 'Allowing mismatching timestamps cannot be combined with token revokation checks.'); } if ($checkIfRevoked) { $tokenAuthenticatedAt = DT::toUTCDateTimeImmutable($verifiedToken->getClaim('auth_time')); $validSince = $this->getUser($verifiedToken->getClaim('sub'))->tokensValidAfterTime; if ($validSince && ($tokenAuthenticatedAt < $validSince)) { throw new RevokedIdToken($verifiedToken); } } return $verifiedToken; } /** * Verifies wether the given email/password combination is correct and returns * a UserRecord when it is, an Exception otherwise. * * This method has the side effect of changing the last login timestamp of the * given user. The recommended way to authenticate users in a client/server * environment is to use a Firebase Client SDK to authenticate the user * and to send an ID Token generated by the client back to the server. * * @param Email|string $email * @param ClearTextPassword|string $password * * @throws InvalidPassword if the given password does not match the given email address * * @return UserRecord if the combination of email and password is correct */ public function verifyPassword($email, $password): UserRecord { $email = $email instanceof Email ? $email : new Email($email); $password = $password instanceof ClearTextPassword ? $password : new ClearTextPassword($password); $response = $this->client->verifyPassword((string) $email, (string) $password); $uid = JSON::decode((string) $response->getBody(), true)['localId']; return $this->getUser($uid); } /** * Revokes all refresh tokens for the specified user identified by the uid provided. * In addition to revoking all refresh tokens for a user, all ID tokens issued * before revocation will also be revoked on the Auth backend. Any request with an * ID token generated before revocation will be rejected with a token expired error. * * @param Uid|string $uid the user whose tokens are to be revoked */ public function revokeRefreshTokens($uid) { $uid = $uid instanceof Uid ? $uid : new Uid($uid); $this->client->revokeRefreshTokens((string) $uid); } public function unlinkProvider($uid, $provider): UserRecord { $uid = $uid instanceof Uid ? $uid : new Uid($uid); $provider = array_map(function ($provider) { return $provider instanceof Provider ? $provider : new Provider($provider); }, (array) $provider); $response = $this->client->unlinkProvider($uid, $provider); $uid = JSON::decode((string) $response->getBody(), true)['localId']; return $this->getUser($uid); } }