Merge pull request #8327 from appwrite/chore-sync-1.5.x-into-main
Sync 1.5.x into main
This commit is contained in:
commit
ae87033974
33 changed files with 289 additions and 719 deletions
3
.github/workflows/tests.yml
vendored
3
.github/workflows/tests.yml
vendored
|
@ -145,3 +145,6 @@ jobs:
|
|||
|
||||
- name: Run ${{matrix.service}} Tests
|
||||
run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug
|
||||
|
||||
- name: Run ${{matrix.service}} Shared Tables Tests
|
||||
run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug
|
||||
|
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,4 +1,4 @@
|
|||
[submodule "app/console"]
|
||||
path = app/console
|
||||
url = https://github.com/appwrite/console
|
||||
branch = 4.3.5
|
||||
branch = 4.3.14
|
||||
|
|
|
@ -29,7 +29,7 @@ ENV VITE_APPWRITE_GROWTH_ENDPOINT=$VITE_APPWRITE_GROWTH_ENDPOINT
|
|||
RUN npm ci
|
||||
RUN npm run build
|
||||
|
||||
FROM appwrite/base:0.9.0 as final
|
||||
FROM appwrite/base:0.9.1 as final
|
||||
|
||||
LABEL maintainer="team@appwrite.io"
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole,
|
|||
if (isset($databases[$dsn->getHost()])) {
|
||||
$database = $databases[$dsn->getHost()];
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
@ -133,7 +133,7 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole,
|
|||
|
||||
$databases[$dsn->getHost()] = $database;
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
|
|
@ -15,7 +15,7 @@ return [
|
|||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '14.0.2',
|
||||
'version' => '15.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -138,7 +138,7 @@ return [
|
|||
[
|
||||
'key' => 'react-native',
|
||||
'name' => 'React Native',
|
||||
'version' => '0.3.2',
|
||||
'version' => '0.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-react-native',
|
||||
'package' => 'https://npmjs.com/package/react-native-appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -267,7 +267,7 @@ return [
|
|||
[
|
||||
'key' => 'deno',
|
||||
'name' => 'Deno',
|
||||
'version' => '10.0.2',
|
||||
'version' => '11.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-deno',
|
||||
'package' => 'https://deno.land/x/appwrite',
|
||||
'enabled' => true,
|
||||
|
|
|
@ -468,7 +468,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_SMS_FROM',
|
||||
'description' => 'Phone number used for sending out messages. Must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789).',
|
||||
'description' => 'Phone number used for sending out messages. If using Twilio, this may be a Messaging Service SID, starting with MG. Otherwise, the number must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789). ',
|
||||
'introduction' => '0.15.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5169fe16d63066f64ab5013c78953aea04e24b53
|
||||
Subproject commit 412bc3331891c15ba7baf4f445e82ac3a678c6be
|
|
@ -86,8 +86,8 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
|||
$factor = (match ($verifiedToken->getAttribute('type')) {
|
||||
Auth::TOKEN_TYPE_MAGIC_URL,
|
||||
Auth::TOKEN_TYPE_OAUTH2,
|
||||
Auth::TOKEN_TYPE_EMAIL => 'email',
|
||||
Auth::TOKEN_TYPE_PHONE => 'phone',
|
||||
Auth::TOKEN_TYPE_EMAIL => Type::EMAIL,
|
||||
Auth::TOKEN_TYPE_PHONE => Type::PHONE,
|
||||
Auth::TOKEN_TYPE_GENERIC => 'token',
|
||||
default => throw new Exception(Exception::USER_INVALID_TOKEN)
|
||||
});
|
||||
|
@ -1508,7 +1508,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
'ip' => $request->getIP(),
|
||||
'factors' => ['email'],
|
||||
'factors' => [TYPE::EMAIL, 'oauth2'], // include a special oauth2 factor to bypass MFA checks
|
||||
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
|
||||
'expire' => DateTime::addSeconds(new \DateTime(), $duration)
|
||||
], $detector->getOS(), $detector->getClient(), $detector->getDevice()));
|
||||
|
@ -2526,6 +2526,7 @@ App::patch('/v1/account/password')
|
|||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('sdk.offline.model', '/account')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->label('abuse-limit', 10)
|
||||
->param('password', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'New user password. Must be at least 8 chars.', false, ['project', 'passwordsDictionary'])
|
||||
->param('oldPassword', '', new Password(), 'Current user password. Must be at least 8 chars.', true)
|
||||
->inject('requestTimestamp')
|
||||
|
|
|
@ -852,7 +852,7 @@ App::get('/v1/health/queue/failed/:name')
|
|||
Event::FUNCTIONS_QUEUE_NAME,
|
||||
Event::USAGE_QUEUE_NAME,
|
||||
Event::USAGE_DUMP_QUEUE_NAME,
|
||||
Event::WEBHOOK_CLASS_NAME,
|
||||
Event::WEBHOOK_QUEUE_NAME,
|
||||
Event::CERTIFICATES_QUEUE_NAME,
|
||||
Event::BUILDS_QUEUE_NAME,
|
||||
Event::MESSAGING_QUEUE_NAME,
|
||||
|
|
|
@ -111,35 +111,8 @@ App::post('/v1/projects')
|
|||
|
||||
$projectId = ($projectId == 'unique()') ? ID::unique() : $projectId;
|
||||
|
||||
$backups['database_db_fra1_v14x_02'] = ['from' => '03:00', 'to' => '05:00'];
|
||||
$backups['database_db_fra1_v14x_03'] = ['from' => '00:00', 'to' => '02:00'];
|
||||
$backups['database_db_fra1_v14x_04'] = ['from' => '00:00', 'to' => '02:00'];
|
||||
$backups['database_db_fra1_v14x_05'] = ['from' => '00:00', 'to' => '02:00'];
|
||||
$backups['database_db_fra1_v14x_06'] = ['from' => '00:00', 'to' => '02:00'];
|
||||
$backups['database_db_fra1_v14x_07'] = ['from' => '00:00', 'to' => '02:00'];
|
||||
|
||||
$databases = Config::getParam('pools-database', []);
|
||||
|
||||
/**
|
||||
* Remove databases from the list that are currently undergoing an backup
|
||||
*/
|
||||
if (count($databases) > 1) {
|
||||
$now = new \DateTime();
|
||||
|
||||
foreach ($databases as $index => $database) {
|
||||
if (empty($backups[$database])) {
|
||||
continue;
|
||||
}
|
||||
$backup = $backups[$database];
|
||||
$from = \DateTime::createFromFormat('H:i', $backup['from']);
|
||||
$to = \DateTime::createFromFormat('H:i', $backup['to']);
|
||||
if ($now >= $from && $now <= $to) {
|
||||
unset($databases[$index]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$databaseOverride = System::getEnv('_APP_DATABASE_OVERRIDE');
|
||||
$index = \array_search($databaseOverride, $databases);
|
||||
if ($index !== false) {
|
||||
|
@ -152,37 +125,12 @@ App::post('/v1/projects')
|
|||
throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project.");
|
||||
}
|
||||
|
||||
// TODO: 1 in 5 projects use shared tables. Temporary until all projects are using shared tables.
|
||||
if (
|
||||
(
|
||||
!\mt_rand(0, 4)
|
||||
&& System::getEnv('_APP_DATABASE_SHARED_TABLES', 'enabled') === 'enabled'
|
||||
&& System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted'
|
||||
) ||
|
||||
(
|
||||
$dsn === DATABASE_SHARED_TABLES
|
||||
)
|
||||
) {
|
||||
// TODO: Temporary until all projects are using shared tables.
|
||||
if ($dsn === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$schema = 'appwrite';
|
||||
$database = 'appwrite';
|
||||
$namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', '');
|
||||
$dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database;
|
||||
|
||||
if (!empty($namespace)) {
|
||||
$dsn .= '&namespace=' . $namespace;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Allow overriding in development mode. Temporary until all projects are using shared tables.
|
||||
if (
|
||||
App::isDevelopment()
|
||||
&& System::getEnv('_APP_EDITION', 'self-hosted') !== 'self-hosted'
|
||||
&& $request->getHeader('x-appwrited-share-tables', false)
|
||||
) {
|
||||
$schema = 'appwrite';
|
||||
$database = 'appwrite';
|
||||
$namespace = System::getEnv('_APP_DATABASE_SHARED_NAMESPACE', '');
|
||||
$dsn = $schema . '://' . DATABASE_SHARED_TABLES . '?database=' . $database;
|
||||
$dsn = $schema . '://' . System::getEnv('_APP_DATABASE_SHARED_TABLES', '') . '?database=' . $database;
|
||||
|
||||
if (!empty($namespace)) {
|
||||
$dsn .= '&namespace=' . $namespace;
|
||||
|
@ -236,7 +184,7 @@ App::post('/v1/projects')
|
|||
$adapter = $pools->get($dsn->getHost())->pop()->getResource();
|
||||
$dbForProject = new Database($adapter, $cache);
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$dbForProject
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
|
|
@ -63,7 +63,7 @@ App::post('/v1/storage/buckets')
|
|||
->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default, no user is granted with any permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('fileSecurity', false, new Boolean(true), 'Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('enabled', true, new Boolean(true), 'Is bucket enabled? When set to \'disabled\', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.', true)
|
||||
->param('maximumFileSize', fn (array $plan) => empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024, fn (array $plan) => new Range(1, empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024 * 1024), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true, ['plan'])
|
||||
->param('maximumFileSize', fn (array $plan) => empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024, fn (array $plan) => new Range(1, empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true, ['plan'])
|
||||
->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true)
|
||||
->param('compression', Compression::NONE, new WhiteList([Compression::NONE, Compression::GZIP, Compression::ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true)
|
||||
->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true)
|
||||
|
@ -240,7 +240,7 @@ App::put('/v1/storage/buckets/:bucketId')
|
|||
->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of permission strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('fileSecurity', false, new Boolean(true), 'Enables configuring permissions for individual file. A user needs one of file or bucket level permissions to access a file. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('enabled', true, new Boolean(true), 'Is bucket enabled? When set to \'disabled\', users cannot access the files in this bucket but Server SDKs with and API key can still access the bucket. No files are lost when this is toggled.', true)
|
||||
->param('maximumFileSize', null, new Range(1, (int) System::getEnv('_APP_STORAGE_LIMIT', 0)), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human((int)System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true)
|
||||
->param('maximumFileSize', fn (array $plan) => empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024, fn (array $plan) => new Range(1, empty($plan['fileSize']) ? (int) System::getEnv('_APP_STORAGE_LIMIT', 0) : $plan['fileSize'] * 1024 * 1024), 'Maximum file size allowed in bytes. Maximum allowed value is ' . Storage::human(System::getEnv('_APP_STORAGE_LIMIT', 0), 0) . '.', true, ['plan'])
|
||||
->param('allowedFileExtensions', [], new ArrayList(new Text(64), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Allowed file extensions. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' extensions are allowed, each 64 characters long.', true)
|
||||
->param('compression', Compression::NONE, new WhiteList([Compression::NONE, Compression::GZIP, Compression::ZSTD]), 'Compression algorithm choosen for compression. Can be one of ' . Compression::NONE . ', [' . Compression::GZIP . '](https://en.wikipedia.org/wiki/Gzip), or [' . Compression::ZSTD . '](https://en.wikipedia.org/wiki/Zstd), For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' compression is skipped even if it\'s enabled', true)
|
||||
->param('encryption', true, new Boolean(true), 'Is encryption enabled? For file size above ' . Storage::human(APP_STORAGE_READ_BUFFER, 0) . ' encryption is skipped even if it\'s enabled', true)
|
||||
|
|
|
@ -1784,7 +1784,7 @@ App::post('/v1/users/:userId/sessions')
|
|||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
$secret = Auth::codeGenerator();
|
||||
$secret = Auth::tokenGenerator(Auth::TOKEN_LENGTH_SESSION);
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
|
||||
|
@ -1801,6 +1801,7 @@ App::post('/v1/users/:userId/sessions')
|
|||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
'ip' => $request->getIP(),
|
||||
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
|
||||
'expire' => $expire,
|
||||
],
|
||||
$detector->getOS(),
|
||||
$detector->getClient(),
|
||||
|
@ -1812,7 +1813,6 @@ App::post('/v1/users/:userId/sessions')
|
|||
$session = $dbForProject->createDocument('sessions', $session);
|
||||
$session
|
||||
->setAttribute('secret', $secret)
|
||||
->setAttribute('expire', $expire)
|
||||
->setAttribute('countryName', $countryName);
|
||||
|
||||
$queueForEvents
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Usage;
|
||||
|
@ -583,7 +584,7 @@ App::init()
|
|||
->addHeader('Server', 'Appwrite')
|
||||
->addHeader('X-Content-Type-Options', 'nosniff')
|
||||
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Forwarded-For, X-Forwarded-User-Agent')
|
||||
->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Origin', $refDomain)
|
||||
->addHeader('Access-Control-Allow-Credentials', 'true');
|
||||
|
@ -634,7 +635,7 @@ App::options()
|
|||
$response
|
||||
->addHeader('Server', 'Appwrite')
|
||||
->addHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent')
|
||||
->addHeader('Access-Control-Allow-Headers', 'Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent')
|
||||
->addHeader('Access-Control-Expose-Headers', 'X-Appwrite-Session, X-Fallback-Cookies')
|
||||
->addHeader('Access-Control-Allow-Origin', $origin)
|
||||
->addHeader('Access-Control-Allow-Credentials', 'true')
|
||||
|
@ -649,7 +650,8 @@ App::error()
|
|||
->inject('project')
|
||||
->inject('logger')
|
||||
->inject('log')
|
||||
->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log) {
|
||||
->inject('queueForUsage')
|
||||
->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Usage $queueForUsage) {
|
||||
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
$route = $utopia->getRoute();
|
||||
$class = \get_class($error);
|
||||
|
@ -738,6 +740,26 @@ App::error()
|
|||
}
|
||||
}
|
||||
|
||||
if ($publish && $project->getId() !== 'console') {
|
||||
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
|
||||
$fileSize = 0;
|
||||
$file = $request->getFiles('file');
|
||||
if (!empty($file)) {
|
||||
$fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size'];
|
||||
}
|
||||
|
||||
$queueForUsage
|
||||
->addMetric(METRIC_NETWORK_REQUESTS, 1)
|
||||
->addMetric(METRIC_NETWORK_INBOUND, $request->getSize() + $fileSize)
|
||||
->addMetric(METRIC_NETWORK_OUTBOUND, $response->getSize());
|
||||
}
|
||||
|
||||
$queueForUsage
|
||||
->setProject($project)
|
||||
->trigger();
|
||||
}
|
||||
|
||||
|
||||
if ($logger && $publish) {
|
||||
try {
|
||||
/** @var Utopia\Database\Document $user */
|
||||
|
|
13
app/init.php
13
app/init.php
|
@ -112,7 +112,7 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return
|
|||
const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_BUSTER = 443;
|
||||
const APP_CACHE_BUSTER = 4314;
|
||||
const APP_VERSION_STABLE = '1.5.7';
|
||||
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
|
||||
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
|
||||
|
@ -143,9 +143,6 @@ const APP_SOCIAL_STACKSHARE = 'https://stackshare.io/appwrite';
|
|||
const APP_SOCIAL_YOUTUBE = 'https://www.youtube.com/c/appwrite?sub_confirmation=1';
|
||||
const APP_HOSTNAME_INTERNAL = 'appwrite';
|
||||
|
||||
// Databases
|
||||
const DATABASE_SHARED_TABLES = 'database_db_fra1_self_hosted_16_0';
|
||||
|
||||
// Database Reconnect
|
||||
const DATABASE_RECONNECT_SLEEP = 2;
|
||||
const DATABASE_RECONNECT_MAX_ATTEMPTS = 10;
|
||||
|
@ -610,9 +607,9 @@ Database::addFilter(
|
|||
])
|
||||
));
|
||||
if (\count($targetIds) > 0) {
|
||||
return $database->find('targets', [
|
||||
return $database->skipValidation(fn () => $database->find('targets', [
|
||||
Query::equal('$internalId', $targetIds)
|
||||
]);
|
||||
]));
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
@ -1338,7 +1335,7 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForConsole,
|
|||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
@ -1391,7 +1388,7 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForConsole,
|
|||
->setMetadata('project', $project->getId())
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS);
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
|
|
@ -92,7 +92,7 @@ if (!function_exists("getProjectDB")) {
|
|||
|
||||
$database = new Database($adapter, getCache());
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
|
|
@ -93,7 +93,7 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register,
|
|||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
@ -126,7 +126,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso
|
|||
if (isset($databases[$dsn->getHost()])) {
|
||||
$database = $databases[$dsn->getHost()];
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
@ -150,7 +150,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForConso
|
|||
|
||||
$databases[$dsn->getHost()] = $database;
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
|
|
|
@ -44,13 +44,13 @@
|
|||
"ext-sockets": "*",
|
||||
"appwrite/php-runtimes": "0.13.*",
|
||||
"appwrite/php-clamav": "2.0.*",
|
||||
"utopia-php/abuse": "0.37.*",
|
||||
"utopia-php/abuse": "0.38.*",
|
||||
"utopia-php/analytics": "0.10.*",
|
||||
"utopia-php/audit": "0.39.*",
|
||||
"utopia-php/cache": "0.9.*",
|
||||
"utopia-php/audit": "0.40.*",
|
||||
"utopia-php/cache": "0.10.*",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.49.*",
|
||||
"utopia-php/database": "0.50.*",
|
||||
"utopia-php/domains": "0.5.*",
|
||||
"utopia-php/dsn": "0.2.1",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
|
@ -58,7 +58,7 @@
|
|||
"utopia-php/image": "0.6.*",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.5.*",
|
||||
"utopia-php/messaging": "0.11.*",
|
||||
"utopia-php/messaging": "0.12.*",
|
||||
"utopia-php/migration": "0.4.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
|
|
163
composer.lock
generated
163
composer.lock
generated
|
@ -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": "18bab1e5f72cc82896aef9e64bf566e8",
|
||||
"content-hash": "89f2552eaa152516be5bf89628c0f86e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -1128,16 +1128,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.30.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||
"reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fd22ab50000ef01661e2a31d850ebaa297f8e03c",
|
||||
"reference": "fd22ab50000ef01661e2a31d850ebaa297f8e03c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1188,7 +1188,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1204,20 +1204,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2024-06-19T12:30:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.30.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
|
||||
"reference": "77fa7995ac1b21ab60769b7323d600a991a90433"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/77fa7995ac1b21ab60769b7323d600a991a90433",
|
||||
"reference": "77fa7995ac1b21ab60769b7323d600a991a90433",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1268,7 +1268,7 @@
|
|||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1284,7 +1284,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2024-05-31T15:07:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "thecodingmachine/safe",
|
||||
|
@ -1427,23 +1427,23 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
"version": "0.37.1",
|
||||
"version": "0.38.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/abuse.git",
|
||||
"reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981"
|
||||
"reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/4dfcff4754c7804d1a70039792c0f2d59a5cc981",
|
||||
"reference": "4dfcff4754c7804d1a70039792c0f2d59a5cc981",
|
||||
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/b7be9086c9d9b4561d810cbd42fdda798742f56c",
|
||||
"reference": "b7be9086c9d9b4561d810cbd42fdda798742f56c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-curl": "*",
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.49.*"
|
||||
"utopia-php/database": "0.50.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.5.*",
|
||||
|
@ -1470,9 +1470,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/abuse/issues",
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.37.1"
|
||||
"source": "https://github.com/utopia-php/abuse/tree/0.38.0"
|
||||
},
|
||||
"time": "2024-06-05T18:03:59+00:00"
|
||||
"time": "2024-06-24T00:52:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/analytics",
|
||||
|
@ -1522,21 +1522,21 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "0.39.1",
|
||||
"version": "0.40.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "7ea91e0ceea7b94293612fea94022b73315677c2"
|
||||
"reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/7ea91e0ceea7b94293612fea94022b73315677c2",
|
||||
"reference": "7ea91e0ceea7b94293612fea94022b73315677c2",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/735ae211ce5fee5b52b736731571b4030b1d7cdc",
|
||||
"reference": "735ae211ce5fee5b52b736731571b4030b1d7cdc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "0.49.*"
|
||||
"utopia-php/database": "0.50.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.5.*",
|
||||
|
@ -1563,22 +1563,22 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.39.1"
|
||||
"source": "https://github.com/utopia-php/audit/tree/0.40.0"
|
||||
},
|
||||
"time": "2024-06-05T19:28:22+00:00"
|
||||
"time": "2024-06-24T00:52:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
"version": "0.9.1",
|
||||
"version": "0.10.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/cache.git",
|
||||
"reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6"
|
||||
"reference": "b22c6eb6d308de246b023efd0fc9758aee8b8247"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/cache/zipball/552b4c554bb14d0c529631ce304cdf4a2b9d06a6",
|
||||
"reference": "552b4c554bb14d0c529631ce304cdf4a2b9d06a6",
|
||||
"url": "https://api.github.com/repos/utopia-php/cache/zipball/b22c6eb6d308de246b023efd0fc9758aee8b8247",
|
||||
"reference": "b22c6eb6d308de246b023efd0fc9758aee8b8247",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1613,9 +1613,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/cache/issues",
|
||||
"source": "https://github.com/utopia-php/cache/tree/0.9.1"
|
||||
"source": "https://github.com/utopia-php/cache/tree/0.10.2"
|
||||
},
|
||||
"time": "2024-03-19T17:07:20+00:00"
|
||||
"time": "2024-06-25T20:36:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cli",
|
||||
|
@ -1719,23 +1719,23 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.49.11",
|
||||
"version": "0.50.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "4f4b35d99ecdee971c3042279bb1ac8264825030"
|
||||
"reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/4f4b35d99ecdee971c3042279bb1ac8264825030",
|
||||
"reference": "4f4b35d99ecdee971c3042279bb1ac8264825030",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/ce3eaccb2f3bbd34b2b97419836fec633b26b8f7",
|
||||
"reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"ext-pdo": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cache": "0.9.*",
|
||||
"utopia-php/cache": "0.10.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/mongo": "0.3.*"
|
||||
},
|
||||
|
@ -1769,9 +1769,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.49.11"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.50.0"
|
||||
},
|
||||
"time": "2024-05-30T12:40:27+00:00"
|
||||
"time": "2024-06-21T03:21:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
@ -2119,16 +2119,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/messaging",
|
||||
"version": "0.11.0",
|
||||
"version": "0.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/messaging.git",
|
||||
"reference": "b499c3ad11af711c28252c62d83f24e6106a2154"
|
||||
"reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/b499c3ad11af711c28252c62d83f24e6106a2154",
|
||||
"reference": "b499c3ad11af711c28252c62d83f24e6106a2154",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/6e466d3511981291843c6ebf9ce3f44fc75e37b0",
|
||||
"reference": "6e466d3511981291843c6ebf9ce3f44fc75e37b0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2164,9 +2164,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/messaging/issues",
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.11.0"
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.12.0"
|
||||
},
|
||||
"time": "2024-05-08T17:10:02+00:00"
|
||||
"time": "2024-05-30T14:58:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
|
@ -2756,22 +2756,22 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/vcs",
|
||||
"version": "0.6.6",
|
||||
"version": "0.6.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/vcs.git",
|
||||
"reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4"
|
||||
"reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/e538264cfee5e3efdfe1771efba04750cf20b2c4",
|
||||
"reference": "e538264cfee5e3efdfe1771efba04750cf20b2c4",
|
||||
"url": "https://api.github.com/repos/utopia-php/vcs/zipball/8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974",
|
||||
"reference": "8d8ff1ac68e991b95adb6f91fcde8f9bb8f24974",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"adhocore/jwt": "^1.1",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/cache": "^0.9.0",
|
||||
"utopia-php/cache": "^0.10.0",
|
||||
"utopia-php/framework": "0.*.*"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -2799,9 +2799,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/vcs/issues",
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.6.6"
|
||||
"source": "https://github.com/utopia-php/vcs/tree/0.6.7"
|
||||
},
|
||||
"time": "2024-05-17T09:36:30+00:00"
|
||||
"time": "2024-06-05T17:38:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/websocket",
|
||||
|
@ -2988,16 +2988,16 @@
|
|||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.38.6",
|
||||
"version": "0.38.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "d7016d6d72545e84709892faca972eb4bf5bd699"
|
||||
"reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/d7016d6d72545e84709892faca972eb4bf5bd699",
|
||||
"reference": "d7016d6d72545e84709892faca972eb4bf5bd699",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a",
|
||||
"reference": "0a66c1149ef05ed9f45ce1c897c4a0ce9ee5e95a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3033,9 +3033,9 @@
|
|||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.38.6"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.38.7"
|
||||
},
|
||||
"time": "2024-05-20T18:00:16+00:00"
|
||||
"time": "2024-06-10T00:23:02+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
|
@ -3156,16 +3156,16 @@
|
|||
},
|
||||
{
|
||||
"name": "laravel/pint",
|
||||
"version": "v1.16.0",
|
||||
"version": "v1.16.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/laravel/pint.git",
|
||||
"reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98"
|
||||
"reference": "9266a47f1b9231b83e0cfd849009547329d871b1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98",
|
||||
"reference": "1b3a3dc5bc6a81ff52828ba7277621f1d49d6d98",
|
||||
"url": "https://api.github.com/repos/laravel/pint/zipball/9266a47f1b9231b83e0cfd849009547329d871b1",
|
||||
"reference": "9266a47f1b9231b83e0cfd849009547329d871b1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3176,13 +3176,13 @@
|
|||
"php": "^8.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^3.57.1",
|
||||
"illuminate/view": "^10.48.10",
|
||||
"larastan/larastan": "^2.9.6",
|
||||
"friendsofphp/php-cs-fixer": "^3.59.3",
|
||||
"illuminate/view": "^10.48.12",
|
||||
"larastan/larastan": "^2.9.7",
|
||||
"laravel-zero/framework": "^10.4.0",
|
||||
"mockery/mockery": "^1.6.12",
|
||||
"nunomaduro/termwind": "^1.15.1",
|
||||
"pestphp/pest": "^2.34.7"
|
||||
"pestphp/pest": "^2.34.8"
|
||||
},
|
||||
"bin": [
|
||||
"builds/pint"
|
||||
|
@ -3218,7 +3218,7 @@
|
|||
"issues": "https://github.com/laravel/pint/issues",
|
||||
"source": "https://github.com/laravel/pint"
|
||||
},
|
||||
"time": "2024-05-21T18:08:25+00:00"
|
||||
"time": "2024-06-18T16:50:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "matthiasmullie/minify",
|
||||
|
@ -3346,16 +3346,16 @@
|
|||
},
|
||||
{
|
||||
"name": "myclabs/deep-copy",
|
||||
"version": "1.11.1",
|
||||
"version": "1.12.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/myclabs/DeepCopy.git",
|
||||
"reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c"
|
||||
"reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
|
||||
"reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c",
|
||||
"url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
|
||||
"reference": "3a6b9a42cd8f8771bd4295d13e1423fa7f3d942c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -3363,11 +3363,12 @@
|
|||
},
|
||||
"conflict": {
|
||||
"doctrine/collections": "<1.6.8",
|
||||
"doctrine/common": "<2.13.3 || >=3,<3.2.2"
|
||||
"doctrine/common": "<2.13.3 || >=3 <3.2.2"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/collections": "^1.6.8",
|
||||
"doctrine/common": "^2.13.3 || ^3.2.2",
|
||||
"phpspec/prophecy": "^1.10",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -3393,7 +3394,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/myclabs/DeepCopy/issues",
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.11.1"
|
||||
"source": "https://github.com/myclabs/DeepCopy/tree/1.12.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -3401,7 +3402,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-03-08T13:26:56+00:00"
|
||||
"time": "2024-06-12T14:39:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
|
@ -5339,16 +5340,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.30.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
|
||||
"reference": "0424dff1c58f028c451efff2045f5d92410bd540"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
|
||||
"reference": "0424dff1c58f028c451efff2045f5d92410bd540",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -5398,7 +5399,7 @@
|
|||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.30.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -5414,7 +5415,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2024-05-31T15:07:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
|
|
|
@ -189,6 +189,7 @@ services:
|
|||
- _APP_CONSOLE_COUNTRIES_DENYLIST
|
||||
- _APP_EXPERIMENT_LOGGING_PROVIDER
|
||||
- _APP_EXPERIMENT_LOGGING_CONFIG
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-realtime:
|
||||
entrypoint: realtime
|
||||
|
@ -238,6 +239,7 @@ services:
|
|||
- _APP_USAGE_STATS
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-audits:
|
||||
entrypoint: worker-audits
|
||||
|
@ -267,6 +269,7 @@ services:
|
|||
- _APP_DB_PASS
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-webhooks:
|
||||
entrypoint: worker-webhooks
|
||||
|
@ -299,6 +302,7 @@ services:
|
|||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_WEBHOOK_MAX_FAILED_ATTEMPTS
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-deletes:
|
||||
entrypoint: worker-deletes
|
||||
|
@ -356,6 +360,7 @@ services:
|
|||
- _APP_LOGGING_CONFIG
|
||||
- _APP_EXECUTOR_SECRET
|
||||
- _APP_EXECUTOR_HOST
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-databases:
|
||||
entrypoint: worker-databases
|
||||
|
@ -387,6 +392,7 @@ services:
|
|||
- _APP_LOGGING_CONFIG
|
||||
- _APP_WORKERS_NUM
|
||||
- _APP_QUEUE_NAME
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-builds:
|
||||
entrypoint: worker-builds
|
||||
|
@ -452,6 +458,7 @@ services:
|
|||
- _APP_STORAGE_WASABI_SECRET
|
||||
- _APP_STORAGE_WASABI_REGION
|
||||
- _APP_STORAGE_WASABI_BUCKET
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-certificates:
|
||||
entrypoint: worker-certificates
|
||||
|
@ -487,6 +494,7 @@ services:
|
|||
- _APP_DB_PASS
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-functions:
|
||||
entrypoint: worker-functions
|
||||
|
@ -526,6 +534,7 @@ services:
|
|||
- _APP_DOCKER_HUB_PASSWORD
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-mails:
|
||||
entrypoint: worker-mails
|
||||
|
@ -560,6 +569,7 @@ services:
|
|||
- _APP_LOGGING_CONFIG
|
||||
- _APP_DOMAIN
|
||||
- _APP_OPTIONS_FORCE_HTTPS
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-messaging:
|
||||
entrypoint: worker-messaging
|
||||
|
@ -614,6 +624,7 @@ services:
|
|||
- _APP_STORAGE_WASABI_SECRET
|
||||
- _APP_STORAGE_WASABI_REGION
|
||||
- _APP_STORAGE_WASABI_BUCKET
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-migrations:
|
||||
entrypoint: worker-migrations
|
||||
|
@ -649,6 +660,7 @@ services:
|
|||
- _APP_LOGGING_CONFIG
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-task-maintenance:
|
||||
entrypoint: maintenance
|
||||
|
@ -686,6 +698,7 @@ services:
|
|||
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
- _APP_MAINTENANCE_DELAY
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-usage:
|
||||
entrypoint: worker-usage
|
||||
|
@ -717,6 +730,7 @@ services:
|
|||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-worker-usage-dump:
|
||||
entrypoint: worker-usage-dump
|
||||
|
@ -748,6 +762,7 @@ services:
|
|||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-task-scheduler-functions:
|
||||
entrypoint: schedule-functions
|
||||
|
@ -775,6 +790,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-task-scheduler-messages:
|
||||
entrypoint: schedule-messages
|
||||
|
@ -802,6 +818,7 @@ services:
|
|||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-assistant:
|
||||
container_name: appwrite-assistant
|
||||
|
@ -900,20 +917,7 @@ services:
|
|||
- MYSQL_USER=${_APP_DB_USER}
|
||||
- MYSQL_PASSWORD=${_APP_DB_PASS}
|
||||
- MARIADB_AUTO_UPGRADE=1
|
||||
command: "mysqld --innodb-flush-method=fsync" # add ' --query_cache_size=0' for DB tests
|
||||
# command: mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bu && mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bu
|
||||
|
||||
# smtp:
|
||||
# image: appwrite/smtp:1.2.0
|
||||
# container_name: appwrite-smtp
|
||||
# restart: unless-stopped
|
||||
# networks:
|
||||
# - appwrite
|
||||
# environment:
|
||||
# - LOCAL_DOMAINS=@
|
||||
# - RELAY_FROM_HOSTS=192.168.0.0/16 ; *.yourdomain.com
|
||||
# - SMARTHOST_HOST=smtp
|
||||
# - SMARTHOST_PORT=587
|
||||
command: "mysqld --innodb-flush-method=fsync"
|
||||
|
||||
redis:
|
||||
image: redis:7.2.4-alpine
|
||||
|
@ -931,14 +935,6 @@ services:
|
|||
volumes:
|
||||
- appwrite-redis:/data:rw
|
||||
|
||||
# clamav:
|
||||
# image: appwrite/clamav:1.2.0
|
||||
# container_name: appwrite-clamav
|
||||
# networks:
|
||||
# - appwrite
|
||||
# volumes:
|
||||
# - appwrite-uploads:/storage/uploads
|
||||
|
||||
# Dev Tools Start ------------------------------------------------------------------------------------------
|
||||
#
|
||||
# The Appwrite Team uses the following tools to help debug, monitor and diagnose the Appwrite stack
|
||||
|
|
|
@ -1 +1 @@
|
|||
Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method. add
|
||||
Verify an authenticator app after adding it using the [add authenticator](/docs/references/cloud/client-web/account#createMfaAuthenticator) method.
|
|
@ -239,7 +239,7 @@ abstract class Migration
|
|||
}
|
||||
|
||||
/**
|
||||
* Creates colletion from the config collection.
|
||||
* Creates collection from the config collection.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $name
|
||||
|
@ -266,6 +266,7 @@ abstract class Migration
|
|||
'type' => $attribute['type'],
|
||||
'size' => $attribute['size'],
|
||||
'required' => $attribute['required'],
|
||||
'default' => $attribute['default'] ?? null,
|
||||
'signed' => $attribute['signed'],
|
||||
'array' => $attribute['array'],
|
||||
'filters' => $attribute['filters'],
|
||||
|
|
|
@ -336,6 +336,32 @@ class V20 extends Migration
|
|||
Console::warning("Purge cache from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'topics':
|
||||
try {
|
||||
$this->projectDB->updateAttributeDefault($id, 'emailTotal', 0);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'topics' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->projectDB->updateAttributeDefault($id, 'pushTotal', 0);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'topics' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->projectDB->updateAttributeDefault($id, 'smsTotal', 0);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'topics' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->projectDB->purgeCachedCollection($id);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Purge cache from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,6 +93,7 @@ class Migrate extends Action
|
|||
// TODO: Iterate through all project DBs
|
||||
/** @var Database $projectDB */
|
||||
$projectDB = $getProjectDB($project);
|
||||
$projectDB->disableValidation();
|
||||
$migration
|
||||
->setProject($project, $projectDB, $dbForConsole)
|
||||
->setPDO($register->get('db', true))
|
||||
|
|
|
@ -498,14 +498,14 @@ class Deletes extends Action
|
|||
$collections = $dbForProject->listCollections($limit);
|
||||
|
||||
foreach ($collections as $collection) {
|
||||
if ($dsn->getHost() !== DATABASE_SHARED_TABLES || !\in_array($collection->getId(), $projectCollectionIds)) {
|
||||
if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '') || !\in_array($collection->getId(), $projectCollectionIds)) {
|
||||
$dbForProject->deleteCollection($collection->getId());
|
||||
} else {
|
||||
$this->deleteByGroup($collection->getId(), [], database: $dbForProject);
|
||||
}
|
||||
}
|
||||
|
||||
if ($dsn->getHost() === DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$collectionsIds = \array_map(fn ($collection) => $collection->getId(), $collections);
|
||||
|
||||
if (empty(\array_diff($collectionsIds, $projectCollectionIds))) {
|
||||
|
@ -554,7 +554,7 @@ class Deletes extends Action
|
|||
], $dbForConsole);
|
||||
|
||||
// Delete metadata table
|
||||
if ($dsn->getHost() !== DATABASE_SHARED_TABLES) {
|
||||
if ($dsn->getHost() !== System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$dbForProject->deleteCollection('_metadata');
|
||||
} else {
|
||||
$this->deleteByGroup('_metadata', [], $dbForProject);
|
||||
|
|
|
@ -399,7 +399,10 @@ class Messaging extends Action
|
|||
'credentials' => match ($host) {
|
||||
'twilio' => [
|
||||
'accountSid' => $user,
|
||||
'authToken' => $password
|
||||
'authToken' => $password,
|
||||
// Twilio Messaging Service SIDs always start with MG
|
||||
// https://www.twilio.com/docs/messaging/services
|
||||
'messagingServiceSid' => \str_starts_with($from, 'MG') ? $from : null
|
||||
],
|
||||
'textmagic' => [
|
||||
'username' => $user,
|
||||
|
@ -420,9 +423,14 @@ class Messaging extends Action
|
|||
],
|
||||
default => null
|
||||
},
|
||||
'options' => [
|
||||
'options' => match ($host) {
|
||||
'twilio' => [
|
||||
'from' => \str_starts_with($from, 'MG') ? null : $from
|
||||
],
|
||||
default => [
|
||||
'from' => $from
|
||||
]
|
||||
}
|
||||
]);
|
||||
|
||||
$adapter = $this->getSmsAdapter($provider);
|
||||
|
@ -465,7 +473,7 @@ class Messaging extends Action
|
|||
|
||||
return match ($provider->getAttribute('provider')) {
|
||||
'mock' => new Mock('username', 'password'),
|
||||
'twilio' => new Twilio($credentials['accountSid'], $credentials['authToken']),
|
||||
'twilio' => new Twilio($credentials['accountSid'], $credentials['authToken'], null, isset($credentials['messagingServiceSid']) ? $credentials['messagingServiceSid'] : null),
|
||||
'textmagic' => new TextMagic($credentials['username'], $credentials['apiKey']),
|
||||
'telesign' => new Telesign($credentials['customerId'], $credentials['apiKey']),
|
||||
'msg91' => new Msg91($credentials['senderId'], $credentials['authKey'], $credentials['templateId']),
|
||||
|
|
|
@ -31,7 +31,7 @@ class HTTPTest extends Scope
|
|||
$this->assertEquals(204, $response['headers']['status-code']);
|
||||
$this->assertEquals('Appwrite', $response['headers']['server']);
|
||||
$this->assertEquals('GET, POST, PUT, PATCH, DELETE', $response['headers']['access-control-allow-methods']);
|
||||
$this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-Appwrite-Shared-Tables, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']);
|
||||
$this->assertEquals('Origin, Cookie, Set-Cookie, X-Requested-With, Content-Type, Access-Control-Allow-Origin, Access-Control-Request-Headers, Accept, X-Appwrite-Project, X-Appwrite-Key, X-Appwrite-Locale, X-Appwrite-Mode, X-Appwrite-JWT, X-Appwrite-Response-Format, X-Appwrite-Timeout, X-SDK-Version, X-SDK-Name, X-SDK-Language, X-SDK-Platform, X-SDK-GraphQL, X-Appwrite-ID, X-Appwrite-Timestamp, Content-Range, Range, Cache-Control, Expires, Pragma, X-Appwrite-Session, X-Fallback-Cookies, X-Forwarded-For, X-Forwarded-User-Agent', $response['headers']['access-control-allow-headers']);
|
||||
$this->assertEquals('X-Appwrite-Session, X-Fallback-Cookies', $response['headers']['access-control-expose-headers']);
|
||||
$this->assertEquals('http://localhost', $response['headers']['access-control-allow-origin']);
|
||||
$this->assertEquals('true', $response['headers']['access-control-allow-credentials']);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Tests\E2E\Services\Functions;
|
||||
|
||||
use Appwrite\Tests\Retry;
|
||||
use CURLFile;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
|
@ -42,6 +43,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
return [];
|
||||
}
|
||||
|
||||
#[Retry(count: 2)]
|
||||
public function testCreateExecution(): array
|
||||
{
|
||||
/**
|
||||
|
@ -164,7 +166,7 @@ class FunctionsCustomClientTest extends Scope
|
|||
$this->assertEquals(202, $execution['headers']['status-code']);
|
||||
|
||||
// Wait for the first scheduled execution to be created
|
||||
sleep(65);
|
||||
sleep(90);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions', [
|
||||
'content-type' => 'application/json',
|
||||
|
|
|
@ -988,7 +988,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals($executions['body']['executions'][0]['logs'], '');
|
||||
$this->assertStringContainsString('timed out', $executions['body']['executions'][0]['errors']);
|
||||
|
||||
sleep(70); //wait for scheduled execution to be created and time out
|
||||
sleep(75); // Wait for scheduled execution to be created and time out
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
@ -999,12 +999,6 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertCount(2, $executions['body']['executions']);
|
||||
$this->assertIsArray($executions['body']['executions']);
|
||||
$this->assertEquals($executions['body']['executions'][1]['trigger'], 'schedule');
|
||||
$this->assertEquals($executions['body']['executions'][1]['status'], 'failed');
|
||||
$this->assertEquals($executions['body']['executions'][1]['responseStatusCode'], 500);
|
||||
$this->assertLessThan(20, $executions['body']['executions'][1]['duration']);
|
||||
$this->assertEquals($executions['body']['executions'][1]['responseBody'], '');
|
||||
$this->assertEquals($executions['body']['executions'][1]['logs'], '');
|
||||
$this->assertStringContainsString('timed out', $executions['body']['executions'][1]['errors']);
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
|
|
|
@ -455,7 +455,7 @@ class HealthCustomServerTest extends Scope
|
|||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals('/CN=www.google.com', $response['body']['name']);
|
||||
$this->assertEquals('www.google.com', $response['body']['subjectSN']);
|
||||
$this->assertEquals('Google Trust Services LLC', $response['body']['issuerOrganisation']);
|
||||
$this->assertStringContainsString('Google Trust Services', $response['body']['issuerOrganisation']);
|
||||
$this->assertIsInt($response['body']['validFrom']);
|
||||
$this->assertIsInt($response['body']['validTo']);
|
||||
|
||||
|
|
|
@ -511,6 +511,55 @@ trait MessagingBase
|
|||
];
|
||||
}
|
||||
|
||||
public function testSubscriberTargetSubQuery()
|
||||
{
|
||||
$response = $this->client->call(Client::METHOD_POST, '/messaging/topics', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'topicId' => 'sub-query-test',
|
||||
'name' => 'sub-query-test',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
$topic = $response['body'];
|
||||
|
||||
$prefix = uniqid();
|
||||
|
||||
for ($i = 1; $i <= 101; $i++) {
|
||||
$response = $this->client->call(Client::METHOD_POST, '/users', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
], [
|
||||
'userId' => "$prefix-$i",
|
||||
'email' => "$prefix-$i@example.com",
|
||||
'password' => 'password',
|
||||
'name' => "User $prefix $i",
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$user = $response['body'];
|
||||
$targets = $user['targets'] ?? [];
|
||||
|
||||
$this->assertGreaterThan(0, count($targets));
|
||||
|
||||
$target = $targets[0];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/messaging/topics/' . $topic['$id'] . '/subscribers', \array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'subscriberId' => $user['$id'],
|
||||
'targetId' => $target['$id'],
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateSubscriber
|
||||
*/
|
||||
|
|
|
@ -9,7 +9,6 @@ use Tests\E2E\General\UsageTest;
|
|||
use Tests\E2E\Scopes\ProjectConsole;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideClient;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
|
@ -3494,504 +3493,4 @@ class ProjectsConsoleClientTest extends Scope
|
|||
|
||||
return $data;
|
||||
}
|
||||
|
||||
public function testTenantIsolation(): void
|
||||
{
|
||||
// Create a team and a project
|
||||
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'teamId' => ID::unique(),
|
||||
'name' => 'Amazing Team',
|
||||
]);
|
||||
|
||||
$teamId = $team['body']['$id'];
|
||||
|
||||
// Project-level isolation
|
||||
$project1 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-shared-tables' => false
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project',
|
||||
'teamId' => $teamId,
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
// Application level isolation (shared tables)
|
||||
$project2 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-shared-tables' => true
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project',
|
||||
'teamId' => $teamId,
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
// Project-level isolation
|
||||
$project3 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-shared-tables' => false
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project',
|
||||
'teamId' => $teamId,
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
// Application level isolation (shared tables)
|
||||
$project4 = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-shared-tables' => true
|
||||
], $this->getHeaders()), [
|
||||
'projectId' => ID::unique(),
|
||||
'name' => 'Amazing Project',
|
||||
'teamId' => $teamId,
|
||||
'region' => 'default'
|
||||
]);
|
||||
|
||||
// Create and API key in each project
|
||||
$key1 = $this->client->call(Client::METHOD_POST, '/projects/' . $project1['body']['$id'] . '/keys', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Key Test',
|
||||
'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'],
|
||||
]);
|
||||
|
||||
$key2 = $this->client->call(Client::METHOD_POST, '/projects/' . $project2['body']['$id'] . '/keys', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Key Test',
|
||||
'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'],
|
||||
]);
|
||||
|
||||
$key3 = $this->client->call(Client::METHOD_POST, '/projects/' . $project3['body']['$id'] . '/keys', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Key Test',
|
||||
'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'],
|
||||
]);
|
||||
|
||||
$key4 = $this->client->call(Client::METHOD_POST, '/projects/' . $project4['body']['$id'] . '/keys', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'name' => 'Key Test',
|
||||
'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.read', 'attributes.write', 'indexes.read', 'indexes.write', 'documents.read', 'documents.write', 'users.read', 'users.write'],
|
||||
]);
|
||||
|
||||
// Create a database in each project
|
||||
$database1 = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Amazing Database',
|
||||
]);
|
||||
|
||||
$database2 = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Amazing Database',
|
||||
]);
|
||||
|
||||
$database3 = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Amazing Database',
|
||||
]);
|
||||
|
||||
$database4 = $this->client->call(Client::METHOD_POST, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
], [
|
||||
'databaseId' => ID::unique(),
|
||||
'name' => 'Amazing Database',
|
||||
]);
|
||||
|
||||
// Create a collection in each project
|
||||
$collection1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database1['body']['$id'],
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Amazing Collection',
|
||||
]);
|
||||
|
||||
$collection2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database2['body']['$id'],
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Amazing Collection',
|
||||
]);
|
||||
|
||||
$collection3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database3['body']['$id'],
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Amazing Collection',
|
||||
]);
|
||||
|
||||
$collection4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database4['body']['$id'],
|
||||
'collectionId' => ID::unique(),
|
||||
'name' => 'Amazing Collection',
|
||||
]);
|
||||
|
||||
// Create an attribute in each project
|
||||
$attribute1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes/string', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database1['body']['$id'],
|
||||
'collectionId' => $collection1['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'size' => 255,
|
||||
'required' => true
|
||||
]);
|
||||
|
||||
$attribute2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes/string', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database2['body']['$id'],
|
||||
'collectionId' => $collection2['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'size' => 255,
|
||||
'required' => true
|
||||
]);
|
||||
|
||||
$attribute3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes/string', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database3['body']['$id'],
|
||||
'collectionId' => $collection3['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'size' => 255,
|
||||
'required' => true
|
||||
]);
|
||||
|
||||
$attribute4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes/string', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database4['body']['$id'],
|
||||
'collectionId' => $collection4['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'size' => 255,
|
||||
'required' => true
|
||||
]);
|
||||
|
||||
// Wait for attributes
|
||||
\sleep(2);
|
||||
|
||||
// Create an index in each project
|
||||
$index1 = $this->client->call(Client::METHOD_POST, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database1['body']['$id'],
|
||||
'collectionId' => $collection1['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => [$attribute1['body']['key']],
|
||||
]);
|
||||
|
||||
$index2 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database2['body']['$id'],
|
||||
'collectionId' => $collection2['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => [$attribute2['body']['key']],
|
||||
]);
|
||||
|
||||
$index3 = $this->client->call(Client::METHOD_POST, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database3['body']['$id'],
|
||||
'collectionId' => $collection3['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => [$attribute3['body']['key']],
|
||||
]);
|
||||
|
||||
$index4 = $this->client->call(Client::METHOD_POST, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database4['body']['$id'],
|
||||
'collectionId' => $collection4['body']['$id'],
|
||||
'key' => ID::unique(),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => [$attribute4['body']['key']],
|
||||
]);
|
||||
|
||||
// Wait for indexes
|
||||
\sleep(2);
|
||||
|
||||
// Assert that each project has only 1 database, 1 collection, 1 attribute and 1 index
|
||||
$databasesProject1 = $this->client->call(Client::METHOD_GET, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $databasesProject1['body']['total']);
|
||||
$this->assertEquals(1, \count($databasesProject1['body']['databases']));
|
||||
|
||||
$databasesProject2 = $this->client->call(Client::METHOD_GET, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $databasesProject2['body']['total']);
|
||||
$this->assertEquals(1, \count($databasesProject2['body']['databases']));
|
||||
|
||||
$databasesProject3 = $this->client->call(Client::METHOD_GET, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $databasesProject3['body']['total']);
|
||||
$this->assertEquals(1, \count($databasesProject3['body']['databases']));
|
||||
|
||||
$databasesProject4 = $this->client->call(Client::METHOD_GET, '/databases', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $databasesProject4['body']['total']);
|
||||
$this->assertEquals(1, \count($databasesProject4['body']['databases']));
|
||||
|
||||
$collectionsProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $collectionsProject1['body']['total']);
|
||||
$this->assertEquals(1, \count($collectionsProject1['body']['collections']));
|
||||
|
||||
$collectionsProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $collectionsProject2['body']['total']);
|
||||
$this->assertEquals(1, \count($collectionsProject2['body']['collections']));
|
||||
|
||||
$collectionsProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $collectionsProject3['body']['total']);
|
||||
$this->assertEquals(1, \count($collectionsProject3['body']['collections']));
|
||||
|
||||
$collectionsProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $collectionsProject4['body']['total']);
|
||||
$this->assertEquals(1, \count($collectionsProject4['body']['collections']));
|
||||
|
||||
$attributesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/attributes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $attributesProject1['body']['total']);
|
||||
$this->assertEquals(1, \count($attributesProject1['body']['attributes']));
|
||||
$this->assertEquals('available', $attributesProject1['body']['attributes'][0]['status']);
|
||||
|
||||
$attributesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/attributes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $attributesProject2['body']['total']);
|
||||
$this->assertEquals(1, \count($attributesProject2['body']['attributes']));
|
||||
$this->assertEquals('available', $attributesProject2['body']['attributes'][0]['status']);
|
||||
|
||||
$attributesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/attributes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $attributesProject3['body']['total']);
|
||||
$this->assertEquals(1, \count($attributesProject3['body']['attributes']));
|
||||
$this->assertEquals('available', $attributesProject3['body']['attributes'][0]['status']);
|
||||
|
||||
$attributesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/attributes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $attributesProject4['body']['total']);
|
||||
$this->assertEquals(1, \count($attributesProject4['body']['attributes']));
|
||||
$this->assertEquals('available', $attributesProject4['body']['attributes'][0]['status']);
|
||||
|
||||
$indexesProject1 = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $indexesProject1['body']['total']);
|
||||
$this->assertEquals(1, \count($indexesProject1['body']['indexes']));
|
||||
|
||||
$indexesProject2 = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $indexesProject2['body']['total']);
|
||||
$this->assertEquals(1, \count($indexesProject2['body']['indexes']));
|
||||
|
||||
$indexesProject3 = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $indexesProject3['body']['total']);
|
||||
$this->assertEquals(1, \count($indexesProject3['body']['indexes']));
|
||||
|
||||
$indexesProject4 = $this->client->call(Client::METHOD_GET, '/databases/' . $database4['body']['$id'] . '/collections/' . $collection4['body']['$id'] . '/indexes', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(1, $indexesProject4['body']['total']);
|
||||
$this->assertEquals(1, \count($indexesProject4['body']['indexes']));
|
||||
|
||||
// Attempt to read cross-type resources
|
||||
$collectionProject2WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database2['body']['$id'] . '/collections/' . $collection2['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $collectionProject2WithProject1Key['headers']['status-code']);
|
||||
|
||||
$collectionProject1WithProject2Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $collectionProject1WithProject2Key['headers']['status-code']);
|
||||
|
||||
// Attempt to read cross-tenant resources
|
||||
$collectionProject3WithProject1Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database3['body']['$id'] . '/collections/' . $collection3['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project1['body']['$id'],
|
||||
'x-appwrite-key' => $key1['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $collectionProject3WithProject1Key['headers']['status-code']);
|
||||
|
||||
$collectionProject1WithProject3Key = $this->client->call(Client::METHOD_GET, '/databases/' . $database1['body']['$id'] . '/collections/' . $collection1['body']['$id'], [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project3['body']['$id'],
|
||||
'x-appwrite-key' => $key3['body']['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(404, $collectionProject1WithProject3Key['headers']['status-code']);
|
||||
|
||||
// Assert that shared project resources can have the same ID as they're unique on tenant + ID not just ID
|
||||
$collection5 = $this->client->call(Client::METHOD_POST, '/databases/' . $database2['body']['$id'] . '/collections', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
], [
|
||||
'databaseId' => $database2['body']['$id'],
|
||||
'collectionId' => $collection4['body']['$id'],
|
||||
'name' => 'Amazing Collection',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $collection5['headers']['status-code']);
|
||||
|
||||
// Assert that users across projects on shared tables can have the same email as they're unique on tenant + email not just email
|
||||
$user1 = $this->client->call(Client::METHOD_POST, '/users', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project2['body']['$id'],
|
||||
'x-appwrite-key' => $key2['body']['secret']
|
||||
], [
|
||||
'userId' => 'user',
|
||||
'email' => 'test@appwrite.io',
|
||||
'password' => 'password',
|
||||
'name' => 'Test User',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $user1['headers']['status-code']);
|
||||
|
||||
$user2 = $this->client->call(Client::METHOD_POST, '/users', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $project4['body']['$id'],
|
||||
'x-appwrite-key' => $key4['body']['secret']
|
||||
], [
|
||||
'userId' => 'user',
|
||||
'email' => 'test@appwrite.io',
|
||||
'password' => 'password',
|
||||
'name' => 'Test User',
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $user2['headers']['status-code']);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -225,7 +225,7 @@ trait StorageBase
|
|||
'bucketId' => ID::unique(),
|
||||
'name' => 'Test Bucket 2',
|
||||
'fileSecurity' => true,
|
||||
'maximumFileSize' => 200000000, //200MB
|
||||
'maximumFileSize' => 6000000000, //6GB
|
||||
'allowedFileExtensions' => ["jpg", "png"],
|
||||
'permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
|
|
|
@ -290,6 +290,28 @@ trait UsersBase
|
|||
$this->assertArrayNotHasKey('secret', $token['body']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateUser
|
||||
*/
|
||||
public function testCreateSession(array $data): void
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_POST, '/users/' . $data['userId'] . '/sessions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
$session = $response['body'];
|
||||
$this->assertEquals($data['userId'], $session['userId']);
|
||||
$this->assertNotEmpty($session['secret']);
|
||||
$this->assertNotEmpty($session['expire']);
|
||||
$this->assertEquals('server', $session['provider']);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests all optional parameters of createUser (email, phone, anonymous..)
|
||||
|
@ -986,7 +1008,7 @@ trait UsersBase
|
|||
'password' => 'password'
|
||||
]);
|
||||
|
||||
$this->assertEquals($session['headers']['status-code'], 401);
|
||||
$this->assertEquals(401, $session['headers']['status-code']);
|
||||
|
||||
$user = $this->client->call(Client::METHOD_PATCH, '/users/' . $data['userId'] . '/password', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
|
Loading…
Reference in a new issue