diff --git a/src/Authentication/JWTAuthenticator.php b/src/Authentication/JWTAuthenticator.php index 35181ce..6fef89a 100644 --- a/src/Authentication/JWTAuthenticator.php +++ b/src/Authentication/JWTAuthenticator.php @@ -3,6 +3,7 @@ namespace Firesphere\GraphQLJWT\Authentication; use BadMethodCallException; +use DateInterval; use DateTimeImmutable; use Exception; use Firesphere\GraphQLJWT\Extensions\MemberExtension; @@ -225,6 +226,7 @@ public function authenticate(array $data, HTTPRequest $request, ValidationResult * @param Member|MemberExtension $member * @return Token * @throws ValidationException + * @throws Exception */ public function generateToken(HTTPRequest $request, Member $member): Token { @@ -242,31 +244,30 @@ public function generateToken(HTTPRequest $request, Member $member): Token // Create builder for this record $builder = new Builder(); - $now = DBDatetime::now()->getTimestamp(); $token = $builder // Configures the issuer (iss claim) - ->setIssuer($request->getHeader('Origin')) + ->issuedBy($request->getHeader('Origin')) // Configures the audience (aud claim) - ->setAudience(Director::absoluteBaseURL()) + ->permittedFor(Director::absoluteBaseURL()) // Configures the id (jti claim), replicating as a header item - ->setId($uniqueID, true) + ->identifiedBy($uniqueID)->withHeader('jti', $uniqueID) // Configures the time that the token was issue (iat claim) - ->setIssuedAt($now) + ->issuedAt($this->getNow()) // Configures the time that the token can be used (nbf claim) - ->setNotBefore($now + $config->get('nbf_time')) + ->canOnlyBeUsedAfter($this->getNowPlus($config->get('nbf_time'))) // Configures the expiration time of the token (nbf claim) - ->setExpiration($now + $config->get('nbf_expiration')) - // Set renew expiration - ->set('rexp', $now + $config->get('nbf_refresh_expiration')) + ->expiresAt($this->getNowPlus($config->get('nbf_expiration'))) + // Set renew expiration (unix timestamp) + ->withClaim('rexp', $this->getNowPlus($config->get('nbf_refresh_expiration')->getTimestamp())) // Configures a new claim, called "rid" - ->set('rid', $record->ID) + ->withClaim('rid', $record->ID) // Set the subject, which is the member - ->setSubject($member->getJWTData()) + ->relatedTo($member->getJWTData()) // Sign the key with the Signer's key - ->sign($this->getSigner(), $this->getPrivateKey()); + ->getToken($this->getSigner(), $this->getPrivateKey()); // Return the token - return $token->getToken(); + return $token; } /** @@ -285,7 +286,7 @@ public function validateToken(?string $token, HTTPrequest $request): array // Find local record for this token /** @var JWTRecord $record */ - $record = JWTRecord::get()->byID($parsedToken->getClaim('rid')); + $record = JWTRecord::get()->byID($parsedToken->claims()->get('rid')); if (!$record) { return [null, TokenStatusEnum::STATUS_INVALID]; } @@ -297,8 +298,7 @@ public function validateToken(?string $token, HTTPrequest $request): array } // If the token is invalid, but not because it has expired, fail - $now = new DateTimeImmutable(DBDatetime::now()->getValue()); - if (!$parsedToken->isExpired($now)) { + if (!$parsedToken->isExpired($this->getNow())) { return [$record, TokenStatusEnum::STATUS_INVALID]; } @@ -346,15 +346,17 @@ protected function parseToken(?string $token): ?Token * @param HTTPRequest $request * @param JWTRecord $record * @return bool + * @throws Exception */ protected function validateParsedToken(Token $parsedToken, HTTPrequest $request, JWTRecord $record): bool { - $now = DBDatetime::now()->getTimestamp(); + // @todo - upgrade + // @see https://lcobucci-jwt.readthedocs.io/en/latest/upgrading/#replace-tokenverify-and-tokenvalidate-with-validation-api $validator = new ValidationData(); $validator->setIssuer($request->getHeader('Origin')); $validator->setAudience(Director::absoluteBaseURL()); $validator->setId($record->UID); - $validator->setCurrentTime($now); + $validator->setCurrentTime($this->getNow()->getTimestamp()); return $parsedToken->validate($validator); } @@ -363,12 +365,12 @@ protected function validateParsedToken(Token $parsedToken, HTTPrequest $request, * * @param Token $parsedToken * @return bool + * @throws Exception */ protected function canTokenBeRenewed(Token $parsedToken): bool { - $renewBefore = $parsedToken->getClaim('rexp'); - $now = DBDatetime::now()->getTimestamp(); - return $renewBefore > $now; + $renewBefore = $parsedToken->claims()->get('rexp'); + return $renewBefore > $this->getNow()->getTimestamp(); } /** @@ -407,4 +409,23 @@ protected function getEnv(string $key, $default = null): ?string } return $default; } + + /** + * @return DateTimeImmutable + * @throws Exception + */ + protected function getNow(): DateTimeImmutable + { + return new DateTimeImmutable(DBDatetime::now()->getValue()); + } + + /** + * @param int $seconds + * @return DateTimeImmutable + * @throws Exception + */ + protected function getNowPlus($seconds) + { + return $this->getNow()->add(new DateInterval(sprintf("PT%dS", $seconds))); + } }