From acc3b9d5ecc4f8e952e385234efa91e59ec750c5 Mon Sep 17 00:00:00 2001
From: Sean Fisher <srtfisher@gmail.com>
Date: Mon, 26 Feb 2024 14:36:56 -0500
Subject: [PATCH 1/2] Allow the claims to be added to a JWT

---
 plugin.php                 | 16 ++++++++++++++--
 tests/RestApiGuardTest.php | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 2 deletions(-)

diff --git a/plugin.php b/plugin.php
index 7434adc..cadc9bd 100644
--- a/plugin.php
+++ b/plugin.php
@@ -321,8 +321,6 @@ function get_jwt_secret(): string {
 /**
  * Generate a JSON Web Token (JWT).
  *
- * The JWT payload is intentionally not filtered to prevent
- *
  * @param int|null         $expiration The expiration time of the JWT in seconds or null for no expiration.
  * @param WP_User|int|null $user The user to include in the JWT or null for no user.
  * @return string
@@ -349,6 +347,20 @@ function generate_jwt( ?int $expiration = null, WP_User|int|null $user = null ):
 
 		$payload['sub']        = $user->ID;
 		$payload['user_login'] = $user->user_login;
+
+		/**
+		 * Filter the additional claims to include in the JWT.
+		 *
+		 * The filer cannot modify any existing claims, only add new ones.
+		 *
+		 * @param array<string, mixed> $additional_claims The additional claims to include in the JWT.
+		 * @param WP_User              $user The user to include in the JWT.
+		 */
+		$additional_claims = apply_filters( 'rest_api_guard_jwt_additional_claims', [], $user );
+
+		if ( is_array( $additional_claims ) ) {
+			$payload = array_merge( $additional_claims, $payload );
+		}
 	}
 
 	return JWT::encode( $payload, get_jwt_secret(), 'HS256' );
diff --git a/tests/RestApiGuardTest.php b/tests/RestApiGuardTest.php
index 2b523f0..2d87c2d 100644
--- a/tests/RestApiGuardTest.php
+++ b/tests/RestApiGuardTest.php
@@ -2,8 +2,10 @@
 namespace Alley\WP\REST_API_Guard\Tests;
 
 use Firebase\JWT\JWT;
+use Firebase\JWT\Key;
 
 use function Alley\WP\REST_API_Guard\generate_jwt;
+use function Alley\WP\REST_API_Guard\get_jwt_secret;
 
 use const Alley\WP\REST_API_Guard\SETTINGS_KEY;
 
@@ -281,4 +283,35 @@ public static function jwtDataProviderAuthenticated(): array {
 			'empty' => [ 'invalid', '' ],
 		];
 	}
+
+	public function test_additional_jwt_claims() {
+		add_filter(
+			'rest_api_guard_jwt_additional_claims',
+			function ( $claims, $user ) {
+				$claims['user_email'] = $user->user_email;
+				$claims['sub']        = 1234;
+
+				return $claims;
+			},
+			10,
+			2,
+		);
+
+		add_filter( 'rest_api_guard_user_authentication_jwt', fn () => true );
+
+		$user = static::factory()->user->create_and_get();
+
+		$token = generate_jwt( user: $user );
+
+		$this
+			->with_header( 'Authorization', "Bearer {$token}" )
+			->get( '/wp-json/wp/v2/users/me' )
+			->assertOk();
+
+		// Ensure the additional claim is present.
+		$decoded = JWT::decode( $token, new Key( get_jwt_secret(), 'HS256' ) );
+
+		$this->assertEquals( $user->user_email, $decoded->user_email );
+		$this->assertEquals( $user->ID, $decoded->sub ); // Ensure it cannot overwrite a claim.
+	}
 }

From b2a2be868c4659a9dffd818cb37eb8a5002fb4f1 Mon Sep 17 00:00:00 2001
From: Sean Fisher <srtfisher@gmail.com>
Date: Mon, 26 Feb 2024 14:38:20 -0500
Subject: [PATCH 2/2] CHANGELOG

---
 CHANGELOG.md | 4 ++++
 README.md    | 2 +-
 plugin.php   | 5 +++--
 readme.txt   | 2 +-
 4 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index e7c56db..4a4303b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,10 @@
 
 All notable changes to `wp-rest-guard` will be documented in this file.
 
+## v1.2.1 - 2024-02-26
+
+- Allow the claims to be added to added to a generated JWT via filter.
+
 ## v1.2.0 - 2024-02-22
 
 - Add support for authenticated users interacting with the REST API.
diff --git a/README.md b/README.md
index a4e90c7..573f177 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 # REST API Guard
 
-Stable tag: 1.2.0
+Stable tag: 1.2.1
 
 Requires at least: 6.0
 
diff --git a/plugin.php b/plugin.php
index cadc9bd..37d1098 100644
--- a/plugin.php
+++ b/plugin.php
@@ -354,9 +354,10 @@ function generate_jwt( ?int $expiration = null, WP_User|int|null $user = null ):
 		 * The filer cannot modify any existing claims, only add new ones.
 		 *
 		 * @param array<string, mixed> $additional_claims The additional claims to include in the JWT.
-		 * @param WP_User              $user The user to include in the JWT.
+		 * @param WP_User|null         $user The user to include in the JWT.
+		 * @param array<string, mixed> $payload The payload of the JWT.
 		 */
-		$additional_claims = apply_filters( 'rest_api_guard_jwt_additional_claims', [], $user );
+		$additional_claims = apply_filters( 'rest_api_guard_jwt_additional_claims', [], $user, $payload );
 
 		if ( is_array( $additional_claims ) ) {
 			$payload = array_merge( $additional_claims, $payload );
diff --git a/readme.txt b/readme.txt
index e9e0902..0f8f867 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,5 +1,5 @@
 === REST API Guard ===
-Stable tag: 1.2.0
+Stable tag: 1.2.1
 Requires at least: 6.0
 Tested up to: 6.3
 Requires PHP: 8.0