32    private const TLS_KEY_ON_COMPLETION = 
"completion";
 
   34    public const MOJANG_AUDIENCE = 
"api://auth-minecraft-services/multiplayer";
 
   48    private bool $authenticated = 
false;
 
   49    private ?
string $clientPublicKeyDer = 
null;
 
   56        private string $issuer,
 
   57        private string $mojangPublicKeyDer,
 
   58        private string $clientDataJwt,
 
   59        private bool $authRequired,
 
   60        \Closure $onCompletion
 
   62        $this->
storeLocal(self::TLS_KEY_ON_COMPLETION, $onCompletion);
 
 
   67            $this->clientPublicKeyDer = $this->validateChain();
 
   70            $disconnectMessage = $e->getDisconnectMessage();
 
 
   75    private function validateChain() : string{
 
   76        $claims = AuthJwtHelper::validateOpenIdAuthToken($this->jwt, $this->mojangPublicKeyDer, issuer: $this->issuer, audience: self::MOJANG_AUDIENCE);
 
   78        $this->authenticated = 
true;
 
   80        $clientDerKey = base64_decode($claims->cpk, strict: 
true);
 
   81        if($clientDerKey === 
false){
 
   82            throw new VerifyLoginException(
"Invalid client public key: base64 error decoding");
 
   85        AuthJwtHelper::validateSelfSignedToken($this->clientDataJwt, $clientDerKey);
 
   95        $callback = $this->fetchLocal(self::TLS_KEY_ON_COMPLETION);
 
   96        $callback($this->authenticated, $this->authRequired, $this->error instanceof 
NonThreadSafeValue ? $this->error->
deserialize() : $this->error, $this->clientPublicKeyDer);