mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Compare commits
69
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f1b3a8e30 | ||
|
|
3d8cee4676 | ||
|
|
7efbae4310 | ||
|
|
1c9fd39fd6 | ||
|
|
8c854b7d07 | ||
|
|
c713357131 | ||
|
|
fe9ecb6fcb | ||
|
|
ab1541808b | ||
|
|
623a8a747d | ||
|
|
21237f8e02 | ||
|
|
f0ed75f585 | ||
|
|
34ce5099e2 | ||
|
|
10171c80da | ||
|
|
c6e4afdb49 | ||
|
|
448e60479d | ||
|
|
8fe7de7ff9 | ||
|
|
8e70a5239d | ||
|
|
28beb27759 | ||
|
|
b1f5b6946a | ||
|
|
9ac594c537 | ||
|
|
6547637c96 | ||
|
|
13a7ead598 | ||
|
|
d40e793137 | ||
|
|
e5fa23ef6c | ||
|
|
053665eef9 | ||
|
|
66afd1064d | ||
|
|
e2758691af | ||
|
|
9a8a42f479 | ||
|
|
3347573f17 | ||
|
|
cceb108fd3 | ||
|
|
b905686c0e | ||
|
|
ad43be5dab | ||
|
|
ceb11e039f | ||
|
|
63e06750cf | ||
|
|
a4f7cf9f73 | ||
|
|
ba10bed271 | ||
|
|
e2979410da | ||
|
|
9b68b54743 | ||
|
|
0fbdbb386f | ||
|
|
50f26e8702 | ||
|
|
a2463f8cc3 | ||
|
|
0cdabbf959 | ||
|
|
4b752c15e8 | ||
|
|
fcce6f8d34 | ||
|
|
2443266ac5 | ||
|
|
4616a2e95d | ||
|
|
9a0e1c1840 | ||
|
|
bdbe94b56f | ||
|
|
0974e1335f | ||
|
|
61f8c99da7 | ||
|
|
150d09f656 | ||
|
|
bfce804f79 | ||
|
|
a479ce63fc | ||
|
|
8765d5650a | ||
|
|
e3ee724178 | ||
|
|
ce2f2d0ebc | ||
|
|
9f7e3146a4 | ||
|
|
e6039cf65e | ||
|
|
3d69998f9c | ||
|
|
d2000ee9d8 | ||
|
|
0718f90405 | ||
|
|
73f5b4227d | ||
|
|
52766cfdba | ||
|
|
ba542554ce | ||
|
|
d36e42377b | ||
|
|
d9522ac6b8 | ||
|
|
b20c493fa6 | ||
|
|
b91268b3cd | ||
|
|
64b4ea9551 |
+10
-18
@@ -40,6 +40,8 @@ Config::setParam('runtimes', (new Runtimes('v5'))->getAll(supported: false));
|
||||
// require controllers after overwriting runtimes
|
||||
require_once __DIR__ . '/controllers/general.php';
|
||||
|
||||
Authorization::disable();
|
||||
|
||||
CLI::setResource('register', fn () => $register);
|
||||
|
||||
CLI::setResource('cache', function ($pools) {
|
||||
@@ -57,13 +59,7 @@ CLI::setResource('pools', function (Registry $register) {
|
||||
return $register->get('pools');
|
||||
}, ['register']);
|
||||
|
||||
CLI::setResource('authorization', function () {
|
||||
$authorization = new Authorization();
|
||||
$authorization->disable();
|
||||
return $authorization;
|
||||
}, []);
|
||||
|
||||
CLI::setResource('dbForPlatform', function ($pools, $cache, $authorization) {
|
||||
CLI::setResource('dbForPlatform', function ($pools, $cache) {
|
||||
$sleep = 3;
|
||||
$maxAttempts = 5;
|
||||
$attempts = 0;
|
||||
@@ -77,7 +73,6 @@ CLI::setResource('dbForPlatform', function ($pools, $cache, $authorization) {
|
||||
$dbForPlatform = new Database($adapter, $cache);
|
||||
|
||||
$dbForPlatform
|
||||
->setAuthorization($authorization)
|
||||
->setNamespace('_console')
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', 'console');
|
||||
@@ -102,7 +97,7 @@ CLI::setResource('dbForPlatform', function ($pools, $cache, $authorization) {
|
||||
}
|
||||
|
||||
return $dbForPlatform;
|
||||
}, ['pools', 'cache', 'authorization']);
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
CLI::setResource('console', function () {
|
||||
return new Document(Config::getParam('console'));
|
||||
@@ -113,10 +108,10 @@ CLI::setResource(
|
||||
fn () => fn (Document $project, string $resourceType, ?string $resourceId) => false
|
||||
);
|
||||
|
||||
CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache, $authorization) {
|
||||
CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) {
|
||||
$databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools
|
||||
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, $authorization, &$databases) {
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, &$databases) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
@@ -149,7 +144,6 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
|
||||
|
||||
$adapter = new DatabasePool($pools->get($dsn->getHost()));
|
||||
$database = new Database($adapter, $cache);
|
||||
|
||||
$databases[$dsn->getHost()] = $database;
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
|
||||
@@ -166,18 +160,17 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
|
||||
}
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId());
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'dbForPlatform', 'cache', 'authorization']);
|
||||
}, ['pools', 'dbForPlatform', 'cache']);
|
||||
|
||||
CLI::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorization $authorization) {
|
||||
CLI::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database = null;
|
||||
|
||||
return function (?Document $project = null) use ($pools, $cache, $database, $authorization) {
|
||||
return function (?Document $project = null) use ($pools, $cache, $database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant((int)$project->getSequence());
|
||||
return $database;
|
||||
@@ -187,7 +180,6 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizatio
|
||||
$database = new Database($adapter, $cache);
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_TASK)
|
||||
@@ -200,7 +192,7 @@ CLI::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizatio
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'cache', 'authorization']);
|
||||
}, ['pools', 'cache']);
|
||||
CLI::setResource('publisher', function (Group $pools) {
|
||||
return new BrokerPool(publisher: $pools->get('publisher'));
|
||||
}, ['pools']);
|
||||
|
||||
@@ -215,7 +215,7 @@ return [
|
||||
'key' => 'ssr',
|
||||
'buildCommand' => 'npm run build',
|
||||
'installCommand' => 'npm install',
|
||||
'outputDirectory' => './dist',
|
||||
'outputDirectory' => './.output',
|
||||
'startCommand' => 'bash helpers/tanstack-start/server.sh',
|
||||
],
|
||||
'static' => [
|
||||
|
||||
@@ -60,7 +60,7 @@ return [
|
||||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '20.3.1',
|
||||
'version' => '20.3.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
@@ -226,7 +226,7 @@ return [
|
||||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '11.1.1',
|
||||
'version' => '12.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite-cli',
|
||||
'enabled' => true,
|
||||
|
||||
@@ -47,10 +47,10 @@ return [ // List of publicly visible scopes
|
||||
'description' => 'Access to create, update, and delete your project\'s database table\'s columns',
|
||||
],
|
||||
'indexes.read' => [
|
||||
'description' => 'Access to read your project\'s database collection\'s indexes',
|
||||
'description' => 'Access to read your project\'s database table\'s indexes',
|
||||
],
|
||||
'indexes.write' => [
|
||||
'description' => 'Access to create, update, and delete your project\'s database collection\'s indexes',
|
||||
'description' => 'Access to create, update, and delete your project\'s database table\'s indexes',
|
||||
],
|
||||
'documents.read' => [
|
||||
'description' => 'Access to read your project\'s database documents',
|
||||
|
||||
@@ -14424,7 +14424,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -14524,7 +14524,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32337,7 +32337,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32438,7 +32438,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -13213,7 +13213,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -13314,7 +13314,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -22861,7 +22861,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -22963,7 +22963,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -14424,7 +14424,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -14524,7 +14524,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32337,7 +32337,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32438,7 +32438,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -13213,7 +13213,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -13314,7 +13314,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -22861,7 +22861,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -22963,7 +22963,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -14366,7 +14366,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -14467,7 +14467,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32441,7 +32441,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32543,7 +32543,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -13182,7 +13182,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -13284,7 +13284,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -23014,7 +23014,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -23117,7 +23117,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -14366,7 +14366,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -14467,7 +14467,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32441,7 +32441,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -32543,7 +32543,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -13182,7 +13182,7 @@
|
||||
"branch",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -13284,7 +13284,7 @@
|
||||
"branch",
|
||||
"commit"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -23014,7 +23014,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": null,
|
||||
"x-enum-name": "TemplateReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
@@ -23117,7 +23117,7 @@
|
||||
"commit",
|
||||
"tag"
|
||||
],
|
||||
"x-enum-name": "VCSDeploymentType",
|
||||
"x-enum-name": "VCSReferenceType",
|
||||
"x-enum-keys": []
|
||||
},
|
||||
"reference": {
|
||||
|
||||
@@ -3,6 +3,4 @@
|
||||
use Utopia\Image\Image;
|
||||
use Utopia\System\System;
|
||||
|
||||
if (\class_exists('Imagick')) {
|
||||
Image::setResourceLimit('memory', intval(System::getEnv('_APP_IMAGES_RESOURCE_LIMIT_MEMORY', 1024*1024*64)));
|
||||
}
|
||||
Image::setResourceLimit('memory', intval(System::getEnv('_APP_IMAGES_RESOURCE_LIMIT_MEMORY', 1024*1024*64)));
|
||||
|
||||
+59
-1019
File diff suppressed because it is too large
Load Diff
@@ -70,9 +70,9 @@ $avatarCallback = function (string $type, string $code, int $width, int $height,
|
||||
unset($image);
|
||||
};
|
||||
|
||||
$getUserGitHub = function (string $userId, Document $project, Database $dbForProject, Database $dbForPlatform, Authorization $authorization, ?Logger $logger) {
|
||||
$getUserGitHub = function (string $userId, Document $project, Database $dbForProject, Database $dbForPlatform, ?Logger $logger) {
|
||||
try {
|
||||
$user = $authorization->skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
$user = Authorization::skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
|
||||
@@ -123,7 +123,7 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro
|
||||
->setAttribute('providerRefreshToken', $refreshToken)
|
||||
->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$oauth2->getAccessTokenExpiry('')));
|
||||
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('sessions', $gitHubSession->getId(), $gitHubSession));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('sessions', $gitHubSession->getId(), $gitHubSession));
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
} catch (Throwable $err) {
|
||||
@@ -131,7 +131,7 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro
|
||||
do {
|
||||
$previousAccessToken = $gitHubSession->getAttribute('providerAccessToken');
|
||||
|
||||
$user = $authorization->skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
$user = Authorization::skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
|
||||
$gitHubSession = new Document();
|
||||
@@ -841,9 +841,8 @@ App::get('/v1/cards/cloud')
|
||||
->inject('contributors')
|
||||
->inject('employees')
|
||||
->inject('logger')
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForPlatform, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger, Authorization $authorization) use ($getUserGitHub) {
|
||||
$user = $authorization->skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForPlatform, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger) use ($getUserGitHub) {
|
||||
$user = Authorization::skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
|
||||
if ($user->isEmpty() && empty($mock)) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
@@ -854,7 +853,7 @@ App::get('/v1/cards/cloud')
|
||||
$email = $user->getAttribute('email', '');
|
||||
$createdAt = new \DateTime($user->getCreatedAt());
|
||||
|
||||
$gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForPlatform, $logger, $authorization);
|
||||
$gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForPlatform, $logger);
|
||||
$githubName = $gitHub['name'] ?? '';
|
||||
$githubId = $gitHub['id'] ?? '';
|
||||
|
||||
@@ -1049,9 +1048,8 @@ App::get('/v1/cards/cloud-back')
|
||||
->inject('contributors')
|
||||
->inject('employees')
|
||||
->inject('logger')
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForPlatform, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger, Authorization $authorization) use ($getUserGitHub) {
|
||||
$user = $authorization->skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForPlatform, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger) use ($getUserGitHub) {
|
||||
$user = Authorization::skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
|
||||
if ($user->isEmpty() && empty($mock)) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
@@ -1061,7 +1059,7 @@ App::get('/v1/cards/cloud-back')
|
||||
$userId = $user->getId();
|
||||
$email = $user->getAttribute('email', '');
|
||||
|
||||
$gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForPlatform, $logger, $authorization);
|
||||
$gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForPlatform, $logger);
|
||||
$githubId = $gitHub['id'] ?? '';
|
||||
|
||||
$isHero = \array_key_exists($email, $heroes);
|
||||
@@ -1128,9 +1126,8 @@ App::get('/v1/cards/cloud-og')
|
||||
->inject('contributors')
|
||||
->inject('employees')
|
||||
->inject('logger')
|
||||
->inject('authorization')
|
||||
->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForPlatform, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger, Authorization $authorization) use ($getUserGitHub) {
|
||||
$user = $authorization->skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
->action(function (string $userId, string $mock, int $width, int $height, Document $user, Document $project, Database $dbForProject, Database $dbForPlatform, Response $response, array $heroes, array $contributors, array $employees, ?Logger $logger) use ($getUserGitHub) {
|
||||
$user = Authorization::skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
|
||||
if ($user->isEmpty() && empty($mock)) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
@@ -1145,7 +1142,7 @@ App::get('/v1/cards/cloud-og')
|
||||
$email = $user->getAttribute('email', '');
|
||||
$createdAt = new \DateTime($user->getCreatedAt());
|
||||
|
||||
$gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForPlatform, $logger, $authorization);
|
||||
$gitHub = $getUserGitHub($user->getId(), $project, $dbForProject, $dbForPlatform, $logger);
|
||||
$githubName = $gitHub['name'] ?? '';
|
||||
$githubId = $gitHub['id'] ?? '';
|
||||
|
||||
|
||||
@@ -28,12 +28,11 @@ use Utopia\Validator\Text;
|
||||
App::init()
|
||||
->groups(['graphql'])
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->action(function (Document $project, Authorization $authorization) {
|
||||
->action(function (Document $project) {
|
||||
if (
|
||||
array_key_exists('graphql', $project->getAttribute('apis', []))
|
||||
&& !$project->getAttribute('apis', [])['graphql']
|
||||
&& !(Auth::isPrivilegedUser($authorization->getRoles()) || Auth::isAppUser($authorization->getRoles()))
|
||||
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
|
||||
) {
|
||||
throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED);
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Authorization\Input;
|
||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||
use Utopia\Database\Validator\Queries;
|
||||
use Utopia\Database\Validator\Query\Cursor;
|
||||
@@ -1071,9 +1070,8 @@ App::get('/v1/messaging/providers')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('response')
|
||||
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Authorization $authorization, Response $response) {
|
||||
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
@@ -1099,7 +1097,7 @@ App::get('/v1/messaging/providers')
|
||||
}
|
||||
|
||||
$providerId = $cursor->getValue();
|
||||
$cursorDocument = $authorization->skip(fn () => $dbForProject->getDocument('providers', $providerId));
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('providers', $providerId));
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Provider '{$providerId}' for the 'cursor' value not found.");
|
||||
@@ -2479,9 +2477,8 @@ App::get('/v1/messaging/topics')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('response')
|
||||
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Authorization $authorization, Response $response) {
|
||||
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
@@ -2507,7 +2504,7 @@ App::get('/v1/messaging/topics')
|
||||
}
|
||||
|
||||
$topicId = $cursor->getValue();
|
||||
$cursorDocument = $authorization->skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Topic '{$topicId}' for the 'cursor' value not found.");
|
||||
@@ -2783,27 +2780,29 @@ App::post('/v1/messaging/topics/:topicId/subscribers')
|
||||
->param('targetId', '', new UID(), 'Target ID. The target ID to link to the specified Topic ID.')
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('response')
|
||||
->action(function (string $subscriberId, string $topicId, string $targetId, Event $queueForEvents, Database $dbForProject, Authorization $authorization, Response $response) {
|
||||
->action(function (string $subscriberId, string $topicId, string $targetId, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$subscriberId = $subscriberId == 'unique()' ? ID::unique() : $subscriberId;
|
||||
|
||||
$topic = $authorization->skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
$topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
|
||||
if ($topic->isEmpty()) {
|
||||
throw new Exception(Exception::TOPIC_NOT_FOUND);
|
||||
}
|
||||
if (!$authorization->isValid(new Input('subscribe', $topic->getAttribute('subscribe')))) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
|
||||
$validator = new Authorization('subscribe');
|
||||
|
||||
if (!$validator->isValid($topic->getAttribute('subscribe'))) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $validator->getDescription());
|
||||
}
|
||||
|
||||
$target = $authorization->skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
$target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $targetId));
|
||||
|
||||
if ($target->isEmpty()) {
|
||||
throw new Exception(Exception::USER_TARGET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$user = $authorization->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId')));
|
||||
$user = Authorization::skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId')));
|
||||
|
||||
$subscriber = new Document([
|
||||
'$id' => $subscriberId,
|
||||
@@ -2836,7 +2835,7 @@ App::post('/v1/messaging/topics/:topicId/subscribers')
|
||||
default => throw new Exception(Exception::TARGET_PROVIDER_INVALID_TYPE),
|
||||
};
|
||||
|
||||
$authorization->skip(fn () => $dbForProject->increaseDocumentAttribute(
|
||||
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute(
|
||||
'topics',
|
||||
$topicId,
|
||||
$totalAttribute,
|
||||
@@ -2881,9 +2880,8 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('response')
|
||||
->action(function (string $topicId, array $queries, string $search, bool $includeTotal, Database $dbForProject, Authorization $authorization, Response $response) {
|
||||
->action(function (string $topicId, array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
@@ -2894,7 +2892,7 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
$queries[] = Query::search('search', $search);
|
||||
}
|
||||
|
||||
$topic = $authorization->skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
$topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
|
||||
if ($topic->isEmpty()) {
|
||||
throw new Exception(Exception::TOPIC_NOT_FOUND);
|
||||
@@ -2917,7 +2915,7 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
}
|
||||
|
||||
$subscriberId = $cursor->getValue();
|
||||
$cursorDocument = $authorization->skip(fn () => $dbForProject->getDocument('subscribers', $subscriberId));
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('subscribers', $subscriberId));
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Subscriber '{$subscriberId}' for the 'cursor' value not found.");
|
||||
@@ -2931,10 +2929,10 @@ App::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
}
|
||||
|
||||
$subscribers = batch(\array_map(function (Document $subscriber) use ($dbForProject, $authorization) {
|
||||
return function () use ($subscriber, $dbForProject, $authorization) {
|
||||
$target = $authorization->skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId')));
|
||||
$user = $authorization->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId')));
|
||||
$subscribers = batch(\array_map(function (Document $subscriber) use ($dbForProject) {
|
||||
return function () use ($subscriber, $dbForProject) {
|
||||
$target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId')));
|
||||
$user = Authorization::skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId')));
|
||||
|
||||
return $subscriber
|
||||
->setAttribute('target', $target)
|
||||
@@ -3069,10 +3067,9 @@ App::get('/v1/messaging/topics/:topicId/subscribers/:subscriberId')
|
||||
->param('topicId', '', new UID(), 'Topic ID. The topic ID subscribed to.')
|
||||
->param('subscriberId', '', new UID(), 'Subscriber ID.')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('response')
|
||||
->action(function (string $topicId, string $subscriberId, Database $dbForProject, Authorization $authorization, Response $response) {
|
||||
$topic = $authorization->skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
->action(function (string $topicId, string $subscriberId, Database $dbForProject, Response $response) {
|
||||
$topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
|
||||
if ($topic->isEmpty()) {
|
||||
throw new Exception(Exception::TOPIC_NOT_FOUND);
|
||||
@@ -3084,8 +3081,8 @@ App::get('/v1/messaging/topics/:topicId/subscribers/:subscriberId')
|
||||
throw new Exception(Exception::SUBSCRIBER_NOT_FOUND);
|
||||
}
|
||||
|
||||
$target = $authorization->skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId')));
|
||||
$user = $authorization->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId')));
|
||||
$target = Authorization::skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId')));
|
||||
$user = Authorization::skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId')));
|
||||
|
||||
$subscriber
|
||||
->setAttribute('target', $target)
|
||||
@@ -3121,10 +3118,9 @@ App::delete('/v1/messaging/topics/:topicId/subscribers/:subscriberId')
|
||||
->param('subscriberId', '', new UID(), 'Subscriber ID.')
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('response')
|
||||
->action(function (string $topicId, string $subscriberId, Event $queueForEvents, Database $dbForProject, Authorization $authorization, Response $response) {
|
||||
$topic = $authorization->skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
->action(function (string $topicId, string $subscriberId, Event $queueForEvents, Database $dbForProject, Response $response) {
|
||||
$topic = Authorization::skip(fn () => $dbForProject->getDocument('topics', $topicId));
|
||||
|
||||
if ($topic->isEmpty()) {
|
||||
throw new Exception(Exception::TOPIC_NOT_FOUND);
|
||||
@@ -3147,7 +3143,7 @@ App::delete('/v1/messaging/topics/:topicId/subscribers/:subscriberId')
|
||||
default => throw new Exception(Exception::TARGET_PROVIDER_INVALID_TYPE),
|
||||
};
|
||||
|
||||
$authorization->skip(fn () => $dbForProject->decreaseDocumentAttribute(
|
||||
Authorization::skip(fn () => $dbForProject->decreaseDocumentAttribute(
|
||||
'topics',
|
||||
$topicId,
|
||||
$totalAttribute,
|
||||
@@ -3704,9 +3700,8 @@ App::get('/v1/messaging/messages')
|
||||
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('response')
|
||||
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Authorization $authorization, Response $response) {
|
||||
->action(function (array $queries, string $search, bool $includeTotal, Database $dbForProject, Response $response) {
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
@@ -3732,7 +3727,7 @@ App::get('/v1/messaging/messages')
|
||||
}
|
||||
|
||||
$messageId = $cursor->getValue();
|
||||
$cursorDocument = $authorization->skip(fn () => $dbForProject->getDocument('messages', $messageId));
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('messages', $messageId));
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Message '{$messageId}' for the 'cursor' value not found.");
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<?php
|
||||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Migration;
|
||||
use Appwrite\Extend\Exception;
|
||||
@@ -335,19 +334,26 @@ App::post('/v1/migrations/csv/imports')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
->inject('project')
|
||||
->inject('deviceForFiles')
|
||||
->inject('deviceForMigrations')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMigrations')
|
||||
->action(function (string $bucketId, string $fileId, string $resourceId, bool $internalFile, Response $response, Database $dbForProject, Database $dbForPlatform, Authorization $authorization, Document $project, Device $deviceForFiles, Device $deviceForMigrations, Event $queueForEvents, Migration $queueForMigrations) {
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
if ($internalFile && !$isPrivilegedUser) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
$bucket = $authorization->skip(function () use ($internalFile, $dbForPlatform, $dbForProject, $bucketId) {
|
||||
->action(function (
|
||||
string $bucketId,
|
||||
string $fileId,
|
||||
string $resourceId,
|
||||
bool $internalFile,
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Device $deviceForFiles,
|
||||
Device $deviceForMigrations,
|
||||
Event $queueForEvents,
|
||||
Migration $queueForMigrations
|
||||
) {
|
||||
$bucket = Authorization::skip(function () use ($internalFile, $dbForPlatform, $dbForProject, $bucketId) {
|
||||
if ($internalFile) {
|
||||
return $dbForPlatform->getDocument('buckets', 'default');
|
||||
}
|
||||
@@ -358,7 +364,7 @@ App::post('/v1/migrations/csv/imports')
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = $authorization->skip(fn () => $internalFile ? $dbForPlatform->getDocument('bucket_' . $bucket->getSequence(), $fileId) : $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $internalFile ? $dbForPlatform->getDocument('bucket_' . $bucket->getSequence(), $fileId) : $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
}
|
||||
@@ -474,7 +480,6 @@ App::post('/v1/migrations/csv/exports')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForMigrations')
|
||||
@@ -492,7 +497,6 @@ App::post('/v1/migrations/csv/exports')
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
Authorization $authorization,
|
||||
Document $project,
|
||||
Event $queueForEvents,
|
||||
Migration $queueForMigrations
|
||||
@@ -503,7 +507,7 @@ App::post('/v1/migrations/csv/exports')
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$bucket = $authorization->skip(fn () => $dbForPlatform->getDocument('buckets', 'default'));
|
||||
$bucket = Authorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'default'));
|
||||
if ($bucket->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
@@ -516,12 +520,12 @@ App::post('/v1/migrations/csv/exports')
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$database = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
if ($database->isEmpty()) {
|
||||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
$collection = $authorization->skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
$collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId));
|
||||
if ($collection->isEmpty()) {
|
||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
@@ -45,10 +45,9 @@ App::get('/v1/project/usage')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('getLogsDB')
|
||||
->inject('smsRates')
|
||||
->action(function (string $startDate, string $endDate, string $period, Response $response, Document $project, Database $dbForProject, Authorization $authorization, callable $getLogsDB, array $smsRates) {
|
||||
->action(function (string $startDate, string $endDate, string $period, Response $response, Document $project, Database $dbForProject, callable $getLogsDB, array $smsRates) {
|
||||
$stats = $total = $usage = [];
|
||||
$format = 'Y-m-d 00:00:00';
|
||||
$firstDay = (new DateTime($startDate))->format($format);
|
||||
@@ -103,7 +102,7 @@ App::get('/v1/project/usage')
|
||||
'1d' => 'Y-m-d\T00:00:00.000P',
|
||||
};
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $dbForLogs, $firstDay, $lastDay, $period, $metrics, $limit, &$total, &$stats) {
|
||||
Authorization::skip(function () use ($dbForProject, $dbForLogs, $firstDay, $lastDay, $period, $metrics, $limit, &$total, &$stats) {
|
||||
foreach ($metrics['total'] as $metric) {
|
||||
$db = ($metric === METRIC_FILES_IMAGES_TRANSFORMED) ? $dbForLogs : $dbForProject;
|
||||
|
||||
@@ -287,7 +286,7 @@ App::get('/v1/project/usage')
|
||||
}, $dbForProject->find('functions'));
|
||||
|
||||
// This total is includes free and paid SMS usage
|
||||
$authPhoneTotal = $authorization->skip(fn () => $dbForProject->sum('stats', 'value', [
|
||||
$authPhoneTotal = Authorization::skip(fn () => $dbForProject->sum('stats', 'value', [
|
||||
Query::equal('metric', [METRIC_AUTH_METHOD_PHONE]),
|
||||
Query::equal('period', ['1d']),
|
||||
Query::greaterThanEqual('time', $firstDay),
|
||||
@@ -295,7 +294,7 @@ App::get('/v1/project/usage')
|
||||
]));
|
||||
|
||||
// This estimate is only for paid SMS usage
|
||||
$authPhoneMetrics = $authorization->skip(fn () => $dbForProject->find('stats', [
|
||||
$authPhoneMetrics = Authorization::skip(fn () => $dbForProject->find('stats', [
|
||||
Query::startsWith('metric', METRIC_AUTH_METHOD_PHONE . '.'),
|
||||
Query::equal('period', ['1d']),
|
||||
Query::greaterThanEqual('time', $firstDay),
|
||||
|
||||
+103
-102
@@ -32,7 +32,6 @@ use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Authorization\Input;
|
||||
use Utopia\Database\Validator\Permissions;
|
||||
use Utopia\Database\Validator\Query\Cursor;
|
||||
use Utopia\Database\Validator\UID;
|
||||
@@ -434,20 +433,20 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
->inject('mode')
|
||||
->inject('deviceForFiles')
|
||||
->inject('deviceForLocal')
|
||||
->inject('authorization')
|
||||
->action(function (string $bucketId, string $fileId, mixed $file, ?array $permissions, Request $request, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, string $mode, Device $deviceForFiles, Device $deviceForLocal, Authorization $authorization) {
|
||||
->action(function (string $bucketId, string $fileId, mixed $file, ?array $permissions, Request $request, Response $response, Database $dbForProject, Document $user, Event $queueForEvents, string $mode, Device $deviceForFiles, Device $deviceForLocal) {
|
||||
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!$authorization->isValid(new Input(Database::PERMISSION_CREATE, $bucket->getCreate()))) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
$validator = new Authorization(Database::PERMISSION_CREATE);
|
||||
if (!$validator->isValid($bucket->getCreate())) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$allowedPermissions = [
|
||||
@@ -470,7 +469,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
}
|
||||
|
||||
// Users can only manage their own roles, API keys and Admin users can manage any
|
||||
$roles = $authorization->getRoles();
|
||||
$roles = Authorization::getRoles();
|
||||
if (!Auth::isAppUser($roles) && !Auth::isPrivilegedUser($roles)) {
|
||||
foreach (Database::PERMISSIONS as $type) {
|
||||
foreach ($permissions as $permission) {
|
||||
@@ -483,7 +482,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
$permission->getIdentifier(),
|
||||
$permission->getDimension()
|
||||
))->toString();
|
||||
if (!$authorization->hasRole($role)) {
|
||||
if (!Authorization::isRole($role)) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
|
||||
}
|
||||
}
|
||||
@@ -703,10 +702,11 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
* However as with chunk upload even if we are updating, we are essentially creating a file
|
||||
* adding it's new chunk so we validate create permission instead of update
|
||||
*/
|
||||
if (!$authorization->isValid(new Input(Database::PERMISSION_CREATE, $bucket->getCreate()))) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
$validator = new Authorization(Database::PERMISSION_CREATE);
|
||||
if (!$validator->isValid($bucket->getCreate())) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
$file = $authorization->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
}
|
||||
} else {
|
||||
if ($file->isEmpty()) {
|
||||
@@ -745,12 +745,13 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||
* However as with chunk upload even if we are updating, we are essentially creating a file
|
||||
* adding it's new chunk so we validate create permission instead of update
|
||||
*/
|
||||
if (!$authorization->isValid(new Input(Database::PERMISSION_CREATE, $bucket->getCreate()))) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
$validator = new Authorization(Database::PERMISSION_CREATE);
|
||||
if (!$validator->isValid($bucket->getCreate())) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
try {
|
||||
$file = $authorization->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
@@ -794,22 +795,22 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('mode')
|
||||
->action(function (string $bucketId, array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject, Authorization $authorization, string $mode) {
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
->action(function (string $bucketId, array $queries, string $search, bool $includeTotal, Response $response, Database $dbForProject, string $mode) {
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
if (!$fileSecurity && !$valid) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$queries = Query::parseQueries($queries);
|
||||
@@ -838,7 +839,7 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
||||
if ($fileSecurity && !$valid) {
|
||||
$cursorDocument = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$cursorDocument = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$cursorDocument = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
@@ -848,13 +849,15 @@ App::get('/v1/storage/buckets/:bucketId/files')
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
$filterQueries = Query::groupByType($queries)['filters'];
|
||||
|
||||
try {
|
||||
if ($fileSecurity && !$valid) {
|
||||
$files = $dbForProject->find('bucket_' . $bucket->getSequence(), $queries);
|
||||
$total = $includeTotal ? $dbForProject->count('bucket_' . $bucket->getSequence(), $queries, APP_LIMIT_COUNT) : 0;
|
||||
$total = $includeTotal ? $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT) : 0;
|
||||
} else {
|
||||
$files = $authorization->skip(fn () => $dbForProject->find('bucket_' . $bucket->getSequence(), $queries));
|
||||
$total = $includeTotal ? $authorization->skip(fn () => $dbForProject->count('bucket_' . $bucket->getSequence(), $queries, APP_LIMIT_COUNT)) : 0;
|
||||
$files = Authorization::skip(fn () => $dbForProject->find('bucket_' . $bucket->getSequence(), $queries));
|
||||
$total = $includeTotal ? Authorization::skip(fn () => $dbForProject->count('bucket_' . $bucket->getSequence(), $filterQueries, APP_LIMIT_COUNT)) : 0;
|
||||
}
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -893,28 +896,28 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
->param('fileId', '', new UID(), 'File ID.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('mode')
|
||||
->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Authorization $authorization, string $mode) {
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, string $mode) {
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
if (!$fileSecurity && !$valid) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
@@ -970,18 +973,17 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
||||
->inject('deviceForFiles')
|
||||
->inject('deviceForLocal')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, ?string $token, Request $request, Response $response, Database $dbForProject, Document $resourceToken, Device $deviceForFiles, Device $deviceForLocal, Document $project, Authorization $authorization) {
|
||||
->action(function (string $bucketId, string $fileId, int $width, int $height, string $gravity, int $quality, int $borderWidth, string $borderColor, int $borderRadius, float $opacity, int $rotation, string $background, string $output, ?string $token, Request $request, Response $response, Database $dbForProject, Document $resourceToken, Device $deviceForFiles, Device $deviceForLocal, Document $project) {
|
||||
|
||||
if (!\extension_loaded('imagick')) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Imagick extension is missing');
|
||||
}
|
||||
|
||||
/* @type Document $bucket */
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -993,20 +995,21 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
if (!$fileSecurity && !$valid && !$isToken) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid && !$isToken) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
/* @type Document $file */
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
@@ -1124,11 +1127,11 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/preview')
|
||||
$contentType = (\array_key_exists($output, $outputs)) ? $outputs[$output] : $outputs['jpg'];
|
||||
|
||||
//Do not update transformedAt if it's a console user
|
||||
if (!Auth::isPrivilegedUser($authorization->getRoles())) {
|
||||
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
|
||||
$transformedAt = $file->getAttribute('transformedAt', '');
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $transformedAt) {
|
||||
$file->setAttribute('transformedAt', DateTime::now());
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('bucket_' . $file->getAttribute('bucketInternalId'), $file->getId(), $file));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $file->getAttribute('bucketInternalId'), $file->getId(), $file));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1168,16 +1171,15 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('mode')
|
||||
->inject('resourceToken')
|
||||
->inject('deviceForFiles')
|
||||
->action(function (string $bucketId, string $fileId, ?string $token, Request $request, Response $response, Database $dbForProject, Authorization $authorization, string $mode, Document $resourceToken, Device $deviceForFiles) {
|
||||
->action(function (string $bucketId, string $fileId, ?string $token, Request $request, Response $response, Database $dbForProject, string $mode, Document $resourceToken, Device $deviceForFiles) {
|
||||
/* @type Document $bucket */
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -1185,20 +1187,21 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/download')
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
if (!$fileSecurity && !$valid && !$isToken) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid && !$isToken) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
/* @type Document $file */
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
@@ -1332,13 +1335,12 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
|
||||
->inject('mode')
|
||||
->inject('resourceToken')
|
||||
->inject('deviceForFiles')
|
||||
->inject('authorization')
|
||||
->action(function (string $bucketId, string $fileId, ?string $token, Response $response, Request $request, Database $dbForProject, string $mode, Document $resourceToken, Device $deviceForFiles, Authorization $authorization) {
|
||||
->action(function (string $bucketId, string $fileId, ?string $token, Response $response, Request $request, Database $dbForProject, string $mode, Document $resourceToken, Device $deviceForFiles) {
|
||||
/* @type Document $bucket */
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -1346,20 +1348,21 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/view')
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
if (!$fileSecurity && !$valid && !$isToken) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if ($fileSecurity && !$valid && !$isToken) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
/* @type Document $file */
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
@@ -1488,14 +1491,13 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
|
||||
->inject('project')
|
||||
->inject('mode')
|
||||
->inject('deviceForFiles')
|
||||
->inject('authorization')
|
||||
->action(function (string $bucketId, string $fileId, string $jwt, Response $response, Request $request, Database $dbForProject, Database $dbForPlatform, Document $project, string $mode, Device $deviceForFiles, Authorization $authorization) {
|
||||
->action(function (string $bucketId, string $fileId, string $jwt, Response $response, Request $request, Database $dbForProject, Database $dbForPlatform, Document $project, string $mode, Device $deviceForFiles) {
|
||||
$decoder = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 3600, 0);
|
||||
|
||||
try {
|
||||
$decoded = $decoder->decode($jwt);
|
||||
} catch (JWTException) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
if (
|
||||
@@ -1503,21 +1505,22 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
|
||||
$decoded['bucketId'] !== $bucketId ||
|
||||
$decoded['fileId'] !== $fileId
|
||||
) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$isInternal = $decoded['internal'] ?? false;
|
||||
$disposition = $decoded['disposition'] ?? 'inline';
|
||||
$dbForProject = $isInternal ? $dbForPlatform : $dbForProject;
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
}
|
||||
@@ -1525,6 +1528,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
|
||||
$mimes = Config::getParam('storage-mimes');
|
||||
|
||||
$path = $file->getAttribute('path', '');
|
||||
|
||||
if (!$deviceForFiles->exists($path)) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND, 'File not found in ' . $path);
|
||||
}
|
||||
@@ -1562,7 +1566,7 @@ App::get('/v1/storage/buckets/:bucketId/files/:fileId/push')
|
||||
->setContentType($contentType)
|
||||
->addHeader('Content-Security-Policy', 'script-src none;')
|
||||
->addHeader('X-Content-Type-Options', 'nosniff')
|
||||
->addHeader('Content-Disposition', 'inline; filename="' . $file->getAttribute('name', '') . '"')
|
||||
->addHeader('Content-Disposition', $disposition . '; filename="' . $file->getAttribute('name', '') . '"')
|
||||
->addHeader('Cache-Control', 'private, max-age=3888000') // 45 days
|
||||
->addHeader('X-Peak', \memory_get_peak_usage());
|
||||
|
||||
@@ -1661,26 +1665,26 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
->inject('user')
|
||||
->inject('mode')
|
||||
->inject('queueForEvents')
|
||||
->inject('authorization')
|
||||
->action(function (string $bucketId, string $fileId, ?string $name, ?array $permissions, Response $response, Database $dbForProject, Document $user, string $mode, Event $queueForEvents, Authorization $authorization) {
|
||||
->action(function (string $bucketId, string $fileId, ?string $name, ?array $permissions, Response $response, Database $dbForProject, Document $user, string $mode, Event $queueForEvents) {
|
||||
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_UPDATE, $bucket->getUpdate()));
|
||||
$validator = new Authorization(Database::PERMISSION_UPDATE);
|
||||
$valid = $validator->isValid($bucket->getUpdate());
|
||||
if (!$fileSecurity && !$valid) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
// Read permission should not be required for update
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
@@ -1694,7 +1698,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
]);
|
||||
|
||||
// Users can only manage their own roles, API keys and Admin users can manage any
|
||||
$roles = $authorization->getRoles();
|
||||
$roles = Authorization::getRoles();
|
||||
if (!Auth::isAppUser($roles) && !Auth::isPrivilegedUser($roles) && !\is_null($permissions)) {
|
||||
foreach (Database::PERMISSIONS as $type) {
|
||||
foreach ($permissions as $permission) {
|
||||
@@ -1707,7 +1711,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
$permission->getIdentifier(),
|
||||
$permission->getDimension()
|
||||
))->toString();
|
||||
if (!$authorization->hasRole($role)) {
|
||||
if (!Authorization::isRole($role)) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'Permissions must be one of: (' . \implode(', ', $roles) . ')');
|
||||
}
|
||||
}
|
||||
@@ -1728,7 +1732,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
if ($fileSecurity && !$valid) {
|
||||
$file = $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file);
|
||||
} else {
|
||||
$file = $authorization->skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getSequence(), $fileId, $file));
|
||||
}
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -1776,34 +1780,33 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
->inject('mode')
|
||||
->inject('deviceForFiles')
|
||||
->inject('queueForDeletes')
|
||||
->inject('authorization')
|
||||
->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Event $queueForEvents, string $mode, Device $deviceForFiles, Delete $queueForDeletes, Authorization $authorization) {
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
->action(function (string $bucketId, string $fileId, Response $response, Database $dbForProject, Event $queueForEvents, string $mode, Device $deviceForFiles, Delete $queueForDeletes) {
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isAPIKey = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_DELETE, $bucket->getDelete()));
|
||||
$validator = new Authorization(Database::PERMISSION_DELETE);
|
||||
$valid = $validator->isValid($bucket->getDelete());
|
||||
if (!$fileSecurity && !$valid) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
// Read permission should not be required for delete
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
|
||||
if ($file->isEmpty()) {
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Make sure we don't delete the file before the document permission check occurs
|
||||
$validFile = $authorization->isValid(new Input(Database::PERMISSION_DELETE, $file->getDelete()));
|
||||
if ($fileSecurity && !$valid && !$validFile) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
|
||||
if ($fileSecurity && !$valid && !$validator->isValid($file->getDelete())) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
|
||||
$deviceDeleted = false;
|
||||
@@ -1827,7 +1830,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
||||
if ($fileSecurity && !$valid) {
|
||||
$deleted = $dbForProject->deleteDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$deleted = $authorization->skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$deleted = Authorization::skip(fn () => $dbForProject->deleteDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -1872,8 +1875,7 @@ App::get('/v1/storage/usage')
|
||||
->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->action(function (string $range, Response $response, Database $dbForProject, Authorization $authorization) {
|
||||
->action(function (string $range, Response $response, Database $dbForProject) {
|
||||
|
||||
$periods = Config::getParam('usage', []);
|
||||
$stats = $usage = [];
|
||||
@@ -1885,7 +1887,7 @@ App::get('/v1/storage/usage')
|
||||
];
|
||||
|
||||
$total = [];
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) {
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats, &$total) {
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
@@ -1963,8 +1965,7 @@ App::get('/v1/storage/:bucketId/usage')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('getLogsDB')
|
||||
->inject('authorization')
|
||||
->action(function (string $bucketId, string $range, Response $response, Document $project, Database $dbForProject, callable $getLogsDB, Authorization $authorization) {
|
||||
->action(function (string $bucketId, string $range, Response $response, Document $project, Database $dbForProject, callable $getLogsDB) {
|
||||
|
||||
$dbForLogs = call_user_func($getLogsDB, $project);
|
||||
$bucket = $dbForProject->getDocument('buckets', $bucketId);
|
||||
@@ -1982,7 +1983,7 @@ App::get('/v1/storage/:bucketId/usage')
|
||||
str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED),
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $dbForLogs, $bucket, $days, $metrics, &$stats) {
|
||||
Authorization::skip(function () use ($dbForProject, $dbForLogs, $bucket, $days, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
$db = ($metric === str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED))
|
||||
? $dbForLogs
|
||||
|
||||
@@ -84,17 +84,16 @@ App::post('/v1/teams')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $teamId, string $name, array $roles, Response $response, Document $user, Database $dbForProject, Authorization $authorization, Event $queueForEvents) {
|
||||
->action(function (string $teamId, string $name, array $roles, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
$isAppUser = Auth::isAppUser(Authorization::getRoles());
|
||||
|
||||
$teamId = $teamId == 'unique()' ? ID::unique() : $teamId;
|
||||
|
||||
try {
|
||||
$team = $authorization->skip(fn () => $dbForProject->createDocument('teams', new Document([
|
||||
$team = Authorization::skip(fn () => $dbForProject->createDocument('teams', new Document([
|
||||
'$id' => $teamId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::team($teamId)),
|
||||
@@ -490,7 +489,6 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('locale')
|
||||
->inject('queueForMails')
|
||||
->inject('queueForMessaging')
|
||||
@@ -498,9 +496,9 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
->inject('timelimit')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('plan')
|
||||
->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, Document $user, Database $dbForProject, Authorization $authorization, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents, callable $timelimit, StatsUsage $queueForStatsUsage, array $plan) {
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents, callable $timelimit, StatsUsage $queueForStatsUsage, array $plan) {
|
||||
$isAppUser = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
$url = htmlentities($url);
|
||||
if (empty($url)) {
|
||||
@@ -575,50 +573,53 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
$emailCanonical = null;
|
||||
}
|
||||
|
||||
$userId = ID::unique();
|
||||
|
||||
$userDocument = new Document([
|
||||
'$id' => $userId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::read(Role::user($userId)),
|
||||
Permission::update(Role::user($userId)),
|
||||
Permission::delete(Role::user($userId)),
|
||||
],
|
||||
'email' => empty($email) ? null : $email,
|
||||
'phone' => empty($phone) ? null : $phone,
|
||||
'emailVerification' => false,
|
||||
'status' => true,
|
||||
// TODO: Set password empty?
|
||||
'password' => Auth::passwordHash(Auth::passwordGenerator(), Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS),
|
||||
'hash' => Auth::DEFAULT_ALGO,
|
||||
'hashOptions' => Auth::DEFAULT_ALGO_OPTIONS,
|
||||
/**
|
||||
* Set the password update time to 0 for users created using
|
||||
* team invite and OAuth to allow password updates without an
|
||||
* old password
|
||||
*/
|
||||
'passwordUpdate' => null,
|
||||
'registration' => DateTime::now(),
|
||||
'reset' => false,
|
||||
'name' => $name,
|
||||
'prefs' => new \stdClass(),
|
||||
'sessions' => null,
|
||||
'tokens' => null,
|
||||
'memberships' => null,
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
'emailCanonical' => $emailCanonical?->getCanonical(),
|
||||
'emailIsCanonical' => $emailCanonical?->isCanonicalSupported(),
|
||||
'emailIsCorporate' => $emailCanonical?->isCorporate(),
|
||||
'emailIsDisposable' => $emailCanonical?->isDisposable(),
|
||||
'emailIsFree' => $emailCanonical?->isFree(),
|
||||
]);
|
||||
|
||||
try {
|
||||
$userId = ID::unique();
|
||||
$invitee = $authorization->skip(fn () => $dbForProject->createDocument('users', new Document([
|
||||
'$id' => $userId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::read(Role::user($userId)),
|
||||
Permission::update(Role::user($userId)),
|
||||
Permission::delete(Role::user($userId)),
|
||||
],
|
||||
'email' => empty($email) ? null : $email,
|
||||
'phone' => empty($phone) ? null : $phone,
|
||||
'emailVerification' => false,
|
||||
'status' => true,
|
||||
// TODO: Set password empty?
|
||||
'password' => Auth::passwordHash(Auth::passwordGenerator(), Auth::DEFAULT_ALGO, Auth::DEFAULT_ALGO_OPTIONS),
|
||||
'hash' => Auth::DEFAULT_ALGO,
|
||||
'hashOptions' => Auth::DEFAULT_ALGO_OPTIONS,
|
||||
/**
|
||||
* Set the password update time to 0 for users created using
|
||||
* team invite and OAuth to allow password updates without an
|
||||
* old password
|
||||
*/
|
||||
'passwordUpdate' => null,
|
||||
'registration' => DateTime::now(),
|
||||
'reset' => false,
|
||||
'name' => $name,
|
||||
'prefs' => new \stdClass(),
|
||||
'sessions' => null,
|
||||
'tokens' => null,
|
||||
'memberships' => null,
|
||||
'search' => implode(' ', [$userId, $email, $name]),
|
||||
'emailCanonical' => $emailCanonical?->getCanonical(),
|
||||
'emailIsCanonical' => $emailCanonical?->isCanonicalSupported(),
|
||||
'emailIsCorporate' => $emailCanonical?->isCorporate(),
|
||||
'emailIsDisposable' => $emailCanonical?->isDisposable(),
|
||||
'emailIsFree' => $emailCanonical?->isFree(),
|
||||
])));
|
||||
$invitee = Authorization::skip(fn () => $dbForProject->createDocument('users', $userDocument));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::USER_ALREADY_EXISTS);
|
||||
}
|
||||
}
|
||||
|
||||
$isOwner = $authorization->hasRole('team:' . $team->getId() . '/owner');
|
||||
$isOwner = Authorization::isRole('team:' . $team->getId() . '/owner');
|
||||
|
||||
if (!$isOwner && !$isPrivilegedUser && !$isAppUser) { // Not owner, not admin, not app (server)
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to send invitations for this team');
|
||||
@@ -654,11 +655,11 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
]);
|
||||
|
||||
$membership = ($isPrivilegedUser || $isAppUser) ?
|
||||
$authorization->skip(fn () => $dbForProject->createDocument('memberships', $membership)) :
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership)) :
|
||||
$dbForProject->createDocument('memberships', $membership);
|
||||
|
||||
if ($isPrivilegedUser || $isAppUser) {
|
||||
$authorization->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
}
|
||||
|
||||
} elseif ($membership->getAttribute('confirm') === false) {
|
||||
@@ -671,7 +672,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
}
|
||||
|
||||
$membership = ($isPrivilegedUser || $isAppUser) ?
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('memberships', $membership->getId(), $membership)) :
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('memberships', $membership->getId(), $membership)) :
|
||||
$dbForProject->updateDocument('memberships', $membership->getId(), $membership);
|
||||
} else {
|
||||
throw new Exception(Exception::MEMBERSHIP_ALREADY_CONFIRMED);
|
||||
@@ -858,8 +859,7 @@ App::get('/v1/teams/:teamId/memberships')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, array $queries, string $search, bool $includeTotal, Response $response, Document $project, Database $dbForProject, Authorization $authorization) {
|
||||
->action(function (string $teamId, array $queries, string $search, bool $includeTotal, Response $response, Document $project, Database $dbForProject) {
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
|
||||
if ($team->isEmpty()) {
|
||||
@@ -929,7 +929,7 @@ App::get('/v1/teams/:teamId/memberships')
|
||||
'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true,
|
||||
];
|
||||
|
||||
$roles = $authorization->getRoles();
|
||||
$roles = Authorization::getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
@@ -1000,8 +1000,7 @@ App::get('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->action(function (string $teamId, string $membershipId, Response $response, Document $project, Database $dbForProject, Authorization $authorization) {
|
||||
->action(function (string $teamId, string $membershipId, Response $response, Document $project, Database $dbForProject) {
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
|
||||
@@ -1021,7 +1020,7 @@ App::get('/v1/teams/:teamId/memberships/:membershipId')
|
||||
'mfa' => $project->getAttribute('auths', [])['membershipsMfa'] ?? true,
|
||||
];
|
||||
|
||||
$roles = $authorization->getRoles();
|
||||
$roles = Authorization::getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
@@ -1100,9 +1099,8 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Authorization $authorization, Event $queueForEvents) {
|
||||
->action(function (string $teamId, string $membershipId, array $roles, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
if ($team->isEmpty()) {
|
||||
@@ -1119,9 +1117,9 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
$isOwner = $authorization->hasRole('team:' . $team->getId() . '/owner');
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
$isAppUser = Auth::isAppUser(Authorization::getRoles());
|
||||
$isOwner = Authorization::isRole('team:' . $team->getId() . '/owner');
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
// Quick check: fetch up to 2 owners to determine if only one exists
|
||||
@@ -1202,11 +1200,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('project')
|
||||
->inject('geodb')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Authorization $authorization, Document $project, Reader $geodb, Event $queueForEvents) {
|
||||
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Reader $geodb, Event $queueForEvents) {
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$membership = $dbForProject->getDocument('memberships', $membershipId);
|
||||
@@ -1215,7 +1212,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
throw new Exception(Exception::MEMBERSHIP_NOT_FOUND);
|
||||
}
|
||||
|
||||
$team = $authorization->skip(fn () => $dbForProject->getDocument('teams', $teamId));
|
||||
$team = Authorization::skip(fn () => $dbForProject->getDocument('teams', $teamId));
|
||||
|
||||
if ($team->isEmpty()) {
|
||||
throw new Exception(Exception::TEAM_NOT_FOUND);
|
||||
@@ -1251,11 +1248,11 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
->setAttribute('confirm', true)
|
||||
;
|
||||
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true)));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('emailVerification', true)));
|
||||
|
||||
// Create session for the user if not logged in
|
||||
if (!$hasSession) {
|
||||
$authorization->addRole(Role::user($user->getId())->toString());
|
||||
Authorization::setRole(Role::user($user->getId())->toString());
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
@@ -1283,7 +1280,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
|
||||
$session = $dbForProject->createDocument('sessions', $session);
|
||||
|
||||
$authorization->addRole(Role::user($userId)->toString());
|
||||
Authorization::setRole(Role::user($userId)->toString());
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
$response->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]));
|
||||
@@ -1316,7 +1313,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$authorization->skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
@@ -1360,9 +1357,8 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->inject('project')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $teamId, string $membershipId, Document $user, Document $project, Response $response, Database $dbForProject, Authorization $authorization, Event $queueForEvents) {
|
||||
->action(function (string $teamId, string $membershipId, Document $user, Document $project, Response $response, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$membership = $dbForProject->getDocument('memberships', $membershipId);
|
||||
|
||||
@@ -1420,7 +1416,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
$dbForProject->purgeCachedDocument('users', $profile->getId());
|
||||
|
||||
if ($membership->getAttribute('confirm')) { // Count only confirmed members
|
||||
$authorization->skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0));
|
||||
Authorization::skip(fn () => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0));
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
|
||||
@@ -2647,8 +2647,8 @@ App::get('/v1/users/usage')
|
||||
->param('range', '30d', new WhiteList(['24h', '30d', '90d'], true), 'Date range.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->action(function (string $range, Response $response, Database $dbForProject, Authorization $authorization) {
|
||||
->inject('register')
|
||||
->action(function (string $range, Response $response, Database $dbForProject) {
|
||||
|
||||
$periods = Config::getParam('usage', []);
|
||||
$stats = $usage = [];
|
||||
@@ -2658,7 +2658,7 @@ App::get('/v1/users/usage')
|
||||
METRIC_SESSIONS,
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
foreach ($metrics as $count => $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
|
||||
+46
-43
@@ -5,6 +5,7 @@ use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Network\Validator\Redirect;
|
||||
use Appwrite\Platform\Modules\Compute\Base as ComputeBase;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -17,7 +18,9 @@ use Appwrite\Vcs\Comment;
|
||||
use Swoole\Coroutine\WaitGroup;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Adapters\Dotenv as ConfigDotenv;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Config\Exceptions\Parse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
@@ -72,7 +75,7 @@ use Utopia\VCS\Exception\RepositoryNotFound;
|
||||
|
||||
use function Swoole\Coroutine\batch;
|
||||
|
||||
$createGitDeployments = function (GitHub $github, string $providerInstallationId, array $repositories, string $providerBranch, string $providerBranchUrl, string $providerRepositoryName, string $providerRepositoryUrl, string $providerRepositoryOwner, string $providerCommitHash, string $providerCommitAuthor, string $providerCommitAuthorUrl, string $providerCommitMessage, string $providerCommitUrl, string $providerPullRequestId, bool $external, Database $dbForPlatform, Authorization $authorization, Build $queueForBuilds, callable $getProjectDB, Request $request) {
|
||||
$createGitDeployments = function (GitHub $github, string $providerInstallationId, array $repositories, string $providerBranch, string $providerBranchUrl, string $providerRepositoryName, string $providerRepositoryUrl, string $providerRepositoryOwner, string $providerCommitHash, string $providerCommitAuthor, string $providerCommitAuthorUrl, string $providerCommitMessage, string $providerCommitUrl, string $providerPullRequestId, bool $external, Database $dbForPlatform, Build $queueForBuilds, callable $getProjectDB, Request $request) {
|
||||
$errors = [];
|
||||
foreach ($repositories as $repository) {
|
||||
try {
|
||||
@@ -83,12 +86,12 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
}
|
||||
|
||||
$projectId = $repository->getAttribute('projectId');
|
||||
$project = $authorization->skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
$resourceCollection = $resourceType === "function" ? 'functions' : 'sites';
|
||||
$resourceId = $repository->getAttribute('resourceId');
|
||||
$resource = $authorization->skip(fn () => $dbForProject->getDocument($resourceCollection, $resourceId));
|
||||
$resource = Authorization::skip(fn () => $dbForProject->getDocument($resourceCollection, $resourceId));
|
||||
$resourceInternalId = $resource->getSequence();
|
||||
|
||||
$deploymentId = ID::unique();
|
||||
@@ -137,7 +140,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
$latestCommentId = '';
|
||||
|
||||
if (!empty($providerPullRequestId) && $resource->getAttribute('providerSilentMode', false) === false) {
|
||||
$latestComment = $authorization->skip(fn () => $dbForPlatform->findOne('vcsComments', [
|
||||
$latestComment = Authorization::skip(fn () => $dbForPlatform->findOne('vcsComments', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::equal('providerPullRequestId', [$providerPullRequestId]),
|
||||
Query::orderDesc('$createdAt'),
|
||||
@@ -176,7 +179,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
|
||||
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
|
||||
} finally {
|
||||
$authorization->skip(fn () => $dbForPlatform->deleteDocument('vcsCommentLocks', $latestCommentId));
|
||||
Authorization::skip(fn () => $dbForPlatform->deleteDocument('vcsCommentLocks', $latestCommentId));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -187,7 +190,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
if (!empty($latestCommentId)) {
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
|
||||
$latestComment = $authorization->skip(fn () => $dbForPlatform->createDocument('vcsComments', new Document([
|
||||
$latestComment = Authorization::skip(fn () => $dbForPlatform->createDocument('vcsComments', new Document([
|
||||
'$id' => ID::unique(),
|
||||
'$permissions' => [
|
||||
Permission::read(Role::team(ID::custom($teamId))),
|
||||
@@ -208,7 +211,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
}
|
||||
}
|
||||
} elseif (!empty($providerBranch)) {
|
||||
$latestComments = $authorization->skip(fn () => $dbForPlatform->find('vcsComments', [
|
||||
$latestComments = Authorization::skip(fn () => $dbForPlatform->find('vcsComments', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::equal('providerBranch', [$providerBranch]),
|
||||
Query::orderDesc('$createdAt'),
|
||||
@@ -247,7 +250,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
|
||||
$latestCommentId = \strval($github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment()));
|
||||
} finally {
|
||||
$authorization->skip(fn () => $dbForPlatform->deleteDocument('vcsCommentLocks', $latestCommentId));
|
||||
Authorization::skip(fn () => $dbForPlatform->deleteDocument('vcsCommentLocks', $latestCommentId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,7 +293,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
$commands[] = $resource->getAttribute('commands', '');
|
||||
}
|
||||
|
||||
$deployment = $authorization->skip(fn () => $dbForProject->createDocument('deployments', new Document([
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->createDocument('deployments', new Document([
|
||||
'$id' => $deploymentId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
@@ -330,7 +333,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
->setAttribute('latestDeploymentInternalId', $deployment->getSequence())
|
||||
->setAttribute('latestDeploymentCreatedAt', $deployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $deployment->getAttribute('status', ''));
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument($resource->getCollection(), $resource->getId(), $resource));
|
||||
|
||||
if ($resource->getCollection() === 'sites') {
|
||||
$projectId = $project->getId();
|
||||
@@ -340,7 +343,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
$domain = ID::unique() . "." . $sitesDomain;
|
||||
$ruleId = md5($domain);
|
||||
$previewRuleId = $ruleId;
|
||||
$authorization->skip(
|
||||
Authorization::skip(
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
@@ -373,7 +376,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
$domain = "branch-{$branchPrefix}-{$resourceProjectHash}.{$sitesDomain}";
|
||||
$ruleId = md5($domain);
|
||||
try {
|
||||
$authorization->skip(
|
||||
Authorization::skip(
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
@@ -404,7 +407,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
$domain = "commit-" . substr($providerCommitHash, 0, 16) . ".{$sitesDomain}";
|
||||
$ruleId = md5($domain);
|
||||
try {
|
||||
$authorization->skip(
|
||||
Authorization::skip(
|
||||
fn () => $dbForPlatform->createDocument('rules', new Document([
|
||||
'$id' => $ruleId,
|
||||
'projectId' => $project->getId(),
|
||||
@@ -431,6 +434,8 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
}
|
||||
}
|
||||
|
||||
ComputeBase::updateEmptyManualRule($project, $resource, $deployment, $dbForPlatform);
|
||||
|
||||
if ($resource->getCollection() === 'sites' && !empty($latestCommentId) && !empty($previewRuleId)) {
|
||||
$retries = 0;
|
||||
$lockAcquired = false;
|
||||
@@ -456,7 +461,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
if ($lockAcquired) {
|
||||
// Wrap in try/finally to ensure lock file gets deleted
|
||||
try {
|
||||
$rule = $authorization->skip(fn () => $dbForPlatform->getDocument('rules', $previewRuleId));
|
||||
$rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', $previewRuleId));
|
||||
|
||||
$protocol = System::getEnv('_APP_OPTIONS_FORCE_HTTPS') === 'disabled' ? 'http' : 'https';
|
||||
$previewUrl = !empty($rule) ? ("{$protocol}://" . $rule->getAttribute('domain', '')) : '';
|
||||
@@ -468,7 +473,7 @@ $createGitDeployments = function (GitHub $github, string $providerInstallationId
|
||||
$github->updateComment($owner, $repositoryName, $latestCommentId, $comment->generateComment());
|
||||
}
|
||||
} finally {
|
||||
$authorization->skip(fn () => $dbForPlatform->deleteDocument('vcsCommentLocks', $latestCommentId));
|
||||
Authorization::skip(fn () => $dbForPlatform->deleteDocument('vcsCommentLocks', $latestCommentId));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -978,14 +983,14 @@ App::post('/v1/vcs/github/installations/:installationId/detections')
|
||||
$contentResponse = $github->getRepositoryContent($owner, $repositoryName, \rtrim($providerRootDirectory, '/') . '/' . $file);
|
||||
$envFile = $contentResponse['content'] ?? '';
|
||||
|
||||
$envLines = \explode("\n", $envFile);
|
||||
foreach ($envLines as $line) {
|
||||
$parts = \explode('=', $line, 2);
|
||||
$envName = \trim($parts[0] ?? '');
|
||||
$envValue = \trim($parts[1] ?? '');
|
||||
if (!empty($envName)) {
|
||||
$configAdapter = new ConfigDotenv();
|
||||
try {
|
||||
$envObject = $configAdapter->parse($envFile);
|
||||
foreach ($envObject as $envName => $envValue) {
|
||||
$envs[$envName] = $envValue;
|
||||
}
|
||||
} catch (Parse $err) {
|
||||
// Silence error, so rest of endpoint can return
|
||||
}
|
||||
} finally {
|
||||
$wg->done();
|
||||
@@ -1192,14 +1197,14 @@ App::get('/v1/vcs/github/installations/:installationId/providerRepositories')
|
||||
$contentResponse = $github->getRepositoryContent($repo['organization'], $repo['name'], $file);
|
||||
$envFile = $contentResponse['content'] ?? '';
|
||||
|
||||
$envLines = \explode("\n", $envFile);
|
||||
foreach ($envLines as $line) {
|
||||
$parts = \explode('=', $line, 2);
|
||||
$envName = \trim($parts[0] ?? '');
|
||||
$envValue = \trim($parts[1] ?? '');
|
||||
if (!empty($envName)) {
|
||||
$configAdapter = new ConfigDotenv();
|
||||
try {
|
||||
$envObject = $configAdapter->parse($envFile);
|
||||
foreach ($envObject as $envName => $envValue) {
|
||||
$envs[$envName] = $envValue;
|
||||
}
|
||||
} catch (Parse) {
|
||||
// Silence error, so rest of endpoint can return
|
||||
}
|
||||
} finally {
|
||||
$wg->done();
|
||||
@@ -1462,11 +1467,10 @@ App::post('/v1/vcs/github/events')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
->inject('getProjectDB')
|
||||
->inject('queueForBuilds')
|
||||
->action(
|
||||
function (GitHub $github, Request $request, Response $response, Database $dbForPlatform, Authorization $authorization, callable $getProjectDB, Build $queueForBuilds) use ($createGitDeployments) {
|
||||
function (GitHub $github, Request $request, Response $response, Database $dbForPlatform, callable $getProjectDB, Build $queueForBuilds) use ($createGitDeployments) {
|
||||
$payload = $request->getRawPayload();
|
||||
$signatureRemote = $request->getHeader('x-hub-signature-256', '');
|
||||
$signatureLocal = System::getEnv('_APP_VCS_GITHUB_WEBHOOK_SECRET', '');
|
||||
@@ -1502,14 +1506,14 @@ App::post('/v1/vcs/github/events')
|
||||
$github->initializeVariables($providerInstallationId, $privateKey, $githubAppId);
|
||||
|
||||
//find resourceId from relevant resources table
|
||||
$repositories = $authorization->skip(fn () => $dbForPlatform->find('repositories', [
|
||||
$repositories = Authorization::skip(fn () => $dbForPlatform->find('repositories', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::limit(100),
|
||||
]));
|
||||
|
||||
// create new deployment only on push (not committed by us) and not when branch is created or deleted
|
||||
if ($providerCommitAuthorEmail !== APP_VCS_GITHUB_EMAIL && !$providerBranchCreated && !$providerBranchDeleted) {
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthorName, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, '', false, $dbForPlatform, $authorization, $queueForBuilds, $getProjectDB, $request);
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthorName, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, '', false, $dbForPlatform, $queueForBuilds, $getProjectDB, $request);
|
||||
}
|
||||
} elseif ($event == $github::EVENT_INSTALLATION) {
|
||||
if ($parsedPayload["action"] == "deleted") {
|
||||
@@ -1522,16 +1526,16 @@ App::post('/v1/vcs/github/events')
|
||||
]);
|
||||
|
||||
foreach ($installations as $installation) {
|
||||
$repositories = $authorization->skip(fn () => $dbForPlatform->find('repositories', [
|
||||
$repositories = Authorization::skip(fn () => $dbForPlatform->find('repositories', [
|
||||
Query::equal('installationInternalId', [$installation->getSequence()]),
|
||||
Query::limit(1000)
|
||||
]));
|
||||
|
||||
foreach ($repositories as $repository) {
|
||||
$authorization->skip(fn () => $dbForPlatform->deleteDocument('repositories', $repository->getId()));
|
||||
Authorization::skip(fn () => $dbForPlatform->deleteDocument('repositories', $repository->getId()));
|
||||
}
|
||||
|
||||
$authorization->skip(fn () => $dbForPlatform->deleteDocument('installations', $installation->getId()));
|
||||
Authorization::skip(fn () => $dbForPlatform->deleteDocument('installations', $installation->getId()));
|
||||
}
|
||||
}
|
||||
} elseif ($event == $github::EVENT_PULL_REQUEST) {
|
||||
@@ -1560,12 +1564,12 @@ App::post('/v1/vcs/github/events')
|
||||
$providerCommitAuthor = $commitDetails["commitAuthor"] ?? '';
|
||||
$providerCommitMessage = $commitDetails["commitMessage"] ?? '';
|
||||
|
||||
$repositories = $authorization->skip(fn () => $dbForPlatform->find('repositories', [
|
||||
$repositories = Authorization::skip(fn () => $dbForPlatform->find('repositories', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::orderDesc('$createdAt')
|
||||
]));
|
||||
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, $providerPullRequestId, $external, $dbForPlatform, $authorization, $queueForBuilds, $getProjectDB, $request);
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerBranchUrl, $providerRepositoryName, $providerRepositoryUrl, $providerRepositoryOwner, $providerCommitHash, $providerCommitAuthor, $providerCommitAuthorUrl, $providerCommitMessage, $providerCommitUrl, $providerPullRequestId, $external, $dbForPlatform, $queueForBuilds, $getProjectDB, $request);
|
||||
} elseif ($parsedPayload["action"] == "closed") {
|
||||
// Allowed external contributions cleanup
|
||||
|
||||
@@ -1574,7 +1578,7 @@ App::post('/v1/vcs/github/events')
|
||||
$external = $parsedPayload["external"] ?? true;
|
||||
|
||||
if ($external) {
|
||||
$repositories = $authorization->skip(fn () => $dbForPlatform->find('repositories', [
|
||||
$repositories = Authorization::skip(fn () => $dbForPlatform->find('repositories', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::orderDesc('$createdAt')
|
||||
]));
|
||||
@@ -1585,7 +1589,7 @@ App::post('/v1/vcs/github/events')
|
||||
if (\in_array($providerPullRequestId, $providerPullRequestIds)) {
|
||||
$providerPullRequestIds = \array_diff($providerPullRequestIds, [$providerPullRequestId]);
|
||||
$repository = $repository->setAttribute('providerPullRequestIds', $providerPullRequestIds);
|
||||
$repository = $authorization->skip(fn () => $dbForPlatform->updateDocument('repositories', $repository->getId(), $repository));
|
||||
$repository = Authorization::skip(fn () => $dbForPlatform->updateDocument('repositories', $repository->getId(), $repository));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1773,17 +1777,16 @@ App::patch('/v1/vcs/github/installations/:installationId/repositories/:repositor
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
->inject('getProjectDB')
|
||||
->inject('queueForBuilds')
|
||||
->action(function (string $installationId, string $repositoryId, string $providerPullRequestId, GitHub $github, Request $request, Response $response, Document $project, Database $dbForPlatform, Authorization $authorization, callable $getProjectDB, Build $queueForBuilds) use ($createGitDeployments) {
|
||||
->action(function (string $installationId, string $repositoryId, string $providerPullRequestId, GitHub $github, Request $request, Response $response, Document $project, Database $dbForPlatform, callable $getProjectDB, Build $queueForBuilds) use ($createGitDeployments) {
|
||||
$installation = $dbForPlatform->getDocument('installations', $installationId);
|
||||
|
||||
if ($installation->isEmpty()) {
|
||||
throw new Exception(Exception::INSTALLATION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$repository = $authorization->skip(fn () => $dbForPlatform->getDocument('repositories', $repositoryId, [
|
||||
$repository = Authorization::skip(fn () => $dbForPlatform->getDocument('repositories', $repositoryId, [
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
]));
|
||||
|
||||
@@ -1800,7 +1803,7 @@ App::patch('/v1/vcs/github/installations/:installationId/repositories/:repositor
|
||||
|
||||
// TODO: Delete from array when PR is closed
|
||||
|
||||
$repository = $authorization->skip(fn () => $dbForPlatform->updateDocument('repositories', $repository->getId(), $repository));
|
||||
$repository = Authorization::skip(fn () => $dbForPlatform->updateDocument('repositories', $repository->getId(), $repository));
|
||||
|
||||
$privateKey = System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY');
|
||||
$githubAppId = System::getEnv('_APP_VCS_GITHUB_APP_ID');
|
||||
@@ -1824,7 +1827,7 @@ App::patch('/v1/vcs/github/installations/:installationId/repositories/:repositor
|
||||
$providerBranch = \explode(':', $pullRequestResponse['head']['label'])[1] ?? '';
|
||||
$providerCommitHash = $pullRequestResponse['head']['sha'] ?? '';
|
||||
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, '', '', '', '', $providerCommitHash, '', '', '', '', $providerPullRequestId, true, $dbForPlatform, $authorization, $queueForBuilds, $getProjectDB, $request);
|
||||
$createGitDeployments($github, $providerInstallationId, $repositories, $providerBranch, $providerCommitHash, $providerPullRequestId, true, $dbForPlatform, $queueForBuilds, $getProjectDB, $request);
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
+28
-34
@@ -57,7 +57,7 @@ Config::setParam('domainVerification', false);
|
||||
Config::setParam('cookieDomain', 'localhost');
|
||||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Authorization $authorization, ?Key $apiKey)
|
||||
function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey)
|
||||
{
|
||||
$host = $request->getHostname() ?? '';
|
||||
if (!empty($previewHostname)) {
|
||||
@@ -66,9 +66,9 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
|
||||
// TODO: @christyjacob remove once we migrate the rules in 1.7.x
|
||||
if (System::getEnv('_APP_RULES_FORMAT') === 'md5') {
|
||||
$rule = $authorization->skip(fn () => $dbForPlatform->getDocument('rules', md5($host)));
|
||||
$rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($host)));
|
||||
} else {
|
||||
$rule = $authorization->skip(
|
||||
$rule = Authorization::skip(
|
||||
fn () => $dbForPlatform->find('rules', [
|
||||
Query::equal('domain', [$host]),
|
||||
Query::limit(1)
|
||||
@@ -109,7 +109,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
}
|
||||
|
||||
$projectId = $rule->getAttribute('projectId');
|
||||
$project = $authorization->skip(
|
||||
$project = Authorization::skip(
|
||||
fn () => $dbForPlatform->getDocument('projects', $projectId)
|
||||
);
|
||||
|
||||
@@ -117,7 +117,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
$accessedAt = $project->getAttribute('accessedAt', 0);
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) {
|
||||
$project->setAttribute('accessedAt', DateTime::now());
|
||||
$authorization->skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
|
||||
Authorization::skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,7 +156,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
|
||||
/** @var Document $deployment */
|
||||
if (!empty($rule->getAttribute('deploymentId', ''))) {
|
||||
$deployment = $authorization->skip(fn () => $dbForProject->getDocument('deployments', $rule->getAttribute('deploymentId')));
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $rule->getAttribute('deploymentId')));
|
||||
} else {
|
||||
// 1.6.x DB schema compatibility
|
||||
// TODO: Make sure deploymentId is never empty, and remove this code
|
||||
@@ -170,15 +170,15 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
|
||||
// Document of site or function
|
||||
$resource = $resourceType === 'function' ?
|
||||
$authorization->skip(fn () => $dbForProject->getDocument('functions', $resourceId)) :
|
||||
$authorization->skip(fn () => $dbForProject->getDocument('sites', $resourceId));
|
||||
Authorization::skip(fn () => $dbForProject->getDocument('functions', $resourceId)) :
|
||||
Authorization::skip(fn () => $dbForProject->getDocument('sites', $resourceId));
|
||||
|
||||
// ID of active deployments
|
||||
// Attempts to use attribute from both schemas (1.6 and 1.7)
|
||||
$activeDeploymentId = $resource->getAttribute('deploymentId', $resource->getAttribute('deployment', ''));
|
||||
|
||||
// Get deployment document, as intended originally
|
||||
$deployment = $authorization->skip(fn () => $dbForProject->getDocument('deployments', $activeDeploymentId));
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $activeDeploymentId));
|
||||
}
|
||||
|
||||
if ($deployment->getAttribute('resourceType', '') === 'functions') {
|
||||
@@ -197,8 +197,8 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
}
|
||||
|
||||
$resource = $type === 'function' ?
|
||||
$authorization->skip(fn () => $dbForProject->getDocument('functions', $deployment->getAttribute('resourceId', ''))) :
|
||||
$authorization->skip(fn () => $dbForProject->getDocument('sites', $deployment->getAttribute('resourceId', '')));
|
||||
Authorization::skip(fn () => $dbForProject->getDocument('functions', $deployment->getAttribute('resourceId', ''))) :
|
||||
Authorization::skip(fn () => $dbForProject->getDocument('sites', $deployment->getAttribute('resourceId', '')));
|
||||
|
||||
$isPreview = $type === 'function' ? false : ($rule->getAttribute('trigger', '') !== 'manual');
|
||||
|
||||
@@ -240,7 +240,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
$userExists = false;
|
||||
$userId = $payload['userId'] ?? '';
|
||||
if (!empty($userId)) {
|
||||
$user = $authorization->skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
$user = Authorization::skip(fn () => $dbForPlatform->getDocument('users', $userId));
|
||||
if (!$user->isEmpty() && $user->getAttribute('status', false)) {
|
||||
$userExists = true;
|
||||
}
|
||||
@@ -253,7 +253,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
||||
}
|
||||
|
||||
$membershipExists = false;
|
||||
$project = $authorization->skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
if (!$project->isEmpty() && isset($user)) {
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
$membership = $user->find('teamId', $teamId, 'memberships');
|
||||
@@ -864,8 +864,7 @@ App::init()
|
||||
->inject('apiKey')
|
||||
->inject('httpReferrer')
|
||||
->inject('httpReferrerSafe')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $platforms, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, Executor $executor, callable $isResourceBlocked, string $previewHostname, Document $devKey, ?Key $apiKey, string $httpReferrer, string $httpReferrerSafe, Authorization $authorization) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Document $console, Document $project, Database $dbForPlatform, callable $getProjectDB, Locale $locale, array $localeCodes, array $platforms, Reader $geodb, StatsUsage $queueForStatsUsage, Event $queueForEvents, Certificate $queueForCertificates, Func $queueForFunctions, Executor $executor, callable $isResourceBlocked, string $previewHostname, Document $devKey, ?Key $apiKey, string $httpReferrer, string $httpReferrerSafe) {
|
||||
/*
|
||||
* Appwrite Router
|
||||
*/
|
||||
@@ -873,7 +872,7 @@ App::init()
|
||||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if ($host !== $mainDomain || !empty($previewHostname)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $authorization, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
@@ -924,7 +923,7 @@ App::init()
|
||||
} elseif (str_starts_with($request->getURI(), '/.well-known/acme-challenge')) {
|
||||
Console::warning('Skipping SSL certificates generation on ACME challenge.');
|
||||
} else {
|
||||
$authorization->disable();
|
||||
Authorization::disable();
|
||||
|
||||
$envDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
$mainDomain = null;
|
||||
@@ -994,7 +993,7 @@ App::init()
|
||||
}
|
||||
$domains[$domain->get()] = true;
|
||||
|
||||
$authorization->reset(); // ensure authorization is re-enabled
|
||||
Authorization::reset(); // ensure authorization is re-enabled
|
||||
}
|
||||
Config::setParam('domains', $domains);
|
||||
}
|
||||
@@ -1130,8 +1129,7 @@ App::options()
|
||||
->inject('project')
|
||||
->inject('devKey')
|
||||
->inject('apiKey')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project, Document $devKey, ?Key $apiKey, Authorization $authorization) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, Document $project, Document $devKey, ?Key $apiKey) {
|
||||
/*
|
||||
* Appwrite Router
|
||||
*/
|
||||
@@ -1139,7 +1137,7 @@ App::options()
|
||||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if ($host !== $mainDomain || !empty($previewHostname)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $authorization, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
@@ -1180,8 +1178,7 @@ App::error()
|
||||
->inject('log')
|
||||
->inject('queueForStatsUsage')
|
||||
->inject('devKey')
|
||||
->inject('authorization')
|
||||
->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, StatsUsage $queueForStatsUsage, Document $devKey, Authorization $authorization) {
|
||||
->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, StatsUsage $queueForStatsUsage) {
|
||||
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
$route = $utopia->getRoute();
|
||||
$class = \get_class($error);
|
||||
@@ -1263,7 +1260,7 @@ App::error()
|
||||
* If not a publishable error, track usage stats. Publishable errors are >= 500 or those explicitly marked as publish=true in errors.php
|
||||
*/
|
||||
if (!$publish && $project->getId() !== 'console') {
|
||||
if (!Auth::isPrivilegedUser($authorization->getRoles())) {
|
||||
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
|
||||
$fileSize = 0;
|
||||
$file = $request->getFiles('file');
|
||||
if (!empty($file)) {
|
||||
@@ -1325,7 +1322,7 @@ App::error()
|
||||
$log->addExtra('file', $error->getFile());
|
||||
$log->addExtra('line', $error->getLine());
|
||||
$log->addExtra('trace', $error->getTraceAsString());
|
||||
$log->addExtra('roles', $authorization->getRoles());
|
||||
$log->addExtra('roles', Authorization::getRoles());
|
||||
|
||||
$action = 'UNKNOWN_NAMESPACE.UNKNOWN.METHOD';
|
||||
if (!empty($sdk)) {
|
||||
@@ -1448,8 +1445,7 @@ App::get('/robots.txt')
|
||||
->inject('isResourceBlocked')
|
||||
->inject('previewHostname')
|
||||
->inject('apiKey')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey, Authorization $authorization) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
$host = $request->getHostname() ?? '';
|
||||
$consoleDomain = System::getEnv('_APP_CONSOLE_DOMAIN', '');
|
||||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
@@ -1458,7 +1454,7 @@ App::get('/robots.txt')
|
||||
$template = new View(__DIR__ . '/../views/general/robots.phtml');
|
||||
$response->text($template->render(false));
|
||||
} else {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $authorization, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
@@ -1483,8 +1479,7 @@ App::get('/humans.txt')
|
||||
->inject('isResourceBlocked')
|
||||
->inject('previewHostname')
|
||||
->inject('apiKey')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey, Authorization $authorization) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Log $log, Database $dbForPlatform, callable $getProjectDB, Event $queueForEvents, StatsUsage $queueForStatsUsage, Func $queueForFunctions, Executor $executor, Reader $geodb, callable $isResourceBlocked, string $previewHostname, ?Key $apiKey) {
|
||||
$host = $request->getHostname() ?? '';
|
||||
$consoleDomain = System::getEnv('_APP_CONSOLE_DOMAIN', '');
|
||||
$mainDomain = System::getEnv('_APP_DOMAIN', '');
|
||||
@@ -1493,7 +1488,7 @@ App::get('/humans.txt')
|
||||
$template = new View(__DIR__ . '/../views/general/humans.phtml');
|
||||
$response->text($template->render(false));
|
||||
} else {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $authorization, $apiKey)) {
|
||||
if (router($utopia, $dbForPlatform, $getProjectDB, $swooleRequest, $request, $response, $log, $queueForEvents, $queueForStatsUsage, $queueForFunctions, $executor, $geodb, $isResourceBlocked, $previewHostname, $apiKey)) {
|
||||
$utopia->getRoute()?->label('router', true);
|
||||
}
|
||||
}
|
||||
@@ -1577,8 +1572,7 @@ App::get('/v1/ping')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('queueForEvents')
|
||||
->inject('authorization')
|
||||
->action(function (Response $response, Document $project, Database $dbForPlatform, Event $queueForEvents, Authorization $authorization) {
|
||||
->action(function (Response $response, Document $project, Database $dbForPlatform, Event $queueForEvents) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
throw new AppwriteException(AppwriteException::PROJECT_NOT_FOUND);
|
||||
}
|
||||
@@ -1590,7 +1584,7 @@ App::get('/v1/ping')
|
||||
->setAttribute('pingCount', $pingCount)
|
||||
->setAttribute('pingedAt', $pingedAt);
|
||||
|
||||
$authorization->skip(function () use ($dbForPlatform, $project) {
|
||||
Authorization::skip(function () use ($dbForPlatform, $project) {
|
||||
$dbForPlatform->updateDocument('projects', $project->getId(), $project);
|
||||
});
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Authorization\Input;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Telemetry\Adapter as Telemetry;
|
||||
@@ -233,8 +232,7 @@ App::init()
|
||||
->inject('mode')
|
||||
->inject('team')
|
||||
->inject('apiKey')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, Request $request, Database $dbForPlatform, Database $dbForProject, Audit $queueForAudits, Document $project, Document $user, ?Document $session, array $servers, string $mode, Document $team, ?Key $apiKey, Authorization $authorization) {
|
||||
->action(function (App $utopia, Request $request, Database $dbForPlatform, Database $dbForProject, Audit $queueForAudits, Document $project, Document $user, ?Document $session, array $servers, string $mode, Document $team, ?Key $apiKey) {
|
||||
$route = $utopia->getRoute();
|
||||
if (System::getEnv('_APP_EDITION', 'self-hosted') === 'self-hosted' && str_starts_with($route->getPath(), '/v1/backups')) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST, 'Database Backups are available on Appwrite Cloud');
|
||||
@@ -266,7 +264,7 @@ App::init()
|
||||
|
||||
if ($apiKey->getRole() === Auth::USER_ROLE_APPS) {
|
||||
// Disable authorization checks for API keys
|
||||
$authorization->setDefaultStatus(false);
|
||||
Authorization::setDefaultStatus(false);
|
||||
|
||||
$user = new Document([
|
||||
'$id' => '',
|
||||
@@ -339,14 +337,14 @@ App::init()
|
||||
$scopes = \array_merge($scopes, $roles[$role]['scopes']);
|
||||
}
|
||||
|
||||
$authorization->setDefaultStatus(false); // Cancel security segmentation for admin users.
|
||||
Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
|
||||
}
|
||||
|
||||
$scopes = \array_unique($scopes);
|
||||
|
||||
$authorization->addRole($role);
|
||||
foreach (Auth::getRoles($user, $authorization) as $authRole) {
|
||||
$authorization->addRole($authRole);
|
||||
Authorization::setRole($role);
|
||||
foreach (Auth::getRoles($user) as $authRole) {
|
||||
Authorization::setRole($authRole);
|
||||
}
|
||||
|
||||
// Update project last activity
|
||||
@@ -354,7 +352,7 @@ App::init()
|
||||
$accessedAt = $project->getAttribute('accessedAt', 0);
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) {
|
||||
$project->setAttribute('accessedAt', DateTime::now());
|
||||
$authorization->skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
|
||||
Authorization::skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,7 +387,7 @@ App::init()
|
||||
if (
|
||||
array_key_exists($namespace, $project->getAttribute('services', []))
|
||||
&& !$project->getAttribute('services', [])[$namespace]
|
||||
&& !(Auth::isPrivilegedUser($authorization->getRoles()) || Auth::isAppUser($authorization->getRoles()))
|
||||
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
|
||||
) {
|
||||
throw new Exception(Exception::GENERAL_SERVICE_DISABLED);
|
||||
}
|
||||
@@ -449,15 +447,14 @@ App::init()
|
||||
->inject('plan')
|
||||
->inject('devKey')
|
||||
->inject('telemetry')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Publisher $publisherFunctions, Publisher $publisherWebhooks, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry, Authorization $authorization) use ($usageDatabaseListener, $eventDatabaseListener) {
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Publisher $publisherFunctions, Publisher $publisherWebhooks, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry) use ($usageDatabaseListener, $eventDatabaseListener) {
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
if (
|
||||
array_key_exists('rest', $project->getAttribute('apis', []))
|
||||
&& !$project->getAttribute('apis', [])['rest']
|
||||
&& !(Auth::isPrivilegedUser($authorization->getRoles()) || Auth::isAppUser($authorization->getRoles()))
|
||||
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
|
||||
) {
|
||||
throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED);
|
||||
}
|
||||
@@ -487,7 +484,7 @@ App::init()
|
||||
|
||||
$closestLimit = null;
|
||||
|
||||
$roles = $authorization->getRoles();
|
||||
$roles = Authorization::getRoles();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
|
||||
$isAppUser = Auth::isAppUser($roles);
|
||||
|
||||
@@ -587,10 +584,10 @@ App::init()
|
||||
if ($useCache) {
|
||||
$route = $utopia->match($request);
|
||||
$isImageTransformation = $route->getPath() === '/v1/storage/buckets/:bucketId/files/:fileId/preview';
|
||||
$isDisabled = isset($plan['imageTransformations']) && $plan['imageTransformations'] === -1 && !Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isDisabled = isset($plan['imageTransformations']) && $plan['imageTransformations'] === -1 && !Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
$key = $request->cacheIdentifier();
|
||||
$cacheLog = $authorization->skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
$cache = new Cache(
|
||||
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId())
|
||||
);
|
||||
@@ -607,10 +604,10 @@ App::init()
|
||||
|
||||
if ($type === 'bucket' && (!$isImageTransformation || !$isDisabled)) {
|
||||
$bucketId = $parts[1] ?? null;
|
||||
$bucket = $authorization->skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
|
||||
|
||||
$isToken = !$resourceToken->isEmpty() && $resourceToken->getAttribute('bucketInternalId') === $bucket->getSequence();
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAppUser && !$isPrivilegedUser)) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
@@ -621,7 +618,8 @@ App::init()
|
||||
}
|
||||
|
||||
$fileSecurity = $bucket->getAttribute('fileSecurity', false);
|
||||
$valid = $authorization->isValid(new Input(Database::PERMISSION_READ, $bucket->getRead()));
|
||||
$validator = new Authorization(Database::PERMISSION_READ);
|
||||
$valid = $validator->isValid($bucket->getRead());
|
||||
if (!$fileSecurity && !$valid && !$isToken) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
}
|
||||
@@ -632,7 +630,7 @@ App::init()
|
||||
if ($fileSecurity && !$valid && !$isToken) {
|
||||
$file = $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId);
|
||||
} else {
|
||||
$file = $authorization->skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getSequence(), $fileId));
|
||||
}
|
||||
|
||||
if (!$resourceToken->isEmpty() && $resourceToken->getAttribute('fileInternalId') !== $file->getSequence()) {
|
||||
@@ -643,11 +641,11 @@ App::init()
|
||||
throw new Exception(Exception::STORAGE_FILE_NOT_FOUND);
|
||||
}
|
||||
//Do not update transformedAt if it's a console user
|
||||
if (!Auth::isPrivilegedUser($authorization->getRoles())) {
|
||||
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
|
||||
$transformedAt = $file->getAttribute('transformedAt', '');
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $transformedAt) {
|
||||
$file->setAttribute('transformedAt', DateTime::now());
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('bucket_' . $file->getAttribute('bucketInternalId'), $file->getId(), $file));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $file->getAttribute('bucketInternalId'), $file->getId(), $file));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -743,8 +741,7 @@ App::shutdown()
|
||||
->inject('queueForWebhooks')
|
||||
->inject('queueForRealtime')
|
||||
->inject('dbForProject')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, StatsUsage $queueForStatsUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject, Authorization $authorization) use ($parseLabel) {
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, StatsUsage $queueForStatsUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, Messaging $queueForMessaging, Func $queueForFunctions, Event $queueForWebhooks, Realtime $queueForRealtime, Database $dbForProject) use ($parseLabel) {
|
||||
|
||||
$responsePayload = $response->getPayload();
|
||||
|
||||
@@ -870,11 +867,11 @@ App::shutdown()
|
||||
|
||||
$key = $request->cacheIdentifier();
|
||||
$signature = md5($data['payload']);
|
||||
$cacheLog = $authorization->skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
$accessedAt = $cacheLog->getAttribute('accessedAt', 0);
|
||||
$now = DateTime::now();
|
||||
if ($cacheLog->isEmpty()) {
|
||||
$authorization->skip(fn () => $dbForProject->createDocument('cache', new Document([
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('cache', new Document([
|
||||
'$id' => $key,
|
||||
'resource' => $resource,
|
||||
'resourceType' => $resourceType,
|
||||
@@ -884,7 +881,7 @@ App::shutdown()
|
||||
])));
|
||||
} elseif (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_CACHE_UPDATE)) > $accessedAt) {
|
||||
$cacheLog->setAttribute('accessedAt', $now);
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
|
||||
// Overwrite the file every APP_CACHE_UPDATE seconds to update the file modified time that is used in the TTL checks in cache->load()
|
||||
$cache->save($key, $data['payload']);
|
||||
}
|
||||
@@ -896,7 +893,7 @@ App::shutdown()
|
||||
}
|
||||
|
||||
if ($project->getId() !== 'console') {
|
||||
if (!Auth::isPrivilegedUser($authorization->getRoles())) {
|
||||
if (!Auth::isPrivilegedUser(Authorization::getRoles())) {
|
||||
$fileSize = 0;
|
||||
$file = $request->getFiles('file');
|
||||
if (!empty($file)) {
|
||||
|
||||
@@ -36,8 +36,7 @@ App::init()
|
||||
->inject('request')
|
||||
->inject('project')
|
||||
->inject('geodb')
|
||||
->inject('authorization')
|
||||
->action(function (App $utopia, Request $request, Document $project, Reader $geodb, Authorization $authorization) {
|
||||
->action(function (App $utopia, Request $request, Document $project, Reader $geodb) {
|
||||
$denylist = System::getEnv('_APP_CONSOLE_COUNTRIES_DENYLIST', '');
|
||||
if (!empty($denylist && $project->getId() === 'console')) {
|
||||
$countries = explode(',', $denylist);
|
||||
@@ -50,8 +49,8 @@ App::init()
|
||||
|
||||
$route = $utopia->match($request);
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser($authorization->getRoles());
|
||||
$isAppUser = Auth::isAppUser($authorization->getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
$isAppUser = Auth::isAppUser(Authorization::getRoles());
|
||||
|
||||
if ($isAppUser || $isPrivilegedUser) { // Skip limits for app and console devs
|
||||
return;
|
||||
|
||||
+11
-17
@@ -25,6 +25,7 @@ use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Logger\Log\User;
|
||||
use Utopia\Pools\Group;
|
||||
@@ -258,9 +259,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
||||
createDatabase($app, 'getLogsDB', 'logs', $collections['logs'], $pools);
|
||||
|
||||
// create appwrite database, `dbForPlatform` is a direct access call.
|
||||
createDatabase($app, 'dbForPlatform', 'appwrite', $collections['console'], $pools, function (Database $dbForPlatform) use ($collections, $app) {
|
||||
$authorization = $app->getResource('authorization');
|
||||
|
||||
createDatabase($app, 'dbForPlatform', 'appwrite', $collections['console'], $pools, function (Database $dbForPlatform) use ($collections) {
|
||||
if ($dbForPlatform->getCollection(Audit::COLLECTION)->isEmpty()) {
|
||||
$audit = new Audit($dbForPlatform);
|
||||
$audit->setup();
|
||||
@@ -319,9 +318,9 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
||||
$dbForPlatform->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes);
|
||||
}
|
||||
|
||||
if ($authorization->skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots')->isEmpty())) {
|
||||
if (Authorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots')->isEmpty())) {
|
||||
Console::info(" └── Creating screenshots bucket...");
|
||||
$authorization->skip(fn () => $dbForPlatform->createDocument('buckets', new Document([
|
||||
Authorization::skip(fn () => $dbForPlatform->createDocument('buckets', new Document([
|
||||
'$id' => ID::custom('screenshots'),
|
||||
'$collection' => ID::custom('buckets'),
|
||||
'name' => 'Screenshots',
|
||||
@@ -336,7 +335,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
||||
'search' => 'buckets Screenshots',
|
||||
])));
|
||||
|
||||
$bucket = $authorization->skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
|
||||
$bucket = Authorization::skip(fn () => $dbForPlatform->getDocument('buckets', 'screenshots'));
|
||||
|
||||
Console::info(" └── Creating files collection for screenshots bucket...");
|
||||
$files = $collections['buckets']['files'] ?? [];
|
||||
@@ -364,7 +363,7 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
||||
'orders' => $index['orders'],
|
||||
]), $files['indexes']);
|
||||
|
||||
$authorization->skip(fn () => $dbForPlatform->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes));
|
||||
Authorization::skip(fn () => $dbForPlatform->createCollection('bucket_' . $bucket->getSequence(), $attributes, $indexes));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -455,12 +454,8 @@ $http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, Swool
|
||||
App::setResource('pools', fn () => $pools);
|
||||
|
||||
try {
|
||||
$authorization = $app->getResource('authorization');
|
||||
|
||||
$request->setAuthorization($authorization);
|
||||
$response->setAuthorization($authorization);
|
||||
$authorization->cleanRoles();
|
||||
$authorization->addRole(Role::any()->toString());
|
||||
Authorization::cleanRoles();
|
||||
Authorization::setRole(Role::any()->toString());
|
||||
|
||||
$app->run($request, $response);
|
||||
} catch (\Throwable $th) {
|
||||
@@ -502,7 +497,7 @@ $http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, Swool
|
||||
$log->addExtra('file', $th->getFile());
|
||||
$log->addExtra('line', $th->getLine());
|
||||
$log->addExtra('trace', $th->getTraceAsString());
|
||||
$log->addExtra('roles', isset($authorization) ? $authorization->getRoles() : []);
|
||||
$log->addExtra('roles', Authorization::getRoles());
|
||||
|
||||
$sdk = $route->getLabel("sdk", false);
|
||||
|
||||
@@ -561,7 +556,7 @@ $http->on(Constant::EVENT_TASK, function () use ($register, $domains) {
|
||||
/** @var Utopia\Database\Database $dbForPlatform */
|
||||
$dbForPlatform = $app->getResource('dbForPlatform');
|
||||
|
||||
Timer::tick(DOMAIN_SYNC_TIMER * 1000, function () use ($dbForPlatform, $domains, &$lastSyncUpdate, $app) {
|
||||
Timer::tick(DOMAIN_SYNC_TIMER * 1000, function () use ($dbForPlatform, $domains, &$lastSyncUpdate) {
|
||||
try {
|
||||
$time = DateTime::now();
|
||||
$limit = 1000;
|
||||
@@ -578,8 +573,7 @@ $http->on(Constant::EVENT_TASK, function () use ($register, $domains) {
|
||||
}
|
||||
$results = [];
|
||||
try {
|
||||
$authorization = $app->getResource('authorization');
|
||||
$results = $authorization->skip(fn () => $dbForPlatform->find('rules', $queries));
|
||||
$results = Authorization::skip(fn () => $dbForPlatform->find('rules', $queries));
|
||||
} catch (Throwable $th) {
|
||||
Console::error($th->getMessage());
|
||||
}
|
||||
|
||||
+39
-36
@@ -1,42 +1,45 @@
|
||||
<?php
|
||||
|
||||
use Utopia\Config\Adapters\PHP;
|
||||
use Utopia\Config\Config;
|
||||
|
||||
require_once __DIR__ . '/../config/storage/resource_limits.php';
|
||||
|
||||
Config::load('template-runtimes', __DIR__ . '/../config/template-runtimes.php');
|
||||
Config::load('events', __DIR__ . '/../config/events.php');
|
||||
Config::load('auth', __DIR__ . '/../config/auth.php');
|
||||
Config::load('apis', __DIR__ . '/../config/apis.php'); // List of APIs
|
||||
Config::load('errors', __DIR__ . '/../config/errors.php');
|
||||
Config::load('oAuthProviders', __DIR__ . '/../config/oAuthProviders.php');
|
||||
Config::load('platforms', __DIR__ . '/../config/platforms.php');
|
||||
Config::load('console', __DIR__ . '/../config/console.php');
|
||||
Config::load('collections', __DIR__ . '/../config/collections.php');
|
||||
Config::load('frameworks', __DIR__ . '/../config/frameworks.php');
|
||||
Config::load('runtimes', __DIR__ . '/../config/runtimes.php');
|
||||
Config::load('runtimes-v2', __DIR__ . '/../config/runtimes-v2.php');
|
||||
Config::load('usage', __DIR__ . '/../config/usage.php');
|
||||
Config::load('roles', __DIR__ . '/../config/roles.php'); // User roles and scopes
|
||||
Config::load('scopes', __DIR__ . '/../config/scopes.php'); // User roles and scopes
|
||||
Config::load('services', __DIR__ . '/../config/services.php'); // List of services
|
||||
Config::load('variables', __DIR__ . '/../config/variables.php'); // List of env variables
|
||||
Config::load('regions', __DIR__ . '/../config/regions.php'); // List of available regions
|
||||
Config::load('avatar-browsers', __DIR__ . '/../config/avatars/browsers.php');
|
||||
Config::load('avatar-credit-cards', __DIR__ . '/../config/avatars/credit-cards.php');
|
||||
Config::load('avatar-flags', __DIR__ . '/../config/avatars/flags.php');
|
||||
Config::load('locale-codes', __DIR__ . '/../config/locale/codes.php');
|
||||
Config::load('locale-currencies', __DIR__ . '/../config/locale/currencies.php');
|
||||
Config::load('locale-eu', __DIR__ . '/../config/locale/eu.php');
|
||||
Config::load('locale-languages', __DIR__ . '/../config/locale/languages.php');
|
||||
Config::load('locale-phones', __DIR__ . '/../config/locale/phones.php');
|
||||
Config::load('locale-countries', __DIR__ . '/../config/locale/countries.php');
|
||||
Config::load('locale-continents', __DIR__ . '/../config/locale/continents.php');
|
||||
Config::load('locale-templates', __DIR__ . '/../config/locale/templates.php');
|
||||
Config::load('storage-logos', __DIR__ . '/../config/storage/logos.php');
|
||||
Config::load('storage-mimes', __DIR__ . '/../config/storage/mimes.php');
|
||||
Config::load('storage-inputs', __DIR__ . '/../config/storage/inputs.php');
|
||||
Config::load('storage-outputs', __DIR__ . '/../config/storage/outputs.php');
|
||||
Config::load('specifications', __DIR__ . '/../config/specifications.php');
|
||||
Config::load('templates-function', __DIR__ . '/../config/templates/function.php');
|
||||
Config::load('templates-site', __DIR__ . '/../config/templates/site.php');
|
||||
$configAdapter = new PHP();
|
||||
|
||||
Config::load('template-runtimes', __DIR__ . '/../config/template-runtimes.php', $configAdapter);
|
||||
Config::load('events', __DIR__ . '/../config/events.php', $configAdapter);
|
||||
Config::load('auth', __DIR__ . '/../config/auth.php', $configAdapter);
|
||||
Config::load('apis', __DIR__ . '/../config/apis.php', $configAdapter); // List of APIs
|
||||
Config::load('errors', __DIR__ . '/../config/errors.php', $configAdapter);
|
||||
Config::load('oAuthProviders', __DIR__ . '/../config/oAuthProviders.php', $configAdapter);
|
||||
Config::load('platforms', __DIR__ . '/../config/platforms.php', $configAdapter);
|
||||
Config::load('console', __DIR__ . '/../config/console.php', $configAdapter);
|
||||
Config::load('collections', __DIR__ . '/../config/collections.php', $configAdapter);
|
||||
Config::load('frameworks', __DIR__ . '/../config/frameworks.php', $configAdapter);
|
||||
Config::load('runtimes', __DIR__ . '/../config/runtimes.php', $configAdapter);
|
||||
Config::load('runtimes-v2', __DIR__ . '/../config/runtimes-v2.php', $configAdapter);
|
||||
Config::load('usage', __DIR__ . '/../config/usage.php', $configAdapter);
|
||||
Config::load('roles', __DIR__ . '/../config/roles.php', $configAdapter); // User roles and scopes
|
||||
Config::load('scopes', __DIR__ . '/../config/scopes.php', $configAdapter); // User roles and scopes
|
||||
Config::load('services', __DIR__ . '/../config/services.php', $configAdapter); // List of services
|
||||
Config::load('variables', __DIR__ . '/../config/variables.php', $configAdapter); // List of env variables
|
||||
Config::load('regions', __DIR__ . '/../config/regions.php', $configAdapter); // List of available regions
|
||||
Config::load('avatar-browsers', __DIR__ . '/../config/avatars/browsers.php', $configAdapter);
|
||||
Config::load('avatar-credit-cards', __DIR__ . '/../config/avatars/credit-cards.php', $configAdapter);
|
||||
Config::load('avatar-flags', __DIR__ . '/../config/avatars/flags.php', $configAdapter);
|
||||
Config::load('locale-codes', __DIR__ . '/../config/locale/codes.php', $configAdapter);
|
||||
Config::load('locale-currencies', __DIR__ . '/../config/locale/currencies.php', $configAdapter);
|
||||
Config::load('locale-eu', __DIR__ . '/../config/locale/eu.php', $configAdapter);
|
||||
Config::load('locale-languages', __DIR__ . '/../config/locale/languages.php', $configAdapter);
|
||||
Config::load('locale-phones', __DIR__ . '/../config/locale/phones.php', $configAdapter);
|
||||
Config::load('locale-countries', __DIR__ . '/../config/locale/countries.php', $configAdapter);
|
||||
Config::load('locale-continents', __DIR__ . '/../config/locale/continents.php', $configAdapter);
|
||||
Config::load('locale-templates', __DIR__ . '/../config/locale/templates.php', $configAdapter);
|
||||
Config::load('storage-logos', __DIR__ . '/../config/storage/logos.php', $configAdapter);
|
||||
Config::load('storage-mimes', __DIR__ . '/../config/storage/mimes.php', $configAdapter);
|
||||
Config::load('storage-inputs', __DIR__ . '/../config/storage/inputs.php', $configAdapter);
|
||||
Config::load('storage-outputs', __DIR__ . '/../config/storage/outputs.php', $configAdapter);
|
||||
Config::load('specifications', __DIR__ . '/../config/specifications.php', $configAdapter);
|
||||
Config::load('templates-function', __DIR__ . '/../config/templates/function.php', $configAdapter);
|
||||
Config::load('templates-site', __DIR__ . '/../config/templates/site.php', $configAdapter);
|
||||
|
||||
@@ -4,6 +4,7 @@ use Appwrite\OpenSSL\OpenSSL;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\System\System;
|
||||
|
||||
Database::addFilter(
|
||||
@@ -175,7 +176,7 @@ Database::addFilter(
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database->getAuthorization()->skip(fn () => $database->find('sessions', [
|
||||
return Authorization::skip(fn () => $database->find('sessions', [
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]));
|
||||
@@ -188,7 +189,7 @@ Database::addFilter(
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database->getAuthorization()->skip(fn () => $database
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('tokens', [
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
@@ -202,7 +203,7 @@ Database::addFilter(
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database->getAuthorization()->skip(fn () => $database
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('challenges', [
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
@@ -216,7 +217,7 @@ Database::addFilter(
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database->getAuthorization()->skip(fn () => $database
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('authenticators', [
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
@@ -230,7 +231,7 @@ Database::addFilter(
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database->getAuthorization()->skip(fn () => $database
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('memberships', [
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
@@ -330,7 +331,7 @@ Database::addFilter(
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database->getAuthorization()->skip(fn () => $database
|
||||
return Authorization::skip(fn () => $database
|
||||
->find('targets', [
|
||||
Query::equal('userInternalId', [$document->getSequence()]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY)
|
||||
@@ -344,7 +345,7 @@ Database::addFilter(
|
||||
return;
|
||||
},
|
||||
function (mixed $value, Document $document, Database $database) {
|
||||
$targetIds = $database->getAuthorization()->skip(fn () => \array_map(
|
||||
$targetIds = Authorization::skip(fn () => \array_map(
|
||||
fn ($document) => $document->getAttribute('targetInternalId'),
|
||||
$database->find('subscribers', [
|
||||
Query::equal('topicInternalId', [$document->getSequence()]),
|
||||
|
||||
+43
-53
@@ -152,7 +152,7 @@ App::setResource('queueForMigrations', function (Publisher $publisher) {
|
||||
App::setResource('queueForStatsResources', function (Publisher $publisher) {
|
||||
return new StatsResources($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('platforms', function (Request $request, Document $console, Document $project, Database $dbForPlatform, Authorization $authorization) {
|
||||
App::setResource('platforms', function (Request $request, Document $console, Document $project, Database $dbForPlatform) {
|
||||
$console->setAttribute('platforms', [ // Always allow current host
|
||||
'$collection' => ID::custom('platforms'),
|
||||
'name' => 'Current Host',
|
||||
@@ -200,9 +200,9 @@ App::setResource('platforms', function (Request $request, Document $console, Doc
|
||||
// Safe if rule with same project ID exists
|
||||
if (!empty($origin)) {
|
||||
if (System::getEnv('_APP_RULES_FORMAT') === 'md5') {
|
||||
$rule = $authorization->skip(fn () => $dbForPlatform->getDocument('rules', md5($origin ?? '')));
|
||||
$rule = Authorization::skip(fn () => $dbForPlatform->getDocument('rules', md5($origin ?? '')));
|
||||
} else {
|
||||
$rule = $authorization->skip(
|
||||
$rule = Authorization::skip(
|
||||
fn () => $dbForPlatform->find('rules', [
|
||||
Query::equal('domain', [$origin]),
|
||||
Query::limit(1)
|
||||
@@ -224,18 +224,17 @@ App::setResource('platforms', function (Request $request, Document $console, Doc
|
||||
...$console->getAttribute('platforms', []),
|
||||
...$project->getAttribute('platforms', []),
|
||||
];
|
||||
}, ['request', 'console', 'project', 'dbForPlatform', 'authorization']);
|
||||
}, ['request', 'console', 'project', 'dbForPlatform']);
|
||||
|
||||
App::setResource('user', function ($mode, $project, $console, $request, $response, $dbForProject, $dbForPlatform, $authorization) {
|
||||
App::setResource('user', function ($mode, $project, $console, $request, $response, $dbForProject, $dbForPlatform) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Database $dbForPlatform */
|
||||
/** @var Utopia\Database\Authorization $authorization */
|
||||
/** @var string $mode */
|
||||
|
||||
$authorization->setDefaultStatus(true);
|
||||
Authorization::setDefaultStatus(true);
|
||||
|
||||
Auth::setCookieName('a_session_' . $project->getId());
|
||||
|
||||
@@ -299,7 +298,7 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
|
||||
|
||||
// if (APP_MODE_ADMIN === $mode) {
|
||||
// if ($user->find('teamInternalId', $project->getAttribute('teamInternalId'), 'memberships')) {
|
||||
// $authorization->setDefaultStatus(false); // Cancel security segmentation for admin users.
|
||||
// Authorization::setDefaultStatus(false); // Cancel security segmentation for admin users.
|
||||
// } else {
|
||||
// $user = new Document([]);
|
||||
// }
|
||||
@@ -337,9 +336,9 @@ App::setResource('user', function ($mode, $project, $console, $request, $respons
|
||||
$dbForPlatform->setMetadata('user', $user->getId());
|
||||
|
||||
return $user;
|
||||
}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForPlatform', 'authorization']);
|
||||
}, ['mode', 'project', 'console', 'request', 'response', 'dbForProject', 'dbForPlatform']);
|
||||
|
||||
App::setResource('project', function ($dbForPlatform, $request, $console, $authorization) {
|
||||
App::setResource('project', function ($dbForPlatform, $request, $console) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Utopia\Database\Database $dbForPlatform */
|
||||
/** @var Utopia\Database\Document $console */
|
||||
@@ -350,10 +349,10 @@ App::setResource('project', function ($dbForPlatform, $request, $console, $autho
|
||||
return $console;
|
||||
}
|
||||
|
||||
$project = $authorization->skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
$project = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $projectId));
|
||||
|
||||
return $project;
|
||||
}, ['dbForPlatform', 'request', 'console', 'authorization']);
|
||||
}, ['dbForPlatform', 'request', 'console']);
|
||||
|
||||
App::setResource('session', function (Document $user) {
|
||||
if ($user->isEmpty()) {
|
||||
@@ -380,11 +379,7 @@ App::setResource('console', function () {
|
||||
return new Document(Config::getParam('console'));
|
||||
}, []);
|
||||
|
||||
App::setResource('authorization', function () {
|
||||
return new Authorization();
|
||||
}, []);
|
||||
|
||||
App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform, Cache $cache, Document $project, Authorization $authorization) {
|
||||
App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform, Cache $cache, Document $project) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
@@ -400,7 +395,6 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform
|
||||
$database = new Database($adapter, $cache);
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId())
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
@@ -421,15 +415,13 @@ App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform
|
||||
}
|
||||
|
||||
return $database;
|
||||
}, ['pools', 'dbForPlatform', 'cache', 'project', 'authorization']);
|
||||
|
||||
App::setResource('dbForPlatform', function (Group $pools, Cache $cache, Authorization $authorization) {
|
||||
}, ['pools', 'dbForPlatform', 'cache', 'project']);
|
||||
|
||||
App::setResource('dbForPlatform', function (Group $pools, Cache $cache) {
|
||||
$adapter = new DatabasePool($pools->get('console'));
|
||||
$database = new Database($adapter, $cache);
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setNamespace('_console')
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', 'console')
|
||||
@@ -437,12 +429,12 @@ App::setResource('dbForPlatform', function (Group $pools, Cache $cache, Authoriz
|
||||
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
|
||||
|
||||
return $database;
|
||||
}, ['pools', 'cache', 'authorization']);
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache, Authorization $authorization) {
|
||||
App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) {
|
||||
$databases = [];
|
||||
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, $authorization, &$databases) {
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, &$databases) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
@@ -454,9 +446,8 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
|
||||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
$configure = (function (Database $database) use ($project, $dsn, $authorization) {
|
||||
$configure = (function (Database $database) use ($project, $dsn) {
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId())
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
@@ -490,12 +481,12 @@ App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'dbForPlatform', 'cache', 'authorization']);
|
||||
}, ['pools', 'dbForPlatform', 'cache']);
|
||||
|
||||
App::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorization $authorization) {
|
||||
App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database = null;
|
||||
|
||||
return function (?Document $project = null) use ($pools, $cache, $authorization, &$database) {
|
||||
return function (?Document $project = null) use ($pools, $cache, &$database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant((int) $project->getSequence());
|
||||
return $database;
|
||||
@@ -505,7 +496,6 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizatio
|
||||
$database = new Database($adapter, $cache);
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_API)
|
||||
@@ -518,7 +508,7 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizatio
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'cache', 'authorization']);
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
App::setResource('telemetry', fn () => new NoTelemetry());
|
||||
|
||||
@@ -712,7 +702,7 @@ App::setResource('promiseAdapter', function ($register) {
|
||||
return $register->get('promiseAdapter');
|
||||
}, ['register']);
|
||||
|
||||
App::setResource('schema', function ($utopia, $dbForProject, $authorization) {
|
||||
App::setResource('schema', function ($utopia, $dbForProject) {
|
||||
|
||||
$complexity = function (int $complexity, array $args) {
|
||||
$queries = Query::parseQueries($args['queries'] ?? []);
|
||||
@@ -722,8 +712,8 @@ App::setResource('schema', function ($utopia, $dbForProject, $authorization) {
|
||||
return $complexity * $limit;
|
||||
};
|
||||
|
||||
$attributes = function (int $limit, int $offset) use ($dbForProject, $authorization) {
|
||||
$attrs = $authorization->skip(fn () => $dbForProject->find('attributes', [
|
||||
$attributes = function (int $limit, int $offset) use ($dbForProject) {
|
||||
$attrs = Authorization::skip(fn () => $dbForProject->find('attributes', [
|
||||
Query::limit($limit),
|
||||
Query::offset($offset),
|
||||
]));
|
||||
@@ -797,7 +787,7 @@ App::setResource('schema', function ($utopia, $dbForProject, $authorization) {
|
||||
$urls,
|
||||
$params,
|
||||
);
|
||||
}, ['utopia', 'dbForProject', 'authorization']);
|
||||
}, ['utopia', 'dbForProject']);
|
||||
|
||||
App::setResource('contributors', function () {
|
||||
$path = 'app/config/contributors.json';
|
||||
@@ -843,7 +833,7 @@ App::setResource('smsRates', function () {
|
||||
return [];
|
||||
});
|
||||
|
||||
App::setResource('devKey', function (Request $request, Document $project, array $servers, Database $dbForPlatform, Authorization $authorization) {
|
||||
App::setResource('devKey', function (Request $request, Document $project, array $servers, Database $dbForPlatform) {
|
||||
$devKey = $request->getHeader('x-appwrite-dev-key', $request->getParam('devKey', ''));
|
||||
|
||||
// Check if given key match project's development keys
|
||||
@@ -862,7 +852,7 @@ App::setResource('devKey', function (Request $request, Document $project, array
|
||||
$accessedAt = $key->getAttribute('accessedAt', 0);
|
||||
if (empty($accessedAt) || DatabaseDateTime::formatTz(DatabaseDateTime::addSeconds(new \DateTime(), -APP_KEY_ACCESS)) > $accessedAt) {
|
||||
$key->setAttribute('accessedAt', DatabaseDateTime::now());
|
||||
$authorization->skip(fn () => $dbForPlatform->updateDocument('devKeys', $key->getId(), $key));
|
||||
Authorization::skip(fn () => $dbForPlatform->updateDocument('devKeys', $key->getId(), $key));
|
||||
$dbForPlatform->purgeCachedDocument('projects', $project->getId());
|
||||
}
|
||||
|
||||
@@ -879,14 +869,14 @@ App::setResource('devKey', function (Request $request, Document $project, array
|
||||
|
||||
/** Update access time as well */
|
||||
$key->setAttribute('accessedAt', DatabaseDateTime::now());
|
||||
$key = $authorization->skip(fn () => $dbForPlatform->updateDocument('devKeys', $key->getId(), $key));
|
||||
$key = Authorization::skip(fn () => $dbForPlatform->updateDocument('devKeys', $key->getId(), $key));
|
||||
$dbForPlatform->purgeCachedDocument('projects', $project->getId());
|
||||
}
|
||||
}
|
||||
return $key;
|
||||
}, ['request', 'project', 'servers', 'dbForPlatform', 'authorization']);
|
||||
}, ['request', 'project', 'servers', 'dbForPlatform']);
|
||||
|
||||
App::setResource('team', function (Document $project, Database $dbForPlatform, App $utopia, Request $request, Authorization $authorization) {
|
||||
App::setResource('team', function (Document $project, Database $dbForPlatform, App $utopia, Request $request) {
|
||||
$teamInternalId = '';
|
||||
if ($project->getId() !== 'console') {
|
||||
$teamInternalId = $project->getAttribute('teamInternalId', '');
|
||||
@@ -896,7 +886,7 @@ App::setResource('team', function (Document $project, Database $dbForPlatform, A
|
||||
if (str_starts_with($path, '/v1/projects/:projectId')) {
|
||||
$uri = $request->getURI();
|
||||
$pid = explode('/', $uri)[3];
|
||||
$p = $authorization->skip(fn () => $dbForPlatform->getDocument('projects', $pid));
|
||||
$p = Authorization::skip(fn () => $dbForPlatform->getDocument('projects', $pid));
|
||||
$teamInternalId = $p->getAttribute('teamInternalId', '');
|
||||
} elseif ($path === '/v1/projects') {
|
||||
$teamId = $request->getParam('teamId', '');
|
||||
@@ -905,7 +895,7 @@ App::setResource('team', function (Document $project, Database $dbForPlatform, A
|
||||
return new Document([]);
|
||||
}
|
||||
|
||||
$team = $authorization->skip(fn () => $dbForPlatform->getDocument('teams', $teamId));
|
||||
$team = Authorization::skip(fn () => $dbForPlatform->getDocument('teams', $teamId));
|
||||
return $team;
|
||||
}
|
||||
}
|
||||
@@ -914,14 +904,14 @@ App::setResource('team', function (Document $project, Database $dbForPlatform, A
|
||||
return new Document([]);
|
||||
}
|
||||
|
||||
$team = $authorization->skip(function () use ($dbForPlatform, $teamInternalId) {
|
||||
$team = Authorization::skip(function () use ($dbForPlatform, $teamInternalId) {
|
||||
return $dbForPlatform->findOne('teams', [
|
||||
Query::equal('$sequence', [$teamInternalId]),
|
||||
]);
|
||||
});
|
||||
|
||||
return $team;
|
||||
}, ['project', 'dbForPlatform', 'utopia', 'request', 'authorization']);
|
||||
}, ['project', 'dbForPlatform', 'utopia', 'request']);
|
||||
|
||||
App::setResource(
|
||||
'isResourceBlocked',
|
||||
@@ -959,7 +949,7 @@ App::setResource('apiKey', function (Request $request, Document $project): ?Key
|
||||
|
||||
App::setResource('executor', fn () => new Executor());
|
||||
|
||||
App::setResource('resourceToken', function ($project, $dbForProject, $request, Authorization $authorization) {
|
||||
App::setResource('resourceToken', function ($project, $dbForProject, $request) {
|
||||
$tokenJWT = $request->getParam('token');
|
||||
|
||||
if (!empty($tokenJWT) && !$project->isEmpty()) { // JWT authentication
|
||||
@@ -976,7 +966,7 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request, A
|
||||
return new Document([]);
|
||||
}
|
||||
|
||||
$token = $authorization->skip(fn () => $dbForProject->getDocument('resourceTokens', $tokenId));
|
||||
$token = Authorization::skip(fn () => $dbForProject->getDocument('resourceTokens', $tokenId));
|
||||
|
||||
if ($token->isEmpty()) {
|
||||
return new Document([]);
|
||||
@@ -994,7 +984,7 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request, A
|
||||
}
|
||||
|
||||
return match ($token->getAttribute('resourceType')) {
|
||||
TOKENS_RESOURCE_TYPE_FILES => (function () use ($token, $dbForProject, $authorization) {
|
||||
TOKENS_RESOURCE_TYPE_FILES => (function () use ($token, $dbForProject) {
|
||||
$sequences = explode(':', $token->getAttribute('resourceInternalId'));
|
||||
$ids = explode(':', $token->getAttribute('resourceId'));
|
||||
|
||||
@@ -1005,7 +995,7 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request, A
|
||||
$accessedAt = $token->getAttribute('accessedAt', 0);
|
||||
if (empty($accessedAt) || DatabaseDateTime::formatTz(DatabaseDateTime::addSeconds(new \DateTime(), -APP_RESOURCE_TOKEN_ACCESS)) > $accessedAt) {
|
||||
$token->setAttribute('accessedAt', DatabaseDateTime::now());
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('resourceTokens', $token->getId(), $token));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('resourceTokens', $token->getId(), $token));
|
||||
}
|
||||
|
||||
return new Document([
|
||||
@@ -1020,7 +1010,7 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request, A
|
||||
};
|
||||
}
|
||||
return new Document([]);
|
||||
}, ['project', 'dbForProject', 'request', 'authorization']);
|
||||
}, ['project', 'dbForProject', 'request']);
|
||||
|
||||
App::setResource('httpReferrer', function (Request $request): string {
|
||||
$referrer = $request->getReferer();
|
||||
@@ -1053,6 +1043,6 @@ App::setResource('httpReferrerSafe', function (Request $request, string $httpRef
|
||||
return $referrer;
|
||||
}, ['request', 'httpReferrer', 'platforms', 'dbForPlatform', 'project', 'utopia']);
|
||||
|
||||
App::setResource('transactionState', function (Database $dbForProject, Authorization $authorization) {
|
||||
return new TransactionState($dbForProject, $authorization);
|
||||
}, ['dbForProject', 'authorization']);
|
||||
App::setResource('transactionState', function (Database $dbForProject) {
|
||||
return new TransactionState($dbForProject);
|
||||
}, ['dbForProject']);
|
||||
|
||||
+12
-11
@@ -28,6 +28,7 @@ use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\DSN\DSN;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Pools\Group;
|
||||
@@ -298,7 +299,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume
|
||||
'value' => '{}'
|
||||
]);
|
||||
|
||||
$statsDocument = $database->getAuthorization()->skip(fn () => $database->createDocument('realtime', $document));
|
||||
$statsDocument = Authorization::skip(fn () => $database->createDocument('realtime', $document));
|
||||
break;
|
||||
} catch (Throwable) {
|
||||
Console::warning("Collection not ready. Retrying connection ({$attempts})...");
|
||||
@@ -328,7 +329,7 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume
|
||||
->setAttribute('timestamp', DateTime::now())
|
||||
->setAttribute('value', json_encode($payload));
|
||||
|
||||
$database->getAuthorization()->skip(fn () => $database->updateDocument('realtime', $statsDocument->getId(), $statsDocument));
|
||||
Authorization::skip(fn () => $database->updateDocument('realtime', $statsDocument->getId(), $statsDocument));
|
||||
} catch (Throwable $th) {
|
||||
$logError($th, "updateWorkerDocument");
|
||||
}
|
||||
@@ -359,7 +360,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
|
||||
|
||||
$payload = [];
|
||||
|
||||
$list = $database->getAuthorization()->skip(fn () => $database->find('realtime', [
|
||||
$list = Authorization::skip(fn () => $database->find('realtime', [
|
||||
Query::greaterThan('timestamp', DateTime::addSeconds(new \DateTime(), -15)),
|
||||
]));
|
||||
|
||||
@@ -453,11 +454,12 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
|
||||
if ($realtime->hasSubscriber($projectId, 'user:' . $userId)) {
|
||||
$connection = array_key_first(reset($realtime->subscriptions[$projectId]['user:' . $userId]));
|
||||
$consoleDatabase = getConsoleDB();
|
||||
$project = $consoleDatabase->getAuthorization()->skip(fn () => $consoleDatabase->getDocument('projects', $projectId));
|
||||
$project = Authorization::skip(fn () => $consoleDatabase->getDocument('projects', $projectId));
|
||||
$database = getProjectDB($project);
|
||||
|
||||
$user = $database->getDocument('users', $userId);
|
||||
$roles = Auth::getRoles($user, $database->getAuthorization());
|
||||
|
||||
$roles = Auth::getRoles($user);
|
||||
$channels = $realtime->connections[$connection]['channels'];
|
||||
|
||||
$realtime->unsubscribe($connection);
|
||||
@@ -513,7 +515,6 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
|
||||
try {
|
||||
/** @var Document $project */
|
||||
$project = $app->getResource('project');
|
||||
$authorization = $app->getResource('authorization');
|
||||
|
||||
/*
|
||||
* Project Check
|
||||
@@ -525,7 +526,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
|
||||
if (
|
||||
array_key_exists('realtime', $project->getAttribute('apis', []))
|
||||
&& !$project->getAttribute('apis', [])['realtime']
|
||||
&& !(Auth::isPrivilegedUser($authorization->getRoles()) || Auth::isAppUser($authorization->getRoles()))
|
||||
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
|
||||
) {
|
||||
throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED);
|
||||
}
|
||||
@@ -562,7 +563,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
|
||||
throw new Exception(Exception::REALTIME_POLICY_VIOLATION, $originValidator->getDescription());
|
||||
}
|
||||
|
||||
$roles = Auth::getRoles($user, $authorization);
|
||||
$roles = Auth::getRoles($user);
|
||||
|
||||
$channels = Realtime::convertChannels($request->getQuery('channels', []), $user->getId());
|
||||
|
||||
@@ -636,8 +637,8 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
|
||||
$database = getConsoleDB();
|
||||
|
||||
if ($projectId !== 'console') {
|
||||
$project = $database->getAuthorization()->skip(fn () => $database->getDocument('projects', $projectId));
|
||||
$database = getProjectDB($project, $database->getAuthorization());
|
||||
$project = Authorization::skip(fn () => $database->getDocument('projects', $projectId));
|
||||
$database = getProjectDB($project);
|
||||
} else {
|
||||
$project = null;
|
||||
}
|
||||
@@ -691,7 +692,7 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
|
||||
throw new Exception(Exception::REALTIME_MESSAGE_FORMAT_INVALID, 'Session is not valid.');
|
||||
}
|
||||
|
||||
$roles = Auth::getRoles($user, $database->getAuthorization());
|
||||
$roles = Auth::getRoles($user);
|
||||
$channels = Realtime::convertChannels(array_flip($realtime->connections[$connection]['channels']), $user->getId());
|
||||
$realtime->subscribe($realtime->connections[$connection]['projectId'], $connection, $roles, $channels);
|
||||
|
||||
|
||||
@@ -859,7 +859,7 @@ $image = $this->getParam('image', '');
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
|
||||
appwrite-browser:
|
||||
image: appwrite/browser:0.3.1
|
||||
image: appwrite/browser:0.3.2
|
||||
container_name: appwrite-browser
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
|
||||
+17
-32
@@ -45,28 +45,19 @@ use Utopia\System\System;
|
||||
use Utopia\Telemetry\Adapter as Telemetry;
|
||||
use Utopia\Telemetry\Adapter\None as NoTelemetry;
|
||||
|
||||
Authorization::disable();
|
||||
Runtime::enableCoroutine();
|
||||
|
||||
Server::setResource('register', fn () => $register);
|
||||
|
||||
Server::setResource('authorization', function () {
|
||||
$authorization = new Authorization();
|
||||
$authorization->disable();
|
||||
return $authorization;
|
||||
}, []);
|
||||
|
||||
Server::setResource('dbForPlatform', function (Cache $cache, Registry $register, Authorization $authorization) {
|
||||
Server::setResource('dbForPlatform', function (Cache $cache, Registry $register) {
|
||||
$pools = $register->get('pools');
|
||||
$adapter = new DatabasePool($pools->get('console'));
|
||||
$dbForPlatform = new Database($adapter, $cache);
|
||||
|
||||
$dbForPlatform
|
||||
->setAuthorization($authorization)
|
||||
->setNamespace('_console');
|
||||
|
||||
$dbForPlatform->setNamespace('_console');
|
||||
|
||||
return $dbForPlatform;
|
||||
}, ['cache', 'register', 'authorization']);
|
||||
}, ['cache', 'register']);
|
||||
|
||||
Server::setResource('project', function (Message $message, Database $dbForPlatform) {
|
||||
$payload = $message->getPayload() ?? [];
|
||||
@@ -79,7 +70,7 @@ Server::setResource('project', function (Message $message, Database $dbForPlatfo
|
||||
return $dbForPlatform->getDocument('projects', $project->getId());
|
||||
}, ['message', 'dbForPlatform']);
|
||||
|
||||
Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForPlatform, Authorization $authorization) {
|
||||
Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForPlatform) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
@@ -110,17 +101,15 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register,
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
|
||||
return $database;
|
||||
}, ['cache', 'register', 'message', 'project', 'dbForPlatform', 'authorization']);
|
||||
}, ['cache', 'register', 'message', 'project', 'dbForPlatform']);
|
||||
|
||||
Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache, Authorization $authorization) {
|
||||
Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) {
|
||||
$databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools
|
||||
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, $authorization, &$databases): Database {
|
||||
return function (Document $project) use ($pools, $dbForPlatform, $cache, &$databases): Database {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
return $dbForPlatform;
|
||||
}
|
||||
@@ -134,7 +123,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
|
||||
|
||||
if (isset($databases[$dsn->getHost()])) {
|
||||
$database = $databases[$dsn->getHost()];
|
||||
$database->setAuthorization($authorization);
|
||||
|
||||
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
||||
|
||||
if (\in_array($dsn->getHost(), $sharedTables)) {
|
||||
@@ -171,17 +160,15 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf
|
||||
->setNamespace('_' . $project->getSequence());
|
||||
}
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
$database->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER);
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'dbForPlatform', 'cache', 'authorization']);
|
||||
}, ['pools', 'dbForPlatform', 'cache']);
|
||||
|
||||
Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorization $authorization) {
|
||||
Server::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
||||
$database = null;
|
||||
return function (?Document $project = null) use ($pools, $cache, $database, $authorization) {
|
||||
return function (?Document $project = null) use ($pools, $cache, $database) {
|
||||
if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$database->setTenant((int)$project->getSequence());
|
||||
return $database;
|
||||
@@ -191,7 +178,6 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authoriza
|
||||
$database = new Database($adapter, $cache);
|
||||
|
||||
$database
|
||||
->setAuthorization($authorization)
|
||||
->setSharedTables(true)
|
||||
->setNamespace('logsV1')
|
||||
->setTimeout(APP_DATABASE_TIMEOUT_MILLISECONDS_WORKER)
|
||||
@@ -204,7 +190,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authoriza
|
||||
|
||||
return $database;
|
||||
};
|
||||
}, ['pools', 'cache', 'authorization']);
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
Server::setResource('abuseRetention', function () {
|
||||
return time() - (int) System::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', 86400); // 1 day
|
||||
@@ -492,8 +478,7 @@ $worker
|
||||
->inject('log')
|
||||
->inject('pools')
|
||||
->inject('project')
|
||||
->inject('authorization')
|
||||
->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project, Authorization $authorization) use ($worker, $queueName) {
|
||||
->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project) use ($worker, $queueName) {
|
||||
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
||||
if ($logger) {
|
||||
@@ -509,7 +494,7 @@ $worker
|
||||
$log->addExtra('file', $error->getFile());
|
||||
$log->addExtra('line', $error->getLine());
|
||||
$log->addExtra('trace', $error->getTraceAsString());
|
||||
$log->addExtra('roles', $authorization->getRoles());
|
||||
$log->addExtra('roles', Authorization::getRoles());
|
||||
|
||||
$isProduction = System::getEnv('_APP_ENV', 'development') === 'production';
|
||||
$log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING);
|
||||
|
||||
+3
-3
@@ -50,8 +50,8 @@
|
||||
"utopia-php/audit": "1.*",
|
||||
"utopia-php/cache": "0.13.*",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "4.*",
|
||||
"utopia-php/config": "1.*.*",
|
||||
"utopia-php/database": "3.*",
|
||||
"utopia-php/detector": "0.2.*",
|
||||
"utopia-php/domains": "0.9.*",
|
||||
"utopia-php/emails": "0.6.*",
|
||||
@@ -63,7 +63,7 @@
|
||||
"utopia-php/locale": "0.8.*",
|
||||
"utopia-php/logger": "0.6.*",
|
||||
"utopia-php/messaging": "0.20.*",
|
||||
"utopia-php/migration": "1.*",
|
||||
"utopia-php/migration": "1.3.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "0.8.*",
|
||||
|
||||
Generated
+63
-67
@@ -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": "3b502f78f5e31f2ea7b4c69e3301283a",
|
||||
"content-hash": "1d3d4b19a835b3be79a63146fcdd389b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -283,16 +283,16 @@
|
||||
},
|
||||
{
|
||||
"name": "brick/math",
|
||||
"version": "0.14.0",
|
||||
"version": "0.14.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/brick/math.git",
|
||||
"reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2"
|
||||
"reference": "f05858549e5f9d7bb45875a75583240a38a281d0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2",
|
||||
"reference": "113a8ee2656b882d4c3164fa31aa6e12cbb7aaa2",
|
||||
"url": "https://api.github.com/repos/brick/math/zipball/f05858549e5f9d7bb45875a75583240a38a281d0",
|
||||
"reference": "f05858549e5f9d7bb45875a75583240a38a281d0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -331,7 +331,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/brick/math/issues",
|
||||
"source": "https://github.com/brick/math/tree/0.14.0"
|
||||
"source": "https://github.com/brick/math/tree/0.14.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -339,7 +339,7 @@
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-08-29T12:40:03+00:00"
|
||||
"time": "2025-11-24T14:40:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
@@ -1763,16 +1763,16 @@
|
||||
},
|
||||
{
|
||||
"name": "php-amqplib/php-amqplib",
|
||||
"version": "v3.7.3",
|
||||
"version": "v3.7.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-amqplib/php-amqplib.git",
|
||||
"reference": "9f50fe69a9f1a19e2cb25596a354d705de36fe59"
|
||||
"reference": "381b6f7c600e0e0c7463cdd7f7a1a3bc6268e5fd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/9f50fe69a9f1a19e2cb25596a354d705de36fe59",
|
||||
"reference": "9f50fe69a9f1a19e2cb25596a354d705de36fe59",
|
||||
"url": "https://api.github.com/repos/php-amqplib/php-amqplib/zipball/381b6f7c600e0e0c7463cdd7f7a1a3bc6268e5fd",
|
||||
"reference": "381b6f7c600e0e0c7463cdd7f7a1a3bc6268e5fd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1838,9 +1838,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/php-amqplib/php-amqplib/issues",
|
||||
"source": "https://github.com/php-amqplib/php-amqplib/tree/v3.7.3"
|
||||
"source": "https://github.com/php-amqplib/php-amqplib/tree/v3.7.4"
|
||||
},
|
||||
"time": "2025-02-18T20:11:13+00:00"
|
||||
"time": "2025-11-23T17:00:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-http/discovery",
|
||||
@@ -3551,21 +3551,21 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "15656acfddb9d6f03c395b73673fc66c793c10a5"
|
||||
"reference": "8c17065c2473d4ca799f65585ca74eb53e1be211"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/15656acfddb9d6f03c395b73673fc66c793c10a5",
|
||||
"reference": "15656acfddb9d6f03c395b73673fc66c793c10a5",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/8c17065c2473d4ca799f65585ca74eb53e1be211",
|
||||
"reference": "8c17065c2473d4ca799f65585ca74eb53e1be211",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "4.*"
|
||||
"utopia-php/database": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
@@ -3592,9 +3592,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/1.0.3"
|
||||
"source": "https://github.com/utopia-php/audit/tree/1.0.2"
|
||||
},
|
||||
"time": "2025-11-04T11:27:42+00:00"
|
||||
"time": "2025-10-20T07:14:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
@@ -3745,24 +3745,26 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/config",
|
||||
"version": "0.2.2",
|
||||
"version": "1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/config.git",
|
||||
"reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc"
|
||||
"reference": "6672bf6c1b54ba608593570cbef31bef75f17dd8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/config/zipball/a3d7bc0312d7150d5e04b1362dc34b2b136908cc",
|
||||
"reference": "a3d7bc0312d7150d5e04b1362dc34b2b136908cc",
|
||||
"url": "https://api.github.com/repos/utopia-php/config/zipball/6672bf6c1b54ba608593570cbef31bef75f17dd8",
|
||||
"reference": "6672bf6c1b54ba608593570cbef31bef75f17dd8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3"
|
||||
"ext-yaml": "*",
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"vimeo/psalm": "4.0.1"
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "^2.0",
|
||||
"phpunit/phpunit": "^9.3"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
@@ -3774,12 +3776,6 @@
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple Config library to managing application config variables",
|
||||
"keywords": [
|
||||
"config",
|
||||
@@ -3790,9 +3786,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/config/issues",
|
||||
"source": "https://github.com/utopia-php/config/tree/0.2.2"
|
||||
"source": "https://github.com/utopia-php/config/tree/1.0.0"
|
||||
},
|
||||
"time": "2020-10-24T09:49:09+00:00"
|
||||
"time": "2025-11-18T17:02:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/console",
|
||||
@@ -3844,16 +3840,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "4.3.0",
|
||||
"version": "3.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "fe7a1326ad623609e65587fe8c01a630a7075fee"
|
||||
"reference": "5da71b65a6123ce2e78795522b05b7458aabfbd7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/fe7a1326ad623609e65587fe8c01a630a7075fee",
|
||||
"reference": "fe7a1326ad623609e65587fe8c01a630a7075fee",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/5da71b65a6123ce2e78795522b05b7458aabfbd7",
|
||||
"reference": "5da71b65a6123ce2e78795522b05b7458aabfbd7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3896,22 +3892,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/4.3.0"
|
||||
"source": "https://github.com/utopia-php/database/tree/3.5.0"
|
||||
},
|
||||
"time": "2025-11-14T03:43:10+00:00"
|
||||
"time": "2025-11-18T08:11:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
"version": "0.2.2",
|
||||
"version": "0.2.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/detector.git",
|
||||
"reference": "9a41be5f21efe2d865de79b08dff94fff85ce5e9"
|
||||
"reference": "c1f49b3e82250c3256ffba48aa9737d6c17a243a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/detector/zipball/9a41be5f21efe2d865de79b08dff94fff85ce5e9",
|
||||
"reference": "9a41be5f21efe2d865de79b08dff94fff85ce5e9",
|
||||
"url": "https://api.github.com/repos/utopia-php/detector/zipball/c1f49b3e82250c3256ffba48aa9737d6c17a243a",
|
||||
"reference": "c1f49b3e82250c3256ffba48aa9737d6c17a243a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3941,9 +3937,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/detector/issues",
|
||||
"source": "https://github.com/utopia-php/detector/tree/0.2.2"
|
||||
"source": "https://github.com/utopia-php/detector/tree/0.2.3"
|
||||
},
|
||||
"time": "2025-10-31T12:43:31+00:00"
|
||||
"time": "2025-11-24T15:52:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/dns",
|
||||
@@ -4212,16 +4208,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.33.29",
|
||||
"version": "0.33.30",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "6e63939fdb33b847f92839499cd6e8df626c278d"
|
||||
"reference": "07cf699a7c47bd1a03b4da1812f1719a66b3c924"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/6e63939fdb33b847f92839499cd6e8df626c278d",
|
||||
"reference": "6e63939fdb33b847f92839499cd6e8df626c278d",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/07cf699a7c47bd1a03b4da1812f1719a66b3c924",
|
||||
"reference": "07cf699a7c47bd1a03b4da1812f1719a66b3c924",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4253,9 +4249,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.29"
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.30"
|
||||
},
|
||||
"time": "2025-11-14T06:33:29+00:00"
|
||||
"time": "2025-11-18T12:18:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
@@ -4460,16 +4456,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "1.3.4",
|
||||
"version": "1.3.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "81e1be6ff3257d4768aa7483cf64628836244a09"
|
||||
"reference": "731b3a963c58c30e0b2368695d57a7e8fcb7455c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/81e1be6ff3257d4768aa7483cf64628836244a09",
|
||||
"reference": "81e1be6ff3257d4768aa7483cf64628836244a09",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/731b3a963c58c30e0b2368695d57a7e8fcb7455c",
|
||||
"reference": "731b3a963c58c30e0b2368695d57a7e8fcb7455c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4478,7 +4474,7 @@
|
||||
"ext-openssl": "*",
|
||||
"php": ">=8.1",
|
||||
"utopia-php/console": "0.0.*",
|
||||
"utopia-php/database": "4.*",
|
||||
"utopia-php/database": "3.*",
|
||||
"utopia-php/dsn": "0.2.*",
|
||||
"utopia-php/storage": "0.18.*"
|
||||
},
|
||||
@@ -4509,9 +4505,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/1.3.4"
|
||||
"source": "https://github.com/utopia-php/migration/tree/1.3.3"
|
||||
},
|
||||
"time": "2025-11-04T11:28:50+00:00"
|
||||
"time": "2025-10-28T04:02:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/mongo",
|
||||
@@ -5383,16 +5379,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "1.5.7",
|
||||
"version": "1.5.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "dc6720ba92ed98e2c62b2a319d4371f167ccc808"
|
||||
"reference": "ee434aa00a9185380b9a39bb46bf86d7104d3a93"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/dc6720ba92ed98e2c62b2a319d4371f167ccc808",
|
||||
"reference": "dc6720ba92ed98e2c62b2a319d4371f167ccc808",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ee434aa00a9185380b9a39bb46bf86d7104d3a93",
|
||||
"reference": "ee434aa00a9185380b9a39bb46bf86d7104d3a93",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -5428,9 +5424,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.5.7"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.5.9"
|
||||
},
|
||||
"time": "2025-11-18T05:57:01+00:00"
|
||||
"time": "2025-11-25T05:22:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@@ -8921,5 +8917,5 @@
|
||||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
services:
|
||||
appwrite:
|
||||
# volumes:
|
||||
# - ~/.ssh:/root/.ssh
|
||||
environment:
|
||||
- GH_TOKEN=
|
||||
- GIT_EMAIL=
|
||||
+1
-1
@@ -958,7 +958,7 @@ services:
|
||||
|
||||
appwrite-browser:
|
||||
container_name: appwrite-browser
|
||||
image: appwrite/browser:0.3.1
|
||||
image: appwrite/browser:0.3.2
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: <REGION>.cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: <REGION>.cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: <REGION>.cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.5.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: <REGION>.cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.6.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.7.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.7.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.7.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.7.0
|
||||
|
||||
@@ -13,7 +13,7 @@ account.createOAuth2Session(
|
||||
OAuthProvider.AMAZON, // provider
|
||||
"https://example.com", // success (optional)
|
||||
"https://example.com", // failure (optional)
|
||||
listOf(), // scopes (optional)
|
||||
List.of(), // scopes (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -13,7 +13,7 @@ account.createOAuth2Token(
|
||||
OAuthProvider.AMAZON, // provider
|
||||
"https://example.com", // success (optional)
|
||||
"https://example.com", // failure (optional)
|
||||
listOf(), // scopes (optional)
|
||||
List.of(), // scopes (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -9,7 +9,7 @@ Client client = new Client(context)
|
||||
Account account = new Account(client);
|
||||
|
||||
account.listIdentities(
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -9,7 +9,7 @@ Client client = new Client(context)
|
||||
Account account = new Account(client);
|
||||
|
||||
account.listLogs(
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -9,10 +9,10 @@ Client client = new Client(context)
|
||||
Account account = new Account(client);
|
||||
|
||||
account.updatePrefs(
|
||||
mapOf(
|
||||
"language" to "en",
|
||||
"timezone" to "UTC",
|
||||
"darkTheme" to true
|
||||
Map.of(
|
||||
"language", "en",
|
||||
"timezone", "UTC",
|
||||
"darkTheme", true
|
||||
), // prefs
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -13,7 +13,7 @@ Avatars avatars = new Avatars(client);
|
||||
|
||||
avatars.getScreenshot(
|
||||
"https://example.com", // url
|
||||
mapOf( "a" to "b" ), // headers (optional)
|
||||
Map.of("a", "b"), // headers (optional)
|
||||
1, // viewportWidth (optional)
|
||||
1, // viewportHeight (optional)
|
||||
0.1, // scale (optional)
|
||||
@@ -26,7 +26,7 @@ avatars.getScreenshot(
|
||||
-180, // longitude (optional)
|
||||
0, // accuracy (optional)
|
||||
false, // touch (optional)
|
||||
listOf(), // permissions (optional)
|
||||
List.of(), // permissions (optional)
|
||||
0, // sleep (optional)
|
||||
0, // width (optional)
|
||||
0, // height (optional)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.Databases;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.Databases;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -14,14 +14,14 @@ databases.createDocument(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<COLLECTION_ID>", // collectionId
|
||||
"<DOCUMENT_ID>", // documentId
|
||||
mapOf(
|
||||
"username" to "walter.obrien",
|
||||
"email" to "walter.obrien@example.com",
|
||||
"fullName" to "Walter O'Brien",
|
||||
"age" to 30,
|
||||
"isAdmin" to false
|
||||
Map.of(
|
||||
"username", "walter.obrien",
|
||||
"email", "walter.obrien@example.com",
|
||||
"fullName", "Walter O'Brien",
|
||||
"age", 30,
|
||||
"isAdmin", false
|
||||
), // data
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -10,17 +10,15 @@ Databases databases = new Databases(client);
|
||||
|
||||
databases.createOperations(
|
||||
"<TRANSACTION_ID>", // transactionId
|
||||
listOf(
|
||||
{
|
||||
"action": "create",
|
||||
"databaseId": "<DATABASE_ID>",
|
||||
"collectionId": "<COLLECTION_ID>",
|
||||
"documentId": "<DOCUMENT_ID>",
|
||||
"data": {
|
||||
"name": "Walter O'Brien"
|
||||
}
|
||||
}
|
||||
), // operations (optional)
|
||||
List.of(Map.of(
|
||||
"action", "create",
|
||||
"databaseId", "<DATABASE_ID>",
|
||||
"collectionId", "<COLLECTION_ID>",
|
||||
"documentId", "<DOCUMENT_ID>",
|
||||
"data", Map.of(
|
||||
"name", "Walter O'Brien"
|
||||
)
|
||||
)), // operations (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -12,7 +12,7 @@ databases.getDocument(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<COLLECTION_ID>", // collectionId
|
||||
"<DOCUMENT_ID>", // documentId
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -11,7 +11,7 @@ Databases databases = new Databases(client);
|
||||
databases.listDocuments(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<COLLECTION_ID>", // collectionId
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
|
||||
@@ -9,7 +9,7 @@ Client client = new Client(context)
|
||||
Databases databases = new Databases(client);
|
||||
|
||||
databases.listTransactions(
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.Databases;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.Databases;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -14,8 +14,8 @@ databases.updateDocument(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<COLLECTION_ID>", // collectionId
|
||||
"<DOCUMENT_ID>", // documentId
|
||||
mapOf( "a" to "b" ), // data (optional)
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
Map.of("a", "b"), // data (optional)
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.Databases;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.Databases;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -14,8 +14,8 @@ databases.upsertDocument(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<COLLECTION_ID>", // collectionId
|
||||
"<DOCUMENT_ID>", // documentId
|
||||
mapOf( "a" to "b" ), // data
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
Map.of("a", "b"), // data
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -15,7 +15,7 @@ functions.createExecution(
|
||||
false, // async (optional)
|
||||
"<PATH>", // path (optional)
|
||||
ExecutionMethod.GET, // method (optional)
|
||||
mapOf( "a" to "b" ), // headers (optional)
|
||||
Map.of("a", "b"), // headers (optional)
|
||||
"<SCHEDULED_AT>", // scheduledAt (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -10,7 +10,7 @@ Functions functions = new Functions(client);
|
||||
|
||||
functions.listExecutions(
|
||||
"<FUNCTION_ID>", // functionId
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -9,7 +9,7 @@ Client client = new Client(context)
|
||||
Graphql graphql = new Graphql(client);
|
||||
|
||||
graphql.mutation(
|
||||
mapOf( "a" to "b" ), // query
|
||||
Map.of("a", "b"), // query
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -9,7 +9,7 @@ Client client = new Client(context)
|
||||
Graphql graphql = new Graphql(client);
|
||||
|
||||
graphql.query(
|
||||
mapOf( "a" to "b" ), // query
|
||||
Map.of("a", "b"), // query
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.models.InputFile;
|
||||
import io.appwrite.services.Storage;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.Storage;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -15,7 +15,7 @@ storage.createFile(
|
||||
"<BUCKET_ID>", // bucketId
|
||||
"<FILE_ID>", // fileId
|
||||
InputFile.fromPath("file.png"), // file
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -10,7 +10,7 @@ Storage storage = new Storage(client);
|
||||
|
||||
storage.listFiles(
|
||||
"<BUCKET_ID>", // bucketId
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
"<SEARCH>", // search (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.Storage;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.Storage;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -14,7 +14,7 @@ storage.updateFile(
|
||||
"<BUCKET_ID>", // bucketId
|
||||
"<FILE_ID>", // fileId
|
||||
"<NAME>", // name (optional)
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -10,17 +10,15 @@ TablesDB tablesDB = new TablesDB(client);
|
||||
|
||||
tablesDB.createOperations(
|
||||
"<TRANSACTION_ID>", // transactionId
|
||||
listOf(
|
||||
{
|
||||
"action": "create",
|
||||
"databaseId": "<DATABASE_ID>",
|
||||
"tableId": "<TABLE_ID>",
|
||||
"rowId": "<ROW_ID>",
|
||||
"data": {
|
||||
"name": "Walter O'Brien"
|
||||
}
|
||||
}
|
||||
), // operations (optional)
|
||||
List.of(Map.of(
|
||||
"action", "create",
|
||||
"databaseId", "<DATABASE_ID>",
|
||||
"tableId", "<TABLE_ID>",
|
||||
"rowId", "<ROW_ID>",
|
||||
"data", Map.of(
|
||||
"name", "Walter O'Brien"
|
||||
)
|
||||
)), // operations (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.TablesDB;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.TablesDB;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -14,14 +14,14 @@ tablesDB.createRow(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<TABLE_ID>", // tableId
|
||||
"<ROW_ID>", // rowId
|
||||
mapOf(
|
||||
"username" to "walter.obrien",
|
||||
"email" to "walter.obrien@example.com",
|
||||
"fullName" to "Walter O'Brien",
|
||||
"age" to 30,
|
||||
"isAdmin" to false
|
||||
Map.of(
|
||||
"username", "walter.obrien",
|
||||
"email", "walter.obrien@example.com",
|
||||
"fullName", "Walter O'Brien",
|
||||
"age", 30,
|
||||
"isAdmin", false
|
||||
), // data
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -12,7 +12,7 @@ tablesDB.getRow(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<TABLE_ID>", // tableId
|
||||
"<ROW_ID>", // rowId
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -11,7 +11,7 @@ TablesDB tablesDB = new TablesDB(client);
|
||||
tablesDB.listRows(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<TABLE_ID>", // tableId
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
|
||||
@@ -9,7 +9,7 @@ Client client = new Client(context)
|
||||
TablesDB tablesDB = new TablesDB(client);
|
||||
|
||||
tablesDB.listTransactions(
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.TablesDB;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.TablesDB;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -14,8 +14,8 @@ tablesDB.updateRow(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<TABLE_ID>", // tableId
|
||||
"<ROW_ID>", // rowId
|
||||
mapOf( "a" to "b" ), // data (optional)
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
Map.of("a", "b"), // data (optional)
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import io.appwrite.Client;
|
||||
import io.appwrite.coroutines.CoroutineCallback;
|
||||
import io.appwrite.services.TablesDB;
|
||||
import io.appwrite.Permission;
|
||||
import io.appwrite.Role;
|
||||
import io.appwrite.services.TablesDB;
|
||||
|
||||
Client client = new Client(context)
|
||||
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -14,8 +14,8 @@ tablesDB.upsertRow(
|
||||
"<DATABASE_ID>", // databaseId
|
||||
"<TABLE_ID>", // tableId
|
||||
"<ROW_ID>", // rowId
|
||||
mapOf( "a" to "b" ), // data (optional)
|
||||
listOf(Permission.read(Role.any())), // permissions (optional)
|
||||
Map.of("a", "b"), // data (optional)
|
||||
List.of(Permission.read(Role.any())), // permissions (optional)
|
||||
"<TRANSACTION_ID>", // transactionId (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
|
||||
@@ -10,7 +10,7 @@ Teams teams = new Teams(client);
|
||||
|
||||
teams.createMembership(
|
||||
"<TEAM_ID>", // teamId
|
||||
listOf(), // roles
|
||||
List.of(), // roles
|
||||
"email@example.com", // email (optional)
|
||||
"<USER_ID>", // userId (optional)
|
||||
"+12065550100", // phone (optional)
|
||||
|
||||
@@ -11,7 +11,7 @@ Teams teams = new Teams(client);
|
||||
teams.create(
|
||||
"<TEAM_ID>", // teamId
|
||||
"<NAME>", // name
|
||||
listOf(), // roles (optional)
|
||||
List.of(), // roles (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -10,7 +10,7 @@ Teams teams = new Teams(client);
|
||||
|
||||
teams.listMemberships(
|
||||
"<TEAM_ID>", // teamId
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
"<SEARCH>", // search (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
|
||||
@@ -9,7 +9,7 @@ Client client = new Client(context)
|
||||
Teams teams = new Teams(client);
|
||||
|
||||
teams.list(
|
||||
listOf(), // queries (optional)
|
||||
List.of(), // queries (optional)
|
||||
"<SEARCH>", // search (optional)
|
||||
false, // total (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
|
||||
@@ -11,7 +11,7 @@ Teams teams = new Teams(client);
|
||||
teams.updateMembership(
|
||||
"<TEAM_ID>", // teamId
|
||||
"<MEMBERSHIP_ID>", // membershipId
|
||||
listOf(), // roles
|
||||
List.of(), // roles
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -10,7 +10,7 @@ Teams teams = new Teams(client);
|
||||
|
||||
teams.updatePrefs(
|
||||
"<TEAM_ID>", // teamId
|
||||
mapOf( "a" to "b" ), // prefs
|
||||
Map.of("a", "b"), // prefs
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -10,15 +10,13 @@ val databases = Databases(client)
|
||||
|
||||
val result = databases.createOperations(
|
||||
transactionId = "<TRANSACTION_ID>",
|
||||
operations = listOf(
|
||||
{
|
||||
"action": "create",
|
||||
"databaseId": "<DATABASE_ID>",
|
||||
"collectionId": "<COLLECTION_ID>",
|
||||
"documentId": "<DOCUMENT_ID>",
|
||||
"data": {
|
||||
"name": "Walter O'Brien"
|
||||
}
|
||||
}
|
||||
), // (optional)
|
||||
operations = listOf(mapOf(
|
||||
"action" to "create",
|
||||
"databaseId" to "<DATABASE_ID>",
|
||||
"collectionId" to "<COLLECTION_ID>",
|
||||
"documentId" to "<DOCUMENT_ID>",
|
||||
"data" to mapOf(
|
||||
"name" to "Walter O'Brien"
|
||||
)
|
||||
)), // (optional)
|
||||
)
|
||||
@@ -10,15 +10,13 @@ val tablesDB = TablesDB(client)
|
||||
|
||||
val result = tablesDB.createOperations(
|
||||
transactionId = "<TRANSACTION_ID>",
|
||||
operations = listOf(
|
||||
{
|
||||
"action": "create",
|
||||
"databaseId": "<DATABASE_ID>",
|
||||
"tableId": "<TABLE_ID>",
|
||||
"rowId": "<ROW_ID>",
|
||||
"data": {
|
||||
"name": "Walter O'Brien"
|
||||
}
|
||||
}
|
||||
), // (optional)
|
||||
operations = listOf(mapOf(
|
||||
"action" to "create",
|
||||
"databaseId" to "<DATABASE_ID>",
|
||||
"tableId" to "<TABLE_ID>",
|
||||
"rowId" to "<ROW_ID>",
|
||||
"data" to mapOf(
|
||||
"name" to "Walter O'Brien"
|
||||
)
|
||||
)), // (optional)
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
POST /v1/account/mfa/challenge HTTP/1.1
|
||||
POST /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.8.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
PUT /v1/account/mfa/challenge HTTP/1.1
|
||||
PUT /v1/account/mfa/challenges HTTP/1.1
|
||||
Host: cloud.appwrite.io
|
||||
Content-Type: application/json
|
||||
X-Appwrite-Response-Format: 1.8.0
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Client, Functions, } from "@appwrite.io/console";
|
||||
import { Client, Functions, TemplateReferenceType } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
@@ -11,7 +11,7 @@ const result = await functions.createTemplateDeployment({
|
||||
repository: '<REPOSITORY>',
|
||||
owner: '<OWNER>',
|
||||
rootDirectory: '<ROOT_DIRECTORY>',
|
||||
type: .Commit,
|
||||
type: TemplateReferenceType.Commit,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false // optional
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Client, Functions, VCSDeploymentType } from "@appwrite.io/console";
|
||||
import { Client, Functions, VCSReferenceType } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
@@ -8,7 +8,7 @@ const functions = new Functions(client);
|
||||
|
||||
const result = await functions.createVcsDeployment({
|
||||
functionId: '<FUNCTION_ID>',
|
||||
type: VCSDeploymentType.Branch,
|
||||
type: VCSReferenceType.Branch,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false // optional
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Client, Sites, } from "@appwrite.io/console";
|
||||
import { Client, Sites, TemplateReferenceType } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
@@ -11,7 +11,7 @@ const result = await sites.createTemplateDeployment({
|
||||
repository: '<REPOSITORY>',
|
||||
owner: '<OWNER>',
|
||||
rootDirectory: '<ROOT_DIRECTORY>',
|
||||
type: .Branch,
|
||||
type: TemplateReferenceType.Branch,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false // optional
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Client, Sites, VCSDeploymentType } from "@appwrite.io/console";
|
||||
import { Client, Sites, VCSReferenceType } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1') // Your API Endpoint
|
||||
@@ -8,7 +8,7 @@ const sites = new Sites(client);
|
||||
|
||||
const result = await sites.createVcsDeployment({
|
||||
siteId: '<SITE_ID>',
|
||||
type: VCSDeploymentType.Branch,
|
||||
type: VCSReferenceType.Branch,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false // optional
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ Deployment result = await functions.createTemplateDeployment(
|
||||
repository: '<REPOSITORY>',
|
||||
owner: '<OWNER>',
|
||||
rootDirectory: '<ROOT_DIRECTORY>',
|
||||
type: .commit,
|
||||
type: TemplateReferenceType.commit,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false, // (optional)
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ Functions functions = Functions(client);
|
||||
|
||||
Deployment result = await functions.createVcsDeployment(
|
||||
functionId: '<FUNCTION_ID>',
|
||||
type: VCSDeploymentType.branch,
|
||||
type: VCSReferenceType.branch,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false, // (optional)
|
||||
);
|
||||
|
||||
@@ -12,7 +12,7 @@ Deployment result = await sites.createTemplateDeployment(
|
||||
repository: '<REPOSITORY>',
|
||||
owner: '<OWNER>',
|
||||
rootDirectory: '<ROOT_DIRECTORY>',
|
||||
type: .branch,
|
||||
type: TemplateReferenceType.branch,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false, // (optional)
|
||||
);
|
||||
|
||||
@@ -9,7 +9,7 @@ Sites sites = Sites(client);
|
||||
|
||||
Deployment result = await sites.createVcsDeployment(
|
||||
siteId: '<SITE_ID>',
|
||||
type: VCSDeploymentType.branch,
|
||||
type: VCSReferenceType.branch,
|
||||
reference: '<REFERENCE>',
|
||||
activate: false, // (optional)
|
||||
);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user