mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Fix request fetching
This commit is contained in:
Generated
+25
-25
@@ -756,16 +756,16 @@
|
||||
},
|
||||
{
|
||||
"name": "google/protobuf",
|
||||
"version": "v4.33.3",
|
||||
"version": "v4.33.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/protocolbuffers/protobuf-php.git",
|
||||
"reference": "281537d44d6c270606354e65bfa75a0969dbd629"
|
||||
"reference": "22d28025cda0d223a2e48c2e16c5284ecc9f5402"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/281537d44d6c270606354e65bfa75a0969dbd629",
|
||||
"reference": "281537d44d6c270606354e65bfa75a0969dbd629",
|
||||
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/22d28025cda0d223a2e48c2e16c5284ecc9f5402",
|
||||
"reference": "22d28025cda0d223a2e48c2e16c5284ecc9f5402",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -794,9 +794,9 @@
|
||||
"proto"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.33.3"
|
||||
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.33.4"
|
||||
},
|
||||
"time": "2026-01-09T21:49:37+00:00"
|
||||
"time": "2026-01-12T17:58:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
@@ -4267,16 +4267,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.33.35",
|
||||
"version": "0.33.36",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "82b139fb04f30045db51b0d322224f222da32313"
|
||||
"reference": "fd835ed77e1cdf327067ce4e650cce86304e7098"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/82b139fb04f30045db51b0d322224f222da32313",
|
||||
"reference": "82b139fb04f30045db51b0d322224f222da32313",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/fd835ed77e1cdf327067ce4e650cce86304e7098",
|
||||
"reference": "fd835ed77e1cdf327067ce4e650cce86304e7098",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4309,9 +4309,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.35"
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.36"
|
||||
},
|
||||
"time": "2025-12-12T08:33:52+00:00"
|
||||
"time": "2026-01-12T07:32:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
@@ -5014,22 +5014,22 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
"version": "0.8.5",
|
||||
"version": "0.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/swoole.git",
|
||||
"reference": "e42b6b8e44c457a7b35d8a857d7af1d67d667c58"
|
||||
"reference": "14b00277c35a258cb263706fd4e05c50368feb4f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/e42b6b8e44c457a7b35d8a857d7af1d67d667c58",
|
||||
"reference": "e42b6b8e44c457a7b35d8a857d7af1d67d667c58",
|
||||
"url": "https://api.github.com/repos/utopia-php/swoole/zipball/14b00277c35a258cb263706fd4e05c50368feb4f",
|
||||
"reference": "14b00277c35a258cb263706fd4e05c50368feb4f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-swoole": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/framework": "0.33.35"
|
||||
"utopia-php/framework": "0.33.36"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
@@ -5059,9 +5059,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/swoole/issues",
|
||||
"source": "https://github.com/utopia-php/swoole/tree/0.8.5"
|
||||
"source": "https://github.com/utopia-php/swoole/tree/0.8.6"
|
||||
},
|
||||
"time": "2025-12-15T14:03:23+00:00"
|
||||
"time": "2026-01-12T07:57:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/system",
|
||||
@@ -5439,16 +5439,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "1.8.10",
|
||||
"version": "1.8.11",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "28217b1d722ad2b217559c3a371eafd4d070614d"
|
||||
"reference": "936404bbcbf4cd692bac102f2912b6c97ac87215"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/28217b1d722ad2b217559c3a371eafd4d070614d",
|
||||
"reference": "28217b1d722ad2b217559c3a371eafd4d070614d",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/936404bbcbf4cd692bac102f2912b6c97ac87215",
|
||||
"reference": "936404bbcbf4cd692bac102f2912b6c97ac87215",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5484,9 +5484,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.8.10"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.8.11"
|
||||
},
|
||||
"time": "2026-01-09T11:40:35+00:00"
|
||||
"time": "2026-01-12T08:41:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "brianium/paratest",
|
||||
|
||||
+2
-2
@@ -1211,7 +1211,7 @@ services:
|
||||
- MAILDEV_INCOMING_PASS=${_APP_SMTP_PASSWORD}
|
||||
|
||||
request-catcher-webhook: # used mainly for dev tests (mock HTTP webhook)
|
||||
image: appwrite/requestcatcher:1.0.0
|
||||
image: appwrite/requestcatcher:1.1.0
|
||||
container_name: appwrite-requestcatcher-webhook
|
||||
<<: *x-logging
|
||||
ports:
|
||||
@@ -1220,7 +1220,7 @@ services:
|
||||
- appwrite
|
||||
|
||||
request-catcher-sms: # used mainly for dev tests (mock SMS auth secret)
|
||||
image: appwrite/requestcatcher:1.0.0
|
||||
image: appwrite/requestcatcher:1.1.0
|
||||
container_name: appwrite-requestcatcher-sms
|
||||
<<: *x-logging
|
||||
ports:
|
||||
|
||||
+95
-14
@@ -152,7 +152,7 @@ abstract class Scope extends TestCase
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use assertLastRequest instead. Used only historically in webhook tests
|
||||
* @deprecated Use getLastRequestForProject instead. Used only historically in webhook tests
|
||||
*/
|
||||
protected function getLastRequest(): array
|
||||
{
|
||||
@@ -163,31 +163,112 @@ abstract class Scope extends TestCase
|
||||
* Get the last webhook request for a specific project.
|
||||
* Polls with retry to handle parallel test race conditions.
|
||||
*/
|
||||
protected function getLastRequestForProject(string $projectId, int $maxAttempts = 10, int $delayMs = 500): array
|
||||
{
|
||||
$hostname = 'request-catcher-webhook';
|
||||
protected function getLastRequestForProject(
|
||||
string $projectId,
|
||||
string $type = self::REQUEST_TYPE_WEBHOOK,
|
||||
array $queryParams = [],
|
||||
int $maxAttempts = 10,
|
||||
int $delayMs = 500,
|
||||
?callable $probe = null
|
||||
): array {
|
||||
$hostname = match ($type) {
|
||||
self::REQUEST_TYPE_WEBHOOK => 'request-catcher-webhook',
|
||||
self::REQUEST_TYPE_SMS => 'request-catcher-sms',
|
||||
default => throw new \Exception('Invalid request catcher type.'),
|
||||
};
|
||||
$enforceProjectId = $type === self::REQUEST_TYPE_WEBHOOK;
|
||||
|
||||
if (empty($queryParams)) {
|
||||
$queryParams = [
|
||||
'header_X-Appwrite-Webhook-Project-Id' => $projectId,
|
||||
];
|
||||
}
|
||||
|
||||
$query = http_build_query($queryParams);
|
||||
|
||||
sleep(2);
|
||||
|
||||
for ($attempt = 0; $attempt < $maxAttempts; $attempt++) {
|
||||
$request = json_decode(file_get_contents('http://' . $hostname . ':5000/__last_request__'), true);
|
||||
if ($request) {
|
||||
$request['data'] = json_decode($request['data'], true);
|
||||
$requests = json_decode(file_get_contents('http://' . $hostname . ':5000/__find_request__?' . $query), true);
|
||||
if (is_array($requests)) {
|
||||
for ($i = count($requests) - 1; $i >= 0; $i--) {
|
||||
$request = $this->decodeRequestData($requests[$i]);
|
||||
if ($probe !== null) {
|
||||
try {
|
||||
$probe($request);
|
||||
return $request;
|
||||
} catch (\Throwable $error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$requestProjectId = $request['headers']['X-Appwrite-Webhook-Project-Id'] ?? '';
|
||||
if ($requestProjectId === $projectId) {
|
||||
return $request;
|
||||
if ($enforceProjectId) {
|
||||
$requestProjectId = $request['headers']['X-Appwrite-Webhook-Project-Id'] ?? '';
|
||||
if ($requestProjectId === $projectId) {
|
||||
return $request;
|
||||
}
|
||||
} else {
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
usleep($delayMs * 1000);
|
||||
}
|
||||
|
||||
$request = json_decode(file_get_contents('http://' . $hostname . ':5000/__last_request__'), true);
|
||||
if ($request) {
|
||||
$request['data'] = json_decode($request['data'], true);
|
||||
$requests = json_decode(file_get_contents('http://' . $hostname . ':5000/__find_request__?' . $query), true);
|
||||
if (is_array($requests)) {
|
||||
for ($i = count($requests) - 1; $i >= 0; $i--) {
|
||||
$request = $this->decodeRequestData($requests[$i]);
|
||||
if ($probe !== null) {
|
||||
try {
|
||||
$probe($request);
|
||||
return $request;
|
||||
} catch (\Throwable $error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($enforceProjectId) {
|
||||
$requestProjectId = $request['headers']['X-Appwrite-Webhook-Project-Id'] ?? '';
|
||||
if ($requestProjectId === $projectId) {
|
||||
return $request;
|
||||
}
|
||||
} else {
|
||||
return $request;
|
||||
}
|
||||
}
|
||||
}
|
||||
return $request ?? [];
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
protected function decodeRequestData(array $request): array
|
||||
{
|
||||
if (!array_key_exists('data', $request)) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
if (is_array($request['data'])) {
|
||||
return $request;
|
||||
}
|
||||
|
||||
if (!is_string($request['data']) || $request['data'] === '') {
|
||||
return $request;
|
||||
}
|
||||
|
||||
$decoded = json_decode($request['data'], true);
|
||||
if (json_last_error() === JSON_ERROR_NONE) {
|
||||
$request['data'] = $decoded;
|
||||
return $request;
|
||||
}
|
||||
|
||||
parse_str($request['data'], $parsed);
|
||||
if (!empty($parsed)) {
|
||||
$request['data'] = $parsed;
|
||||
}
|
||||
|
||||
return $request;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2530,14 +2530,23 @@ class AccountCustomClientTest extends Scope
|
||||
|
||||
$userId = $response['body']['userId'];
|
||||
|
||||
$smsRequest = $this->assertLastRequest(function (array $request) use ($number) {
|
||||
$this->assertEquals('Appwrite Mock Message Sender', $request['headers']['User-Agent']);
|
||||
$this->assertEquals('username', $request['headers']['X-Username']);
|
||||
$this->assertEquals('password', $request['headers']['X-Key']);
|
||||
$this->assertEquals('POST', $request['method']);
|
||||
$this->assertEquals('+123456789', $request['data']['from']);
|
||||
$this->assertEquals($number, $request['data']['to']);
|
||||
}, Scope::REQUEST_TYPE_SMS);
|
||||
$smsRequest = $this->getLastRequestForProject(
|
||||
$this->getProject()['$id'],
|
||||
Scope::REQUEST_TYPE_SMS,
|
||||
[
|
||||
'header_X-Username' => 'username',
|
||||
'header_X-Key' => 'password',
|
||||
'method' => 'POST',
|
||||
],
|
||||
probe: function (array $request) use ($number) {
|
||||
$this->assertEquals('Appwrite Mock Message Sender', $request['headers']['User-Agent'] ?? null);
|
||||
$this->assertEquals('username', $request['headers']['X-Username'] ?? null);
|
||||
$this->assertEquals('password', $request['headers']['X-Key'] ?? null);
|
||||
$this->assertEquals('POST', $request['method'] ?? null);
|
||||
$this->assertEquals('+123456789', $request['data']['from'] ?? null);
|
||||
$this->assertEquals($number, $request['data']['to'] ?? null);
|
||||
}
|
||||
);
|
||||
|
||||
$data['token'] = $smsRequest['data']['message'];
|
||||
$data['id'] = $userId;
|
||||
@@ -2887,15 +2896,30 @@ class AccountCustomClientTest extends Scope
|
||||
|
||||
$tokenCreatedAt = $response['body']['$createdAt'];
|
||||
|
||||
$smsRequest = $this->assertLastRequest(function ($request) use ($tokenCreatedAt) {
|
||||
$this->assertArrayHasKey('data', $request);
|
||||
$this->assertArrayHasKey('time', $request);
|
||||
$this->assertArrayHasKey('message', $request['data'], "Last request missing message: " . \json_encode($request));
|
||||
$phone = $data['phone'] ?? '';
|
||||
$smsQuery = [
|
||||
'header_X-Username' => 'username',
|
||||
'header_X-Key' => 'password',
|
||||
'method' => 'POST',
|
||||
];
|
||||
|
||||
// Ensure we are not using token from last sms login
|
||||
$tokenRecievedAt = $request['time'];
|
||||
$this->assertGreaterThan($tokenCreatedAt, $tokenRecievedAt);
|
||||
}, Scope::REQUEST_TYPE_SMS);
|
||||
$smsRequest = $this->getLastRequestForProject(
|
||||
$this->getProject()['$id'],
|
||||
Scope::REQUEST_TYPE_SMS,
|
||||
$smsQuery,
|
||||
probe: function (array $request) use ($tokenCreatedAt, $phone) {
|
||||
$this->assertArrayHasKey('data', $request);
|
||||
$this->assertArrayHasKey('time', $request);
|
||||
$this->assertArrayHasKey('message', $request['data'], "Last request missing message: " . \json_encode($request));
|
||||
if (!empty($phone)) {
|
||||
$this->assertEquals($phone, $request['data']['to'] ?? null);
|
||||
}
|
||||
|
||||
// Ensure we are not using token from last sms login
|
||||
$tokenRecievedAt = $request['time'];
|
||||
$this->assertGreaterThan($tokenCreatedAt, $tokenRecievedAt);
|
||||
}
|
||||
);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
|
||||
Reference in New Issue
Block a user