From e63ea439d64b49a9276cebd63dc8d91ac977e3ef Mon Sep 17 00:00:00 2001
From: Dave Mc Nicoll <dave.mcnicoll@cslsj.qc.ca>
Date: Fri, 31 May 2024 19:00:04 +0000
Subject: [PATCH] - Added JsonWebToken encoder

---
 src/Authorize/Bearer/JsonWebTokenDecoder.php |  7 ++--
 src/Authorize/Bearer/JsonWebTokenEncoder.php | 39 ++++++++++++++++++++
 src/Authorize/Header/BearerMethod.php        |  2 +-
 3 files changed, 43 insertions(+), 5 deletions(-)

diff --git a/src/Authorize/Bearer/JsonWebTokenDecoder.php b/src/Authorize/Bearer/JsonWebTokenDecoder.php
index 34215f2..90e1ff6 100644
--- a/src/Authorize/Bearer/JsonWebTokenDecoder.php
+++ b/src/Authorize/Bearer/JsonWebTokenDecoder.php
@@ -8,10 +8,9 @@ class JsonWebTokenDecoder
 
     protected array $payload;
 
-    protected JsonWebTokenAlgorithmEnum $algrithm;
-
     public function __construct(
-        public string $encoded
+        public string $encoded,
+        public string $secretKey,
     ) {}
 
     protected function parse() : bool
@@ -42,7 +41,7 @@ class JsonWebTokenDecoder
                 }
             }
 
-            JsonWebTokenValidate::validateSignature($this->header['alg'], getenv('LEAN_RANDOM'), $encodedHeader, $encodedPayload, $signature);
+            JsonWebTokenValidate::validateSignature($this->header['alg'], $this->secretKey, $encodedHeader, $encodedPayload, $signature);
         }
         catch(\Throwable $t) {
             throw new JsonWebTokenDecodingError($t->getMessage(), $t->getCode(), $t);
diff --git a/src/Authorize/Bearer/JsonWebTokenEncoder.php b/src/Authorize/Bearer/JsonWebTokenEncoder.php
index f510a8c..a49992d 100644
--- a/src/Authorize/Bearer/JsonWebTokenEncoder.php
+++ b/src/Authorize/Bearer/JsonWebTokenEncoder.php
@@ -4,9 +4,48 @@ namespace Ulmus\User\Authorize\Bearer;
 
 class JsonWebTokenEncoder
 {
+    protected string $token;
+
+    protected array $header = [
+        "typ" => "JWT",
+    ];
+
+    public function __construct(
+        public array $payload,
+        public string $secretKey,
+        protected JsonWebTokenAlgorithmEnum $algorithm = JsonWebTokenAlgorithmEnum::HS256,
+    ) {
+        $this->header['alg'] = $this->algorithm->name;
+    }
 
     public static function base64url_encode($data) : string
     {
         return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
     }
+
+    public function encode() : string
+    {
+        $jsonHeader = json_encode($this->header);
+        $jsonPayload = json_encode($this->payload);
+
+        $encodedHeader = static::base64url_encode($jsonHeader);
+        $encodedPayload = static::base64url_encode($jsonPayload);
+
+        list($algo, $method, ) = $this->algorithm->phpAlgoMethods();
+
+        switch($method) {
+            case 'hash_hmac':
+                $signature = hash_hmac($algo, sprintf("%s.%s", $encodedHeader, $encodedPayload), $this->secretKey, true);
+                break;
+        }
+
+        $this->token = sprintf("%s.%s.%s", $encodedHeader, $encodedPayload, static::base64url_encode($signature));
+
+        return $this->getToken();
+    }
+
+    public function getToken() : string
+    {
+        return $this->token;
+    }
 }
\ No newline at end of file
diff --git a/src/Authorize/Header/BearerMethod.php b/src/Authorize/Header/BearerMethod.php
index 53be05c..ccd010c 100644
--- a/src/Authorize/Header/BearerMethod.php
+++ b/src/Authorize/Header/BearerMethod.php
@@ -47,7 +47,7 @@ class BearerMethod implements MethodInterface
 
     public function autodetectTokenType() : BearerTokenTypeEnum
     {
-        $this->jwt = new JsonWebTokenDecoder($this->token);
+        $this->jwt = new JsonWebTokenDecoder($this->token, getenv('LEAN_RANDOM'));
 
         if ( $this->jwt->isJWT() ) {
             return BearerTokenTypeEnum::JsonWebToken;