Merge branch '1.5.x' of https://github.com/appwrite/appwrite into feat-mfa
@@ -344,13 +344,13 @@ Things to remember when releasing SDKs:
|
||||
|
||||
## Debug
|
||||
|
||||
Appwrite uses [yasd](https://github.com/swoole/yasd) debugger, which can be made available during build of Appwrite. You can connect to the debugger using VS Code's [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension.
|
||||
Appwrite uses [XDebug](https://github.com/xdebug/xdebug) debugger, which can be made available during build of Appwrite. You can connect to the debugger using VS Code's [PHP Debug](https://marketplace.visualstudio.com/items?itemName=felixfbecker.php-debug) extension.
|
||||
|
||||
If you are in PHP Storm you don't need any plugin. Below are the settings required for remote debugger connection:
|
||||
|
||||
1. Create an init file.
|
||||
2. Duplicate **dev/yasd_init.php.stub** file and name it **dev/yasd_init.php**.
|
||||
3. Set **DEBUG** build arg in **appwrite** service in **docker-compose.yml** file.
|
||||
1. Set **DEBUG** build arg in **appwrite** service in **docker-compose.yml** file.
|
||||
2. If needed edit the **dev/xdebug.ini** file to your needs.
|
||||
3. Launch your Appwrite instance while your debugger is listening for connections.
|
||||
|
||||
### VS Code Launch Configuration
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ ENV VITE_APPWRITE_GROWTH_ENDPOINT=$VITE_APPWRITE_GROWTH_ENDPOINT
|
||||
RUN npm ci
|
||||
RUN npm run build
|
||||
|
||||
FROM appwrite/base:0.4.3 as final
|
||||
FROM appwrite/base:0.7.2 as final
|
||||
|
||||
LABEL maintainer="team@appwrite.io"
|
||||
|
||||
@@ -56,6 +56,7 @@ COPY ./public /usr/src/code/public
|
||||
COPY ./bin /usr/local/bin
|
||||
COPY ./docs /usr/src/code/docs
|
||||
COPY ./src /usr/src/code/src
|
||||
COPY ./dev /usr/src/code/dev
|
||||
|
||||
# Set Volumes
|
||||
RUN mkdir -p /storage/uploads && \
|
||||
@@ -126,9 +127,10 @@ RUN chmod +x /usr/local/bin/calc-tier-stats && \
|
||||
RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/
|
||||
|
||||
# Enable Extensions
|
||||
RUN if [ "$DEBUG" == "true" ]; then printf "zend_extension=yasd \nyasd.debug_mode=remote \nyasd.init_file=/usr/src/code/dev/yasd_init.php \nyasd.remote_port=9005 \nyasd.log_level=-1" >> /usr/local/etc/php/conf.d/yasd.ini; fi
|
||||
|
||||
RUN if [ "$DEBUG" == "true" ]; then cp /usr/src/code/dev/xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini; fi
|
||||
RUN if [ "$DEBUG" == "true" ]; then echo "opcache.enable=0" >> /usr/local/etc/php/conf.d/appwrite.ini; fi
|
||||
RUN if [ "$DEBUG" = "false" ]; then rm -rf /usr/src/code/dev; fi
|
||||
RUN if [ "$DEBUG" = "false" ]; then rm -f /usr/local/lib/php/extensions/no-debug-non-zts-20220829/xdebug.so; fi
|
||||
RUN echo "opcache.preload_user=www-data" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
RUN echo "opcache.preload=/usr/src/code/app/preload.php" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
RUN echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/appwrite.ini
|
||||
|
||||
@@ -72,7 +72,7 @@ CLI::setResource('dbForConsole', function ($pools, $cache) {
|
||||
$collections = Config::getParam('collections', [])['console'];
|
||||
$last = \array_key_last($collections);
|
||||
|
||||
if (!($dbForConsole->exists($dbForConsole->getDefaultDatabase(), $last))) { /** TODO cache ready variable using registry */
|
||||
if (!($dbForConsole->exists($dbForConsole->getDatabase(), $last))) { /** TODO cache ready variable using registry */
|
||||
throw new Exception('Tables not ready yet.');
|
||||
}
|
||||
|
||||
|
||||
@@ -1731,17 +1731,6 @@ $commonCollections = [
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('description'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 256,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => '',
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('status'),
|
||||
'type' => Database::VAR_STRING,
|
||||
@@ -1902,17 +1891,6 @@ $commonCollections = [
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('description'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 2048,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('total'),
|
||||
'type' => Database::VAR_INTEGER,
|
||||
@@ -2194,6 +2172,17 @@ $commonCollections = [
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('expired'),
|
||||
'type' => Database::VAR_BOOLEAN,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => false,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
],
|
||||
'indexes' => [
|
||||
[
|
||||
|
||||
@@ -816,6 +816,11 @@ return [
|
||||
'description' => 'Provider with the requested ID is of the incorrect type.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::PROVIDER_MISSING_CREDENTIALS => [
|
||||
'name' => Exception::PROVIDER_MISSING_CREDENTIALS,
|
||||
'description' => 'Provider with the requested ID is missing credentials.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Topics */
|
||||
Exception::TOPIC_NOT_FOUND => [
|
||||
|
||||
@@ -174,7 +174,8 @@ App::post('/v1/account')
|
||||
]);
|
||||
$user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]);
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate) {
|
||||
throw new Exception(Exception::USER_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -279,7 +280,7 @@ App::post('/v1/account/sessions/email')
|
||||
$dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$session = $dbForProject->createDocument('sessions', $session->setAttribute('$permissions', [
|
||||
Permission::read(Role::user($user->getId())),
|
||||
@@ -613,7 +614,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
$currentDocument = $dbForProject->getDocument('sessions', $current);
|
||||
if (!$currentDocument->isEmpty()) {
|
||||
$dbForProject->deleteDocument('sessions', $currentDocument->getId());
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -876,7 +877,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), (new \DateTime($expire))->getTimestamp(), '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'));
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$state['success']['query'] = URLParser::unparseQuery($query);
|
||||
$state['success'] = URLParser::unparse($state['success']);
|
||||
@@ -915,7 +916,7 @@ App::get('/v1/account/identities')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -1098,7 +1099,7 @@ App::post('/v1/account/tokens/magic-url')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
if (empty($url)) {
|
||||
$url = $request->getProtocol() . '://' . $request->getHostname() . '/auth/magic-url';
|
||||
@@ -1336,7 +1337,7 @@ App::post('/v1/account/tokens/email')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$subject = $locale->getText("emails.otpSession.subject");
|
||||
$customTemplate = $project->getAttribute('templates', [])['email.otpSession-' . $locale->default] ?? [];
|
||||
@@ -1509,9 +1510,9 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
Authorization::skip(fn () => $dbForProject->deleteDocument('tokens', $verifiedToken->getId()));
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
if ($verifiedToken->getAttribute('type') === Auth::TOKEN_TYPE_MAGIC_URL) {
|
||||
$user->setAttribute('emailVerification', true);
|
||||
@@ -1708,7 +1709,7 @@ App::post('/v1/account/tokens/phone')
|
||||
]);
|
||||
$user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]);
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
}
|
||||
|
||||
$secret = Auth::codeGenerator();
|
||||
@@ -1734,7 +1735,7 @@ App::post('/v1/account/tokens/phone')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl');
|
||||
|
||||
@@ -1894,7 +1895,7 @@ App::post('/v1/account/sessions/anonymous')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -2030,7 +2031,7 @@ App::post('/v1/account/targets/push')
|
||||
} catch (Duplicate) {
|
||||
throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS);
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -2408,7 +2409,7 @@ App::patch('/v1/account/email')
|
||||
if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) {
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email)));
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -2489,7 +2490,7 @@ App::patch('/v1/account/phone')
|
||||
if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) {
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $phone)));
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::USER_PHONE_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -2635,7 +2636,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
||||
;
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -2714,7 +2715,7 @@ App::patch('/v1/account/sessions/:sessionId')
|
||||
|
||||
// Save changes
|
||||
$dbForProject->updateDocument('sessions', $sessionId, $session);
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -2775,7 +2776,7 @@ App::delete('/v1/account/sessions')
|
||||
}
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -2860,7 +2861,7 @@ App::post('/v1/account/recovery')
|
||||
Permission::delete(Role::user($profile->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $profile->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $profile->getId());
|
||||
|
||||
$url = Template::parseURL($url);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $profile->getId(), 'secret' => $secret, 'expire' => $expire]);
|
||||
@@ -3036,7 +3037,7 @@ App::put('/v1/account/recovery')
|
||||
* the recovery token but actually we don't need it anymore.
|
||||
*/
|
||||
$dbForProject->deleteDocument('tokens', $verifiedToken->getId());
|
||||
$dbForProject->deleteCachedDocument('users', $profile->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $profile->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $profile->getId())
|
||||
@@ -3107,7 +3108,7 @@ App::post('/v1/account/verification')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$url = Template::parseURL($url);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['userId' => $user->getId(), 'secret' => $verificationSecret, 'expire' => $expire]);
|
||||
@@ -3256,7 +3257,7 @@ App::put('/v1/account/verification')
|
||||
* the verification token but actually we don't need it anymore.
|
||||
*/
|
||||
$dbForProject->deleteDocument('tokens', $verifiedToken->getId());
|
||||
$dbForProject->deleteCachedDocument('users', $profile->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $profile->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $userId)
|
||||
@@ -3329,7 +3330,7 @@ App::post('/v1/account/verification/phone')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$message = Template::fromFile(__DIR__ . '/../../config/locale/templates/sms-base.tpl');
|
||||
|
||||
@@ -3425,7 +3426,7 @@ App::put('/v1/account/verification/phone')
|
||||
* We act like we're updating and validating the verification token but actually we don't need it anymore.
|
||||
*/
|
||||
$dbForProject->deleteDocument('tokens', $verifiedToken->getId());
|
||||
$dbForProject->deleteCachedDocument('users', $profile->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $profile->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -3865,7 +3866,7 @@ App::put('/v1/account/targets/:targetId/push')
|
||||
$target->setAttribute('name', "{$device['deviceBrand']} {$device['deviceModel']}");
|
||||
|
||||
$target = $dbForProject->updateDocument('targets', $target->getId(), $target);
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
|
||||
@@ -116,7 +116,7 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro
|
||||
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('sessions', $gitHubSession->getId(), $gitHubSession));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Throwable $err) {
|
||||
$index = 0;
|
||||
do {
|
||||
@@ -521,7 +521,7 @@ App::get('/v1/avatars/initials')
|
||||
// if there is no space, try to split by `_` underscore
|
||||
$words = (count($words) == 1) ? \explode('_', \strtoupper($name)) : $words;
|
||||
|
||||
$initials = null;
|
||||
$initials = '';
|
||||
$code = 0;
|
||||
|
||||
foreach ($words as $key => $w) {
|
||||
|
||||
@@ -28,7 +28,6 @@ use Utopia\Database\Exception\Limit as LimitException;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Exception\Restricted as RestrictedException;
|
||||
use Utopia\Database\Exception\Structure as StructureException;
|
||||
use Utopia\Database\Exception\Timeout as TimeoutException;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
@@ -153,13 +152,13 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
} catch (LimitException) {
|
||||
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED, 'Attribute limit exceeded');
|
||||
} catch (\Exception $e) {
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->deleteCachedCollection('database_' . $db->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->deleteCachedCollection('database_' . $db->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
|
||||
if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) {
|
||||
$twoWayKey = $options['twoWayKey'];
|
||||
@@ -197,13 +196,13 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
|
||||
$dbForProject->deleteDocument('attributes', $attribute->getId());
|
||||
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED, 'Attribute limit exceeded');
|
||||
} catch (\Exception $e) {
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->deleteCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->deleteCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
}
|
||||
|
||||
$queueForDatabase
|
||||
@@ -358,7 +357,7 @@ function updateAttribute(
|
||||
$relatedOptions = \array_merge($relatedAttribute->getAttribute('options'), $options);
|
||||
$relatedAttribute->setAttribute('options', $relatedOptions);
|
||||
$dbForProject->updateDocument('attributes', $db->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $primaryDocumentOptions['twoWayKey'], $relatedAttribute);
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId());
|
||||
}
|
||||
} else {
|
||||
$dbForProject->updateAttribute(
|
||||
@@ -371,7 +370,7 @@ function updateAttribute(
|
||||
}
|
||||
|
||||
$attribute = $dbForProject->updateDocument('attributes', $db->getInternalId() . '_' . $collection->getInternalId() . '_' . $key, $attribute);
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collection->getId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $collection->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setContext('collection', $collection)
|
||||
@@ -496,7 +495,7 @@ App::get('/v1/databases')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -703,8 +702,8 @@ App::delete('/v1/databases/:databaseId')
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove collection from DB');
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('databases', $database->getId());
|
||||
$dbForProject->deleteCachedCollection('databases_' . $database->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('databases', $database->getId());
|
||||
$dbForProject->purgeCachedCollection('databases_' . $database->getInternalId());
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_DELETE_DATABASE)
|
||||
@@ -818,7 +817,7 @@ App::get('/v1/databases/:databaseId/collections')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -901,6 +900,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/logs')
|
||||
if ($database->isEmpty()) {
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collectionDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$collection = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $collectionDocument->getInternalId());
|
||||
|
||||
@@ -1076,7 +1076,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId')
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove collection from DB');
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_DELETE_COLLECTION)
|
||||
@@ -1672,7 +1672,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
|
||||
$cursor = \reset($cursor);
|
||||
@@ -2248,8 +2248,8 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
|
||||
$attribute = $dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'deleting'));
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->deleteCachedCollection('database_' . $db->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
|
||||
if ($attribute->getAttribute('type') === Database::VAR_RELATIONSHIP) {
|
||||
$options = $attribute->getAttribute('options');
|
||||
@@ -2270,8 +2270,8 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
|
||||
$dbForProject->updateDocument('attributes', $relatedAttribute->getId(), $relatedAttribute->setAttribute('status', 'deleting'));
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $options['relatedCollection']);
|
||||
$dbForProject->deleteCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $options['relatedCollection']);
|
||||
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2330,7 +2330,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('key', null, new Key(), 'Index Key.')
|
||||
->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE, Database::INDEX_SPATIAL, Database::INDEX_ARRAY]), 'Index type.')
|
||||
->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE, Database::INDEX_SPATIAL]), 'Index type.')
|
||||
->param('attributes', null, new ArrayList(new Key(true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of attributes to index. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' attributes are allowed, each 32 characters long.')
|
||||
->param('orders', [], new ArrayList(new WhiteList(['ASC', 'DESC'], false, Database::VAR_STRING), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of index orders. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' orders are allowed.', true)
|
||||
->inject('response')
|
||||
@@ -2453,7 +2453,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
throw new Exception(Exception::INDEX_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_CREATE_INDEX)
|
||||
@@ -2509,7 +2509,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
|
||||
@@ -2620,7 +2620,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
|
||||
$index = $dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'deleting'));
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $collectionId);
|
||||
|
||||
$queueForDatabase
|
||||
->setType(DATABASE_TYPE_DELETE_INDEX)
|
||||
@@ -2893,13 +2893,13 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
->label('sdk.offline.model', '/databases/{databaseId}/collections/{collectionId}/documents')
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
|
||||
->param('queries', [], new JSON(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('mode')
|
||||
->action(function (string $databaseId, string $collectionId, array $queries, Response $response, Database $dbForProject, string $mode) {
|
||||
$queries = Query::parseQueries($queries);
|
||||
$database = Authorization::skip(fn() => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
@@ -2913,11 +2913,9 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$queries = Query::parseQueries($queries);
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
|
||||
$cursor = \reset($cursor);
|
||||
@@ -2934,11 +2932,10 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
$filters = Query::groupByType($queries)['filters'];
|
||||
|
||||
try {
|
||||
$documents = $dbForProject->find('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries);
|
||||
$total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $filters, APP_LIMIT_COUNT);
|
||||
$total = $dbForProject->count('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $queries, APP_LIMIT_COUNT);
|
||||
} catch (AuthorizationException) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
} catch (QueryException $e) {
|
||||
@@ -3020,7 +3017,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
|
||||
->param('databaseId', '', new UID(), 'Database ID.')
|
||||
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
|
||||
->param('documentId', '', new UID(), 'Document ID.')
|
||||
->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Only method allowed is select.', true)
|
||||
->param('queries', [], new JSON(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('mode')
|
||||
|
||||
@@ -374,7 +374,7 @@ App::get('/v1/functions')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -1268,7 +1268,7 @@ App::get('/v1/functions/:functionId/deployments')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -1805,7 +1805,7 @@ App::get('/v1/functions/:functionId/executions')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
|
||||
@@ -35,6 +35,7 @@ use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\JSON;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use MaxMind\Db\Reader;
|
||||
use Utopia\Database\DateTime;
|
||||
@@ -61,30 +62,20 @@ App::post('/v1/messaging/providers/mailgun')
|
||||
->param('apiKey', '', new Text(0), 'Mailgun API Key.', true)
|
||||
->param('domain', '', new Text(0), 'Mailgun Domain.', true)
|
||||
->param('isEuRegion', null, new Boolean(), 'Set as EU region.', true)
|
||||
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
|
||||
->param('fromName', '', new Text(128), 'Sender Name.', true)
|
||||
->param('fromName', '', new Text(128, 0), 'Sender Name.', true)
|
||||
->param('fromEmail', '', new Email(), 'Sender email address.', true)
|
||||
->param('replyToName', '', new Text(128), 'Name set in the reply to field for the mail. Default value is sender name. Reply to name must have reply to email as well.', true)
|
||||
->param('replyToEmail', '', new Text(128), 'Email set in the reply to field for the mail. Default value is sender email. Reply to email must have reply to name as well.', true)
|
||||
->param('replyToName', '', new Text(128, 0), 'Name set in the reply to field for the mail. Default value is sender name. Reply to name must have reply to email as well.', true)
|
||||
->param('replyToEmail', '', new Email(), 'Email set in the reply to field for the mail. Default value is sender email. Reply to email must have reply to name as well.', true)
|
||||
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $providerId, string $name, string $apiKey, string $domain, ?bool $isEuRegion, ?bool $enabled, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
->action(function (string $providerId, string $name, string $apiKey, string $domain, ?bool $isEuRegion, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$providerId = $providerId == 'unique()' ? ID::unique() : $providerId;
|
||||
|
||||
$options = [
|
||||
'fromName' => $fromName,
|
||||
'fromEmail' => $fromEmail,
|
||||
];
|
||||
|
||||
if (!empty($replyToName) && !empty($replyToEmail)) {
|
||||
$options['replyToName'] = $replyToName;
|
||||
$options['replyToEmail'] = $replyToEmail;
|
||||
}
|
||||
|
||||
$credentials = [];
|
||||
|
||||
if ($isEuRegion === true || $isEuRegion === false) {
|
||||
if (!\is_null($isEuRegion)) {
|
||||
$credentials['isEuRegion'] = $isEuRegion;
|
||||
}
|
||||
|
||||
@@ -96,12 +87,19 @@ App::post('/v1/messaging/providers/mailgun')
|
||||
$credentials['domain'] = $domain;
|
||||
}
|
||||
|
||||
$options = [
|
||||
'fromName' => $fromName,
|
||||
'fromEmail' => $fromEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'replyToEmail' => $replyToEmail,
|
||||
];
|
||||
|
||||
if (
|
||||
$enabled === true &&
|
||||
\array_key_exists('isEuRegion', $credentials) &&
|
||||
\array_key_exists('apiKey', $credentials) &&
|
||||
\array_key_exists('domain', $credentials) &&
|
||||
\array_key_exists('from', $options)
|
||||
$enabled === true
|
||||
&& !empty($fromEmail)
|
||||
&& \array_key_exists('isEuRegion', $credentials)
|
||||
&& \array_key_exists('apiKey', $credentials)
|
||||
&& \array_key_exists('domain', $credentials)
|
||||
) {
|
||||
$enabled = true;
|
||||
} else {
|
||||
@@ -149,37 +147,34 @@ App::post('/v1/messaging/providers/sendgrid')
|
||||
->param('providerId', '', new CustomId(), 'Provider ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('name', '', new Text(128), 'Provider name.')
|
||||
->param('apiKey', '', new Text(0), 'Sendgrid API key.', true)
|
||||
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
|
||||
->param('fromName', '', new Text(128), 'Sender Name.', true)
|
||||
->param('fromName', '', new Text(128, 0), 'Sender Name.', true)
|
||||
->param('fromEmail', '', new Email(), 'Sender email address.', true)
|
||||
->param('replyToName', '', new Text(128), 'Name set in the reply to field for the mail. Default value is sender name.', true)
|
||||
->param('replyToEmail', '', new Text(128), 'Email set in the reply to field for the mail. Default value is sender email.', true)
|
||||
->param('replyToName', '', new Text(128, 0), 'Name set in the reply to field for the mail. Default value is sender name.', true)
|
||||
->param('replyToEmail', '', new Email(), 'Email set in the reply to field for the mail. Default value is sender email.', true)
|
||||
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $providerId, string $name, string $apiKey, ?bool $enabled, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
->action(function (string $providerId, string $name, string $apiKey, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$providerId = $providerId == 'unique()' ? ID::unique() : $providerId;
|
||||
|
||||
$options = [
|
||||
'fromName' => $fromName,
|
||||
'fromEmail' => $fromEmail,
|
||||
];
|
||||
|
||||
if (!empty($replyToName) && !empty($replyToEmail)) {
|
||||
$options['replyToName'] = $replyToName;
|
||||
$options['replyToEmail'] = $replyToEmail;
|
||||
}
|
||||
|
||||
$credentials = [];
|
||||
|
||||
if (!empty($apiKey)) {
|
||||
$credentials['apiKey'] = $apiKey;
|
||||
}
|
||||
|
||||
$options = [
|
||||
'fromName' => $fromName,
|
||||
'fromEmail' => $fromEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'replyToEmail' => $replyToEmail,
|
||||
];
|
||||
|
||||
if (
|
||||
$enabled === true
|
||||
&& !empty($fromEmail)
|
||||
&& \array_key_exists('apiKey', $credentials)
|
||||
&& \array_key_exists('from', $options)
|
||||
) {
|
||||
$enabled = true;
|
||||
} else {
|
||||
@@ -210,6 +205,94 @@ App::post('/v1/messaging/providers/sendgrid')
|
||||
->dynamic($provider, Response::MODEL_PROVIDER);
|
||||
});
|
||||
|
||||
App::post('/v1/messaging/providers/smtp')
|
||||
->desc('Create SMTP provider')
|
||||
->groups(['api', 'messaging'])
|
||||
->label('audits.event', 'provider.create')
|
||||
->label('audits.resource', 'provider/{response.$id}')
|
||||
->label('event', 'providers.[providerId].create')
|
||||
->label('scope', 'providers.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'messaging')
|
||||
->label('sdk.method', 'createSMTPProvider')
|
||||
->label('sdk.description', '/docs/references/messaging/create-smtp-provider.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_PROVIDER)
|
||||
->param('providerId', '', new CustomId(), 'Provider ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
|
||||
->param('name', '', new Text(128), 'Provider name.')
|
||||
->param('host', '', new Text(0), 'SMTP hosts. Either a single hostname or multiple semicolon-delimited hostnames. You can also specify a different port for each host by using this format: [hostname:port] (e.g. "smtp1.example.com:25;smtp2.example.com"). You can also specify encryption type, for example: (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465"). Hosts will be tried in order.')
|
||||
->param('port', 587, new Range(1, 65535), 'The default SMTP server port.', true)
|
||||
->param('username', '', new Text(0), 'Authentication username.', true)
|
||||
->param('password', '', new Text(0), 'Authentication password.', true)
|
||||
->param('encryption', '', new WhiteList(['none', 'ssl', 'tls']), 'Encryption type. Can be omitted, \'ssl\', or \'tls\'', true)
|
||||
->param('autoTLS', true, new Boolean(), 'Enable SMTP AutoTLS feature.', true)
|
||||
->param('mailer', '', new Text(0), 'The value to use for the X-Mailer header.', true)
|
||||
->param('fromName', '', new Text(128, 0), 'Sender Name.', true)
|
||||
->param('fromEmail', '', new Email(), 'Sender email address.', true)
|
||||
->param('replyToName', '', new Text(128, 0), 'Name set in the reply to field for the mail. Default value is sender name.', true)
|
||||
->param('replyToEmail', '', new Email(), 'Email set in the reply to field for the mail. Default value is sender email.', true)
|
||||
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $providerId, string $name, string $host, int $port, string $username, string $password, string $encryption, bool $autoTLS, string $mailer, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$providerId = $providerId == 'unique()' ? ID::unique() : $providerId;
|
||||
|
||||
$credentials = [
|
||||
'port' => $port,
|
||||
'username' => $username,
|
||||
'password' => $password,
|
||||
];
|
||||
|
||||
if (!empty($host)) {
|
||||
$credentials['host'] = $host;
|
||||
}
|
||||
|
||||
$options = [
|
||||
'fromName' => $fromName,
|
||||
'fromEmail' => $fromEmail,
|
||||
'replyToName' => $replyToName,
|
||||
'replyToEmail' => $replyToEmail,
|
||||
'encryption' => $encryption === 'none' ? '' : $encryption,
|
||||
'autoTLS' => $autoTLS,
|
||||
'mailer' => $mailer,
|
||||
];
|
||||
|
||||
if (
|
||||
$enabled === true
|
||||
&& !empty($fromEmail)
|
||||
&& \array_key_exists('host', $credentials)
|
||||
) {
|
||||
$enabled = true;
|
||||
} else {
|
||||
$enabled = false;
|
||||
}
|
||||
|
||||
$provider = new Document([
|
||||
'$id' => $providerId,
|
||||
'name' => $name,
|
||||
'provider' => 'smtp',
|
||||
'type' => MESSAGE_TYPE_EMAIL,
|
||||
'enabled' => $enabled,
|
||||
'credentials' => $credentials,
|
||||
'options' => $options,
|
||||
]);
|
||||
|
||||
try {
|
||||
$provider = $dbForProject->createDocument('providers', $provider);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::PROVIDER_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
->setParam('providerId', $provider->getId());
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($provider, Response::MODEL_PROVIDER);
|
||||
});
|
||||
|
||||
App::post('/v1/messaging/providers/msg91')
|
||||
->desc('Create Msg91 provider')
|
||||
->groups(['api', 'messaging'])
|
||||
@@ -616,9 +699,13 @@ App::post('/v1/messaging/providers/fcm')
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $providerId, string $name, ?array $serviceAccountJSON, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
->action(function (string $providerId, string $name, array|string|null $serviceAccountJSON, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$providerId = $providerId == 'unique()' ? ID::unique() : $providerId;
|
||||
|
||||
$serviceAccountJSON = \is_string($serviceAccountJSON)
|
||||
? \json_decode($serviceAccountJSON, true)
|
||||
: $serviceAccountJSON;
|
||||
|
||||
$credentials = [];
|
||||
|
||||
if (!\is_null($serviceAccountJSON)) {
|
||||
@@ -757,7 +844,7 @@ App::get('/v1/messaging/providers')
|
||||
}
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
|
||||
if ($cursor) {
|
||||
@@ -917,9 +1004,10 @@ App::patch('/v1/messaging/providers/mailgun/:providerId')
|
||||
if ($provider->isEmpty()) {
|
||||
throw new Exception(Exception::PROVIDER_NOT_FOUND);
|
||||
}
|
||||
$providerAttr = $provider->getAttribute('provider');
|
||||
|
||||
if ($providerAttr !== 'mailgun') {
|
||||
$providerProvider = $provider->getAttribute('provider');
|
||||
|
||||
if ($providerProvider !== 'mailgun') {
|
||||
throw new Exception(Exception::PROVIDER_INCORRECT_TYPE);
|
||||
}
|
||||
|
||||
@@ -949,7 +1037,7 @@ App::patch('/v1/messaging/providers/mailgun/:providerId')
|
||||
|
||||
$credentials = $provider->getAttribute('credentials');
|
||||
|
||||
if ($isEuRegion === true || $isEuRegion === false) {
|
||||
if (!\is_null($isEuRegion)) {
|
||||
$credentials['isEuRegion'] = $isEuRegion;
|
||||
}
|
||||
|
||||
@@ -963,19 +1051,21 @@ App::patch('/v1/messaging/providers/mailgun/:providerId')
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true &&
|
||||
\array_key_exists('isEuRegion', $credentials) &&
|
||||
\array_key_exists('apiKey', $credentials) &&
|
||||
\array_key_exists('domain', $credentials) &&
|
||||
\array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('isEuRegion', $credentials) &&
|
||||
\array_key_exists('apiKey', $credentials) &&
|
||||
\array_key_exists('domain', $credentials) &&
|
||||
\array_key_exists('fromEmail', $options)
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1054,17 +1144,138 @@ App::patch('/v1/messaging/providers/sendgrid/:providerId')
|
||||
]);
|
||||
}
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true
|
||||
&& \array_key_exists('apiKey', $provider->getAttribute('credentials'))
|
||||
&& \array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('apiKey', $provider->getAttribute('credentials')) &&
|
||||
\array_key_exists('fromEmail', $provider->getAttribute('options'))
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('providerId', $provider->getId());
|
||||
|
||||
$response
|
||||
->dynamic($provider, Response::MODEL_PROVIDER);
|
||||
});
|
||||
|
||||
App::patch('/v1/messaging/providers/smtp/:providerId')
|
||||
->desc('Update SMTP provider')
|
||||
->groups(['api', 'messaging'])
|
||||
->label('audits.event', 'provider.update')
|
||||
->label('audits.resource', 'provider/{response.$id}')
|
||||
->label('event', 'providers.[providerId].update')
|
||||
->label('scope', 'providers.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'messaging')
|
||||
->label('sdk.method', 'updateSMTPProvider')
|
||||
->label('sdk.description', '/docs/references/messaging/update-smtp-provider.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_PROVIDER)
|
||||
->param('providerId', '', new UID(), 'Provider ID.')
|
||||
->param('name', '', new Text(128), 'Provider name.', true)
|
||||
->param('host', '', new Text(0), 'SMTP hosts. Either a single hostname or multiple semicolon-delimited hostnames. You can also specify a different port for each host by using this format: [hostname:port] (e.g. "smtp1.example.com:25;smtp2.example.com"). You can also specify encryption type, for example: (e.g. "tls://smtp1.example.com:587;ssl://smtp2.example.com:465"). Hosts will be tried in order.', true)
|
||||
->param('port', null, new Range(1, 65535), 'SMTP port.', true)
|
||||
->param('username', '', new Text(0), 'Authentication username.', true)
|
||||
->param('password', '', new Text(0), 'Authentication password.', true)
|
||||
->param('encryption', '', new WhiteList(['none', 'ssl', 'tls']), 'Encryption type. Can be \'ssl\' or \'tls\'', true)
|
||||
->param('autoTLS', null, new Boolean(), 'Enable SMTP AutoTLS feature.', true)
|
||||
->param('fromName', '', new Text(128), 'Sender Name.', true)
|
||||
->param('fromEmail', '', new Email(), 'Sender email address.', true)
|
||||
->param('replyToName', '', new Text(128), 'Name set in the Reply To field for the mail. Default value is Sender Name.', true)
|
||||
->param('replyToEmail', '', new Text(128), 'Email set in the Reply To field for the mail. Default value is Sender Email.', true)
|
||||
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $providerId, string $name, string $host, ?int $port, string $username, string $password, string $encryption, ?bool $autoTLS, string $fromName, string $fromEmail, string $replyToName, string $replyToEmail, ?bool $enabled, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$provider = $dbForProject->getDocument('providers', $providerId);
|
||||
|
||||
if ($provider->isEmpty()) {
|
||||
throw new Exception(Exception::PROVIDER_NOT_FOUND);
|
||||
}
|
||||
|
||||
$providerAttr = $provider->getAttribute('provider');
|
||||
|
||||
if ($providerAttr !== 'smtp') {
|
||||
throw new Exception(Exception::PROVIDER_INCORRECT_TYPE);
|
||||
}
|
||||
|
||||
if (!empty($name)) {
|
||||
$provider->setAttribute('name', $name);
|
||||
}
|
||||
|
||||
$options = $provider->getAttribute('options');
|
||||
|
||||
if (!empty($fromName)) {
|
||||
$options['fromName'] = $fromName;
|
||||
}
|
||||
|
||||
if (!empty($fromEmail)) {
|
||||
$options['fromEmail'] = $fromEmail;
|
||||
}
|
||||
|
||||
if (!empty($replyToName)) {
|
||||
$options['replyToName'] = $replyToName;
|
||||
}
|
||||
|
||||
if (!empty($replyToEmail)) {
|
||||
$options['replyToEmail'] = $replyToEmail;
|
||||
}
|
||||
|
||||
$provider->setAttribute('options', $options);
|
||||
|
||||
$credentials = $provider->getAttribute('credentials');
|
||||
|
||||
if (!empty($host)) {
|
||||
$credentials['host'] = $host;
|
||||
}
|
||||
|
||||
if (!\is_null($port)) {
|
||||
$credentials['port'] = $port;
|
||||
}
|
||||
|
||||
if (!empty($username)) {
|
||||
$credentials['username'] = $username;
|
||||
}
|
||||
|
||||
if (!empty($password)) {
|
||||
$credentials['password'] = $password;
|
||||
}
|
||||
|
||||
if (!empty($encryption)) {
|
||||
$credentials['encryption'] = $encryption === 'none' ? '' : $encryption;
|
||||
}
|
||||
|
||||
if (!\is_null($autoTLS)) {
|
||||
$credentials['autoTLS'] = $autoTLS;
|
||||
}
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
!empty($options['fromEmail'])
|
||||
&& \array_key_exists('host', $credentials)
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1133,18 +1344,20 @@ App::patch('/v1/messaging/providers/msg91/:providerId')
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true
|
||||
&& \array_key_exists('senderId', $credentials)
|
||||
&& \array_key_exists('authKey', $credentials)
|
||||
&& \array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('senderId', $credentials) &&
|
||||
\array_key_exists('authKey', $credentials) &&
|
||||
\array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1213,19 +1426,20 @@ App::patch('/v1/messaging/providers/telesign/:providerId')
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true
|
||||
&& \array_key_exists('username', $credentials)
|
||||
&& \array_key_exists('password', $credentials)
|
||||
&& \array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('username', $credentials) &&
|
||||
\array_key_exists('password', $credentials) &&
|
||||
\array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1294,19 +1508,20 @@ App::patch('/v1/messaging/providers/textmagic/:providerId')
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true
|
||||
&& \array_key_exists('username', $credentials)
|
||||
&& \array_key_exists('apiKey', $credentials)
|
||||
&& \array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('username', $credentials) &&
|
||||
\array_key_exists('apiKey', $credentials) &&
|
||||
\array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1375,19 +1590,20 @@ App::patch('/v1/messaging/providers/twilio/:providerId')
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true
|
||||
&& \array_key_exists('accountSid', $credentials)
|
||||
&& \array_key_exists('authToken', $credentials)
|
||||
&& \array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('accountSid', $credentials) &&
|
||||
\array_key_exists('authToken', $credentials) &&
|
||||
\array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1456,19 +1672,20 @@ App::patch('/v1/messaging/providers/vonage/:providerId')
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true
|
||||
&& \array_key_exists('apiKey', $credentials)
|
||||
&& \array_key_exists('apiSecret', $credentials)
|
||||
&& \array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('apiKey', $credentials) &&
|
||||
\array_key_exists('apiSecret', $credentials) &&
|
||||
\array_key_exists('from', $provider->getAttribute('options'))
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1501,7 +1718,7 @@ App::patch('/v1/messaging/providers/fcm/:providerId')
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $providerId, string $name, ?bool $enabled, ?array $serviceAccountJSON, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
->action(function (string $providerId, string $name, ?bool $enabled, array|string|null $serviceAccountJSON, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$provider = $dbForProject->getDocument('providers', $providerId);
|
||||
|
||||
if ($provider->isEmpty()) {
|
||||
@@ -1518,17 +1735,25 @@ App::patch('/v1/messaging/providers/fcm/:providerId')
|
||||
}
|
||||
|
||||
if (!\is_null($serviceAccountJSON)) {
|
||||
$provider->setAttribute('credentials', ['serviceAccountJSON' => $serviceAccountJSON]);
|
||||
$serviceAccountJSON = \is_string($serviceAccountJSON)
|
||||
? \json_decode($serviceAccountJSON, true)
|
||||
: $serviceAccountJSON;
|
||||
|
||||
$provider->setAttribute('credentials', [
|
||||
'serviceAccountJSON' => $serviceAccountJSON
|
||||
]);
|
||||
}
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if ($enabled === true && \array_key_exists('serviceAccountJSON', $provider->getAttribute('credentials'))) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (\array_key_exists('serviceAccountJSON', $provider->getAttribute('credentials'))) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1601,20 +1826,21 @@ App::patch('/v1/messaging/providers/apns/:providerId')
|
||||
|
||||
$provider->setAttribute('credentials', $credentials);
|
||||
|
||||
if ($enabled === true || $enabled === false) {
|
||||
if (
|
||||
$enabled === true
|
||||
&& \array_key_exists('authKey', $credentials)
|
||||
&& \array_key_exists('authKeyId', $credentials)
|
||||
&& \array_key_exists('teamId', $credentials)
|
||||
&& \array_key_exists('bundleId', $credentials)
|
||||
) {
|
||||
$enabled = true;
|
||||
if (!\is_null($enabled)) {
|
||||
if ($enabled) {
|
||||
if (
|
||||
\array_key_exists('authKey', $credentials) &&
|
||||
\array_key_exists('authKeyId', $credentials) &&
|
||||
\array_key_exists('teamId', $credentials) &&
|
||||
\array_key_exists('bundleId', $credentials)
|
||||
) {
|
||||
$provider->setAttribute('enabled', true);
|
||||
} else {
|
||||
throw new Exception(Exception::PROVIDER_MISSING_CREDENTIALS);
|
||||
}
|
||||
} else {
|
||||
$enabled = false;
|
||||
$provider->setAttribute('enabled', false);
|
||||
}
|
||||
|
||||
$provider->setAttribute('enabled', $enabled);
|
||||
}
|
||||
|
||||
$provider = $dbForProject->updateDocument('providers', $provider->getId(), $provider);
|
||||
@@ -1677,17 +1903,15 @@ App::post('/v1/messaging/topics')
|
||||
->label('sdk.response.model', Response::MODEL_TOPIC)
|
||||
->param('topicId', '', new CustomId(), 'Topic ID. Choose a custom Topic ID or a new Topic ID.')
|
||||
->param('name', '', new Text(128), 'Topic Name.')
|
||||
->param('description', '', new Text(2048), 'Topic Description.', true)
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $topicId, string $name, string $description, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
->action(function (string $topicId, string $name, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$topicId = $topicId == 'unique()' ? ID::unique() : $topicId;
|
||||
|
||||
$topic = new Document([
|
||||
'$id' => $topicId,
|
||||
'name' => $name,
|
||||
'description' => $description
|
||||
]);
|
||||
|
||||
try {
|
||||
@@ -1727,7 +1951,7 @@ App::get('/v1/messaging/topics')
|
||||
}
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
|
||||
if ($cursor) {
|
||||
@@ -1874,11 +2098,10 @@ App::patch('/v1/messaging/topics/:topicId')
|
||||
->label('sdk.response.model', Response::MODEL_TOPIC)
|
||||
->param('topicId', '', new UID(), 'Topic ID.')
|
||||
->param('name', '', new Text(128), 'Topic Name.', true)
|
||||
->param('description', '', new Text(2048), 'Topic Description.', true)
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('response')
|
||||
->action(function (string $topicId, string $name, string $description, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
->action(function (string $topicId, string $name, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$topic = $dbForProject->getDocument('topics', $topicId);
|
||||
|
||||
if ($topic->isEmpty()) {
|
||||
@@ -1889,10 +2112,6 @@ App::patch('/v1/messaging/topics/:topicId')
|
||||
$topic->setAttribute('name', $name);
|
||||
}
|
||||
|
||||
if (!empty($description)) {
|
||||
$topic->setAttribute('description', $description);
|
||||
}
|
||||
|
||||
$topic = $dbForProject->updateDocument('topics', $topicId, $topic);
|
||||
|
||||
$queueForEvents
|
||||
@@ -2054,7 +2273,7 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
\array_push($queries, Query::equal('topicInternalId', [$topic->getInternalId()]));
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
|
||||
if ($cursor) {
|
||||
@@ -2277,7 +2496,6 @@ App::post('/v1/messaging/messages/email')
|
||||
->param('targets', [], new ArrayList(new UID()), 'List of Targets IDs.', true)
|
||||
->param('cc', [], new ArrayList(new UID()), 'Array of target IDs to be added as CC.', true)
|
||||
->param('bcc', [], new ArrayList(new UID()), 'Array of target IDs to be added as BCC.', true)
|
||||
->param('description', '', new Text(256), 'Description for message.', true)
|
||||
->param('status', MessageStatus::DRAFT, new WhiteList([MessageStatus::DRAFT, MessageStatus::SCHEDULED, MessageStatus::PROCESSING]), 'Message Status. Value must be one of: ' . implode(', ', [MessageStatus::DRAFT, MessageStatus::SCHEDULED, MessageStatus::PROCESSING]) . '.', true)
|
||||
->param('html', false, new Boolean(), 'Is content of type HTML', true)
|
||||
->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true)
|
||||
@@ -2287,7 +2505,7 @@ App::post('/v1/messaging/messages/email')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, string $subject, string $content, array $topics, array $users, array $targets, array $cc, array $bcc, string $description, string $status, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, string $subject, string $content, array $topics, array $users, array $targets, array $cc, array $bcc, string $status, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
$messageId = $messageId == 'unique()'
|
||||
? ID::unique()
|
||||
: $messageId;
|
||||
@@ -2326,7 +2544,6 @@ App::post('/v1/messaging/messages/email')
|
||||
'topics' => $topics,
|
||||
'users' => $users,
|
||||
'targets' => $targets,
|
||||
'description' => $description,
|
||||
'scheduledAt' => $scheduledAt,
|
||||
'data' => [
|
||||
'subject' => $subject,
|
||||
@@ -2396,7 +2613,6 @@ App::post('/v1/messaging/messages/sms')
|
||||
->param('topics', [], new ArrayList(new UID()), 'List of Topic IDs.', true)
|
||||
->param('users', [], new ArrayList(new UID()), 'List of User IDs.', true)
|
||||
->param('targets', [], new ArrayList(new UID()), 'List of Targets IDs.', true)
|
||||
->param('description', '', new Text(256), 'Description for Message.', true)
|
||||
->param('status', MessageStatus::DRAFT, new WhiteList([MessageStatus::DRAFT, MessageStatus::SCHEDULED, MessageStatus::PROCESSING]), 'Message Status. Value must be one of: ' . implode(', ', [MessageStatus::DRAFT, MessageStatus::SCHEDULED, MessageStatus::PROCESSING]) . '.', true)
|
||||
->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true)
|
||||
->inject('queueForEvents')
|
||||
@@ -2405,7 +2621,7 @@ App::post('/v1/messaging/messages/sms')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, string $content, array $topics, array $users, array $targets, string $description, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, string $content, array $topics, array $users, array $targets, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
$messageId = $messageId == 'unique()'
|
||||
? ID::unique()
|
||||
: $messageId;
|
||||
@@ -2442,7 +2658,6 @@ App::post('/v1/messaging/messages/sms')
|
||||
'topics' => $topics,
|
||||
'users' => $users,
|
||||
'targets' => $targets,
|
||||
'description' => $description,
|
||||
'data' => [
|
||||
'content' => $content,
|
||||
],
|
||||
@@ -2508,7 +2723,6 @@ App::post('/v1/messaging/messages/push')
|
||||
->param('topics', [], new ArrayList(new UID()), 'List of Topic IDs.', true)
|
||||
->param('users', [], new ArrayList(new UID()), 'List of User IDs.', true)
|
||||
->param('targets', [], new ArrayList(new UID()), 'List of Targets IDs.', true)
|
||||
->param('description', '', new Text(256), 'Description for Message.', true)
|
||||
->param('data', null, new JSON(), 'Additional Data for push notification.', true)
|
||||
->param('action', '', new Text(256), 'Action for push notification.', true)
|
||||
->param('icon', '', new Text(256), 'Icon for push notification. Available only for Android and Web Platform.', true)
|
||||
@@ -2524,7 +2738,7 @@ App::post('/v1/messaging/messages/push')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, string $title, string $body, array $topics, array $users, array $targets, string $description, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, string $title, string $body, array $topics, array $users, array $targets, ?array $data, string $action, string $icon, string $sound, string $color, string $tag, string $badge, string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
$messageId = $messageId == 'unique()'
|
||||
? ID::unique()
|
||||
: $messageId;
|
||||
@@ -2571,7 +2785,6 @@ App::post('/v1/messaging/messages/push')
|
||||
'topics' => $topics,
|
||||
'users' => $users,
|
||||
'targets' => $targets,
|
||||
'description' => $description,
|
||||
'scheduledAt' => $scheduledAt,
|
||||
'data' => $pushData,
|
||||
'status' => $status,
|
||||
@@ -2639,7 +2852,7 @@ App::get('/v1/messaging/messages')
|
||||
}
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
|
||||
if ($cursor) {
|
||||
@@ -2782,7 +2995,7 @@ App::get('/v1/messaging/messages/:messageId/targets')
|
||||
$queries[] = Query::equal('$id', $targetIDs);
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
|
||||
if ($cursor) {
|
||||
@@ -2845,7 +3058,6 @@ App::patch('/v1/messaging/messages/email/:messageId')
|
||||
->param('users', null, new ArrayList(new UID()), 'List of User IDs.', true)
|
||||
->param('targets', null, new ArrayList(new UID()), 'List of Targets IDs.', true)
|
||||
->param('subject', null, new Text(998), 'Email Subject.', true)
|
||||
->param('description', null, new Text(256), 'Description for Message.', true)
|
||||
->param('content', null, new Text(64230), 'Email Content.', true)
|
||||
->param('status', MessageStatus::DRAFT, new WhiteList([MessageStatus::DRAFT, MessageStatus::SCHEDULED, MessageStatus::PROCESSING]), 'Message Status. Value must be one of: ' . implode(', ', [MessageStatus::DRAFT, MessageStatus::SCHEDULED, MessageStatus::PROCESSING]) . '.', true)
|
||||
->param('html', null, new Boolean(), 'Is content of type HTML', true)
|
||||
@@ -2858,7 +3070,7 @@ App::patch('/v1/messaging/messages/email/:messageId')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $subject, ?string $description, ?string $content, ?string $status, ?bool $html, ?array $cc, ?array $bcc, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $subject, ?string $content, ?string $status, ?bool $html, ?array $cc, ?array $bcc, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
@@ -2909,10 +3121,6 @@ App::patch('/v1/messaging/messages/email/:messageId')
|
||||
|
||||
$message->setAttribute('data', $data);
|
||||
|
||||
if (!\is_null($description)) {
|
||||
$message->setAttribute('description', $description);
|
||||
}
|
||||
|
||||
if (!\is_null($status)) {
|
||||
$message->setAttribute('status', $status);
|
||||
}
|
||||
@@ -2983,7 +3191,6 @@ App::patch('/v1/messaging/messages/sms/:messageId')
|
||||
->param('topics', null, new ArrayList(new UID()), 'List of Topic IDs.', true)
|
||||
->param('users', null, new ArrayList(new UID()), 'List of User IDs.', true)
|
||||
->param('targets', null, new ArrayList(new UID()), 'List of Targets IDs.', true)
|
||||
->param('description', null, new Text(256), 'Description for Message.', true)
|
||||
->param('content', null, new Text(64230), 'Email Content.', true)
|
||||
->param('status', null, new WhiteList(['draft', 'cancelled', 'processing']), 'Message Status. Value must be either draft or cancelled or processing.', true)
|
||||
->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true)
|
||||
@@ -2993,7 +3200,7 @@ App::patch('/v1/messaging/messages/sms/:messageId')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $description, ?string $content, ?string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $content, ?string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
@@ -3032,10 +3239,6 @@ App::patch('/v1/messaging/messages/sms/:messageId')
|
||||
$message->setAttribute('status', $status);
|
||||
}
|
||||
|
||||
if (!\is_null($description)) {
|
||||
$message->setAttribute('description', $description);
|
||||
}
|
||||
|
||||
if (!\is_null($scheduledAt)) {
|
||||
if (\is_null($message->getAttribute(('scheduleId')))) {
|
||||
$schedule = $dbForConsole->createDocument('schedules', new Document([
|
||||
@@ -3102,7 +3305,6 @@ App::patch('/v1/messaging/messages/push/:messageId')
|
||||
->param('topics', null, new ArrayList(new UID()), 'List of Topic IDs.', true)
|
||||
->param('users', null, new ArrayList(new UID()), 'List of User IDs.', true)
|
||||
->param('targets', null, new ArrayList(new UID()), 'List of Targets IDs.', true)
|
||||
->param('description', null, new Text(256), 'Description for Message.', true)
|
||||
->param('title', null, new Text(256), 'Title for push notification.', true)
|
||||
->param('body', null, new Text(64230), 'Body for push notification.', true)
|
||||
->param('data', null, new JSON(), 'Additional Data for push notification.', true)
|
||||
@@ -3120,7 +3322,7 @@ App::patch('/v1/messaging/messages/push/:messageId')
|
||||
->inject('project')
|
||||
->inject('queueForMessaging')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $description, ?string $title, ?string $body, ?array $data, ?string $action, ?string $icon, ?string $sound, ?string $color, ?string $tag, ?int $badge, ?string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $title, ?string $body, ?array $data, ?string $action, ?string $icon, ?string $sound, ?string $color, ?string $tag, ?int $badge, ?string $status, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForConsole, Document $project, Messaging $queueForMessaging, Response $response) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
@@ -3191,10 +3393,6 @@ App::patch('/v1/messaging/messages/push/:messageId')
|
||||
$message->setAttribute('status', $status);
|
||||
}
|
||||
|
||||
if (!\is_null($description)) {
|
||||
$message->setAttribute('description', $description);
|
||||
}
|
||||
|
||||
if (!\is_null($scheduledAt)) {
|
||||
if (\is_null($message->getAttribute(('scheduleId')))) {
|
||||
$schedule = $dbForConsole->createDocument('schedules', new Document([
|
||||
@@ -3242,3 +3440,59 @@ App::patch('/v1/messaging/messages/push/:messageId')
|
||||
$response
|
||||
->dynamic($message, Response::MODEL_MESSAGE);
|
||||
});
|
||||
|
||||
App::delete('/v1/messaging/messages/:messageId')
|
||||
->desc('Delete a message')
|
||||
->groups(['api', 'messaging'])
|
||||
->label('audits.event', 'message.delete')
|
||||
->label('audits.resource', 'message/{request.route.messageId}')
|
||||
->label('event', 'messages.[messageId].delete')
|
||||
->label('scope', 'messages.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN, APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'messaging')
|
||||
->label('sdk.method', 'delete')
|
||||
->label('sdk.description', '/docs/references/messaging/delete-message.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->param('messageId', '', new UID(), 'Message ID.')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForConsole')
|
||||
->inject('response')
|
||||
->action(function (string $messageId, Database $dbForProject, Database $dbForConsole, Response $response) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
throw new Exception(Exception::MESSAGE_NOT_FOUND);
|
||||
}
|
||||
|
||||
switch ($message->getAttribute('status')) {
|
||||
case MessageStatus::PROCESSING:
|
||||
throw new Exception(Exception::MESSAGE_ALREADY_SCHEDULED);
|
||||
case MessageStatus::SCHEDULED:
|
||||
$scheduleId = $message->getAttribute('scheduleId');
|
||||
$scheduledAt = $message->getAttribute('scheduledAt');
|
||||
|
||||
$now = DateTime::now();
|
||||
$scheduledDate = DateTime::formatTz($scheduledAt);
|
||||
|
||||
if ($now > $scheduledDate) {
|
||||
throw new Exception(Exception::MESSAGE_ALREADY_SCHEDULED);
|
||||
}
|
||||
|
||||
if (!empty($scheduleId)) {
|
||||
try {
|
||||
$dbForConsole->deleteDocument('schedules', $scheduleId);
|
||||
} catch (Exception) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
$dbForProject->deleteDocument('messages', $message->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
@@ -392,7 +392,7 @@ App::get('/v1/migrations')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
|
||||
@@ -249,7 +249,7 @@ App::get('/v1/projects')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -825,7 +825,7 @@ App::post('/v1/projects/:projectId/webhooks')
|
||||
|
||||
$webhook = $dbForConsole->createDocument('webhooks', $webhook);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
@@ -952,7 +952,7 @@ App::put('/v1/projects/:projectId/webhooks/:webhookId')
|
||||
}
|
||||
|
||||
$dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook);
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
|
||||
});
|
||||
@@ -991,7 +991,7 @@ App::patch('/v1/projects/:projectId/webhooks/:webhookId/signature')
|
||||
$webhook->setAttribute('signatureKey', \bin2hex(\random_bytes(64)));
|
||||
|
||||
$dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook);
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->dynamic($webhook, Response::MODEL_WEBHOOK);
|
||||
});
|
||||
@@ -1028,7 +1028,7 @@ App::delete('/v1/projects/:projectId/webhooks/:webhookId')
|
||||
|
||||
$dbForConsole->deleteDocument('webhooks', $webhook->getId());
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
@@ -1078,7 +1078,7 @@ App::post('/v1/projects/:projectId/keys')
|
||||
|
||||
$key = $dbForConsole->createDocument('keys', $key);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
@@ -1192,7 +1192,7 @@ App::put('/v1/projects/:projectId/keys/:keyId')
|
||||
|
||||
$dbForConsole->updateDocument('keys', $key->getId(), $key);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->dynamic($key, Response::MODEL_KEY);
|
||||
});
|
||||
@@ -1229,7 +1229,7 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
|
||||
|
||||
$dbForConsole->deleteDocument('keys', $key->getId());
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
@@ -1279,7 +1279,7 @@ App::post('/v1/projects/:projectId/platforms')
|
||||
|
||||
$platform = $dbForConsole->createDocument('platforms', $platform);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
@@ -1394,7 +1394,7 @@ App::put('/v1/projects/:projectId/platforms/:platformId')
|
||||
|
||||
$dbForConsole->updateDocument('platforms', $platform->getId(), $platform);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->dynamic($platform, Response::MODEL_PLATFORM);
|
||||
});
|
||||
@@ -1431,7 +1431,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
|
||||
|
||||
$dbForConsole->deleteDocument('platforms', $platformId);
|
||||
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
@@ -164,7 +164,7 @@ App::get('/v1/proxy/rules')
|
||||
$queries[] = Query::equal('projectInternalId', [$project->getInternalId()]);
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
/** @var Query $cursor */
|
||||
|
||||
@@ -169,7 +169,7 @@ App::get('/v1/storage/buckets')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -451,7 +451,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
}
|
||||
|
||||
$idValidator = new UID();
|
||||
if (!$idValidator->isValid($request->getHeader('x-appwrite-id'))) {
|
||||
if (!$idValidator->isValid($fileId)) {
|
||||
throw new Exception(Exception::STORAGE_INVALID_APPWRITE_ID);
|
||||
}
|
||||
|
||||
@@ -745,7 +745,7 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -963,7 +963,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
||||
break;
|
||||
}
|
||||
|
||||
$image = new Image($source);
|
||||
try {
|
||||
$image = new Image($source);
|
||||
} catch (ImagickException $e) {
|
||||
throw new Exception(Exception::STORAGE_FILE_TYPE_UNSUPPORTED, $e->getMessage());
|
||||
}
|
||||
|
||||
$image->crop((int) $width, (int) $height, $gravity);
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ App::post('/v1/teams')
|
||||
]);
|
||||
|
||||
$membership = $dbForProject->createDocument('memberships', $membership);
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
}
|
||||
|
||||
$queueForEvents->setParam('teamId', $team->getId());
|
||||
@@ -154,7 +154,7 @@ App::get('/v1/teams')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -537,7 +537,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
$team->setAttribute('total', $team->getAttribute('total', 0) + 1);
|
||||
$team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $invitee->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $invitee->getId());
|
||||
} else {
|
||||
try {
|
||||
$membership = $dbForProject->createDocument('memberships', $membership);
|
||||
@@ -710,7 +710,7 @@ App::get('/v1/teams/:teamId/memberships')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -857,7 +857,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
/**
|
||||
* Replace membership on profile
|
||||
*/
|
||||
$dbForProject->deleteCachedDocument('users', $profile->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $profile->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('teamId', $team->getId())
|
||||
@@ -974,13 +974,13 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
Permission::delete(Role::user($user->getId())),
|
||||
]));
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
Authorization::setRole(Role::user($userId)->toString());
|
||||
|
||||
$membership = $dbForProject->updateDocument('memberships', $membership->getId(), $membership);
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team->setAttribute('total', $team->getAttribute('total', 0) + 1)));
|
||||
|
||||
@@ -1059,7 +1059,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove membership from DB');
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
if ($membership->getAttribute('confirm')) { // Count only confirmed members
|
||||
$team->setAttribute('total', \max($team->getAttribute('total', 0) - 1, 0));
|
||||
|
||||
@@ -145,7 +145,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
|
||||
}
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::USER_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -508,7 +508,7 @@ App::post('/v1/users/:userId/targets')
|
||||
} catch (Duplicate) {
|
||||
throw new Exception(Exception::USER_TARGET_ALREADY_EXISTS);
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -544,7 +544,7 @@ App::get('/v1/users')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -839,7 +839,7 @@ App::get('/v1/users/:userId/targets')
|
||||
$queries[] = Query::equal('userId', [$userId]);
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
|
||||
if ($cursor) {
|
||||
@@ -884,7 +884,7 @@ App::get('/v1/users/identities')
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = \array_filter($queries, function ($query) {
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
return \in_array($query->getMethod(), [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
});
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
@@ -958,7 +958,7 @@ App::put('/v1/users/:userId/labels')
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->param('userId', '', new UID(), 'User ID.')
|
||||
->param('labels', [], new ArrayList(new Text(36, allowList: [...Text::NUMBERS, ...Text::ALPHABET_UPPER, ...Text::ALPHABET_LOWER]), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of user labels. Replaces the previous labels. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' labels are allowed, each up to 36 alphanumeric characters long.')
|
||||
->param('labels', [], new ArrayList(new Text(36, allowList: [...Text::NUMBERS, ...Text::ALPHABET_UPPER, ...Text::ALPHABET_LOWER]), APP_LIMIT_ARRAY_LABELS_SIZE), 'Array of user labels. Replaces the previous labels. Maximum of ' . APP_LIMIT_ARRAY_LABELS_SIZE . ' labels are allowed, each up to 36 alphanumeric characters long.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
@@ -1184,7 +1184,7 @@ App::patch('/v1/users/:userId/email')
|
||||
if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) {
|
||||
$dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $email));
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -1246,7 +1246,7 @@ App::patch('/v1/users/:userId/phone')
|
||||
if ($oldTarget instanceof Document && !$oldTarget->isEmpty()) {
|
||||
$dbForProject->updateDocument('targets', $oldTarget->getId(), $oldTarget->setAttribute('identifier', $number));
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::USER_PHONE_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -1408,7 +1408,7 @@ App::patch('/v1/users/:userId/targets/:targetId')
|
||||
}
|
||||
|
||||
$target = $dbForProject->updateDocument('targets', $target->getId(), $target);
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -1657,7 +1657,7 @@ App::post('/v1/users/:userId/tokens')
|
||||
]);
|
||||
|
||||
$token = $dbForProject->createDocument('tokens', $token);
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$token->setAttribute('secret', $secret);
|
||||
|
||||
@@ -1704,7 +1704,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
|
||||
}
|
||||
|
||||
$dbForProject->deleteDocument('sessions', $session->getId());
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -1747,7 +1747,7 @@ App::delete('/v1/users/:userId/sessions')
|
||||
//TODO: fix this
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -1815,10 +1815,10 @@ App::delete('/v1/users/:userId/targets/:targetId')
|
||||
->param('userId', '', new UID(), 'User ID.')
|
||||
->param('targetId', '', new UID(), 'Target ID.')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForDeletes')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $userId, string $targetId, Event $queueForEvents, Response $response, Database $dbForProject) {
|
||||
|
||||
->action(function (string $userId, string $targetId, Event $queueForEvents, Delete $queueForDeletes, Response $response, Database $dbForProject) {
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
||||
if ($user->isEmpty()) {
|
||||
@@ -1836,7 +1836,11 @@ App::delete('/v1/users/:userId/targets/:targetId')
|
||||
}
|
||||
|
||||
$dbForProject->deleteDocument('targets', $target->getId());
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_TARGET)
|
||||
->setDocument($target);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
|
||||
@@ -978,7 +978,7 @@ App::get('/v1/vcs/installations')
|
||||
}
|
||||
|
||||
// Get cursor document if there was a cursor query
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE]);
|
||||
$cursor = Query::getByType($queries, [Query::TYPE_CURSOR_AFTER, Query::TYPE_CURSOR_BEFORE]);
|
||||
$cursor = reset($cursor);
|
||||
if ($cursor) {
|
||||
/** @var Query $cursor */
|
||||
|
||||
@@ -510,7 +510,7 @@ App::init()
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_KEY_ACCCESS)) > $accessedAt) {
|
||||
$key->setAttribute('accessedAt', DateTime::now());
|
||||
$dbForConsole->updateDocument('keys', $key->getId(), $key);
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
}
|
||||
|
||||
$sdkValidator = new WhiteList($servers, true);
|
||||
@@ -524,7 +524,7 @@ App::init()
|
||||
/** Update access time as well */
|
||||
$key->setAttribute('accessedAt', Datetime::now());
|
||||
$dbForConsole->updateDocument('keys', $key->getId(), $key);
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -753,7 +753,7 @@ App::error()
|
||||
'code' => $code,
|
||||
'file' => $file,
|
||||
'line' => $line,
|
||||
'trace' => $trace,
|
||||
'trace' => \json_encode($trace, JSON_UNESCAPED_UNICODE) === false ? [] : $trace, // check for failing encode
|
||||
'version' => $version,
|
||||
'type' => $type,
|
||||
] : [
|
||||
|
||||
@@ -410,7 +410,7 @@ App::shutdown()
|
||||
$session = array_shift($sessions);
|
||||
$dbForProject->deleteDocument('sessions', $session->getId());
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $userId);
|
||||
$dbForProject->purgeCachedDocument('users', $userId);
|
||||
});
|
||||
|
||||
App::shutdown()
|
||||
|
||||
@@ -148,7 +148,7 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
||||
$dbForConsole->createCollection($key, $attributes, $indexes);
|
||||
}
|
||||
|
||||
if ($dbForConsole->getDocument('buckets', 'default')->isEmpty() && !$dbForConsole->exists($dbForConsole->getDefaultDatabase(), 'bucket_1')) {
|
||||
if ($dbForConsole->getDocument('buckets', 'default')->isEmpty() && !$dbForConsole->exists($dbForConsole->getDatabase(), 'bucket_1')) {
|
||||
Console::success('[Setup] - Creating default bucket...');
|
||||
$dbForConsole->createDocument('buckets', new Document([
|
||||
'$id' => ID::custom('default'),
|
||||
|
||||
@@ -34,6 +34,7 @@ use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\OpenSSL\OpenSSL;
|
||||
use Appwrite\URL\URL as AppwriteURL;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Adapter\SQL;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\Cache\Adapter\Redis as RedisCache;
|
||||
use Utopia\Cache\Cache;
|
||||
@@ -99,6 +100,7 @@ const APP_LIMIT_ANTIVIRUS = 20_000_000; //20MB
|
||||
const APP_LIMIT_ENCRYPTION = 20_000_000; //20MB
|
||||
const APP_LIMIT_COMPRESSION = 20_000_000; //20MB
|
||||
const APP_LIMIT_ARRAY_PARAMS_SIZE = 100; // Default maximum of how many elements can there be in API parameter that expects array value
|
||||
const APP_LIMIT_ARRAY_LABELS_SIZE = 1000; // Default maximum of how many labels elements can there be in API parameter that expects array value
|
||||
const APP_LIMIT_ARRAY_ELEMENT_SIZE = 4096; // Default maximum length of element in array parameter represented by maximum URL length.
|
||||
const APP_LIMIT_SUBQUERY = 1000;
|
||||
const APP_LIMIT_SUBSCRIBERS_SUBQUERY = 1_000_000;
|
||||
@@ -174,6 +176,7 @@ const DELETE_TYPE_CACHE_BY_RESOURCE = 'cacheByResource';
|
||||
const DELETE_TYPE_SCHEDULES = 'schedules';
|
||||
const DELETE_TYPE_TOPIC = 'topic';
|
||||
const DELETE_TYPE_TARGET = 'target';
|
||||
const DELETE_TYPE_EXPIRED_TARGETS = 'invalid_targets';
|
||||
// Mail Types
|
||||
const MAIL_TYPE_VERIFICATION = 'verification';
|
||||
const MAIL_TYPE_MAGIC_SESSION = 'magicSession';
|
||||
@@ -817,10 +820,10 @@ $register->set('pools', function () {
|
||||
$resource = function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) {
|
||||
return new PDOProxy(function () use ($dsnHost, $dsnPort, $dsnUser, $dsnPass, $dsnDatabase) {
|
||||
return new PDO("mysql:host={$dsnHost};port={$dsnPort};dbname={$dsnDatabase};charset=utf8mb4", $dsnUser, $dsnPass, array(
|
||||
// No need to set PDO::ATTR_ERRMODE it is overwitten in PDOProxy
|
||||
PDO::ATTR_TIMEOUT => 3, // Seconds
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_ERRMODE => App::isDevelopment() ? PDO::ERRMODE_WARNING : PDO::ERRMODE_SILENT, // If in production mode, warnings are not displayed
|
||||
PDO::ATTR_EMULATE_PREPARES => true,
|
||||
PDO::ATTR_STRINGIFY_FETCHES => true
|
||||
));
|
||||
@@ -842,12 +845,10 @@ $register->set('pools', function () {
|
||||
|
||||
default:
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Invalid scheme");
|
||||
break;
|
||||
}
|
||||
|
||||
$pool = new Pool($name, $poolSize, function () use ($type, $resource, $dsn) {
|
||||
// Get Adapter
|
||||
$adapter = null;
|
||||
switch ($type) {
|
||||
case 'database':
|
||||
$adapter = match ($dsn->getScheme()) {
|
||||
@@ -856,7 +857,7 @@ $register->set('pools', function () {
|
||||
default => null
|
||||
};
|
||||
|
||||
$adapter->setDefaultDatabase($dsn->getPath());
|
||||
$adapter->setDatabase($dsn->getPath());
|
||||
break;
|
||||
case 'pubsub':
|
||||
$adapter = $resource();
|
||||
@@ -876,7 +877,6 @@ $register->set('pools', function () {
|
||||
|
||||
default:
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, "Server error: Missing adapter implementation.");
|
||||
break;
|
||||
}
|
||||
|
||||
return $adapter;
|
||||
@@ -893,22 +893,18 @@ $register->set('pools', function () {
|
||||
|
||||
$register->set('db', function () {
|
||||
// This is usually for our workers or CLI commands scope
|
||||
$dbHost = App::getEnv('_APP_DB_HOST', '');
|
||||
$dbPort = App::getEnv('_APP_DB_PORT', '');
|
||||
$dbUser = App::getEnv('_APP_DB_USER', '');
|
||||
$dbPass = App::getEnv('_APP_DB_PASS', '');
|
||||
$dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
|
||||
$dbHost = App::getEnv('_APP_DB_HOST', '');
|
||||
$dbPort = App::getEnv('_APP_DB_PORT', '');
|
||||
$dbUser = App::getEnv('_APP_DB_USER', '');
|
||||
$dbPass = App::getEnv('_APP_DB_PASS', '');
|
||||
$dbScheme = App::getEnv('_APP_DB_SCHEMA', '');
|
||||
|
||||
$pdo = new PDO("mysql:host={$dbHost};port={$dbPort};dbname={$dbScheme};charset=utf8mb4", $dbUser, $dbPass, array(
|
||||
PDO::ATTR_TIMEOUT => 3, // Seconds
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
PDO::ATTR_EMULATE_PREPARES => true,
|
||||
PDO::ATTR_STRINGIFY_FETCHES => true,
|
||||
));
|
||||
|
||||
return $pdo;
|
||||
return new PDO(
|
||||
"mysql:host={$dbHost};port={$dbPort};dbname={$dbScheme};charset=utf8mb4",
|
||||
$dbUser,
|
||||
$dbPass,
|
||||
SQL::getPDOAttributes()
|
||||
);
|
||||
});
|
||||
|
||||
$register->set('smtp', function () {
|
||||
|
||||
@@ -43,20 +43,20 @@
|
||||
"ext-sockets": "*",
|
||||
"appwrite/php-runtimes": "0.13.*",
|
||||
"appwrite/php-clamav": "2.0.*",
|
||||
"utopia-php/abuse": "0.33.*",
|
||||
"utopia-php/abuse": "0.36.*",
|
||||
"utopia-php/analytics": "0.10.*",
|
||||
"utopia-php/audit": "0.35.*",
|
||||
"utopia-php/audit": "0.38.*",
|
||||
"utopia-php/cache": "0.9.*",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.45.*",
|
||||
"utopia-php/database": "0.48.*",
|
||||
"utopia-php/domains": "0.5.*",
|
||||
"utopia-php/dsn": "0.1.*",
|
||||
"utopia-php/dsn": "0.2.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/image": "0.5.*",
|
||||
"utopia-php/image": "0.6.*",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.3.*",
|
||||
"utopia-php/messaging": "0.8.*",
|
||||
"utopia-php/messaging": "0.9.*",
|
||||
"utopia-php/migration": "0.3.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.5.*",
|
||||
@@ -75,7 +75,7 @@
|
||||
"adhocore/jwt": "1.1.2",
|
||||
"spomky-labs/otphp": "^10.0",
|
||||
"webonyx/graphql-php": "14.11.*",
|
||||
"league/csv": "9.7.1"
|
||||
"league/csv": "^9.14"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
@@ -97,7 +97,7 @@
|
||||
},
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "8.0"
|
||||
"php": "8.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "6ccadcec8172eb800888228b5f653f08",
|
||||
"content-hash": "3b43bf6f0fca50a3a2834e1bbaa90d63",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -530,34 +530,39 @@
|
||||
},
|
||||
{
|
||||
"name": "league/csv",
|
||||
"version": "9.7.1",
|
||||
"version": "9.14.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/csv.git",
|
||||
"reference": "0ec57e8264ec92565974ead0d1724cf1026e10c1"
|
||||
"reference": "34bf0df7340b60824b9449b5c526fcc3325070d5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/csv/zipball/0ec57e8264ec92565974ead0d1724cf1026e10c1",
|
||||
"reference": "0ec57e8264ec92565974ead0d1724cf1026e10c1",
|
||||
"url": "https://api.github.com/repos/thephpleague/csv/zipball/34bf0df7340b60824b9449b5c526fcc3325070d5",
|
||||
"reference": "34bf0df7340b60824b9449b5c526fcc3325070d5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-filter": "*",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.3 || ^8.0"
|
||||
"php": "^8.1.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-curl": "*",
|
||||
"doctrine/collections": "^2.1.4",
|
||||
"ext-dom": "*",
|
||||
"friendsofphp/php-cs-fixer": "^2.16",
|
||||
"phpstan/phpstan": "^0.12.0",
|
||||
"phpstan/phpstan-phpunit": "^0.12.0",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.0",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
"ext-xdebug": "*",
|
||||
"friendsofphp/php-cs-fixer": "^v3.22.0",
|
||||
"phpbench/phpbench": "^1.2.15",
|
||||
"phpstan/phpstan": "^1.10.50",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.1.4",
|
||||
"phpstan/phpstan-phpunit": "^1.3.15",
|
||||
"phpstan/phpstan-strict-rules": "^1.5.2",
|
||||
"phpunit/phpunit": "^10.5.3",
|
||||
"symfony/var-dumper": "^6.4.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-dom": "Required to use the XMLConverter and or the HTMLConverter classes",
|
||||
"ext-dom": "Required to use the XMLConverter and the HTMLConverter classes",
|
||||
"ext-iconv": "Needed to ease transcoding CSV using iconv stream filters"
|
||||
},
|
||||
"type": "library",
|
||||
@@ -587,7 +592,7 @@
|
||||
}
|
||||
],
|
||||
"description": "CSV data manipulation made easy in PHP",
|
||||
"homepage": "http://csv.thephpleague.com",
|
||||
"homepage": "https://csv.thephpleague.com",
|
||||
"keywords": [
|
||||
"convert",
|
||||
"csv",
|
||||
@@ -610,7 +615,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-04-17T16:32:08+00:00"
|
||||
"time": "2023-12-29T07:34:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matomo/device-detector",
|
||||
@@ -1246,23 +1251,23 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.33.0",
|
||||
"version": "0.36.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "1ba8d5f2793885cbf779e3b5b9d886968af43d2c"
|
||||
"reference": "d3d09b4fa0db75935110714ad4b2a87f3ace31ed"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/1ba8d5f2793885cbf779e3b5b9d886968af43d2c",
|
||||
"reference": "1ba8d5f2793885cbf779e3b5b9d886968af43d2c",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/d3d09b4fa0db75935110714ad4b2a87f3ace31ed",
|
||||
"reference": "d3d09b4fa0db75935110714ad4b2a87f3ace31ed",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.45.*"
|
||||
"utopia-php/database": "0.48.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.5.*",
|
||||
@@ -1289,9 +1294,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.33.0"
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.36.0"
|
||||
},
|
||||
"time": "2023-11-01T08:51:33+00:00"
|
||||
"time": "2024-01-19T09:32:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
@@ -1341,21 +1346,21 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.35.0",
|
||||
"version": "0.38.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "ed9366ef05556da040de7a8b570f4160c7d8ea4a"
|
||||
"reference": "a9067f4af76e8787f1d29850a8ec94fc32bb6539"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/ed9366ef05556da040de7a8b570f4160c7d8ea4a",
|
||||
"reference": "ed9366ef05556da040de7a8b570f4160c7d8ea4a",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/a9067f4af76e8787f1d29850a8ec94fc32bb6539",
|
||||
"reference": "a9067f4af76e8787f1d29850a8ec94fc32bb6539",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.45.*"
|
||||
"utopia-php/database": "0.48.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.5.*",
|
||||
@@ -1382,9 +1387,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.35.0"
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.38.0"
|
||||
},
|
||||
"time": "2023-11-01T08:51:29+00:00"
|
||||
"time": "2024-01-19T09:33:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
@@ -1538,16 +1543,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.45.5",
|
||||
"version": "0.48.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "0b66a017f817a910acb83e6aea92bccea9571fe6"
|
||||
"reference": "2651f41b9d3909dc123d26becfb6a3a44fb63077"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/0b66a017f817a910acb83e6aea92bccea9571fe6",
|
||||
"reference": "0b66a017f817a910acb83e6aea92bccea9571fe6",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/2651f41b9d3909dc123d26becfb6a3a44fb63077",
|
||||
"reference": "2651f41b9d3909dc123d26becfb6a3a44fb63077",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1588,9 +1593,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.45.5"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.48.0"
|
||||
},
|
||||
"time": "2024-01-08T17:08:15+00:00"
|
||||
"time": "2024-01-19T08:17:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
@@ -1654,16 +1659,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/dsn",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/dsn.git",
|
||||
"reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea"
|
||||
"reference": "c11f37a12c3f6aaf9fea97ca7cb363dcc93668d7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/dsn/zipball/17a5935eab1b89fb4b95600db50a1b6d5faa6cea",
|
||||
"reference": "17a5935eab1b89fb4b95600db50a1b6d5faa6cea",
|
||||
"url": "https://api.github.com/repos/utopia-php/dsn/zipball/c11f37a12c3f6aaf9fea97ca7cb363dcc93668d7",
|
||||
"reference": "c11f37a12c3f6aaf9fea97ca7cb363dcc93668d7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1695,22 +1700,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/dsn/issues",
|
||||
"source": "https://github.com/utopia-php/dsn/tree/0.1.0"
|
||||
"source": "https://github.com/utopia-php/dsn/tree/0.2.0"
|
||||
},
|
||||
"time": "2022-10-26T10:06:20+00:00"
|
||||
"time": "2023-11-02T12:01:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.33.1",
|
||||
"version": "0.33.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "b745607aa1875554a0ad52e28f6db918da1ce11c"
|
||||
"reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/b745607aa1875554a0ad52e28f6db918da1ce11c",
|
||||
"reference": "b745607aa1875554a0ad52e28f6db918da1ce11c",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/b1423ca3e3b61c6c4c2e619d2cb80672809a19f3",
|
||||
"reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1740,22 +1745,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.1"
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.2"
|
||||
},
|
||||
"time": "2024-01-17T16:48:32+00:00"
|
||||
"time": "2024-01-31T10:35:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
"version": "0.5.4",
|
||||
"version": "0.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/image.git",
|
||||
"reference": "ca5f436f9aa22dedaa6648f24f3687733808e336"
|
||||
"reference": "88f7209172bdabd81e76ac981c95fac117dc6e08"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336",
|
||||
"reference": "ca5f436f9aa22dedaa6648f24f3687733808e336",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/88f7209172bdabd81e76ac981c95fac117dc6e08",
|
||||
"reference": "88f7209172bdabd81e76ac981c95fac117dc6e08",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1763,6 +1768,8 @@
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "1.9.x-dev",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"vimeo/psalm": "4.13.1"
|
||||
},
|
||||
@@ -1776,12 +1783,6 @@
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple Image manipulation library",
|
||||
"keywords": [
|
||||
"framework",
|
||||
@@ -1792,9 +1793,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/image/issues",
|
||||
"source": "https://github.com/utopia-php/image/tree/0.5.4"
|
||||
"source": "https://github.com/utopia-php/image/tree/0.6.0"
|
||||
},
|
||||
"time": "2022-05-11T12:30:41+00:00"
|
||||
"time": "2024-01-24T06:59:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
@@ -1902,16 +1903,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/messaging",
|
||||
"version": "0.8.1",
|
||||
"version": "0.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/messaging.git",
|
||||
"reference": "bfb5014d3a8752901e50da1ae21bf309a6af5006"
|
||||
"reference": "df54ba51570e886724590edeb03dbd455bb0464d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/bfb5014d3a8752901e50da1ae21bf309a6af5006",
|
||||
"reference": "bfb5014d3a8752901e50da1ae21bf309a6af5006",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/df54ba51570e886724590edeb03dbd455bb0464d",
|
||||
"reference": "df54ba51570e886724590edeb03dbd455bb0464d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1946,9 +1947,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/messaging/issues",
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.8.1"
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.9.0"
|
||||
},
|
||||
"time": "2024-01-10T23:55:03+00:00"
|
||||
"time": "2024-01-31T11:51:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
@@ -2821,16 +2822,16 @@
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
"version": "1.1.2",
|
||||
"version": "1.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/deprecations.git",
|
||||
"reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931"
|
||||
"reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
|
||||
"reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
|
||||
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
|
||||
"reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2862,9 +2863,9 @@
|
||||
"homepage": "https://www.doctrine-project.org/",
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/deprecations/issues",
|
||||
"source": "https://github.com/doctrine/deprecations/tree/1.1.2"
|
||||
"source": "https://github.com/doctrine/deprecations/tree/1.1.3"
|
||||
},
|
||||
"time": "2023-09-27T20:04:15+00:00"
|
||||
"time": "2024-01-30T19:34:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
@@ -5520,7 +5521,7 @@
|
||||
"ext-fileinfo": "*"
|
||||
},
|
||||
"platform-overrides": {
|
||||
"php": "8.0"
|
||||
"php": "8.2"
|
||||
},
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
zend_extension=xdebug
|
||||
|
||||
[xdebug]
|
||||
xdebug.mode=develop,debug
|
||||
xdebug.client_host=host.docker.internal
|
||||
xdebug.start_with_request=yes
|
||||
@@ -1,4 +0,0 @@
|
||||
<?php
|
||||
|
||||
echo 'execute init_file success' . PHP_EOL;
|
||||
Yasd\Api\setRemoteHost('host.docker.internal'); //Set your development machine's IP
|
||||
@@ -885,7 +885,7 @@ services:
|
||||
- OPR_PROXY_HEALTHCHECK=enabled
|
||||
|
||||
mariadb:
|
||||
image: mariadb:10.7 # fix issues when upgrading using: mysql_upgrade -u root -p
|
||||
image: mariadb:10.11 # fix issues when upgrading using: mysql_upgrade -u root -p
|
||||
container_name: appwrite-mariadb
|
||||
<<: *x-logging
|
||||
networks:
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Delete a message by its unique ID.
|
||||
@@ -60,7 +60,8 @@ class Scryptmodified extends Hash
|
||||
$saltBytes = \base64_decode($options['salt']);
|
||||
$saltSeparatorBytes = \base64_decode($options['saltSeparator']);
|
||||
|
||||
$derivedKey = \scrypt(\utf8_encode($password), $saltBytes . $saltSeparatorBytes, 16384, 8, 1, 64);
|
||||
$password = mb_convert_encoding($password, 'UTF-8');
|
||||
$derivedKey = \scrypt($password, $saltBytes . $saltSeparatorBytes, 16384, 8, 1, 64);
|
||||
$derivedKey = \hex2bin($derivedKey);
|
||||
|
||||
return $derivedKey;
|
||||
|
||||
@@ -43,10 +43,10 @@ class PersonalData extends Password
|
||||
|
||||
if (!$this->strict) {
|
||||
$password = strtolower($password);
|
||||
$this->userId = strtolower($this->userId);
|
||||
$this->email = strtolower($this->email);
|
||||
$this->name = strtolower($this->name);
|
||||
$this->phone = strtolower($this->phone);
|
||||
$this->userId = strtolower($this->userId ?? '');
|
||||
$this->email = strtolower($this->email ?? '');
|
||||
$this->name = strtolower($this->name ?? '');
|
||||
$this->phone = strtolower($this->phone ?? '');
|
||||
}
|
||||
|
||||
if ($this->userId && strpos($password, $this->userId) !== false) {
|
||||
|
||||
@@ -249,7 +249,7 @@ class Exception extends \Exception
|
||||
public const PROVIDER_NOT_FOUND = 'provider_not_found';
|
||||
public const PROVIDER_ALREADY_EXISTS = 'provider_already_exists';
|
||||
public const PROVIDER_INCORRECT_TYPE = 'provider_incorrect_type';
|
||||
public const PROVIDER_INTERNAL_UPDATE_DISABLED = 'provider_internal_update_disabled';
|
||||
public const PROVIDER_MISSING_CREDENTIALS = 'provider_missing_credentials';
|
||||
|
||||
/** Topic */
|
||||
public const TOPIC_NOT_FOUND = 'topic_not_found';
|
||||
|
||||
@@ -397,7 +397,7 @@ abstract class Migration
|
||||
*/
|
||||
protected function changeAttributeInternalType(string $collection, string $attribute, string $type): void
|
||||
{
|
||||
$stmt = $this->pdo->prepare("ALTER TABLE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$collection}` MODIFY `$attribute` $type;");
|
||||
$stmt = $this->pdo->prepare("ALTER TABLE `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_{$collection}` MODIFY `$attribute` $type;");
|
||||
|
||||
try {
|
||||
$stmt->execute();
|
||||
|
||||
@@ -295,7 +295,7 @@ class V15 extends Migration
|
||||
protected function removeWritePermissions(string $table): void
|
||||
{
|
||||
try {
|
||||
$this->pdo->prepare("DELETE FROM `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$table}_perms` WHERE _type = 'write'")->execute();
|
||||
$this->pdo->prepare("DELETE FROM `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}_perms` WHERE _type = 'write'")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Remove 'write' permissions from {$table}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -311,7 +311,7 @@ class V15 extends Migration
|
||||
*/
|
||||
protected function getSQLColumnTypes(string $table): array
|
||||
{
|
||||
$query = $this->pdo->prepare("SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '_{$this->project->getInternalId()}_{$table}' AND table_schema = '{$this->projectDB->getDefaultDatabase()}'");
|
||||
$query = $this->pdo->prepare("SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '_{$this->project->getInternalId()}_{$table}' AND table_schema = '{$this->projectDB->getDatabase()}'");
|
||||
$query->execute();
|
||||
|
||||
return array_reduce($query->fetchAll(), function (array $carry, array $item) {
|
||||
@@ -333,8 +333,8 @@ class V15 extends Migration
|
||||
|
||||
if ($columns[$attribute] === 'int') {
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$table}` MODIFY {$attribute} VARCHAR(64)")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$table}` SET {$attribute} = IF({$attribute} = 0, NULL, FROM_UNIXTIME({$attribute}))")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` MODIFY {$attribute} VARCHAR(64)")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` SET {$attribute} = IF({$attribute} = 0, NULL, FROM_UNIXTIME({$attribute}))")->execute();
|
||||
$columns[$attribute] = 'varchar';
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
@@ -343,7 +343,7 @@ class V15 extends Migration
|
||||
|
||||
if ($columns[$attribute] === 'varchar') {
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$table}` MODIFY {$attribute} DATETIME(3)")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` MODIFY {$attribute} DATETIME(3)")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
@@ -372,7 +372,7 @@ class V15 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($table);
|
||||
$this->projectDB->purgeCachedCollection($table);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,7 +389,7 @@ class V15 extends Migration
|
||||
|
||||
if (!array_key_exists('_permissions', $columns)) {
|
||||
try {
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$table}` ADD `_permissions` MEDIUMTEXT DEFAULT NULL")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE IF EXISTS `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}` ADD `_permissions` MEDIUMTEXT DEFAULT NULL")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Add '_permissions' column to '{$table}': {$th->getMessage()}");
|
||||
}
|
||||
@@ -410,7 +410,7 @@ class V15 extends Migration
|
||||
{
|
||||
$table ??= $document->getCollection();
|
||||
|
||||
$query = $this->pdo->prepare("SELECT * FROM `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_{$table}_perms` WHERE _document = '{$document->getId()}'");
|
||||
$query = $this->pdo->prepare("SELECT * FROM `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_{$table}_perms` WHERE _document = '{$document->getId()}'");
|
||||
$query->execute();
|
||||
$results = $query->fetchAll();
|
||||
$permissions = [];
|
||||
@@ -479,7 +479,7 @@ class V15 extends Migration
|
||||
$this->createCollection('cache');
|
||||
Console::log('Created new Collection "variables" collection');
|
||||
$this->createCollection('variables');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
break;
|
||||
|
||||
case 'abuse':
|
||||
@@ -1472,9 +1472,9 @@ class V15 extends Migration
|
||||
$from = $this->pdo->quote($from);
|
||||
$to = $this->pdo->quote($to);
|
||||
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_stats` SET metric = {$to} WHERE metric = {$from}")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_stats` SET metric = {$to} WHERE metric = {$from}")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Migrating steps from {$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}_stats:" . $th->getMessage());
|
||||
Console::warning("Migrating steps from {$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}_stats:" . $th->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ class V17 extends Migration
|
||||
|
||||
try {
|
||||
$this->projectDB->updateAttribute($id, 'mimeType', Database::VAR_STRING, 255, true, false);
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'mimeType' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -76,7 +76,7 @@ class V17 extends Migration
|
||||
* Create 'size' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'size');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'size' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -88,7 +88,7 @@ class V17 extends Migration
|
||||
* Update 'mimeType' attribute size (127->255)
|
||||
*/
|
||||
$this->projectDB->updateAttribute($id, 'mimeType', Database::VAR_STRING, 255, true, false);
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'mimeType' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -98,7 +98,7 @@ class V17 extends Migration
|
||||
* Create 'bucketInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'bucketInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -110,7 +110,7 @@ class V17 extends Migration
|
||||
* Delete 'endTime' attribute (use startTime+duration if needed)
|
||||
*/
|
||||
$this->projectDB->deleteAttribute($id, 'endTime');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'endTime' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -120,7 +120,7 @@ class V17 extends Migration
|
||||
* Rename 'outputPath' to 'path'
|
||||
*/
|
||||
$this->projectDB->renameAttribute($id, 'outputPath', 'path');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'path' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -130,7 +130,7 @@ class V17 extends Migration
|
||||
* Create 'deploymentInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -142,7 +142,7 @@ class V17 extends Migration
|
||||
* Delete 'type' attribute
|
||||
*/
|
||||
$this->projectDB->deleteAttribute($id, 'type');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'type' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -154,7 +154,7 @@ class V17 extends Migration
|
||||
* Create 'resourceInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'resourceInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'resourceInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -166,7 +166,7 @@ class V17 extends Migration
|
||||
* Create 'deploymentInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -176,7 +176,7 @@ class V17 extends Migration
|
||||
* Create 'scheduleInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'scheduleInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'scheduleInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -186,7 +186,7 @@ class V17 extends Migration
|
||||
* Delete 'scheduleUpdatedAt' attribute
|
||||
*/
|
||||
$this->projectDB->deleteAttribute($id, 'scheduleUpdatedAt');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'scheduleUpdatedAt' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -198,7 +198,7 @@ class V17 extends Migration
|
||||
* Create 'resourceInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'resourceInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'resourceInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -208,7 +208,7 @@ class V17 extends Migration
|
||||
* Create 'buildInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'buildInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'buildInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -220,7 +220,7 @@ class V17 extends Migration
|
||||
* Create 'functionInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'functionInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'functionInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -230,7 +230,7 @@ class V17 extends Migration
|
||||
* Create 'deploymentInternalId' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'deploymentInternalId');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'deploymentInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ class V18 extends Migration
|
||||
* Create 'passwordHistory' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'passwordHistory');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'passwordHistory' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -117,7 +117,7 @@ class V18 extends Migration
|
||||
* Create 'prefs' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'prefs');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'prefs' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -128,7 +128,7 @@ class V18 extends Migration
|
||||
* Create 'options' attribute
|
||||
*/
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'options');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'options' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -244,7 +244,7 @@ class V18 extends Migration
|
||||
/**
|
||||
* Create 'documentSecurity' column
|
||||
*/
|
||||
$this->pdo->prepare("ALTER TABLE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}__metadata` ADD COLUMN IF NOT EXISTS documentSecurity TINYINT(1);")->execute();
|
||||
$this->pdo->prepare("ALTER TABLE `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}__metadata` ADD COLUMN IF NOT EXISTS documentSecurity TINYINT(1);")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
@@ -253,7 +253,7 @@ class V18 extends Migration
|
||||
/**
|
||||
* Set 'documentSecurity' column to 1 if NULL
|
||||
*/
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDefaultDatabase()}`.`_{$this->project->getInternalId()}__metadata` SET documentSecurity = 1 WHERE documentSecurity IS NULL")->execute();
|
||||
$this->pdo->prepare("UPDATE `{$this->projectDB->getDatabase()}`.`_{$this->project->getInternalId()}__metadata` SET documentSecurity = 1 WHERE documentSecurity IS NULL")->execute();
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning($th->getMessage());
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ class V19 extends Migration
|
||||
|
||||
protected function migrateDomains(): void
|
||||
{
|
||||
if ($this->consoleDB->exists($this->consoleDB->getDefaultDatabase(), 'domains')) {
|
||||
if ($this->consoleDB->exists($this->consoleDB->getDatabase(), 'domains')) {
|
||||
foreach ($this->documentsIterator('domains') as $domain) {
|
||||
$status = 'created';
|
||||
if ($domain->getAttribute('verification', false)) {
|
||||
@@ -106,7 +106,7 @@ class V19 extends Migration
|
||||
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->projectDB, $id, 'bucketInternalId', 'files');
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'bucketInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
@@ -166,7 +166,7 @@ class V19 extends Migration
|
||||
Console::warning("'error' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'buckets':
|
||||
@@ -194,7 +194,7 @@ class V19 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'builds':
|
||||
@@ -217,7 +217,7 @@ class V19 extends Migration
|
||||
Console::warning("'path' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'certificates':
|
||||
@@ -233,7 +233,7 @@ class V19 extends Migration
|
||||
Console::warning("'logs' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'databases':
|
||||
@@ -243,7 +243,7 @@ class V19 extends Migration
|
||||
Console::warning("'enabled' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'deployments':
|
||||
@@ -306,7 +306,7 @@ class V19 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'executions':
|
||||
@@ -367,7 +367,7 @@ class V19 extends Migration
|
||||
Console::warning("'_key_responseStatusCode' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'files':
|
||||
@@ -394,7 +394,7 @@ class V19 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'functions':
|
||||
@@ -456,7 +456,7 @@ class V19 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'memberships':
|
||||
@@ -466,7 +466,7 @@ class V19 extends Migration
|
||||
Console::warning("'teamInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
// Intentional fall through to update memberships.userInternalId
|
||||
case 'sessions':
|
||||
@@ -477,7 +477,7 @@ class V19 extends Migration
|
||||
Console::warning("'userInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'domains':
|
||||
@@ -490,7 +490,7 @@ class V19 extends Migration
|
||||
Console::warning("'projectInternalId' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'projects':
|
||||
@@ -508,7 +508,7 @@ class V19 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'stats':
|
||||
@@ -521,26 +521,26 @@ class V19 extends Migration
|
||||
// Holding off on these until a future release
|
||||
// try {
|
||||
// $this->projectDB->deleteAttribute($id, 'type');
|
||||
// $this->projectDB->deleteCachedCollection($id);
|
||||
// $this->projectDB->purgeCachedCollection($id);
|
||||
// } catch (\Throwable $th) {
|
||||
// Console::warning("'type' from {$id}: {$th->getMessage()}");
|
||||
// }
|
||||
|
||||
// try {
|
||||
// $this->projectDB->deleteIndex($id, '_key_metric_period_time');
|
||||
// $this->projectDB->deleteCachedCollection($id);
|
||||
// $this->projectDB->purgeCachedCollection($id);
|
||||
// } catch (\Throwable $th) {
|
||||
// Console::warning("'_key_metric_period_time' from {$id}: {$th->getMessage()}");
|
||||
// }
|
||||
|
||||
// try {
|
||||
// $this->createIndexFromCollection($this->projectDB, $id, '_key_metric_period_time');
|
||||
// $this->projectDB->deleteCachedCollection($id);
|
||||
// $this->projectDB->purgeCachedCollection($id);
|
||||
// } catch (\Throwable $th) {
|
||||
// Console::warning("'_key_metric_period_time' from {$id}: {$th->getMessage()}");
|
||||
// }
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'users':
|
||||
@@ -568,7 +568,7 @@ class V19 extends Migration
|
||||
Console::warning("'_key_accessedAt' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
case 'variables':
|
||||
@@ -616,7 +616,7 @@ class V19 extends Migration
|
||||
}
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection($id);
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
|
||||
break;
|
||||
default:
|
||||
@@ -775,7 +775,7 @@ class V19 extends Migration
|
||||
Console::warning("'domains' from projects: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection('projects');
|
||||
$this->projectDB->purgeCachedCollection('projects');
|
||||
|
||||
try {
|
||||
$this->projectDB->deleteAttribute('builds', 'stderr');
|
||||
@@ -789,7 +789,7 @@ class V19 extends Migration
|
||||
Console::warning("'stdout' from builds: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->projectDB->deleteCachedCollection('builds');
|
||||
$this->projectDB->purgeCachedCollection('builds');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -90,12 +90,12 @@ class DeleteOrphanedProjects extends Action
|
||||
->getResource();
|
||||
|
||||
$dbForProject = new Database($adapter, $cache);
|
||||
$dbForProject->setDefaultDatabase('appwrite');
|
||||
$dbForProject->setDatabase('appwrite');
|
||||
$dbForProject->setNamespace('_' . $project->getInternalId());
|
||||
|
||||
$collectionsCreated = 0;
|
||||
$cnt++;
|
||||
if ($dbForProject->exists($dbForProject->getDefaultDatabase(), Database::METADATA)) {
|
||||
if ($dbForProject->exists($dbForProject->getDatabase(), Database::METADATA)) {
|
||||
$collectionsCreated = $dbForProject->count(Database::METADATA);
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ class DeleteOrphanedProjects extends Action
|
||||
foreach ($collections as $collection) {
|
||||
if ($commit) {
|
||||
$dbForProject->deleteCollection($collection->getId());
|
||||
$dbForConsole->deleteCachedCollection($collection->getId());
|
||||
$dbForConsole->purgeCachedCollection($collection->getId());
|
||||
}
|
||||
Console::info('--Deleting collection (' . $collection->getId() . ') project no (' . $project->getInternalId() . ')');
|
||||
}
|
||||
@@ -121,12 +121,12 @@ class DeleteOrphanedProjects extends Action
|
||||
|
||||
if ($commit) {
|
||||
$dbForConsole->deleteDocument('projects', $project->getId());
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
if ($dbForProject->exists($dbForProject->getDefaultDatabase(), Database::METADATA)) {
|
||||
try {
|
||||
$dbForProject->deleteCollection(Database::METADATA);
|
||||
$dbForProject->deleteCachedCollection(Database::METADATA);
|
||||
$dbForProject->purgeCachedCollection(Database::METADATA);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Metadata collection does not exist');
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ class Maintenance extends Action
|
||||
$this->renewCertificates($dbForConsole, $queueForCertificates);
|
||||
$this->notifyDeleteCache($cacheRetention, $queueForDeletes);
|
||||
$this->notifyDeleteSchedules($schedulesDeletionRetention, $queueForDeletes);
|
||||
$this->notifyDeleteTargets($queueForDeletes);
|
||||
}, $interval);
|
||||
}
|
||||
|
||||
@@ -161,8 +162,7 @@ class Maintenance extends Action
|
||||
|
||||
private function notifyDeleteCache($interval, Delete $queueForDeletes): void
|
||||
{
|
||||
|
||||
($queueForDeletes)
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_CACHE_BY_TIMESTAMP)
|
||||
->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval))
|
||||
->trigger();
|
||||
@@ -170,10 +170,16 @@ class Maintenance extends Action
|
||||
|
||||
private function notifyDeleteSchedules($interval, Delete $queueForDeletes): void
|
||||
{
|
||||
|
||||
($queueForDeletes)
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_SCHEDULES)
|
||||
->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval))
|
||||
->trigger();
|
||||
}
|
||||
|
||||
private function notifyDeleteTargets(Delete $queueForDeletes): void
|
||||
{
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_EXPIRED_TARGETS)
|
||||
->trigger();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ abstract class ScheduleBase extends Action
|
||||
'$id' => $schedule->getId(),
|
||||
'resourceId' => $schedule->getAttribute('resourceId'),
|
||||
'schedule' => $schedule->getAttribute('schedule'),
|
||||
'active' => $schedule->getAttribute('active'),
|
||||
'resourceUpdatedAt' => $schedule->getAttribute('resourceUpdatedAt'),
|
||||
'project' => $project, // TODO: @Meldiron Send only ID to worker to reduce memory usage here
|
||||
'resource' => $resource, // TODO: @Meldiron Send only ID to worker to reduce memory usage here
|
||||
|
||||
@@ -33,6 +33,10 @@ class ScheduleMessages extends ScheduleBase
|
||||
protected function enqueueResources(Group $pools, Database $dbForConsole): void
|
||||
{
|
||||
foreach ($this->schedules as $schedule) {
|
||||
if (!$schedule['active']) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$now = DateTime::now();
|
||||
$scheduledAt = DateTime::formatTz($schedule['schedule']);
|
||||
|
||||
@@ -44,24 +48,17 @@ class ScheduleMessages extends ScheduleBase
|
||||
$queue = $pools->get('queue')->pop();
|
||||
$connection = $queue->getResource();
|
||||
$queueForMessaging = new Messaging($connection);
|
||||
$queueForDeletes = new Delete($connection);
|
||||
|
||||
$queueForMessaging
|
||||
->setMessageId($schedule['resourceId'])
|
||||
->setProject($schedule['project'])
|
||||
->trigger();
|
||||
|
||||
$dbForConsole->updateDocument(
|
||||
$dbForConsole->deleteDocument(
|
||||
'schedules',
|
||||
$schedule['$id'],
|
||||
new Document(['active' => false])
|
||||
);
|
||||
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_SCHEDULES)
|
||||
->setDocument($schedule)
|
||||
->trigger();
|
||||
|
||||
$queue->reclaim();
|
||||
|
||||
unset($this->schedules[$schedule['resourceId']]);
|
||||
|
||||
@@ -195,10 +195,10 @@ class Databases extends Action
|
||||
}
|
||||
|
||||
if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) {
|
||||
$dbForProject->deleteCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -346,12 +346,12 @@ class Databases extends Action
|
||||
}
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->deleteCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId());
|
||||
|
||||
if (!$relatedCollection->isEmpty() && !$relatedAttribute->isEmpty()) {
|
||||
$dbForProject->deleteCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->deleteCachedCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $database->getInternalId() . '_collection_' . $relatedCollection->getInternalId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ class Databases extends Action
|
||||
$this->trigger($database, $collection, $index, $project, $projectId, $events);
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -471,7 +471,7 @@ class Databases extends Action
|
||||
$this->trigger($database, $collection, $index, $project, $projectId, $events);
|
||||
}
|
||||
|
||||
$dbForProject->deleteCachedDocument('database_' . $database->getInternalId(), $collection->getId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collection->getId());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -526,8 +526,8 @@ class Databases extends Action
|
||||
}
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $databaseInternalId, $relationship['relatedCollection']);
|
||||
$dbForProject->deleteDocument('attributes', $databaseInternalId . '_' . $relatedCollection->getInternalId() . '_' . $relationship['twoWayKey']);
|
||||
$dbForProject->deleteCachedDocument('database_' . $databaseInternalId, $relatedCollection->getId());
|
||||
$dbForProject->deleteCachedCollection('database_' . $databaseInternalId . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $databaseInternalId, $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $databaseInternalId . '_collection_' . $relatedCollection->getInternalId());
|
||||
}
|
||||
|
||||
$dbForProject->deleteCollection('database_' . $databaseInternalId . '_collection_' . $collection->getInternalId());
|
||||
|
||||
@@ -122,11 +122,9 @@ class Deletes extends Action
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_EXECUTIONS:
|
||||
$this->deleteExecutionLogs($project, $getProjectDB, $executionRetention);
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_AUDIT:
|
||||
if (!$project->isEmpty()) {
|
||||
$this->deleteAuditLogs($project, $getProjectDB, $auditRetention);
|
||||
@@ -139,11 +137,9 @@ class Deletes extends Action
|
||||
case DELETE_TYPE_ABUSE:
|
||||
$this->deleteAbuseLogs($project, $getProjectDB, $abuseRetention);
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_REALTIME:
|
||||
$this->deleteRealtimeUsage($dbForConsole, $datetime);
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_SESSIONS:
|
||||
$this->deleteExpiredSessions($project, $getProjectDB);
|
||||
break;
|
||||
@@ -157,17 +153,19 @@ class Deletes extends Action
|
||||
$this->deleteCacheByDate($project, $getProjectDB, $datetime);
|
||||
break;
|
||||
case DELETE_TYPE_SCHEDULES:
|
||||
$this->deleteSchedules($dbForConsole, $getProjectDB, $datetime, $document);
|
||||
$this->deleteSchedules($dbForConsole, $getProjectDB, $datetime);
|
||||
break;
|
||||
case DELETE_TYPE_TOPIC:
|
||||
$this->deleteTopic($project, $getProjectDB, $document);
|
||||
break;
|
||||
case DELETE_TYPE_TARGET:
|
||||
$this->deleteTarget($project, $getProjectDB, $document);
|
||||
$this->deleteTargetSubscribers($project, $getProjectDB, $document);
|
||||
break;
|
||||
case DELETE_TYPE_EXPIRED_TARGETS:
|
||||
$this->deleteExpiredTargets($project, $getProjectDB);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('No delete operation for type: ' . \strval($type));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,13 +181,12 @@ class Deletes extends Action
|
||||
* @throws Structure
|
||||
* @throws DatabaseException
|
||||
*/
|
||||
private function deleteSchedules(Database $dbForConsole, callable $getProjectDB, string $datetime, ?Document $document = null): void
|
||||
private function deleteSchedules(Database $dbForConsole, callable $getProjectDB, string $datetime): void
|
||||
{
|
||||
$this->listByGroup(
|
||||
'schedules',
|
||||
[
|
||||
Query::equal('region', [App::getEnv('_APP_REGION', 'default')]),
|
||||
Query::equal('resourceType', [$document->getAttribute('resourceType')]),
|
||||
Query::lessThanEqual('resourceUpdatedAt', $datetime),
|
||||
Query::equal('active', [false]),
|
||||
],
|
||||
@@ -230,17 +227,20 @@ class Deletes extends Action
|
||||
* @param Document $topic
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function deleteTopic(Document $project, callable $getProjectDB, Document $topic)
|
||||
private function deleteTopic(Document $project, callable $getProjectDB, Document $topic)
|
||||
{
|
||||
if ($topic->isEmpty()) {
|
||||
Console::error('Failed to delete subscribers. Topic not found');
|
||||
return;
|
||||
}
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
$this->deleteByGroup('subscribers', [
|
||||
Query::equal('topicInternalId', [$topic->getInternalId()])
|
||||
], $dbForProject);
|
||||
$this->deleteByGroup(
|
||||
'subscribers',
|
||||
[
|
||||
Query::equal('topicInternalId', [$topic->getInternalId()])
|
||||
],
|
||||
$getProjectDB($project)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,7 +249,7 @@ class Deletes extends Action
|
||||
* @param Document $target
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function deleteTarget(Document $project, callable $getProjectDB, Document $target)
|
||||
private function deleteTargetSubscribers(Document $project, callable $getProjectDB, Document $target)
|
||||
{
|
||||
/** @var Database */
|
||||
$dbForProject = $getProjectDB($project);
|
||||
@@ -272,6 +272,27 @@ class Deletes extends Action
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Document $project
|
||||
* @param callable $getProjectDB
|
||||
* @param Document $target
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
private function deleteExpiredTargets(Document $project, callable $getProjectDB)
|
||||
{
|
||||
$this->deleteByGroup(
|
||||
'targets',
|
||||
[
|
||||
Query::equal('expired', [true])
|
||||
],
|
||||
$getProjectDB($project),
|
||||
function (Document $target) use ($getProjectDB, $project) {
|
||||
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Document $project
|
||||
* @param callable $getProjectDB
|
||||
@@ -390,8 +411,8 @@ class Deletes extends Action
|
||||
}
|
||||
$relatedCollection = $dbForProject->getDocument('database_' . $databaseInternalId, $relationship['relatedCollection']);
|
||||
$dbForProject->deleteDocument('attributes', $databaseInternalId . '_' . $relatedCollection->getInternalId() . '_' . $relationship['twoWayKey']);
|
||||
$dbForProject->deleteCachedDocument('database_' . $databaseInternalId, $relatedCollection->getId());
|
||||
$dbForProject->deleteCachedCollection('database_' . $databaseInternalId . '_collection_' . $relatedCollection->getInternalId());
|
||||
$dbForProject->purgeCachedDocument('database_' . $databaseInternalId, $relatedCollection->getId());
|
||||
$dbForProject->purgeCachedCollection('database_' . $databaseInternalId . '_collection_' . $relatedCollection->getInternalId());
|
||||
}
|
||||
|
||||
$dbForProject->deleteCollection('database_' . $databaseInternalId . '_collection_' . $document->getInternalId());
|
||||
@@ -447,7 +468,7 @@ class Deletes extends Action
|
||||
$dbForProject,
|
||||
function (Document $membership) use ($dbForProject) {
|
||||
$userId = $membership->getAttribute('userId');
|
||||
$dbForProject->deleteCachedDocument('users', $userId);
|
||||
$dbForProject->purgeCachedDocument('users', $userId);
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -582,7 +603,7 @@ class Deletes extends Action
|
||||
Query::equal('userInternalId', [$userInternalId])
|
||||
], $dbForProject);
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $userId);
|
||||
$dbForProject->purgeCachedDocument('users', $userId);
|
||||
|
||||
// Delete Memberships and decrement team membership counts
|
||||
$this->deleteByGroup('memberships', [
|
||||
@@ -613,14 +634,14 @@ class Deletes extends Action
|
||||
], $dbForProject);
|
||||
|
||||
// Delete targets
|
||||
$this->listByGroup(
|
||||
$this->deleteByGroup(
|
||||
'targets',
|
||||
[
|
||||
Query::equal('userInternalId', [$userInternalId])
|
||||
],
|
||||
$dbForProject,
|
||||
function (Document $target) use ($getProjectDB, $project) {
|
||||
$this->deleteTarget($project, $getProjectDB, $target);
|
||||
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ use Utopia\Database\Query;
|
||||
use Utopia\Messaging\Adapter\Email as EmailAdapter;
|
||||
use Utopia\Messaging\Adapter\Email\Mailgun;
|
||||
use Utopia\Messaging\Adapter\Email\Sendgrid;
|
||||
use Utopia\Messaging\Adapter\Email\SMTP;
|
||||
use Utopia\Messaging\Adapter\Push as PushAdapter;
|
||||
use Utopia\Messaging\Adapter\Push\APNS;
|
||||
use Utopia\Messaging\Adapter\Push\FCM;
|
||||
@@ -216,8 +217,8 @@ class Messaging extends Action
|
||||
$batches = \array_chunk($identifiers, $maxBatchSize);
|
||||
$batchIndex = 0;
|
||||
|
||||
return batch(\array_map(function ($batch) use ($message, $provider, $adapter, $batchIndex, $dbForProject) {
|
||||
return function () use ($batch, $message, $provider, $adapter, $batchIndex, $dbForProject) {
|
||||
return batch(\array_map(function ($batch) use ($message, $provider, $adapter, &$batchIndex, $dbForProject) {
|
||||
return function () use ($batch, $message, $provider, $adapter, &$batchIndex, $dbForProject) {
|
||||
$deliveredTotal = 0;
|
||||
$deliveryErrors = [];
|
||||
$messageData = clone $message;
|
||||
@@ -248,7 +249,11 @@ class Messaging extends Action
|
||||
]);
|
||||
|
||||
if ($target instanceof Document && !$target->isEmpty()) {
|
||||
$dbForProject->deleteDocument('targets', $target->getId());
|
||||
$dbForProject->updateDocument(
|
||||
'targets',
|
||||
$target->getId(),
|
||||
$target->setAttribute('expired', true)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -403,10 +408,24 @@ class Messaging extends Action
|
||||
|
||||
private function email(Document $provider): ?EmailAdapter
|
||||
{
|
||||
$credentials = $provider->getAttribute('credentials');
|
||||
$credentials = $provider->getAttribute('credentials', []);
|
||||
$options = $provider->getAttribute('options', []);
|
||||
return match ($provider->getAttribute('provider')) {
|
||||
'mock' => new Mock('username', 'password'),
|
||||
'mailgun' => new Mailgun($credentials['apiKey'], $credentials['domain'], $credentials['isEuRegion']),
|
||||
'smtp' => new SMTP(
|
||||
$credentials['host'],
|
||||
$credentials['port'],
|
||||
$credentials['username'],
|
||||
$credentials['password'],
|
||||
$options['encryption'],
|
||||
$options['autoTLS'],
|
||||
$options['mailer'],
|
||||
),
|
||||
'mailgun' => new Mailgun(
|
||||
$credentials['apiKey'],
|
||||
$credentials['domain'],
|
||||
$credentials['isEuRegion']
|
||||
),
|
||||
'sendgrid' => new Sendgrid($credentials['apiKey']),
|
||||
default => null
|
||||
};
|
||||
@@ -414,16 +433,10 @@ class Messaging extends Action
|
||||
|
||||
private function buildEmailMessage(Database $dbForProject, Document $message, Document $provider): Email
|
||||
{
|
||||
$fromName = $provider['options']['fromName'];
|
||||
$fromEmail = $provider['options']['fromEmail'];
|
||||
$replyToEmail = null;
|
||||
$replyToName = null;
|
||||
|
||||
if (isset($provider['options']['replyToName']) && isset($provider['options']['replyToEmail'])) {
|
||||
$replyToName = $provider['options']['replyToName'];
|
||||
$replyToEmail = $provider['options']['replyToEmail'];
|
||||
}
|
||||
|
||||
$fromName = $provider['options']['fromName'] ?? null;
|
||||
$fromEmail = $provider['options']['fromEmail'] ?? null;
|
||||
$replyToEmail = $provider['options']['replyToEmail'] ?? null;
|
||||
$replyToName = $provider['options']['replyToName'] ?? null;
|
||||
$data = $message['data'] ?? [];
|
||||
$ccTargets = $data['cc'] ?? [];
|
||||
$bccTargets = $data['bcc'] ?? [];
|
||||
|
||||
@@ -225,7 +225,7 @@ class Migrations extends Action
|
||||
]);
|
||||
|
||||
$this->dbForConsole->createDocument('keys', $key);
|
||||
$this->dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$this->dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
return $key;
|
||||
}
|
||||
|
||||
@@ -163,13 +163,13 @@ class Webhooks extends Action
|
||||
}
|
||||
|
||||
$dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook);
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
|
||||
$this->errors[] = $logs;
|
||||
} else {
|
||||
$webhook->setAttribute('attempts', 0); // Reset attempts on success
|
||||
$dbForConsole->updateDocument('webhooks', $webhook->getId(), $webhook);
|
||||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
$dbForConsole->purgeCachedDocument('projects', $project->getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Tests\E2E\Services\Account;
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
trait AccountBase
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\SideClient;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
|
||||
use function sleep;
|
||||
@@ -344,7 +345,9 @@ class AccountCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session,
|
||||
]), [
|
||||
'queries' => [ 'limit(1)' ],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($responseLimit['headers']['status-code'], 200);
|
||||
@@ -361,7 +364,9 @@ class AccountCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session,
|
||||
]), [
|
||||
'queries' => [ 'offset(1)' ],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($responseOffset['headers']['status-code'], 200);
|
||||
@@ -378,7 +383,10 @@ class AccountCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $session,
|
||||
]), [
|
||||
'queries' => [ 'limit(1)', 'offset(1)' ],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
Query::limit(1)->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($responseLimitOffset['headers']['status-code'], 200);
|
||||
|
||||
@@ -6,13 +6,152 @@ use Appwrite\Extend\Exception;
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
use Utopia\Validator\JSON;
|
||||
|
||||
trait DatabasesBase
|
||||
{
|
||||
/**
|
||||
* @throws \Utopia\Database\Exception
|
||||
* @throws \Utopia\Database\Exception\Query
|
||||
*/
|
||||
public function testOrQueries(): void
|
||||
{
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Or queries'
|
||||
]);
|
||||
|
||||
$this->assertNotEmpty($database['body']['$id']);
|
||||
$this->assertEquals(201, $database['headers']['status-code']);
|
||||
$this->assertEquals('Or queries', $database['body']['name']);
|
||||
|
||||
$databaseId = $database['body']['$id'];
|
||||
|
||||
// Create Collection
|
||||
$presidents = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'USA Presidents',
|
||||
'documentSecurity' => true,
|
||||
'permissions' => [
|
||||
Permission::create(Role::user($this->getUser()['$id'])),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $presidents['headers']['status-code']);
|
||||
$this->assertEquals($presidents['body']['name'], 'USA Presidents');
|
||||
|
||||
// Create Attributes
|
||||
$firstName = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $presidents['body']['$id'] . '/attributes/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'first_name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
$this->assertEquals(202, $firstName['headers']['status-code']);
|
||||
|
||||
$lastName = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $presidents['body']['$id'] . '/attributes/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'last_name',
|
||||
'size' => 256,
|
||||
'required' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $lastName['headers']['status-code']);
|
||||
|
||||
// Wait for worker
|
||||
sleep(2);
|
||||
|
||||
$document1 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $presidents['body']['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'first_name' => 'Donald',
|
||||
'last_name' => 'Trump',
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
]
|
||||
]);
|
||||
$this->assertEquals(201, $document1['headers']['status-code']);
|
||||
|
||||
$document2 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $presidents['body']['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'first_name' => 'George',
|
||||
'last_name' => 'Bush',
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
]
|
||||
]);
|
||||
$this->assertEquals(201, $document2['headers']['status-code']);
|
||||
|
||||
$document3 = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $presidents['body']['$id'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'documentId' => ID::unique(),
|
||||
'data' => [
|
||||
'first_name' => 'Joe',
|
||||
'last_name' => 'Biden',
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $document3['headers']['status-code']);
|
||||
|
||||
$documents = $this->client->call(
|
||||
Client::METHOD_GET,
|
||||
'/databases/' . $databaseId . '/collections/' . $presidents['body']['$id'] . '/documents',
|
||||
array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()),
|
||||
[
|
||||
'queries' => [
|
||||
Query::select(['first_name', 'last_name'])->toString(),
|
||||
Query::or([
|
||||
Query::equal('first_name', ['Donald']),
|
||||
Query::equal('last_name', ['Bush'])
|
||||
])->toString(),
|
||||
Query::limit(999)->toString(),
|
||||
Query::offset(0)->toString()
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertCount(2, $documents['body']['documents']);
|
||||
}
|
||||
|
||||
public function testCreateDatabase(): array
|
||||
{
|
||||
/**
|
||||
@@ -243,6 +382,18 @@ trait DatabasesBase
|
||||
'twoWayKey' => 'movie'
|
||||
]);
|
||||
|
||||
$integers = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/attributes/integer', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'integers',
|
||||
'required' => false,
|
||||
'array' => true,
|
||||
'min' => 10,
|
||||
'max' => 99,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $title['headers']['status-code']);
|
||||
$this->assertEquals($title['body']['key'], 'title');
|
||||
$this->assertEquals($title['body']['type'], 'string');
|
||||
@@ -293,6 +444,13 @@ trait DatabasesBase
|
||||
$this->assertEquals($relationship['body']['twoWay'], true);
|
||||
$this->assertEquals($relationship['body']['twoWayKey'], 'movie');
|
||||
|
||||
$this->assertEquals(202, $integers['headers']['status-code']);
|
||||
$this->assertEquals($integers['body']['key'], 'integers');
|
||||
$this->assertEquals($integers['body']['type'], 'integer');
|
||||
$this->assertArrayNotHasKey('size', $integers['body']);
|
||||
$this->assertEquals($integers['body']['required'], false);
|
||||
$this->assertEquals($integers['body']['array'], true);
|
||||
|
||||
// wait for database worker to create attributes
|
||||
sleep(2);
|
||||
|
||||
@@ -303,7 +461,7 @@ trait DatabasesBase
|
||||
]));
|
||||
|
||||
$this->assertIsArray($movies['body']['attributes']);
|
||||
$this->assertCount(8, $movies['body']['attributes']);
|
||||
$this->assertCount(9, $movies['body']['attributes']);
|
||||
$this->assertEquals($movies['body']['attributes'][0]['key'], $title['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][1]['key'], $description['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][2]['key'], $tagline['body']['key']);
|
||||
@@ -312,6 +470,7 @@ trait DatabasesBase
|
||||
$this->assertEquals($movies['body']['attributes'][5]['key'], $actors['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][6]['key'], $datetime['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][7]['key'], $relationship['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][8]['key'], $integers['body']['key']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
@@ -327,7 +486,11 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'queries' => ['equal("type", "string")', 'limit(2)', 'cursorAfter(title)'],
|
||||
'queries' => [
|
||||
Query::equal('type', ['string'])->toString(),
|
||||
Query::limit(2)->toString(),
|
||||
Query::cursorAfter(new Document(['$id' => 'title']))->toString()
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(2, \count($response['body']['attributes']));
|
||||
@@ -336,7 +499,7 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'queries' => ['select(["key"])'],
|
||||
'queries' => [Query::select(['key'])->toString()],
|
||||
]);
|
||||
$this->assertEquals(Exception::GENERAL_ARGUMENT_INVALID, $response['body']['type']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
@@ -531,6 +694,29 @@ trait DatabasesBase
|
||||
'twoWayKey' => 'twoWayKey'
|
||||
]);
|
||||
|
||||
$strings = $this->client->call(Client::METHOD_POST, $attributesPath . '/string', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'names',
|
||||
'size' => 512,
|
||||
'required' => false,
|
||||
'array' => true,
|
||||
]);
|
||||
|
||||
$integers = $this->client->call(Client::METHOD_POST, $attributesPath . '/integer', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]), [
|
||||
'key' => 'numbers',
|
||||
'required' => false,
|
||||
'array' => true,
|
||||
'min' => 1,
|
||||
'max' => 999,
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $string['headers']['status-code']);
|
||||
$this->assertEquals('string', $string['body']['key']);
|
||||
$this->assertEquals('string', $string['body']['type']);
|
||||
@@ -615,6 +801,22 @@ trait DatabasesBase
|
||||
$this->assertEquals(true, $relationship['body']['twoWay']);
|
||||
$this->assertEquals('twoWayKey', $relationship['body']['twoWayKey']);
|
||||
|
||||
$this->assertEquals(202, $strings['headers']['status-code']);
|
||||
$this->assertEquals('names', $strings['body']['key']);
|
||||
$this->assertEquals('string', $strings['body']['type']);
|
||||
$this->assertEquals(false, $strings['body']['required']);
|
||||
$this->assertEquals(true, $strings['body']['array']);
|
||||
$this->assertEquals(null, $strings['body']['default']);
|
||||
|
||||
$this->assertEquals(202, $integers['headers']['status-code']);
|
||||
$this->assertEquals('numbers', $integers['body']['key']);
|
||||
$this->assertEquals('integer', $integers['body']['type']);
|
||||
$this->assertEquals(false, $integers['body']['required']);
|
||||
$this->assertEquals(true, $integers['body']['array']);
|
||||
$this->assertEquals(1, $integers['body']['min']);
|
||||
$this->assertEquals(999, $integers['body']['max']);
|
||||
$this->assertEquals(null, $integers['body']['default']);
|
||||
|
||||
// Wait for database worker to create attributes
|
||||
sleep(5);
|
||||
|
||||
@@ -678,6 +880,18 @@ trait DatabasesBase
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$stringsResponse = $this->client->call(Client::METHOD_GET, $attributesPath . '/' . $strings['body']['key'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$integersResponse = $this->client->call(Client::METHOD_GET, $attributesPath . '/' . $integers['body']['key'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
$this->assertEquals(200, $stringResponse['headers']['status-code']);
|
||||
$this->assertEquals($string['body']['key'], $stringResponse['body']['key']);
|
||||
$this->assertEquals($string['body']['type'], $stringResponse['body']['type']);
|
||||
@@ -778,11 +992,11 @@ trait DatabasesBase
|
||||
]));
|
||||
|
||||
$this->assertEquals(200, $attributes['headers']['status-code']);
|
||||
$this->assertEquals(10, $attributes['body']['total']);
|
||||
$this->assertEquals(12, $attributes['body']['total']);
|
||||
|
||||
$attributes = $attributes['body']['attributes'];
|
||||
$this->assertIsArray($attributes);
|
||||
$this->assertCount(10, $attributes);
|
||||
$this->assertCount(12, $attributes);
|
||||
|
||||
$this->assertEquals($stringResponse['body']['key'], $attributes[0]['key']);
|
||||
$this->assertEquals($stringResponse['body']['type'], $attributes[0]['type']);
|
||||
@@ -867,6 +1081,22 @@ trait DatabasesBase
|
||||
$this->assertEquals($relationshipResponse['body']['twoWay'], $attributes[9]['twoWay']);
|
||||
$this->assertEquals($relationshipResponse['body']['twoWayKey'], $attributes[9]['twoWayKey']);
|
||||
|
||||
$this->assertEquals($stringsResponse['body']['key'], $attributes[10]['key']);
|
||||
$this->assertEquals($stringsResponse['body']['type'], $attributes[10]['type']);
|
||||
$this->assertEquals($stringsResponse['body']['status'], $attributes[10]['status']);
|
||||
$this->assertEquals($stringsResponse['body']['required'], $attributes[10]['required']);
|
||||
$this->assertEquals($stringsResponse['body']['array'], $attributes[10]['array']);
|
||||
$this->assertEquals($stringsResponse['body']['default'], $attributes[10]['default']);
|
||||
|
||||
$this->assertEquals($integersResponse['body']['key'], $attributes[11]['key']);
|
||||
$this->assertEquals($integersResponse['body']['type'], $attributes[11]['type']);
|
||||
$this->assertEquals($integersResponse['body']['status'], $attributes[11]['status']);
|
||||
$this->assertEquals($integersResponse['body']['required'], $attributes[11]['required']);
|
||||
$this->assertEquals($integersResponse['body']['array'], $attributes[11]['array']);
|
||||
$this->assertEquals($integersResponse['body']['default'], $attributes[11]['default']);
|
||||
$this->assertEquals($integersResponse['body']['min'], $attributes[11]['min']);
|
||||
$this->assertEquals($integersResponse['body']['max'], $attributes[11]['max']);
|
||||
|
||||
$collection = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
@@ -878,7 +1108,7 @@ trait DatabasesBase
|
||||
$attributes = $collection['body']['attributes'];
|
||||
|
||||
$this->assertIsArray($attributes);
|
||||
$this->assertCount(10, $attributes);
|
||||
$this->assertCount(12, $attributes);
|
||||
|
||||
$this->assertEquals($stringResponse['body']['key'], $attributes[0]['key']);
|
||||
$this->assertEquals($stringResponse['body']['type'], $attributes[0]['type']);
|
||||
@@ -963,6 +1193,22 @@ trait DatabasesBase
|
||||
$this->assertEquals($relationshipResponse['body']['twoWay'], $attributes[9]['twoWay']);
|
||||
$this->assertEquals($relationshipResponse['body']['twoWayKey'], $attributes[9]['twoWayKey']);
|
||||
|
||||
$this->assertEquals($stringsResponse['body']['key'], $attributes[10]['key']);
|
||||
$this->assertEquals($stringsResponse['body']['type'], $attributes[10]['type']);
|
||||
$this->assertEquals($stringsResponse['body']['status'], $attributes[10]['status']);
|
||||
$this->assertEquals($stringsResponse['body']['required'], $attributes[10]['required']);
|
||||
$this->assertEquals($stringsResponse['body']['array'], $attributes[10]['array']);
|
||||
$this->assertEquals($stringsResponse['body']['default'], $attributes[10]['default']);
|
||||
|
||||
$this->assertEquals($integersResponse['body']['key'], $attributes[11]['key']);
|
||||
$this->assertEquals($integersResponse['body']['type'], $attributes[11]['type']);
|
||||
$this->assertEquals($integersResponse['body']['status'], $attributes[11]['status']);
|
||||
$this->assertEquals($integersResponse['body']['required'], $attributes[11]['required']);
|
||||
$this->assertEquals($integersResponse['body']['array'], $attributes[11]['array']);
|
||||
$this->assertEquals($integersResponse['body']['default'], $attributes[11]['default']);
|
||||
$this->assertEquals($integersResponse['body']['min'], $attributes[11]['min']);
|
||||
$this->assertEquals($integersResponse['body']['max'], $attributes[11]['max']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
@@ -1127,6 +1373,56 @@ trait DatabasesBase
|
||||
$this->assertEquals(400, $tooLong['headers']['status-code']);
|
||||
$this->assertStringContainsString('Index length is longer than the maximum', $tooLong['body']['message']);
|
||||
|
||||
$fulltextArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'key' => 'ft',
|
||||
'type' => 'fulltext',
|
||||
'attributes' => ['actors'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $fulltextArray['headers']['status-code']);
|
||||
$this->assertEquals('"Fulltext" index is forbidden on array attributes', $fulltextArray['body']['message']);
|
||||
|
||||
$actorsArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'key' => 'index-actors',
|
||||
'type' => 'key',
|
||||
'attributes' => ['actors'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $actorsArray['headers']['status-code']);
|
||||
|
||||
$twoLevelsArray = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'key' => 'index-ip-actors',
|
||||
'type' => 'key',
|
||||
'attributes' => ['releaseYear', 'actors'], // 2 levels
|
||||
]);
|
||||
|
||||
$this->assertEquals(202, $twoLevelsArray['headers']['status-code']);
|
||||
|
||||
$unknown = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'key' => 'index-unknown',
|
||||
'type' => 'key',
|
||||
'attributes' => ['Unknown'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $unknown['headers']['status-code']);
|
||||
$this->assertEquals('Unknown attribute: Unknown', $unknown['body']['message']);
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
@@ -1141,7 +1437,10 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'queries' => ['equal("type", "key")', 'limit(2)'],
|
||||
'queries' => [
|
||||
Query::equal('type', ['key'])->toString(),
|
||||
Query::limit(2)->toString()
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(2, \count($response['body']['indexes']));
|
||||
@@ -1150,7 +1449,9 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]), [
|
||||
'queries' => ['select(["key"])'],
|
||||
'queries' => [
|
||||
Query::select(['key'])->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(Exception::GENERAL_ARGUMENT_INVALID, $response['body']['type']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
@@ -1196,7 +1497,8 @@ trait DatabasesBase
|
||||
'Tom Holland',
|
||||
'Zendaya Maree Stoermer',
|
||||
'Samuel Jackson',
|
||||
]
|
||||
],
|
||||
'integers' => [50,60]
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
@@ -1219,6 +1521,7 @@ trait DatabasesBase
|
||||
'Tom Holland',
|
||||
'Zendaya Maree Stoermer',
|
||||
],
|
||||
'integers' => [50]
|
||||
],
|
||||
'permissions' => [
|
||||
Permission::read(Role::user($this->getUser()['$id'])),
|
||||
@@ -1269,6 +1572,8 @@ trait DatabasesBase
|
||||
$this->assertEquals($document2['body']['actors'][1], 'Zendaya Maree Stoermer');
|
||||
$this->assertEquals($document2['body']['actors'][2], 'Samuel Jackson');
|
||||
$this->assertEquals($document2['body']['birthDay'], null);
|
||||
$this->assertEquals($document2['body']['integers'][0], 50);
|
||||
$this->assertEquals($document2['body']['integers'][1], 60);
|
||||
|
||||
$this->assertEquals(201, $document3['headers']['status-code']);
|
||||
$this->assertEquals($data['moviesId'], $document3['body']['$collectionId']);
|
||||
@@ -1305,7 +1610,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderAsc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderAsc('releaseYear')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1327,7 +1634,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderDesc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderDesc('releaseYear')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1377,7 +1686,7 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'select(["title", "releaseYear", "$id"])',
|
||||
Query::select(['title', 'releaseYear', '$id'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -1411,7 +1720,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][0]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['documents'][0]['$id']]))->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1423,7 +1734,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][2]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['documents'][2]['$id']]))->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1436,7 +1749,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderAsc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderAsc('releaseYear')->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
@@ -1449,7 +1764,10 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][1]['$id'] . '")', 'orderAsc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['documents'][1]['$id']]))->toString(),
|
||||
Query::orderAsc('releaseYear')->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1463,7 +1781,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderDesc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderDesc('releaseYear')->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
@@ -1476,7 +1796,10 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['documents'][1]['$id'] . '")', 'orderDesc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['documents'][1]['$id']]))->toString(),
|
||||
Query::orderDesc('releaseYear')->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1490,7 +1813,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("unknown")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
@@ -1522,7 +1847,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][2]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['documents'][2]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1534,7 +1861,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][0]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['documents'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1547,7 +1876,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderAsc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderAsc('releaseYear')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
@@ -1560,7 +1891,10 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][1]['$id'] . '")', 'orderAsc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['documents'][1]['$id']]))->toString(),
|
||||
Query::orderAsc('releaseYear')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1574,7 +1908,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderDesc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderDesc('releaseYear')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $base['headers']['status-code']);
|
||||
@@ -1587,7 +1923,10 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['documents'][1]['$id'] . '")', 'orderDesc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['documents'][1]['$id']]))->toString(),
|
||||
Query::orderDesc('releaseYear')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1607,7 +1946,10 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)', 'orderAsc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderAsc('releaseYear')->toString(),
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1618,7 +1960,11 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(2)', 'offset(1)', 'orderAsc("releaseYear")'],
|
||||
'queries' => [
|
||||
Query::orderAsc('releaseYear')->toString(),
|
||||
Query::limit(2)->toString(),
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1639,7 +1985,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['search("title", "Captain America")'],
|
||||
'queries' => [
|
||||
Query::search('title', 'Captain America')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1650,7 +1998,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("$id", "' . $documents['body']['documents'][0]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::equal('$id', [$documents['body']['documents'][0]['$id']])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1661,7 +2011,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['search("title", "Homecoming")'],
|
||||
'queries' => [
|
||||
Query::search('title', 'Homecoming')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1672,7 +2024,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['search("title", "spider")'],
|
||||
'queries' => [
|
||||
Query::search('title', 'spider')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1684,7 +2038,21 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("releaseYear", 1944)'],
|
||||
'queries' => [
|
||||
Query::contains('title', ['spi'])->toString(), // like query
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(2, $documents['body']['total']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::equal('releaseYear', [1944])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $documents['body']['documents']);
|
||||
@@ -1694,7 +2062,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['notEqual("releaseYear", 1944)'],
|
||||
'queries' => [
|
||||
Query::notEqual('releaseYear', 1944)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(2, $documents['body']['documents']);
|
||||
@@ -1705,7 +2075,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['greaterThan("$createdAt", "1976-06-12")'],
|
||||
'queries' => [
|
||||
Query::greaterThan('$createdAt', '1976-06-12')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(3, $documents['body']['documents']);
|
||||
@@ -1714,7 +2086,9 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['lessThan("$createdAt", "1976-06-12")'],
|
||||
'queries' => [
|
||||
Query::lessThan('$createdAt', '1976-06-12')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(0, $documents['body']['documents']);
|
||||
@@ -1723,15 +2097,45 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("actors", "Tom Holland")'],
|
||||
'queries' => [
|
||||
Query::contains('actors', ['Tom Holland', 'Samuel Jackson'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(3, $documents['body']['total']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['greaterThan("birthDay", "1960-01-01 10:10:10+02:30")'],
|
||||
'queries' => [
|
||||
Query::contains('actors', ['Tom'])->toString(), // Full-match not like
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(0, $documents['body']['total']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::greaterThan('birthDay', '16/01/2024 12:00:00AM')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
$this->assertEquals('Invalid query: Query value is invalid for attribute "birthDay"', $documents['body']['message']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::greaterThan('birthDay', '1960-01-01 10:10:10+02:30')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
@@ -1739,6 +2143,18 @@ trait DatabasesBase
|
||||
$this->assertEquals('1975-06-12T18:12:55.000+00:00', $documents['body']['documents'][1]['birthDay']);
|
||||
$this->assertCount(2, $documents['body']['documents']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::isNull('integers')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $documents['headers']['status-code']);
|
||||
$this->assertEquals(1, $documents['body']['total']);
|
||||
|
||||
/**
|
||||
* Test for Failure
|
||||
*/
|
||||
@@ -1752,34 +2168,41 @@ trait DatabasesBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("releaseYear", [' . implode(',', $conditions) . '])'],
|
||||
'queries' => [
|
||||
Query::equal('releaseYear', $conditions)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
$this->assertEquals('Invalid query: Query on attribute has greater than 100 values: releaseYear', $documents['body']['message']);
|
||||
|
||||
$conditions = [];
|
||||
$value = '';
|
||||
|
||||
for ($i = 0; $i < 101; $i++) {
|
||||
$conditions[] = "[" . $i . "] Too long title to cross 2k chars query limit";
|
||||
$value .= "[" . $i . "] Too long title to cross 2k chars query limit ";
|
||||
}
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['search("title", ' . implode(',', $conditions) . ')'],
|
||||
'queries' => [
|
||||
Query::search('title', $value)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
// Todo: Not sure what to do we with Query length Test VS old? JSON validator will fails if query string will be truncated?
|
||||
//$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
|
||||
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['search("actors", "Tom")'],
|
||||
'queries' => [
|
||||
Query::search('actors', 'Tom')->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(400, $documents['headers']['status-code']);
|
||||
$this->assertEquals('Searching by attribute "actors" requires a fulltext index.', $documents['body']['message']);
|
||||
$this->assertEquals('Invalid query: Cannot query search on attribute "actors" because it is an array.', $documents['body']['message']);
|
||||
|
||||
return [];
|
||||
}
|
||||
@@ -3520,9 +3943,9 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'equal("library", "library1")',
|
||||
'select(["fullName","library.*"])'
|
||||
]
|
||||
Query::select(['fullName', 'library.*'])->toString(),
|
||||
Query::equal('library', ['library1'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $documents['body']['total']);
|
||||
@@ -3534,7 +3957,7 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'equal("library.libraryName", ["Library 1"])',
|
||||
Query::equal('library.libraryName', ['Library 1'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -4040,10 +4463,10 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'isNotNull("$id")',
|
||||
'startsWith("fullName", "Stevie")',
|
||||
'endsWith("fullName", "Wonder")',
|
||||
'between("$createdAt", "1975-12-06", "2050-12-06")',
|
||||
Query::isNotNull('$id')->toString(),
|
||||
Query::startsWith('fullName', 'Stevie')->toString(),
|
||||
Query::endsWith('fullName', 'Wonder')->toString(),
|
||||
Query::between('$createdAt', '1975-12-06', '2050-12-0')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -4058,9 +4481,9 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'isNotNull("$id")',
|
||||
'isNull("fullName")',
|
||||
'select(["fullName"])'
|
||||
Query::isNotNull('$id')->toString(),
|
||||
Query::isNull('fullName')->toString(),
|
||||
Query::select(['fullName'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -4080,8 +4503,8 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'equal("fullName", "Stevie Wonder")',
|
||||
'select(["fullName"])'
|
||||
Query::equal('fullName', ['Stevie Wonder'])->toString(),
|
||||
Query::select(['fullName'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -4093,7 +4516,7 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'select(["libraries.*", "$id"])',
|
||||
Query::select(['libraries.*', '$id'])->toString(),
|
||||
],
|
||||
]);
|
||||
$document = $response['body']['documents'][0];
|
||||
@@ -4105,7 +4528,7 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
'select(["fullName", "$id"])'
|
||||
Query::select(['fullName', '$id'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -4275,7 +4698,9 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-timeout' => 1,
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['notEqual("longtext", "appwrite")'],
|
||||
'queries' => [
|
||||
Query::notEqual('longtext', 'appwrite')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(408, $response['headers']['status-code']);
|
||||
|
||||
@@ -9,6 +9,7 @@ use Tests\E2E\Scopes\SideConsole;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class DatabasesConsoleClientTest extends Scope
|
||||
{
|
||||
@@ -279,6 +280,7 @@ class DatabasesConsoleClientTest extends Scope
|
||||
|
||||
/**
|
||||
* @depends testCreateCollection
|
||||
* @throws \Utopia\Database\Exception\Query
|
||||
*/
|
||||
public function testGetCollectionLogs(array $data)
|
||||
{
|
||||
@@ -299,7 +301,7 @@ class DatabasesConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)']
|
||||
'queries' => [Query::limit(1)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $logs['headers']['status-code']);
|
||||
@@ -311,7 +313,7 @@ class DatabasesConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)']
|
||||
'queries' => [Query::offset(1)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $logs['headers']['status-code']);
|
||||
@@ -322,7 +324,7 @@ class DatabasesConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)', 'limit(1)']
|
||||
'queries' => [Query::offset(1)->toString(), Query::limit(1)->toString()]
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $logs['headers']['status-code']);
|
||||
|
||||
@@ -7,9 +7,11 @@ use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class DatabasesCustomServerTest extends Scope
|
||||
{
|
||||
@@ -57,7 +59,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $databases['headers']['status-code']);
|
||||
$this->assertCount(1, $databases['body']['databases']);
|
||||
@@ -66,7 +70,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)'],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $databases['headers']['status-code']);
|
||||
$this->assertCount(1, $databases['body']['databases']);
|
||||
@@ -75,7 +81,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("name", ["Test 1", "Test 2"])'],
|
||||
'queries' => [
|
||||
Query::equal('name', ['Test 1', 'Test 2'])->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $databases['headers']['status-code']);
|
||||
$this->assertCount(2, $databases['body']['databases']);
|
||||
@@ -84,7 +92,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("name", "Test 2")'],
|
||||
'queries' => [
|
||||
Query::equal('name', ['Test 2'])->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $databases['headers']['status-code']);
|
||||
$this->assertCount(1, $databases['body']['databases']);
|
||||
@@ -93,7 +103,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("$id", "first")'],
|
||||
'queries' => [
|
||||
Query::equal('$id', ['first'])->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $databases['headers']['status-code']);
|
||||
$this->assertCount(1, $databases['body']['databases']);
|
||||
@@ -105,7 +117,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderDesc("")'],
|
||||
'queries' => [
|
||||
Query::orderDesc()->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(2, $databases['body']['total']);
|
||||
@@ -124,7 +138,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['databases'][0]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['databases'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $databases['body']['databases']);
|
||||
@@ -134,7 +150,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['databases'][1]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['databases'][1]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(0, $databases['body']['databases']);
|
||||
@@ -152,7 +170,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['databases'][1]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['databases'][1]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $databases['body']['databases']);
|
||||
@@ -162,7 +182,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['databases'][0]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['databases'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(0, $databases['body']['databases']);
|
||||
@@ -208,7 +230,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("unknown")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
@@ -375,7 +399,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)']
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $collections['headers']['status-code']);
|
||||
@@ -385,7 +411,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)']
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $collections['headers']['status-code']);
|
||||
@@ -395,7 +423,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("enabled", true)']
|
||||
'queries' => [
|
||||
Query::equal('enabled', [true])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $collections['headers']['status-code']);
|
||||
@@ -405,7 +435,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("enabled", false)']
|
||||
'queries' => [
|
||||
Query::equal('enabled', [false])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $collections['headers']['status-code']);
|
||||
@@ -418,7 +450,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderDesc("")'],
|
||||
'queries' => [
|
||||
Query::orderDesc()->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(2, $collections['body']['total']);
|
||||
@@ -437,7 +471,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['collections'][0]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['collections'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $collections['body']['collections']);
|
||||
@@ -447,7 +483,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $base['body']['collections'][1]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['collections'][1]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(0, $collections['body']['collections']);
|
||||
@@ -465,7 +503,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['collections'][1]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['collections'][1]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(1, $collections['body']['collections']);
|
||||
@@ -475,7 +515,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("' . $base['body']['collections'][0]['$id'] . '")'],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['collections'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(0, $collections['body']['collections']);
|
||||
@@ -521,7 +563,9 @@ class DatabasesCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("unknown")'],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
@@ -1376,7 +1420,7 @@ class DatabasesCustomServerTest extends Scope
|
||||
// Test indexLimit = 64
|
||||
// MariaDB, MySQL, and MongoDB create 5 indexes per new collection
|
||||
// Add up to the limit, then check if the next index throws IndexLimitException
|
||||
for ($i = 0; $i < 59; $i++) {
|
||||
for ($i = 0; $i < 58; $i++) {
|
||||
// $this->assertEquals(true, static::getDatabase()->createIndex('indexLimit', "index{$i}", Database::INDEX_KEY, ["test{$i}"], [16]));
|
||||
$index = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
@@ -1405,7 +1449,7 @@ class DatabasesCustomServerTest extends Scope
|
||||
$this->assertIsArray($collection['body']['attributes']);
|
||||
$this->assertIsArray($collection['body']['indexes']);
|
||||
$this->assertCount(64, $collection['body']['attributes']);
|
||||
$this->assertCount(59, $collection['body']['indexes']);
|
||||
$this->assertCount(58, $collection['body']['indexes']);
|
||||
|
||||
$tooMany = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/indexes', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
||||
@@ -7,8 +7,10 @@ use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideClient;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class FunctionsCustomClientTest extends Scope
|
||||
{
|
||||
@@ -474,7 +476,9 @@ class FunctionsCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'queries' => [ 'limit(1)' ]
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
@@ -485,7 +489,9 @@ class FunctionsCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'queries' => [ 'offset(1)' ]
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
@@ -496,7 +502,9 @@ class FunctionsCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'queries' => [ 'equal("status", ["completed"])' ]
|
||||
'queries' => [
|
||||
Query::equal('status', ['completed'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
@@ -507,7 +515,9 @@ class FunctionsCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'queries' => [ 'equal("status", ["failed"])' ]
|
||||
'queries' => [
|
||||
Query::equal('status', ['failed'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
@@ -518,7 +528,9 @@ class FunctionsCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'queries' => [ 'cursorAfter("' . $base['body']['executions'][0]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $base['body']['executions'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertCount(2, $executions['body']['executions']);
|
||||
@@ -529,7 +541,9 @@ class FunctionsCustomClientTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
'x-appwrite-key' => $apikey,
|
||||
], [
|
||||
'queries' => [ 'cursorBefore("' . $base['body']['executions'][1]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $base['body']['executions'][1]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
// Cleanup : Delete function
|
||||
|
||||
@@ -9,7 +9,9 @@ use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
|
||||
class FunctionsCustomServerTest extends Scope
|
||||
@@ -121,7 +123,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)' ]
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -131,7 +135,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(1)' ]
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -141,7 +147,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("enabled", true)' ]
|
||||
'queries' => [
|
||||
Query::equal('enabled', [true])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -151,7 +159,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("enabled", false)' ]
|
||||
'queries' => [
|
||||
Query::equal('enabled', [false])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -244,7 +254,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $functions['body']['functions'][0]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $functions['body']['functions'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -255,7 +267,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorBefore("' . $functions['body']['functions'][1]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $functions['body']['functions'][1]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -269,7 +283,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("unknown")' ],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -532,7 +548,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)' ]
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($function['headers']['status-code'], 200);
|
||||
@@ -542,7 +560,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(1)' ]
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($function['headers']['status-code'], 200);
|
||||
@@ -552,7 +572,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("entrypoint", "index.php")' ]
|
||||
'queries' => [
|
||||
Query::equal('entrypoint', ['index.php'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($function['headers']['status-code'], 200);
|
||||
@@ -562,7 +584,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("entrypoint", "index.js")' ]
|
||||
'queries' => [
|
||||
Query::equal('entrypoint', ['index.js'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($function['headers']['status-code'], 200);
|
||||
@@ -690,7 +714,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)' ]
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -700,7 +726,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(1)' ]
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -710,7 +738,9 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("trigger", "http")' ]
|
||||
'queries' => [
|
||||
Query::equal('trigger', ['http'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -1459,7 +1489,10 @@ class FunctionsCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("resourceId", "' . $functionId . '")', 'equal("resourceType", "function")' ]
|
||||
'queries' => [
|
||||
Query::equal('resourceId', [$functionId])->toString(),
|
||||
Query::equal('resourceType', ['function'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $rules['headers']['status-code']);
|
||||
|
||||
@@ -29,7 +29,7 @@ class AvatarsTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $graphQLPayload);
|
||||
|
||||
$this->assertEquals(18767, \strlen($creditCardIcon['body']));
|
||||
$this->assertEquals(18546, \strlen($creditCardIcon['body']));
|
||||
|
||||
return $creditCardIcon['body'];
|
||||
}
|
||||
@@ -50,7 +50,7 @@ class AvatarsTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $graphQLPayload);
|
||||
|
||||
$this->assertEquals(11100, \strlen($browserIcon['body']));
|
||||
$this->assertEquals(13312, \strlen($browserIcon['body']));
|
||||
|
||||
return $browserIcon['body'];
|
||||
}
|
||||
@@ -71,7 +71,7 @@ class AvatarsTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $graphQLPayload);
|
||||
|
||||
$this->assertEquals(7460, \strlen($countryFlag['body']));
|
||||
$this->assertEquals(8814, \strlen($countryFlag['body']));
|
||||
|
||||
return $countryFlag['body'];
|
||||
}
|
||||
@@ -92,7 +92,7 @@ class AvatarsTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $graphQLPayload);
|
||||
|
||||
$this->assertEquals(36036, \strlen($image['body']));
|
||||
$this->assertEquals(52585, \strlen($image['body']));
|
||||
|
||||
return $image['body'];
|
||||
}
|
||||
@@ -134,7 +134,7 @@ class AvatarsTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $graphQLPayload);
|
||||
|
||||
$this->assertEquals(14771, \strlen($qrCode['body']));
|
||||
$this->assertEquals(29428, \strlen($qrCode['body']));
|
||||
|
||||
return $qrCode['body'];
|
||||
}
|
||||
@@ -155,7 +155,7 @@ class AvatarsTest extends Scope
|
||||
'x-appwrite-project' => $projectId,
|
||||
], $this->getHeaders()), $graphQLPayload);
|
||||
|
||||
$this->assertEquals(5041, \strlen($initials['body']));
|
||||
$this->assertEquals(5025, \strlen($initials['body']));
|
||||
|
||||
return $initials['body'];
|
||||
}
|
||||
|
||||
@@ -207,6 +207,7 @@ trait Base
|
||||
// Providers
|
||||
public static string $CREATE_MAILGUN_PROVIDER = 'create_mailgun_provider';
|
||||
public static string $CREATE_SENDGRID_PROVIDER = 'create_sendgrid_provider';
|
||||
public static string $CREATE_SMTP_PROVIDER = 'create_smtp_provider';
|
||||
public static string $CREATE_TWILIO_PROVIDER = 'create_twilio_provider';
|
||||
public static string $CREATE_TELESIGN_PROVIDER = 'create_telesign_provider';
|
||||
public static string $CREATE_TEXTMAGIC_PROVIDER = 'create_textmagic_provider';
|
||||
@@ -218,6 +219,7 @@ trait Base
|
||||
public static string $GET_PROVIDER = 'get_provider';
|
||||
public static string $UPDATE_MAILGUN_PROVIDER = 'update_mailgun_provider';
|
||||
public static string $UPDATE_SENDGRID_PROVIDER = 'update_sendgrid_provider';
|
||||
public static string $UPDATE_SMTP_PROVIDER = 'update_smtp_provider';
|
||||
public static string $UPDATE_TWILIO_PROVIDER = 'update_twilio_provider';
|
||||
public static string $UPDATE_TELESIGN_PROVIDER = 'update_telesign_provider';
|
||||
public static string $UPDATE_TEXTMAGIC_PROVIDER = 'update_textmagic_provider';
|
||||
@@ -1809,6 +1811,16 @@ trait Base
|
||||
enabled
|
||||
}
|
||||
}';
|
||||
case self::$CREATE_SMTP_PROVIDER:
|
||||
return 'mutation createSMTPProvider($providerId: String!, $name: String!, $host: String!, $port: Int!, $username: String!, $password: String!, $encryption: String!, $autoTLS: Boolean! $fromName: String!, $fromEmail: String!, $replyToName: String, $replyToEmail: String) {
|
||||
messagingCreateSMTPProvider(providerId: $providerId, name: $name, host: $host, port: $port, username: $username, password: $password, encryption: $encryption, autoTLS: $autoTLS, fromName: $fromName, fromEmail: $fromEmail, replyToName: $replyToName, replyToEmail: $replyToEmail) {
|
||||
_id
|
||||
name
|
||||
provider
|
||||
type
|
||||
enabled
|
||||
}
|
||||
}';
|
||||
case self::$CREATE_TWILIO_PROVIDER:
|
||||
return 'mutation createTwilioProvider($providerId: String!, $name: String!, $from: String!, $accountSid: String!, $authToken: String!) {
|
||||
messagingCreateTwilioProvider(providerId: $providerId, name: $name, from: $from, accountSid: $accountSid, authToken: $authToken) {
|
||||
@@ -1923,6 +1935,16 @@ trait Base
|
||||
enabled
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_SMTP_PROVIDER:
|
||||
return 'mutation updateSMTPProvider($providerId: String!, $name: String!, $host: String!, $port: Int!, $username: String!, $password: String!, $encryption: String!, $autoTLS: Boolean!, $fromName: String, $fromEmail: String, $enabled: Boolean) {
|
||||
messagingUpdateSMTPProvider(providerId: $providerId, name: $name, host: $host, port: $port, username: $username, password: $password, encryption: $encryption, autoTLS: $autoTLS, fromName: $fromName, fromEmail: $fromEmail, enabled: $enabled) {
|
||||
_id
|
||||
name
|
||||
provider
|
||||
type
|
||||
enabled
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_TWILIO_PROVIDER:
|
||||
return 'mutation updateTwilioProvider($providerId: String!, $name: String!, $accountSid: String!, $authToken: String!) {
|
||||
messagingUpdateTwilioProvider(providerId: $providerId, name: $name, accountSid: $accountSid, authToken: $authToken) {
|
||||
@@ -2000,11 +2022,10 @@ trait Base
|
||||
}
|
||||
}';
|
||||
case self::$CREATE_TOPIC:
|
||||
return 'mutation createTopic($topicId: String!, $name: String!, $description: String!) {
|
||||
messagingCreateTopic(topicId: $topicId, name: $name, description: $description) {
|
||||
return 'mutation createTopic($topicId: String!, $name: String!) {
|
||||
messagingCreateTopic(topicId: $topicId, name: $name) {
|
||||
_id
|
||||
name
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$LIST_TOPICS:
|
||||
@@ -2014,7 +2035,6 @@ trait Base
|
||||
topics {
|
||||
_id
|
||||
name
|
||||
description
|
||||
}
|
||||
}
|
||||
}';
|
||||
@@ -2023,15 +2043,13 @@ trait Base
|
||||
messagingGetTopic(topicId: $topicId) {
|
||||
_id
|
||||
name
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_TOPIC:
|
||||
return 'mutation updateTopic($topicId: String!, $name: String!, $description: String!) {
|
||||
messagingUpdateTopic(topicId: $topicId, name: $name, description: $description) {
|
||||
return 'mutation updateTopic($topicId: String!, $name: String!) {
|
||||
messagingUpdateTopic(topicId: $topicId, name: $name) {
|
||||
_id
|
||||
name
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$DELETE_TOPIC:
|
||||
@@ -2098,8 +2116,8 @@ trait Base
|
||||
}
|
||||
}';
|
||||
case self::$CREATE_EMAIL:
|
||||
return 'mutation createEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String!, $content: String!, $status: String, $description: String, $html: Boolean, $cc: [String], $bcc: [String], $scheduledAt: String) {
|
||||
messagingCreateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, description: $description, html: $html, cc: $cc, bcc: $bcc, scheduledAt: $scheduledAt) {
|
||||
return 'mutation createEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String!, $content: String!, $status: String, $html: Boolean, $cc: [String], $bcc: [String], $scheduledAt: String) {
|
||||
messagingCreateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, html: $html, cc: $cc, bcc: $bcc, scheduledAt: $scheduledAt) {
|
||||
_id
|
||||
topics
|
||||
users
|
||||
@@ -2109,12 +2127,11 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$CREATE_SMS:
|
||||
return 'mutation createSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String!, $status: String, $description: String, $scheduledAt: String) {
|
||||
messagingCreateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, description: $description, scheduledAt: $scheduledAt) {
|
||||
return 'mutation createSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String!, $status: String, $scheduledAt: String) {
|
||||
messagingCreateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, scheduledAt: $scheduledAt) {
|
||||
_id
|
||||
topics
|
||||
users
|
||||
@@ -2124,12 +2141,11 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$CREATE_PUSH_NOTIFICATION:
|
||||
return 'mutation createPushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String!, $body: String!, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $description: String, $scheduledAt: String) {
|
||||
messagingCreatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, description: $description, scheduledAt: $scheduledAt) {
|
||||
return 'mutation createPushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String!, $body: String!, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $scheduledAt: String) {
|
||||
messagingCreatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, scheduledAt: $scheduledAt) {
|
||||
_id
|
||||
topics
|
||||
users
|
||||
@@ -2139,7 +2155,6 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$LIST_MESSAGES:
|
||||
@@ -2157,7 +2172,6 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}
|
||||
}';
|
||||
@@ -2174,12 +2188,11 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_EMAIL:
|
||||
return 'mutation updateEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String, $content: String, $status: String, $description: String, $html: Boolean, $cc: [String], $bcc: [String], $scheduledAt: String) {
|
||||
messagingUpdateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, description: $description, html: $html, cc: $cc, bcc: $bcc, scheduledAt: $scheduledAt) {
|
||||
return 'mutation updateEmail($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $subject: String, $content: String, $status: String, , $html: Boolean, $cc: [String], $bcc: [String], $scheduledAt: String) {
|
||||
messagingUpdateEmail(messageId: $messageId, topics: $topics, users: $users, targets: $targets, subject: $subject, content: $content, status: $status, html: $html, cc: $cc, bcc: $bcc, scheduledAt: $scheduledAt) {
|
||||
_id
|
||||
topics
|
||||
users
|
||||
@@ -2189,12 +2202,11 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_SMS:
|
||||
return 'mutation updateSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String, $status: String, $description: String, $scheduledAt: String) {
|
||||
messagingUpdateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, description: $description, scheduledAt: $scheduledAt) {
|
||||
return 'mutation updateSMS($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $content: String, $status: String, $scheduledAt: String) {
|
||||
messagingUpdateSMS(messageId: $messageId, topics: $topics, users: $users, targets: $targets, content: $content, status: $status, scheduledAt: $scheduledAt) {
|
||||
_id
|
||||
topics
|
||||
users
|
||||
@@ -2204,12 +2216,11 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$UPDATE_PUSH_NOTIFICATION:
|
||||
return 'mutation updatePushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String, $body: String, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $description: String, $scheduledAt: String) {
|
||||
messagingUpdatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, description: $description, scheduledAt: $scheduledAt) {
|
||||
return 'mutation updatePushNotification($messageId: String!, $topics: [String!], $users: [String!], $targets: [String!], $title: String, $body: String, $data: Json, $action: String, $icon: String, $sound: String, $color: String, $tag: String, $badge: String, $status: String, $scheduledAt: String) {
|
||||
messagingUpdatePushNotification(messageId: $messageId, topics: $topics, users: $users, targets: $targets, title: $title, body: $body, data: $data, action: $action, icon: $icon, sound: $sound, color: $color, tag: $tag, badge: $badge, status: $status, scheduledAt: $scheduledAt) {
|
||||
_id
|
||||
topics
|
||||
users
|
||||
@@ -2219,7 +2230,6 @@ trait Base
|
||||
deliveryErrors
|
||||
deliveredTotal
|
||||
status
|
||||
description
|
||||
}
|
||||
}';
|
||||
case self::$COMPLEX_QUERY:
|
||||
|
||||
@@ -285,7 +285,6 @@ class MessagingTest extends Scope
|
||||
'variables' => [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'topic1',
|
||||
'description' => 'Active users',
|
||||
],
|
||||
];
|
||||
$response = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([
|
||||
@@ -296,7 +295,6 @@ class MessagingTest extends Scope
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('topic1', $response['body']['data']['messagingCreateTopic']['name']);
|
||||
$this->assertEquals('Active users', $response['body']['data']['messagingCreateTopic']['description']);
|
||||
|
||||
return $response['body']['data']['messagingCreateTopic'];
|
||||
}
|
||||
@@ -313,7 +311,6 @@ class MessagingTest extends Scope
|
||||
'variables' => [
|
||||
'topicId' => $topicId,
|
||||
'name' => 'topic2',
|
||||
'description' => 'Inactive users',
|
||||
],
|
||||
];
|
||||
$response = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([
|
||||
@@ -324,7 +321,6 @@ class MessagingTest extends Scope
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('topic2', $response['body']['data']['messagingUpdateTopic']['name']);
|
||||
$this->assertEquals('Inactive users', $response['body']['data']['messagingUpdateTopic']['description']);
|
||||
|
||||
return $topicId;
|
||||
}
|
||||
@@ -368,7 +364,6 @@ class MessagingTest extends Scope
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('topic2', $response['body']['data']['messagingGetTopic']['name']);
|
||||
$this->assertEquals('Inactive users', $response['body']['data']['messagingGetTopic']['description']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -594,7 +589,6 @@ class MessagingTest extends Scope
|
||||
'variables' => [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'topic1',
|
||||
'description' => 'Active users',
|
||||
],
|
||||
];
|
||||
$topic = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([
|
||||
@@ -801,7 +795,6 @@ class MessagingTest extends Scope
|
||||
'variables' => [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'topic1',
|
||||
'description' => 'Active users',
|
||||
],
|
||||
];
|
||||
$topic = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([
|
||||
@@ -1006,7 +999,6 @@ class MessagingTest extends Scope
|
||||
'variables' => [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'topic1',
|
||||
'description' => 'Active users',
|
||||
],
|
||||
];
|
||||
$topic = $this->client->call(Client::METHOD_POST, '/graphql', \array_merge([
|
||||
|
||||
@@ -34,7 +34,7 @@ class ScopeTest extends Scope
|
||||
'x-appwrite-key' => $apiKey,
|
||||
], $gqlPayload);
|
||||
|
||||
$message = "app.${projectId}@service.localhost (role: applications) missing scope (databases.write)";
|
||||
$message = "app.{$projectId}@service.localhost (role: applications) missing scope (databases.write)";
|
||||
$this->assertArrayHasKey('errors', $database['body']);
|
||||
$this->assertEquals($message, $database['body']['errors'][0]['message']);
|
||||
}
|
||||
|
||||
@@ -104,8 +104,8 @@ class UsersTest extends Scope
|
||||
'query' => $query,
|
||||
'variables' => [
|
||||
'queries' => [
|
||||
'limit(100)',
|
||||
'offset(0)',
|
||||
Query::limit(100)->toString(),
|
||||
Query::offset(0)->toString(),
|
||||
],
|
||||
]
|
||||
];
|
||||
|
||||
@@ -6,6 +6,7 @@ use Appwrite\Enum\MessageStatus;
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\DSN\DSN;
|
||||
|
||||
trait MessagingBase
|
||||
@@ -28,6 +29,17 @@ trait MessagingBase
|
||||
'fromEmail' => 'sender-email@my-domain.com',
|
||||
'isEuRegion' => false,
|
||||
],
|
||||
'smtp' => [
|
||||
'providerId' => ID::unique(),
|
||||
'name' => 'SMTP1',
|
||||
'host' => 'smtp.appwrite.io',
|
||||
'port' => 587,
|
||||
'security' => 'tls',
|
||||
'username' => 'my-username',
|
||||
'password' => 'my-password',
|
||||
'fromName' => 'sender name',
|
||||
'fromEmail' => 'tester@appwrite.io',
|
||||
],
|
||||
'twilio' => [
|
||||
'providerId' => ID::unique(),
|
||||
'name' => 'Twilio1',
|
||||
@@ -114,6 +126,14 @@ trait MessagingBase
|
||||
'apiKey' => 'my-apikey',
|
||||
'domain' => 'my-domain',
|
||||
],
|
||||
'smtp' => [
|
||||
'name' => 'SMTP2',
|
||||
'host' => 'smtp.appwrite.io',
|
||||
'port' => 587,
|
||||
'security' => 'tls',
|
||||
'username' => 'my-username',
|
||||
'password' => 'my-password',
|
||||
],
|
||||
'twilio' => [
|
||||
'name' => 'Twilio2',
|
||||
'accountSid' => 'my-accountSid',
|
||||
@@ -185,6 +205,32 @@ trait MessagingBase
|
||||
return $providers;
|
||||
}
|
||||
|
||||
public function testUpdateProviderMissingCredentialsThrows(): void
|
||||
{
|
||||
// Create new FCM provider with no serviceAccountJSON
|
||||
$response = $this->client->call(Client::METHOD_POST, '/messaging/providers/fcm', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'providerId' => ID::unique(),
|
||||
'name' => 'FCM3',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
// Enable provider with no serviceAccountJSON
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/messaging/providers/fcm/' . $response['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'enabled' => true,
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testUpdateProviders
|
||||
*/
|
||||
@@ -197,7 +243,7 @@ trait MessagingBase
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(\count($providers), \count($response['body']['providers']));
|
||||
$this->assertEquals(11, \count($response['body']['providers']));
|
||||
|
||||
return $providers;
|
||||
}
|
||||
@@ -243,7 +289,6 @@ trait MessagingBase
|
||||
]);
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals('my-app', $response['body']['name']);
|
||||
$this->assertEquals('', $response['body']['description']);
|
||||
|
||||
return $response['body'];
|
||||
}
|
||||
@@ -259,11 +304,9 @@ trait MessagingBase
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'name' => 'android-app',
|
||||
'description' => 'updated-description'
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('android-app', $response['body']['name']);
|
||||
$this->assertEquals('updated-description', $response['body']['description']);
|
||||
return $response['body']['$id'];
|
||||
}
|
||||
|
||||
@@ -272,24 +315,13 @@ trait MessagingBase
|
||||
*/
|
||||
public function testListTopic(string $topicId)
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/topics', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'search' => 'updated-description',
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(1, \count($response['body']['topics']));
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/topics', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => [
|
||||
'equal("total", [0])'
|
||||
Query::equal('total', [0])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -302,7 +334,7 @@ trait MessagingBase
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => [
|
||||
'greaterThan("total", 0)'
|
||||
Query::greaterThan('total', 0)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -324,7 +356,6 @@ trait MessagingBase
|
||||
]);
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('android-app', $response['body']['name']);
|
||||
$this->assertEquals('updated-description', $response['body']['description']);
|
||||
$this->assertEquals(0, $response['body']['total']);
|
||||
}
|
||||
|
||||
@@ -381,7 +412,6 @@ trait MessagingBase
|
||||
|
||||
$this->assertEquals(200, $topic['headers']['status-code']);
|
||||
$this->assertEquals('android-app', $topic['body']['name']);
|
||||
$this->assertEquals('updated-description', $topic['body']['description']);
|
||||
$this->assertEquals(1, $topic['body']['total']);
|
||||
|
||||
return [
|
||||
@@ -493,7 +523,9 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['limit(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -506,7 +538,9 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['offset(1)'],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -518,7 +552,10 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['limit(1)', 'offset(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -534,7 +571,9 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['limit(-1)']
|
||||
'queries' => [
|
||||
Query::limit(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -544,7 +583,9 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['offset(-1)']
|
||||
'queries' => [
|
||||
Query::offset(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -554,7 +595,9 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['equal("$id", "asdf")']
|
||||
'queries' => [
|
||||
Query::equal('$id', ['asdf'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -564,7 +607,9 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['orderAsc("$id")']
|
||||
'queries' => [
|
||||
Query::orderAsc('$id')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -574,7 +619,9 @@ trait MessagingBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'queries' => ['cursorAsc("$id")']
|
||||
'queries' => [
|
||||
'{ "method": "cursorAsc", "attribute": "$id" }'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -600,7 +647,6 @@ trait MessagingBase
|
||||
|
||||
$this->assertEquals(200, $topic['headers']['status-code']);
|
||||
$this->assertEquals('android-app', $topic['body']['name']);
|
||||
$this->assertEquals('updated-description', $topic['body']['description']);
|
||||
$this->assertEquals(0, $topic['body']['total']);
|
||||
}
|
||||
|
||||
@@ -617,6 +663,60 @@ trait MessagingBase
|
||||
$this->assertEquals(204, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateDraftEmail
|
||||
*/
|
||||
public function testListTargets(array $message)
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/messages/does_not_exist/targets', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/messages/' . $message['$id'] . '/targets', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$targetList = $response['body'];
|
||||
$this->assertEquals(1, $targetList['total']);
|
||||
$this->assertEquals(1, count($targetList['targets']));
|
||||
$this->assertEquals($message['targets'][0], $targetList['targets'][0]['$id']);
|
||||
|
||||
// Test for empty targets
|
||||
$response = $this->client->call(Client::METHOD_POST, '/messaging/messages/email', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'messageId' => ID::unique(),
|
||||
'subject' => 'New blog post',
|
||||
'content' => 'Check out the new blog post at http://localhost',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
$message = $response['body'];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/messages/' . $message['$id'] . '/targets', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$targetList = $response['body'];
|
||||
$this->assertEquals(0, $targetList['total']);
|
||||
$this->assertEquals(0, count($targetList['targets']));
|
||||
}
|
||||
|
||||
public function testCreateDraftEmail()
|
||||
{
|
||||
// Create User
|
||||
@@ -634,7 +734,7 @@ trait MessagingBase
|
||||
$this->assertEquals(201, $response['headers']['status-code'], "Error creating user: " . var_export($response['body'], true));
|
||||
|
||||
$user = $response['body'];
|
||||
var_dump($user);
|
||||
|
||||
$this->assertEquals(1, \count($user['targets']));
|
||||
$targetId = $user['targets'][0]['$id'];
|
||||
|
||||
@@ -698,7 +798,6 @@ trait MessagingBase
|
||||
], [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'topic1',
|
||||
'description' => 'Test Topic'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $topic['headers']['status-code']);
|
||||
@@ -720,7 +819,6 @@ trait MessagingBase
|
||||
// Get target
|
||||
$target = $user['body']['targets'][0];
|
||||
|
||||
|
||||
// Create Subscriber
|
||||
$subscriber = $this->client->call(Client::METHOD_POST, '/messaging/topics/' . $topic['body']['$id'] . '/subscribers', \array_merge([
|
||||
'content-type' => 'application/json',
|
||||
@@ -759,14 +857,19 @@ trait MessagingBase
|
||||
$this->assertEquals(1, $message['body']['deliveredTotal']);
|
||||
$this->assertEquals(0, \count($message['body']['deliveryErrors']));
|
||||
|
||||
return $message;
|
||||
return [
|
||||
'message' => $email['body'],
|
||||
'topic' => $topic['body'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testSendEmail
|
||||
*/
|
||||
public function testUpdateEmail(array $email): void
|
||||
public function testUpdateEmail(array $params): void
|
||||
{
|
||||
$email = $params['message'];
|
||||
|
||||
$message = $this->client->call(Client::METHOD_PATCH, '/messaging/messages/email/' . $email['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
@@ -855,7 +958,6 @@ trait MessagingBase
|
||||
], [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'topic1',
|
||||
'description' => 'Test Topic'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $topic['headers']['status-code']);
|
||||
@@ -1016,7 +1118,6 @@ trait MessagingBase
|
||||
], [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'topic1',
|
||||
'description' => 'Test Topic'
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $topic['headers']['status-code']);
|
||||
@@ -1144,56 +1245,50 @@ trait MessagingBase
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateDraftEmail
|
||||
* @depends testSendEmail
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function testListTargets(array $message)
|
||||
public function testDeleteMessage(array $params): void
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/messages/does_not_exist/targets', [
|
||||
$message = $params['message'];
|
||||
$topic = $params['topic'];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/messaging/messages/' . $message['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
$this->assertEquals(204, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/messages/' . $message['$id'] . '/targets', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$targetList = $response['body'];
|
||||
$this->assertEquals(1, $targetList['total']);
|
||||
$this->assertEquals(1, count($targetList['targets']));
|
||||
$this->assertEquals($message['targets'][0], $targetList['targets'][0]['$id']);
|
||||
|
||||
// Test for empty targets
|
||||
// Test for FAILURE
|
||||
$response = $this->client->call(Client::METHOD_POST, '/messaging/messages/email', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'messageId' => ID::unique(),
|
||||
'subject' => 'New blog post',
|
||||
'content' => 'Check out the new blog post at http://localhost',
|
||||
'status' => 'processing',
|
||||
'topics' => [$topic['$id']],
|
||||
'subject' => 'Test subject',
|
||||
'content' => 'Test content',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
$message = $response['body'];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/messaging/messages/' . $message['$id'] . '/targets', [
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/messaging/messages/' . $response['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
$targetList = $response['body'];
|
||||
$this->assertEquals(0, $targetList['total']);
|
||||
$this->assertEquals(0, count($targetList['targets']));
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/messaging/messages/does_not_exist', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $response['headers']['status-code']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideConsole;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class MessagingConsoleClientTest extends Scope
|
||||
{
|
||||
@@ -67,7 +68,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -79,7 +82,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)'],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -90,7 +95,10 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)', 'offset(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -105,7 +113,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(-1)']
|
||||
'queries' => [
|
||||
Query::limit(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -114,7 +124,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(-1)']
|
||||
'queries' => [
|
||||
Query::offset(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -123,7 +135,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("$id", "asdf")']
|
||||
'queries' => [
|
||||
Query::equal('$id', ['asdf'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -132,7 +146,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderAsc("$id")']
|
||||
'queries' => [
|
||||
Query::orderAsc('$id')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -141,7 +157,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAsc("$id")']
|
||||
'queries' => [
|
||||
'{ "method": "cursorAsc", "attribute":"$id" }'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -170,7 +188,6 @@ class MessagingConsoleClientTest extends Scope
|
||||
], $this->getHeaders()), [
|
||||
'topicId' => ID::unique(),
|
||||
'name' => 'my-app',
|
||||
'description' => 'web app'
|
||||
]);
|
||||
$this->assertEquals(201, $topic['headers']['status-code']);
|
||||
|
||||
@@ -178,7 +195,7 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'description' => 'updated-description'
|
||||
'name' => 'android-app'
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -197,7 +214,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -209,7 +228,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)'],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -220,7 +241,10 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)', 'offset(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -235,7 +259,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(-1)']
|
||||
'queries' => [
|
||||
Query::limit(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -244,7 +270,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(-1)']
|
||||
'queries' => [
|
||||
Query::offset(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -253,7 +281,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("$id", "asdf")']
|
||||
'queries' => [
|
||||
Query::equal('$id', ['asdf'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -262,7 +292,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderAsc("$id")']
|
||||
'queries' => [
|
||||
Query::orderAsc('$id')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -271,7 +303,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAsc("$id")']
|
||||
'queries' => [
|
||||
'{"method":"cursorAsc","attribute":"$id","values":[]}'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -331,7 +365,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -343,7 +379,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)'],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -354,7 +392,10 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)', 'offset(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -369,7 +410,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(-1)']
|
||||
'queries' => [
|
||||
Query::limit(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -378,7 +421,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(-1)']
|
||||
'queries' => [
|
||||
Query::offset(-1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -387,7 +432,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("$id", "asdf")']
|
||||
'queries' => [
|
||||
Query::equal('$id', ['asdf'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -396,7 +443,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderAsc("$id")']
|
||||
'queries' => [
|
||||
Query::orderAsc('$id')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -405,7 +454,9 @@ class MessagingConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAsc("$id")']
|
||||
'queries' => [
|
||||
'{"method":"cursorAsc","attribute":"$id","values":[]}'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
|
||||
@@ -10,7 +10,9 @@ use Tests\E2E\Scopes\SideClient;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\General\UsageTest;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class ProjectsConsoleClientTest extends Scope
|
||||
{
|
||||
@@ -288,7 +290,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("teamId", "' . $team['body']['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::equal('teamId', [$team['body']['$id']])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -300,7 +304,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)' ],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -312,7 +318,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(3)' ],
|
||||
'queries' => [
|
||||
Query::offset(3)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -324,7 +332,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("name", "Project Test 2")' ],
|
||||
'queries' => [
|
||||
Query::equal('name', ['Project Test 2'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -336,7 +346,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'orderDesc("")' ],
|
||||
'queries' => [
|
||||
Query::orderDesc()->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -360,7 +372,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $response['body']['projects'][0]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $response['body']['projects'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -372,7 +386,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorBefore("' . $response['body']['projects'][0]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => $response['body']['projects'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -387,7 +403,9 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("unknown")' ],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
@@ -9,6 +9,7 @@ use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
|
||||
trait StorageBase
|
||||
@@ -27,7 +28,7 @@ trait StorageBase
|
||||
'name' => 'Test Bucket',
|
||||
'fileSecurity' => true,
|
||||
'maximumFileSize' => 2000000, //2MB
|
||||
'allowedFileExtensions' => ["jpg", "png", 'jfif'],
|
||||
'allowedFileExtensions' => ['jpg', 'png', 'jfif'],
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::create(Role::any()),
|
||||
@@ -380,7 +381,9 @@ trait StorageBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)' ]
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $files['headers']['status-code']);
|
||||
$this->assertEquals(1, count($files['body']['files']));
|
||||
@@ -389,7 +392,9 @@ trait StorageBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(1)' ]
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $files['headers']['status-code']);
|
||||
$this->assertEquals(0, count($files['body']['files']));
|
||||
@@ -398,7 +403,9 @@ trait StorageBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("mimeType", "image/png")' ]
|
||||
'queries' => [
|
||||
Query::equal('mimeType', ['image/png'])->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $files['headers']['status-code']);
|
||||
$this->assertEquals(1, count($files['body']['files']));
|
||||
@@ -407,7 +414,9 @@ trait StorageBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("mimeType", "image/jpeg")' ]
|
||||
'queries' => [
|
||||
Query::equal('mimeType', ['image/jpeg'])->toString(),
|
||||
],
|
||||
]);
|
||||
$this->assertEquals(200, $files['headers']['status-code']);
|
||||
$this->assertEquals(0, count($files['body']['files']));
|
||||
|
||||
@@ -6,7 +6,9 @@ use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideServer;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
|
||||
class StorageCustomServerTest extends Scope
|
||||
@@ -98,7 +100,9 @@ class StorageCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)' ],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -108,7 +112,9 @@ class StorageCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(1)' ],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -118,7 +124,9 @@ class StorageCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("$id", "bucket1")' ],
|
||||
'queries' => [
|
||||
Query::equal('$id', ['bucket1'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -128,7 +136,9 @@ class StorageCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("fileSecurity", true)' ],
|
||||
'queries' => [
|
||||
Query::equal('fileSecurity', [true])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -138,7 +148,9 @@ class StorageCustomServerTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $response['body']['buckets'][0]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $response['body']['buckets'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
@@ -4,7 +4,9 @@ namespace Tests\E2E\Services\Teams;
|
||||
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
|
||||
trait TeamsBase
|
||||
@@ -147,7 +149,9 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(2)' ],
|
||||
'queries' => [
|
||||
Query::limit(2)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -157,7 +161,9 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(1)' ],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -167,7 +173,9 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'greaterThanEqual("total", 0)' ],
|
||||
'queries' => [
|
||||
Query::greaterThanEqual('total', 0)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -177,7 +185,9 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("name", ["Arsenal", "Newcastle"])' ],
|
||||
'queries' => [
|
||||
Query::equal('name', ['Arsenal', 'Newcastle'])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -226,7 +236,9 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(2)' ],
|
||||
'queries' => [
|
||||
Query::limit(2)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $teams['headers']['status-code']);
|
||||
@@ -238,7 +250,10 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)', 'cursorAfter("' . $teams['body']['teams'][0]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
Query::cursorAfter(new Document(['$id' => $teams['body']['teams'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -251,7 +266,10 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)', 'cursorBefore("' . $teams['body']['teams'][1]['$id'] . '")' ],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
Query::cursorBefore(new Document(['$id' => $teams['body']['teams'][1]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -267,7 +285,9 @@ trait TeamsBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("unknown")' ],
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
|
||||
@@ -4,7 +4,9 @@ namespace Tests\E2E\Services\Teams;
|
||||
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
|
||||
trait TeamsBaseClient
|
||||
@@ -40,7 +42,9 @@ trait TeamsBaseClient
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'limit(1)' ]
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -50,7 +54,9 @@ trait TeamsBaseClient
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'offset(1)' ]
|
||||
'queries' => [
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -60,7 +66,9 @@ trait TeamsBaseClient
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("confirm", true)' ]
|
||||
'queries' => [
|
||||
Query::equal('confirm', [true])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -70,7 +78,9 @@ trait TeamsBaseClient
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'equal("confirm", false)' ]
|
||||
'queries' => [
|
||||
Query::equal('confirm', [false])->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -362,7 +372,9 @@ trait TeamsBaseClient
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [ 'cursorAfter("' . $memberships['body']['memberships'][0]['$id'] . '")' ]
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $memberships['body']['memberships'][0]['$id']]))->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
@@ -527,7 +539,7 @@ trait TeamsBaseClient
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
]), [
|
||||
'secret' => $secret,
|
||||
'userId' => ID::custom(''),
|
||||
'userId' => ID::custom('asdf'),
|
||||
]);
|
||||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
@@ -5,7 +5,9 @@ namespace Tests\E2E\Services\Users;
|
||||
use Appwrite\Tests\Retry;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Tests\E2E\Client;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
trait UsersBase
|
||||
{
|
||||
@@ -409,7 +411,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("name", "' . $user1['name'] . '")']
|
||||
'queries' => [
|
||||
Query::equal('name', [$user1['name']])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -418,11 +422,14 @@ trait UsersBase
|
||||
$this->assertCount(1, $response['body']['users']);
|
||||
$this->assertEquals($response['body']['users'][0]['name'], $user1['name']);
|
||||
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("email", "' . $user1['email'] . '")']
|
||||
'queries' => [
|
||||
Query::equal('name', [$user1['name']])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -435,7 +442,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("status", true)']
|
||||
'queries' => [
|
||||
Query::equal('status', [true])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -451,7 +460,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("status", false)']
|
||||
'queries' => [
|
||||
Query::equal('status', [false])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -463,7 +474,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("passwordUpdate", "' . $user1['passwordUpdate'] . '")']
|
||||
'queries' => [
|
||||
Query::equal('passwordUpdate', [$user1['passwordUpdate']])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -476,7 +489,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("registration", "' . $user1['registration'] . '")']
|
||||
'queries' => [
|
||||
Query::equal('registration', [$user1['registration']])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -489,7 +504,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("emailVerification", false)']
|
||||
'queries' => [
|
||||
Query::equal('emailVerification', [false])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -505,7 +522,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("emailVerification", true)']
|
||||
'queries' => [
|
||||
Query::equal('emailVerification', [true])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -517,7 +536,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("phoneVerification", false)']
|
||||
'queries' => [
|
||||
Query::equal('phoneVerification', [false])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -529,7 +550,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("phoneVerification", true)']
|
||||
'queries' => [
|
||||
Query::equal('phoneVerification', [true])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -541,7 +564,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("' . $data['userId'] . '")']
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => $data['userId']]))->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -554,7 +579,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorBefore("user1")']
|
||||
'queries' => [
|
||||
Query::cursorBefore(new Document(['$id' => 'user1']))->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
@@ -674,7 +701,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAfter("unknown")']
|
||||
'queries' => [
|
||||
Query::cursorAfter(new Document(['$id' => 'unknown']))->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
@@ -1203,7 +1232,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -1215,7 +1246,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(1)'],
|
||||
'queries' => [
|
||||
Query::offset(1)->toString()
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -1226,7 +1259,10 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(1)', 'offset(1)'],
|
||||
'queries' => [
|
||||
Query::limit(1)->toString(),
|
||||
Query::offset(1)->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
@@ -1241,7 +1277,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['limit(-1)']
|
||||
'queries' => [
|
||||
Query::limit(-1)->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -1250,7 +1288,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['offset(-1)']
|
||||
'queries' => [
|
||||
Query::offset(-1)->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -1259,7 +1299,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['equal("$id", "asdf")']
|
||||
'queries' => [
|
||||
Query::equal('$id', ['asdf'])->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -1268,7 +1310,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['orderAsc("$id")']
|
||||
'queries' => [
|
||||
Query::orderAsc('$id')->toString()
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
@@ -1277,7 +1321,9 @@ trait UsersBase
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => ['cursorAsc("$id")']
|
||||
'queries' => [
|
||||
'{ "method": "cursorAsc", "attribute": "$id" }'
|
||||
]
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 400);
|
||||
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 11 KiB |
@@ -7,10 +7,7 @@ use PHPUnit\Framework\TestCase;
|
||||
|
||||
class CustomIdTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Key
|
||||
*/
|
||||
protected $object = null;
|
||||
protected ?CustomId $object = null;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
|
||||
@@ -7,10 +7,7 @@ use PHPUnit\Framework\TestCase;
|
||||
|
||||
class ProjectIdTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @var Key
|
||||
*/
|
||||
protected $object = null;
|
||||
protected ?ProjectId $object = null;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
|
||||
@@ -4,6 +4,8 @@ namespace Tests\Unit\Utopia\Database\Validator\Queries;
|
||||
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Base;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class CollectionTest extends TestCase
|
||||
{
|
||||
@@ -25,17 +27,17 @@ class CollectionTest extends TestCase
|
||||
public function testValid(): void
|
||||
{
|
||||
$validator = new Base('users', ['name', 'search']);
|
||||
$this->assertEquals(true, $validator->isValid(['cursorAfter("asdf")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['equal("name", "value")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['limit(10)']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['offset(10)']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['orderAsc("name")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::cursorAfter(new Document(['$id' => 'asdf']))]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::equal('name', ['value'])]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::limit(10)]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::offset(10)]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::orderAsc('name')]), $validator->getDescription());
|
||||
}
|
||||
|
||||
public function testMissingIndex(): void
|
||||
{
|
||||
$validator = new Base('users', ['name']);
|
||||
$this->assertEquals(false, $validator->isValid(['equal("dne", "value")']), $validator->getDescription());
|
||||
$this->assertEquals(false, $validator->isValid(['orderAsc("dne")']), $validator->getDescription());
|
||||
$this->assertEquals(false, $validator->isValid([Query::equal('dne', ['value'])]), $validator->getDescription());
|
||||
$this->assertEquals(false, $validator->isValid([Query::orderAsc('dne')]), $validator->getDescription());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Tests\Unit\Utopia\Database\Validator\Queries;
|
||||
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Users;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class UsersTest extends TestCase
|
||||
{
|
||||
@@ -23,17 +24,17 @@ class UsersTest extends TestCase
|
||||
* Test for Success
|
||||
*/
|
||||
$this->assertEquals(true, $validator->isValid([]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['equal("name", "value")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['equal("email", "value")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['equal("phone", "value")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['greaterThan("passwordUpdate", "2020-10-15 06:38")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['greaterThan("registration", "2020-10-15 06:38")']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['equal("emailVerification", true)']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid(['equal("phoneVerification", true)']), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::equal('name', ['value'])]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::equal('email', ['value'])]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::equal('phone', ['value'])]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::greaterThan('passwordUpdate', '2020-10-15 06:38')]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::greaterThan('registration', '2020-10-15 06:38')]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::equal('emailVerification', [true])]), $validator->getDescription());
|
||||
$this->assertEquals(true, $validator->isValid([Query::equal('phoneVerification', [true])]), $validator->getDescription());
|
||||
|
||||
/**
|
||||
* Test for Failure
|
||||
*/
|
||||
$this->assertEquals(false, $validator->isValid(['equal("password", "value")']), $validator->getDescription());
|
||||
$this->assertEquals(false, $validator->isValid([Query::equal('password', ['value'])]), $validator->getDescription());
|
||||
}
|
||||
}
|
||||
|
||||