diff --git a/src/Appwrite/Auth/Key.php b/src/Appwrite/Auth/Key.php index 5fda012eaf..5143b243bf 100644 --- a/src/Appwrite/Auth/Key.php +++ b/src/Appwrite/Auth/Key.php @@ -52,6 +52,15 @@ class Key return $this->usage; } + /** + * Decode the given secret key into a Key object, containing the project ID, type, role, scopes, and name. + * Can be a stored API key or a dynamic key (JWT). + * + * @param Document $project + * @param string $key + * @return Key + * @throws Exception + */ public static function decode( Document $project, string $key diff --git a/src/Appwrite/Platform/Workers/Migrations.php b/src/Appwrite/Platform/Workers/Migrations.php index 4cae89f352..3c0055e637 100644 --- a/src/Appwrite/Platform/Workers/Migrations.php +++ b/src/Appwrite/Platform/Workers/Migrations.php @@ -193,6 +193,7 @@ class Migrations extends Action protected function generateAPIKey(Document $project): string { $jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 86400, 0); + $apiKey = $jwt->encode([ 'projectId' => $project->getId(), 'usage' => false, diff --git a/tests/unit/Auth/KeyTest.php b/tests/unit/Auth/KeyTest.php new file mode 100644 index 0000000000..78c4866a41 --- /dev/null +++ b/tests/unit/Auth/KeyTest.php @@ -0,0 +1,57 @@ + $projectId,]); + $decoded = Key::decode($project, $key); + + $this->assertEquals($projectId, $decoded->getProjectId()); + $this->assertEquals(API_KEY_DYNAMIC, $decoded->getType()); + $this->assertEquals(Auth::USER_ROLE_APPS, $decoded->getRole()); + $this->assertEquals(\array_merge($scopes, $roleScopes), $decoded->getScopes()); + } + + private static function generateKey( + string $projectId, + bool $usage, + array $scopes, + ): string + { + $jwt = new JWT( + key: System::getEnv('_APP_OPENSSL_KEY_V1'), + algo: 'HS256', + maxAge: 86400, + leeway: 0, + ); + + $apiKey = $jwt->encode([ + 'projectId' => $projectId, + 'usage' => $usage, + 'scopes' => $scopes, + ]); + + return API_KEY_DYNAMIC . '_' . $apiKey; + } +} \ No newline at end of file