getJwtFacade()->issue( $this->getSigner(), $this->getSigningKey(), function (Builder $builder, \DateTimeImmutable $immutable) use ($sub, $callable) { $builder = $builder->identifiedBy($sub) ->issuedBy($this->getConfig('claims.'.RegisteredClaims::ISSUER,'')); if ($callable !== null) { $builder = $callable($builder); } return $builder->expiresAt($this->getExpireAt($immutable)); } ); } /** * @param string $sub * @param \Closure|null $callable * @return UnencryptedToken */ public function builderRefreshToken(string $sub, ?\Closure $callable = null): UnencryptedToken { return $this->getJwtFacade()->issue( $this->getSigner(), $this->getSigningKey(), function (Builder $builder, \DateTimeImmutable $immutable) use ($sub, $callable) { $builder = $builder->identifiedBy($sub) ->issuedBy($this->getConfig('claims.'.RegisteredClaims::ISSUER,'')) ->expiresAt($this->getRefreshExpireAt($immutable)); if ($callable !== null) { $builder = $callable($builder); } return $builder->relatedTo('refresh'); } ); } /** * @param string $accessToken * @return UnencryptedToken */ public function parserAccessToken(string $accessToken): UnencryptedToken { return $this->getJwtFacade() ->parse( $accessToken, new SignedWith( $this->getSigner(), $this->getSigningKey() ), new StrictValidAt( $this->clock, $this->clock->now()->diff($this->getExpireAt($this->clock->now())) ), $this->getBlackListConstraint(), $this->refreshTokenConstraint ); } /** * @param string $refreshToken * @return UnencryptedToken */ public function parserRefreshToken(string $refreshToken): UnencryptedToken { return $this->getJwtFacade() ->parse( $refreshToken, new SignedWith( $this->getSigner(), $this->getSigningKey() ), new StrictValidAt( $this->clock, $this->clock->now()->diff($this->getRefreshExpireAt($this->clock->now())) ), $this->getBlackListConstraint(), $this->accessTokenConstraint ); } /** * @param UnencryptedToken $token * @return bool * @throws InvalidArgumentException */ public function addBlackList(UnencryptedToken $token): bool { return $this->getCacheDriver()->set($token->toString(), 1, $this->getBlackConfig('ttl', 600)); } /** * @param UnencryptedToken $token * @return bool * @throws InvalidArgumentException */ public function hasBlackList(UnencryptedToken $token): bool { return $this->getCacheDriver()->has($token->toString()); } /** * @param UnencryptedToken $token * @return bool * @throws InvalidArgumentException */ public function removeBlackList(UnencryptedToken $token): bool { return $this->getCacheDriver()->delete($token->toString()); } /** * @param string $key * @param mixed|null $default * @return mixed */ public function getConfig(string $key, mixed $default = null): mixed { return Arr::get($this->config, $key, $default); } /** * @return JwtFacade */ private function getJwtFacade(): JwtFacade { return new JwtFacade(clock: $this->clock); } /** * @return Signer */ private function getSigner(): Signer { return Arr::get($this->config, 'alg'); } /** * @return Key */ private function getSigningKey(): Key { return Arr::get($this->config, 'key'); } /** * @return DriverInterface */ private function getCacheDriver(): DriverInterface { return $this->cacheManager->getDriver($this->getBlackConfig('connection')); } /** * @param string $name * @param mixed|null $default * @return mixed */ private function getBlackConfig(string $name, mixed $default = null): mixed { return Arr::get($this->config, 'blacklist.' . $name, $default); } /** * @return Constraint */ private function getBlackListConstraint(): Constraint { return new BlackListConstraint((bool) $this->getBlackConfig('enable', false), $this->getCacheDriver()); } /** * @param \DateTimeImmutable $immutable * @return \DateTimeImmutable */ private function getExpireAt(\DateTimeImmutable $immutable): \DateTimeImmutable { return Carbon::create($immutable) ->addSeconds(Arr::get($this->config, 'ttl', 3600)) ->toDateTimeImmutable(); } /** * @param \DateTimeImmutable $immutable * @return \DateTimeImmutable */ private function getRefreshExpireAt(\DateTimeImmutable $immutable): \DateTimeImmutable { return Carbon::create($immutable) ->addSeconds(Arr::get($this->config, 'refresh_ttl', 7200)) ->toDateTimeImmutable(); } }