diff --git a/app/init.php b/app/init.php index 971986920b..55781a89b1 100644 --- a/app/init.php +++ b/app/init.php @@ -1910,9 +1910,38 @@ App::setResource( fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false ); -App::setResource('previewHostname', function (Request $request) { - // TODO: @Meldiron Allow in production too for internal communication (authorized with secret) - if (App::isDevelopment()) { +/** + * JWT key from x-appwrite-key header. + * + * @return array Decoded key-value pair from JWT + */ +App::setResource('dynamicKey', function (Request $request) { + $apiKey = $request->getHeader('x-appwrite-key', ''); + + if (empty($apiKey) || !\str_contains($apiKey, '_')) { + return []; + } + + [ $keyType, $authKey ] = \explode('_', $apiKey, 2); + + if($keyType !== API_KEY_DYNAMIC) { + return []; + } + + $jwtObj = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 86400, 0); + + try { + $payload = $jwtObj->decode($authKey); + } catch (JWTException $error) { + return []; + } + + return $payload; + +}, ['request']); + +App::setResource('previewHostname', function (Request $request, array $dynamicKey) { + if (App::isDevelopment() || $dynamicKey['overrideHostname'] ?? false) { $host = $request->getQuery('appwrite-hostname', $request->getHeader('x-appwrite-hostname', '')); if (!empty($host)) { return $host; @@ -1920,4 +1949,4 @@ App::setResource('previewHostname', function (Request $request) { } return ''; -}, ['request']); +}, ['request', 'dynamicKey']); diff --git a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php index bc577a7d08..eb8d31ea59 100644 --- a/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php +++ b/src/Appwrite/Platform/Modules/Functions/Workers/Builds.php @@ -738,8 +738,17 @@ class Builds extends Action ], ]; + $jwtObj = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 0); + $apiKey = $jwtObj->encode([ + 'overrideHostname' => true + ]); + // TODO: @Meldiron if becomes too slow, do concurrently foreach ($configs as $key => $config) { + $config['headers'] = \array_merge($config['headers'] ?? [], [ + 'x-appwrite-key' => API_KEY_DYNAMIC . '_' . $apiKey + ]); + $response = $client->fetch( url: 'http://appwrite-browser:3000/v1/screenshots', method: 'POST',