mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
807ce0469c | ||
|
|
f9613e919e | ||
|
|
7eae0bff3d | ||
|
|
227b410252 | ||
|
|
ddc8d0e444 | ||
|
|
724c07914d |
@@ -73,12 +73,11 @@ _APP_EXECUTOR_SECRET=your-secret-key
|
||||
_APP_EXECUTOR_HOST=http://proxy/v1
|
||||
_APP_FUNCTIONS_RUNTIMES=php-8.0,node-18.0,python-3.9,ruby-3.1
|
||||
_APP_MAINTENANCE_INTERVAL=86400
|
||||
_APP_MAINTENANCE_DELAY=
|
||||
_APP_MAINTENANCE_RETENTION_CACHE=2592000
|
||||
_APP_MAINTENANCE_RETENTION_EXECUTION=1209600
|
||||
_APP_MAINTENANCE_RETENTION_ABUSE=86400
|
||||
_APP_MAINTENANCE_RETENTION_AUDIT=1209600
|
||||
_APP_USAGE_AGGREGATION_INTERVAL=20
|
||||
_APP_USAGE_AGGREGATION_INTERVAL=60000
|
||||
_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000
|
||||
_APP_MAINTENANCE_RETENTION_SCHEDULES=86400
|
||||
_APP_USAGE_STATS=enabled
|
||||
|
||||
@@ -17,12 +17,6 @@ jobs:
|
||||
fetch-depth: 2
|
||||
submodules: recursive
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
with:
|
||||
@@ -41,11 +35,11 @@ jobs:
|
||||
uses: docker/build-push-action@v4
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
platforms: linux/amd64
|
||||
build-args: |
|
||||
VERSION=${{ steps.meta.outputs.version }}
|
||||
VITE_APPWRITE_GROWTH_ENDPOINT=https://growth.appwrite.io/v1
|
||||
VITE_GA_PROJECT=G-L7G2B6PLDS
|
||||
VITE_CONSOLE_MODE=cloud
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
+1
-16
@@ -98,24 +98,9 @@ RUN chmod +x /usr/local/bin/doctor && \
|
||||
chmod +x /usr/local/bin/worker-messaging && \
|
||||
chmod +x /usr/local/bin/worker-webhooks && \
|
||||
chmod +x /usr/local/bin/worker-migrations && \
|
||||
chmod +x /usr/local/bin/worker-hamster && \
|
||||
chmod +x /usr/local/bin/worker-usage && \
|
||||
chmod +x /usr/local/bin/worker-usage-dump
|
||||
chmod +x /usr/local/bin/worker-usage
|
||||
|
||||
|
||||
# Cloud Executabless
|
||||
RUN chmod +x /usr/local/bin/hamster && \
|
||||
chmod +x /usr/local/bin/volume-sync && \
|
||||
chmod +x /usr/local/bin/patch-delete-schedule-updated-at-attribute && \
|
||||
chmod +x /usr/local/bin/patch-recreate-repositories-documents && \
|
||||
chmod +x /usr/local/bin/patch-delete-project-collections && \
|
||||
chmod +x /usr/local/bin/delete-orphaned-projects && \
|
||||
chmod +x /usr/local/bin/clear-card-cache && \
|
||||
chmod +x /usr/local/bin/calc-users-stats && \
|
||||
chmod +x /usr/local/bin/calc-tier-stats && \
|
||||
chmod +x /usr/local/bin/get-migration-stats && \
|
||||
chmod +x /usr/local/bin/create-inf-metric
|
||||
|
||||
# Letsencrypt Permissions
|
||||
RUN mkdir -p /etc/letsencrypt/live/ && chmod -Rf 755 /etc/letsencrypt/live/
|
||||
|
||||
|
||||
+3
-25
@@ -31,7 +31,7 @@ return [
|
||||
Exception::GENERAL_SERVICE_DISABLED => [
|
||||
'name' => Exception::GENERAL_SERVICE_DISABLED,
|
||||
'description' => 'The requested service is disabled. You can enable the service from the Appwrite console.',
|
||||
'code' => 403,
|
||||
'code' => 503,
|
||||
],
|
||||
Exception::GENERAL_UNAUTHORIZED_SCOPE => [
|
||||
'name' => Exception::GENERAL_UNAUTHORIZED_SCOPE,
|
||||
@@ -103,11 +103,6 @@ return [
|
||||
'description' => 'This method was not fully implemented yet. If you believe this is a mistake, please upgrade your Appwrite server version.',
|
||||
'code' => 405,
|
||||
],
|
||||
Exception::GENERAL_BAD_REQUEST => [
|
||||
'name' => Exception::GENERAL_BAD_REQUEST,
|
||||
'description' => 'There was an error processing your request. Please check the inputs and try again.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** User Errors */
|
||||
Exception::USER_COUNT_EXCEEDED => [
|
||||
@@ -256,11 +251,6 @@ return [
|
||||
'description' => 'User phone is already verified',
|
||||
'code' => 409
|
||||
],
|
||||
Exception::USER_DELETION_PROHIBITED => [
|
||||
'name' => Exception::USER_DELETION_PROHIBITED,
|
||||
'description' => 'User deletion is not allowed for users with active memberships. Please delete all confirmed memberships before deleting the account.',
|
||||
'code' => 400
|
||||
],
|
||||
|
||||
/** Teams */
|
||||
Exception::TEAM_NOT_FOUND => [
|
||||
@@ -778,22 +768,10 @@ return [
|
||||
],
|
||||
|
||||
/** Health */
|
||||
Exception::HEALTH_QUEUE_SIZE_EXCEEDED => [
|
||||
'name' => Exception::HEALTH_QUEUE_SIZE_EXCEEDED,
|
||||
Exception::QUEUE_SIZE_EXCEEDED => [
|
||||
'name' => Exception::QUEUE_SIZE_EXCEEDED,
|
||||
'description' => 'Queue size threshold hit.',
|
||||
'code' => 503,
|
||||
'publish' => false
|
||||
],
|
||||
|
||||
Exception::HEALTH_CERTIFICATE_EXPIRED => [
|
||||
'name' => Exception::HEALTH_CERTIFICATE_EXPIRED,
|
||||
'description' => 'The SSL certificate for the specified domain has expired and is no longer valid.',
|
||||
'code' => 404,
|
||||
],
|
||||
|
||||
Exception::HEALTH_INVALID_HOST => [
|
||||
'name' => Exception::HEALTH_INVALID_HOST,
|
||||
'description' => 'Failed to establish a connection to the specified domain. Please verify the domain name and ensure that the server is running and accessible.',
|
||||
'code' => 404,
|
||||
],
|
||||
];
|
||||
|
||||
@@ -303,7 +303,7 @@ return [
|
||||
[
|
||||
'key' => 'ruby',
|
||||
'name' => 'Ruby',
|
||||
'version' => '10.1.1',
|
||||
'version' => '10.1.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-ruby',
|
||||
'package' => 'https://rubygems.org/gems/appwrite',
|
||||
'enabled' => true,
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -408,7 +408,7 @@ return [
|
||||
],
|
||||
[
|
||||
'name' => '_APP_SMTP_SECURE',
|
||||
'description' => 'SMTP secure connection protocol. Empty by default, change to \'tls\' or \'ssl\' if running on a secure connection.',
|
||||
'description' => 'SMTP secure connection protocol. Empty by default, change to \'tls\' if running on a secure connection.',
|
||||
'introduction' => '',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
@@ -948,15 +948,6 @@ return [
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_MAINTENANCE_DELAY',
|
||||
'description' => 'Delay value containing the number of seconds that the Appwrite maintenance process should wait before executing system cleanups and optimizations. The default value is 0 seconds.',
|
||||
'introduction' => '1.5.0',
|
||||
'default' => '0',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_MAINTENANCE_RETENTION_CACHE',
|
||||
'description' => 'The maximum duration (in seconds) upto which to retain cached files. The default value is 2592000 seconds (30 days).',
|
||||
|
||||
@@ -110,7 +110,7 @@ App::post('/v1/account')
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
if ($project->getAttribute('auths', [])['personalDataCheck'] ?? false) {
|
||||
@@ -637,7 +637,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -695,7 +695,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
Query::notEqual('userId', $user->getId()),
|
||||
]);
|
||||
if (!empty($identitiesWithMatchingEmail)) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$dbForProject->createDocument('identities', new Document([
|
||||
@@ -944,7 +944,7 @@ App::post('/v1/account/sessions/magic-url')
|
||||
Query::equal('providerEmail', [$email]),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$userId = $userId === 'unique()' ? ID::unique() : $userId;
|
||||
@@ -1336,6 +1336,8 @@ App::post('/v1/account/sessions/phone')
|
||||
$message = $message->setParam('{{token}}', $secret);
|
||||
$message = $message->render();
|
||||
|
||||
var_dump($request->getIP());
|
||||
var_dump($project->getId());
|
||||
$queueForMessaging
|
||||
->setRecipient($phone)
|
||||
->setMessage($message)
|
||||
@@ -1988,7 +1990,7 @@ App::patch('/v1/account/email')
|
||||
Query::notEqual('userId', $user->getId()),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$user
|
||||
@@ -2007,7 +2009,7 @@ App::patch('/v1/account/email')
|
||||
try {
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
} catch (Duplicate) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
@@ -2526,7 +2528,7 @@ App::post('/v1/account/recovery')
|
||||
|
||||
$queueForMails
|
||||
->setRecipient($profile->getAttribute('email', ''))
|
||||
->setName($profile->getAttribute('name', ''))
|
||||
->setName($profile->getAttribute('name'))
|
||||
->setBody($body)
|
||||
->setVariables($emailVariables)
|
||||
->setSubject($subject)
|
||||
@@ -2937,6 +2939,8 @@ App::post('/v1/account/verification/phone')
|
||||
$message = $message->setParam('{{token}}', $secret);
|
||||
$message = $message->render();
|
||||
|
||||
var_dump($request->getIP());
|
||||
var_dump($project->getId());
|
||||
$queueForMessaging
|
||||
->setRecipient($user->getAttribute('phone'))
|
||||
->setMessage($message)
|
||||
@@ -3034,27 +3038,15 @@ App::delete('/v1/account')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
||||
->label('sdk.response.model', Response::MODEL_NONE)
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForDeletes')
|
||||
->action(function (Document $user, Document $project, Response $response, Database $dbForProject, Event $queueForEvents, Delete $queueForDeletes) {
|
||||
->action(function (Document $user, Response $response, Database $dbForProject, Event $queueForEvents, Delete $queueForDeletes) {
|
||||
if ($user->isEmpty()) {
|
||||
throw new Exception(Exception::USER_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
// get all memberships
|
||||
$memberships = $user->getAttribute('memberships', []);
|
||||
foreach ($memberships as $membership) {
|
||||
// prevent deletion if at least one active membership
|
||||
if ($membership->getAttribute('confirm', false)) {
|
||||
throw new Exception(Exception::USER_DELETION_PROHIBITED);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$dbForProject->deleteDocument('users', $user->getId());
|
||||
|
||||
$queueForDeletes
|
||||
|
||||
@@ -5,19 +5,14 @@ use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
App::init()
|
||||
->groups(['console'])
|
||||
->inject('project')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (Document $project, float $startTime, Log $log) {
|
||||
$log->addExtra('consoleInitStart', \strval(\microtime(true)));
|
||||
->action(function (Document $project) {
|
||||
if ($project->getId() !== 'console') {
|
||||
throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN);
|
||||
}
|
||||
$log->addExtra('consoleInitEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -55,7 +55,6 @@ use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
/**
|
||||
* * Create attribute of varying type
|
||||
@@ -388,16 +387,12 @@ App::init()
|
||||
->groups(['api', 'database'])
|
||||
->inject('request')
|
||||
->inject('dbForProject')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (Request $request, Database $dbForProject, float $startTime, Log $log) {
|
||||
$log->addExtra('databaseInitStart', \strval(\microtime(true)));
|
||||
->action(function (Request $request, Database $dbForProject) {
|
||||
$timeout = \intval($request->getHeader('x-appwrite-timeout'));
|
||||
|
||||
if (!empty($timeout) && App::isDevelopment()) {
|
||||
$dbForProject->setTimeout($timeout);
|
||||
}
|
||||
$log->addExtra('databaseInitEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
App::post('/v1/databases')
|
||||
@@ -3002,33 +2997,6 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
|
||||
$processDocument($collection, $document);
|
||||
}
|
||||
|
||||
$select = \array_reduce($queries, function ($result, $query) {
|
||||
return $result || ($query->getMethod() === Query::TYPE_SELECT);
|
||||
}, false);
|
||||
|
||||
// Check if the SELECT query includes $databaseId and $collectionId
|
||||
$hasDatabaseId = false;
|
||||
$hasCollectionId = false;
|
||||
if ($select) {
|
||||
$hasDatabaseId = \array_reduce($queries, function ($result, $query) {
|
||||
return $result || ($query->getMethod() === Query::TYPE_SELECT && \in_array('$databaseId', $query->getValues()));
|
||||
}, false);
|
||||
$hasCollectionId = \array_reduce($queries, function ($result, $query) {
|
||||
return $result || ($query->getMethod() === Query::TYPE_SELECT && \in_array('$collectionId', $query->getValues()));
|
||||
}, false);
|
||||
}
|
||||
|
||||
if ($select) {
|
||||
foreach ($documents as $document) {
|
||||
if (!$hasDatabaseId) {
|
||||
$document->removeAttribute('$databaseId');
|
||||
}
|
||||
if (!$hasCollectionId) {
|
||||
$document->removeAttribute('$collectionId');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $total,
|
||||
'documents' => $documents,
|
||||
|
||||
@@ -16,7 +16,6 @@ use Utopia\App;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Validator\JSON;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
App::get('/v1/graphql')
|
||||
->desc('GraphQL endpoint')
|
||||
@@ -293,10 +292,6 @@ function processResult($result, $debugFlags): array
|
||||
App::shutdown()
|
||||
->groups(['schema'])
|
||||
->inject('project')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (Document $project, float $startTime, Log $log) {
|
||||
$log->addExtra('GraphQLShutdownStart', \strval(\microtime(true)));
|
||||
->action(function (Document $project) {
|
||||
Schema::setDirty($project->getId());
|
||||
$log->addExtra('GraphQLShutdownEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
+12
-106
@@ -7,7 +7,6 @@ use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Domains\Validator\PublicDomain;
|
||||
use Utopia\Pools\Group;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
@@ -15,9 +14,7 @@ use Utopia\Registry\Registry;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\Validator\Domain;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Multiple;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
@@ -359,7 +356,7 @@ App::get('/v1/health/queue/webhooks')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -386,62 +383,12 @@ App::get('/v1/health/queue/logs')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/certificate')
|
||||
->desc('Get the SSL certificate for a domain')
|
||||
->groups(['api', 'health'])
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getCertificate')
|
||||
->label('sdk.description', '/docs/references/health/get-certificate.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_CERTIFICATE)
|
||||
->param('domain', null, new Multiple([new Domain(), new PublicDomain()]), Multiple::TYPE_STRING, 'Domain name')
|
||||
->inject('response')
|
||||
->action(function (string $domain, Response $response) {
|
||||
if (filter_var($domain, FILTER_VALIDATE_URL)) {
|
||||
$domain = parse_url($domain, PHP_URL_HOST);
|
||||
}
|
||||
|
||||
$sslContext = stream_context_create([
|
||||
"ssl" => [
|
||||
"capture_peer_cert" => true
|
||||
]
|
||||
]);
|
||||
$sslSocket = stream_socket_client("ssl://" . $domain . ":443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $sslContext);
|
||||
if (!$sslSocket) {
|
||||
throw new Exception(Exception::HEALTH_INVALID_HOST);
|
||||
}
|
||||
|
||||
$streamContextParams = stream_context_get_params($sslSocket);
|
||||
$peerCertificate = $streamContextParams['options']['ssl']['peer_certificate'];
|
||||
$certificatePayload = openssl_x509_parse($peerCertificate);
|
||||
|
||||
|
||||
$sslExpiration = $certificatePayload['validTo_time_t'];
|
||||
$status = $sslExpiration < time() ? 'fail' : 'pass';
|
||||
|
||||
if ($status === 'fail') {
|
||||
throw new Exception(Exception::HEALTH_CERTIFICATE_EXPIRED);
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'name' => $certificatePayload['name'],
|
||||
'subjectSN' => $certificatePayload['subject']['CN'],
|
||||
'issuerOrganisation' => $certificatePayload['issuer']['O'],
|
||||
'validFrom' => $certificatePayload['validFrom_time_t'],
|
||||
'validTo' => $certificatePayload['validTo_time_t'],
|
||||
'signatureTypeSN' => $certificatePayload['signatureTypeSN'],
|
||||
]), Response::MODEL_HEALTH_CERTIFICATE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/certificates')
|
||||
->desc('Get certificates queue')
|
||||
->groups(['api', 'health'])
|
||||
@@ -463,7 +410,7 @@ App::get('/v1/health/queue/certificates')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -490,7 +437,7 @@ App::get('/v1/health/queue/builds')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -518,7 +465,7 @@ App::get('/v1/health/queue/databases')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -545,7 +492,7 @@ App::get('/v1/health/queue/deletes')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -572,7 +519,7 @@ App::get('/v1/health/queue/mails')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -599,7 +546,7 @@ App::get('/v1/health/queue/messaging')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -626,7 +573,7 @@ App::get('/v1/health/queue/migrations')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -653,7 +600,7 @@ App::get('/v1/health/queue/functions')
|
||||
$size = $client->getQueueSize();
|
||||
|
||||
if ($size >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
|
||||
@@ -702,47 +649,6 @@ App::get('/v1/health/storage/local')
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
|
||||
});
|
||||
|
||||
App::get('/v1/health/storage')
|
||||
->desc('Get storage')
|
||||
->groups(['api', 'health'])
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getStorage')
|
||||
->label('sdk.description', '/docs/references/health/get-storage.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_STATUS)
|
||||
->inject('response')
|
||||
->inject('deviceFiles')
|
||||
->inject('deviceFunctions')
|
||||
->inject('deviceBuilds')
|
||||
->action(function (Response $response, Device $deviceFiles, Device $deviceFunctions, Device $deviceBuilds) {
|
||||
$devices = [$deviceFiles, $deviceFunctions, $deviceBuilds];
|
||||
$checkStart = \microtime(true);
|
||||
|
||||
foreach ($devices as $device) {
|
||||
if (!$device->write($device->getPath('health.txt'), 'test', 'text/plain')) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot());
|
||||
}
|
||||
|
||||
if ($device->read($device->getPath('health.txt')) !== 'test') {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot());
|
||||
}
|
||||
|
||||
if (!$device->delete($device->getPath('health.txt'))) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot());
|
||||
}
|
||||
}
|
||||
|
||||
$output = [
|
||||
'status' => 'pass',
|
||||
'ping' => \round((\microtime(true) - $checkStart) / 1000)
|
||||
];
|
||||
|
||||
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
|
||||
});
|
||||
|
||||
App::get('/v1/health/anti-virus')
|
||||
->desc('Get antivirus')
|
||||
->groups(['api', 'health'])
|
||||
@@ -789,7 +695,7 @@ App::get('/v1/health/queue/failed/:name')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getFailedJobs')
|
||||
->param('name', '', new WhiteList([
|
||||
->param('queueName', '', new WhiteList([
|
||||
Event::DATABASE_QUEUE_NAME,
|
||||
Event::DELETE_QUEUE_NAME,
|
||||
Event::AUDITS_QUEUE_NAME,
|
||||
@@ -817,7 +723,7 @@ App::get('/v1/health/queue/failed/:name')
|
||||
$failed = $client->countFailedJobs();
|
||||
|
||||
if ($failed >= $threshold) {
|
||||
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue failed jobs threshold hit. Current size is {$failed} and threshold is {$threshold}.");
|
||||
throw new Exception(Exception::QUEUE_SIZE_EXCEEDED, "Queue failed jobs threshold hit. Current size is {$failed} and threshold is {$threshold}.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([ 'size' => $failed ]), Response::MODEL_HEALTH_QUEUE);
|
||||
|
||||
@@ -144,30 +144,9 @@ App::get('/v1/project/usage')
|
||||
];
|
||||
}, $dbForProject->find('buckets'));
|
||||
|
||||
// merge network inbound + outbound
|
||||
$projectBandwidth = [];
|
||||
foreach ($usage[METRIC_NETWORK_INBOUND] as $item) {
|
||||
$projectBandwidth[$item['date']] ??= 0;
|
||||
$projectBandwidth[$item['date']] += $item['value'];
|
||||
}
|
||||
|
||||
foreach ($usage[METRIC_NETWORK_OUTBOUND] as $item) {
|
||||
$projectBandwidth[$item['date']] ??= 0;
|
||||
$projectBandwidth[$item['date']] += $item['value'];
|
||||
}
|
||||
|
||||
|
||||
$network = [];
|
||||
foreach ($projectBandwidth as $date => $value) {
|
||||
$network[] = [
|
||||
'date' => $date,
|
||||
'value' => $value
|
||||
];
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'requests' => ($usage[METRIC_NETWORK_REQUESTS]),
|
||||
'network' => $network,
|
||||
'network' => ($usage[METRIC_NETWORK_INBOUND] + $usage[METRIC_NETWORK_OUTBOUND]),
|
||||
'users' => ($usage[METRIC_USERS]),
|
||||
'executions' => ($usage[METRIC_EXECUTIONS]),
|
||||
'executionsTotal' => $total[METRIC_EXECUTIONS],
|
||||
|
||||
@@ -38,19 +38,14 @@ use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\URL;
|
||||
use Utopia\Validator\WhiteList;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
App::init()
|
||||
->groups(['projects'])
|
||||
->inject('project')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (Document $project, float $startTime, Log $log) {
|
||||
$log->addExtra('projectInitStart', \strval(\microtime(true)));
|
||||
->action(function (Document $project) {
|
||||
if ($project->getId() !== 'console') {
|
||||
throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN);
|
||||
}
|
||||
$log->addExtra('projectInitEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
App::post('/v1/projects')
|
||||
@@ -1451,7 +1446,7 @@ App::patch('/v1/projects/:projectId/smtp')
|
||||
->param('port', 587, new Integer(), 'SMTP server port', true)
|
||||
->param('username', '', new Text(0, 0), 'SMTP server username', true)
|
||||
->param('password', '', new Text(0, 0), 'SMTP server password', true)
|
||||
->param('secure', '', new WhiteList(['tls', 'ssl'], true), 'Does SMTP server use secure connection', true)
|
||||
->param('secure', '', new WhiteList(['tls'], true), 'Does SMTP server use secure connection', true)
|
||||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->action(function (string $projectId, bool $enabled, string $senderName, string $senderEmail, string $replyTo, string $host, int $port, string $username, string $password, string $secure, Response $response, Database $dbForConsole) {
|
||||
|
||||
@@ -380,6 +380,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
->param('roles', [], new ArrayList(new Key(), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of strings. Use this param to set the user roles in the team. A role can be any string. Learn more about [roles and permissions](https://appwrite.io/docs/permissions). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' roles are allowed, each 32 characters long.')
|
||||
->param('url', '', fn($clients) => new Host($clients), 'URL to redirect the user back to your app from the invitation email. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['clients']) // TODO add our own built-in confirm page
|
||||
->param('name', '', new Text(128), 'Name of the new team member. Max length: 128 chars.', true)
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
@@ -388,7 +389,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
->inject('queueForMails')
|
||||
->inject('queueForMessaging')
|
||||
->inject('queueForEvents')
|
||||
->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, EventPhone $queueForMessaging, Event $queueForEvents) {
|
||||
->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Request $request, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Mail $queueForMails, EventPhone $queueForMessaging, Event $queueForEvents) {
|
||||
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
|
||||
@@ -638,6 +639,8 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
$message = $message->setParam('{{token}}', $url);
|
||||
$message = $message->render();
|
||||
|
||||
var_dump($request->getIP());
|
||||
var_dump($project->getId());
|
||||
$queueForMessaging
|
||||
->setRecipient($phone)
|
||||
->setMessage($message)
|
||||
@@ -967,7 +970,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
|
||||
Authorization::skip(fn() => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
$team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team->setAttribute('total', $team->getAttribute('total', 0) + 1)));
|
||||
|
||||
$queueForEvents
|
||||
->setParam('teamId', $team->getId())
|
||||
@@ -1047,7 +1050,8 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
$dbForProject->deleteCachedDocument('users', $user->getId());
|
||||
|
||||
if ($membership->getAttribute('confirm')) { // Count only confirmed members
|
||||
Authorization::skip(fn() => $dbForProject->decreaseDocumentAttribute('teams', $team->getId(), 'total', 1, 0));
|
||||
$team->setAttribute('total', \max($team->getAttribute('total', 0) - 1, 0));
|
||||
Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team));
|
||||
}
|
||||
|
||||
$queueForEvents
|
||||
|
||||
@@ -9,7 +9,6 @@ use Appwrite\Event\Event;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Identities;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Validator\Queries;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Users;
|
||||
use Utopia\Database\Validator\Query\Limit;
|
||||
@@ -142,6 +141,7 @@ App::post('/v1/users')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, ?string $email, ?string $phone, ?string $password, string $name, Response $response, Document $project, Database $dbForProject, Event $queueForEvents, Hooks $hooks) {
|
||||
$user = createUser('plaintext', '{}', $userId, $email, $password, $phone, $name, $project, $dbForProject, $queueForEvents, $hooks);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($user, Response::MODEL_USER);
|
||||
|
||||
+54
-255
@@ -9,8 +9,9 @@ use Utopia\Logger\Logger;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Logger\Log\User;
|
||||
use Swoole\Http\Request as SwooleRequest;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Pools\Group;
|
||||
use Appwrite\Utopia\Request;
|
||||
use MaxMind\Db\Reader;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\View;
|
||||
use Appwrite\Extend\Exception as AppwriteException;
|
||||
@@ -18,8 +19,6 @@ use Utopia\Config\Config;
|
||||
use Utopia\Domains\Domain;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Usage;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Response\Filters\V11 as ResponseV11;
|
||||
use Appwrite\Utopia\Response\Filters\V12 as ResponseV12;
|
||||
@@ -32,7 +31,6 @@ use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Validator\Hostname;
|
||||
use Appwrite\Utopia\Request\Filters\V12 as RequestV12;
|
||||
@@ -40,7 +38,6 @@ use Appwrite\Utopia\Request\Filters\V13 as RequestV13;
|
||||
use Appwrite\Utopia\Request\Filters\V14 as RequestV14;
|
||||
use Appwrite\Utopia\Request\Filters\V15 as RequestV15;
|
||||
use Appwrite\Utopia\Request\Filters\V16 as RequestV16;
|
||||
use Executor\Executor;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
@@ -48,7 +45,7 @@ Config::setParam('domainVerification', false);
|
||||
Config::setParam('cookieDomain', 'localhost');
|
||||
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
|
||||
|
||||
function router(App $utopia, Database $dbForConsole, callable $getProjectDB, SwooleRequest $swooleRequest, Request $request, Response $response, Event $queueForEvents, Usage $queueForUsage, Reader $geodb)
|
||||
function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleRequest, Request $request, Response $response)
|
||||
{
|
||||
$utopia->getRoute()?->label('error', __DIR__ . '/../views/general/error.phtml');
|
||||
|
||||
@@ -120,226 +117,49 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo
|
||||
$path .= '?' . $query;
|
||||
}
|
||||
|
||||
|
||||
$body = $swooleRequest->getContent() ?? '';
|
||||
$method = $swooleRequest->server['request_method'];
|
||||
|
||||
$requestHeaders = $request->getHeaders();
|
||||
|
||||
$project = Authorization::skip(fn () => $dbForConsole->getDocument('projects', $projectId));
|
||||
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
|
||||
|
||||
if ($function->isEmpty() || !$function->getAttribute('enabled')) {
|
||||
throw new AppwriteException(AppwriteException::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$version = $function->getAttribute('version', 'v2');
|
||||
$runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);
|
||||
|
||||
$runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null;
|
||||
|
||||
if (\is_null($runtime)) {
|
||||
throw new AppwriteException(AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported');
|
||||
}
|
||||
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', '')));
|
||||
|
||||
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
|
||||
throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
|
||||
}
|
||||
|
||||
if ($deployment->isEmpty()) {
|
||||
throw new AppwriteException(AppwriteException::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
|
||||
}
|
||||
|
||||
/** Check if build has completed */
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
if ($build->isEmpty()) {
|
||||
throw new AppwriteException(AppwriteException::BUILD_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($build->getAttribute('status') !== 'ready') {
|
||||
throw new AppwriteException(AppwriteException::BUILD_NOT_READY);
|
||||
}
|
||||
|
||||
$permissions = $function->getAttribute('execute');
|
||||
|
||||
if (!(\in_array('any', $permissions)) && (\in_array('guests', $permissions))) {
|
||||
throw new AppwriteException(AppwriteException::USER_UNAUTHORIZED, 'To execute function using domain, execute permissions must include "any" or "guests"');
|
||||
}
|
||||
|
||||
$headers = \array_merge([], $requestHeaders);
|
||||
$headers['x-appwrite-trigger'] = 'http';
|
||||
$headers['x-appwrite-user-id'] = '';
|
||||
$headers['x-appwrite-user-jwt'] = '';
|
||||
$headers['x-appwrite-country-code'] = '';
|
||||
$headers['x-appwrite-continent-code'] = '';
|
||||
$headers['x-appwrite-continent-eu'] = 'false';
|
||||
|
||||
$ip = $headers['x-real-ip'] ?? '';
|
||||
if (!empty($ip)) {
|
||||
$record = $geodb->get($ip);
|
||||
|
||||
if ($record) {
|
||||
$eu = Config::getParam('locale-eu');
|
||||
|
||||
$headers['x-appwrite-country-code'] = $record['country']['iso_code'] ?? '';
|
||||
$headers['x-appwrite-continent-code'] = $record['continent']['code'] ?? '';
|
||||
$headers['x-appwrite-continent-eu'] = (\in_array($record['country']['iso_code'], $eu)) ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
|
||||
$headersFiltered = [];
|
||||
foreach ($headers as $key => $value) {
|
||||
if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_REQUEST)) {
|
||||
$headersFiltered[] = ['name' => $key, 'value' => $value];
|
||||
}
|
||||
}
|
||||
|
||||
$executionId = ID::unique();
|
||||
|
||||
$execution = new Document([
|
||||
'$id' => $executionId,
|
||||
'$permissions' => [],
|
||||
'functionInternalId' => $function->getInternalId(),
|
||||
'functionId' => $function->getId(),
|
||||
'deploymentInternalId' => $deployment->getInternalId(),
|
||||
'deploymentId' => $deployment->getId(),
|
||||
'trigger' => 'http', // http / schedule / event
|
||||
'status' => 'processing', // waiting / processing / completed / failed
|
||||
'responseStatusCode' => 0,
|
||||
'responseHeaders' => [],
|
||||
'requestPath' => $path,
|
||||
'requestMethod' => $method,
|
||||
'requestHeaders' => $headersFiltered,
|
||||
'errors' => '',
|
||||
'logs' => '',
|
||||
'duration' => 0.0,
|
||||
'search' => implode(' ', [$functionId, $executionId]),
|
||||
$body = \json_encode([
|
||||
'async' => false,
|
||||
'body' => $swooleRequest->getContent() ?? '',
|
||||
'method' => $swooleRequest->server['request_method'],
|
||||
'path' => $path,
|
||||
'headers' => $requestHeaders
|
||||
]);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('functionId', $function->getId())
|
||||
->setParam('executionId', $execution->getId())
|
||||
->setContext('function', $function);
|
||||
$headers = [
|
||||
'Content-Type: application/json',
|
||||
'Content-Length: ' . \strlen($body),
|
||||
'X-Appwrite-Project: ' . $projectId
|
||||
];
|
||||
|
||||
$durationStart = \microtime(true);
|
||||
$ch = \curl_init();
|
||||
\curl_setopt($ch, CURLOPT_URL, "http://localhost/v1/functions/{$functionId}/executions");
|
||||
\curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
|
||||
\curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
|
||||
\curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
\curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
// \curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
\curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
\curl_setopt($ch, CURLOPT_TIMEOUT, 30);
|
||||
|
||||
$vars = [];
|
||||
$executionResponse = \curl_exec($ch);
|
||||
$statusCode = \curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
$error = \curl_error($ch);
|
||||
$errNo = \curl_errno($ch);
|
||||
|
||||
// V2 vars
|
||||
if ($version === 'v2') {
|
||||
$vars = \array_merge($vars, [
|
||||
'APPWRITE_FUNCTION_TRIGGER' => $headers['x-appwrite-trigger'] ?? '',
|
||||
'APPWRITE_FUNCTION_DATA' => $body ?? '',
|
||||
'APPWRITE_FUNCTION_USER_ID' => $headers['x-appwrite-user-id'] ?? '',
|
||||
'APPWRITE_FUNCTION_JWT' => $headers['x-appwrite-user-jwt'] ?? ''
|
||||
]);
|
||||
\curl_close($ch);
|
||||
|
||||
if ($errNo !== 0) {
|
||||
throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Internal error: " . $error);
|
||||
}
|
||||
|
||||
// Shared vars
|
||||
foreach ($function->getAttribute('varsProject', []) as $var) {
|
||||
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
|
||||
if ($statusCode >= 400) {
|
||||
$error = \json_decode($executionResponse, true)['message'];
|
||||
throw new AppwriteException(AppwriteException::GENERAL_ARGUMENT_INVALID, "Execution error: " . $error);
|
||||
}
|
||||
|
||||
// Function vars
|
||||
foreach ($function->getAttribute('vars', []) as $var) {
|
||||
$vars[$var->getAttribute('key')] = $var->getAttribute('value', '');
|
||||
}
|
||||
|
||||
// Appwrite vars
|
||||
$vars = \array_merge($vars, [
|
||||
'APPWRITE_FUNCTION_ID' => $functionId,
|
||||
'APPWRITE_FUNCTION_NAME' => $function->getAttribute('name'),
|
||||
'APPWRITE_FUNCTION_DEPLOYMENT' => $deployment->getId(),
|
||||
'APPWRITE_FUNCTION_PROJECT_ID' => $project->getId(),
|
||||
'APPWRITE_FUNCTION_RUNTIME_NAME' => $runtime['name'] ?? '',
|
||||
'APPWRITE_FUNCTION_RUNTIME_VERSION' => $runtime['version'] ?? '',
|
||||
]);
|
||||
|
||||
/** Execute function */
|
||||
$executor = new Executor(App::getEnv('_APP_EXECUTOR_HOST'));
|
||||
try {
|
||||
$version = $function->getAttribute('version', 'v2');
|
||||
$command = $runtime['startCommand'];
|
||||
$command = $version === 'v2' ? '' : 'cp /tmp/code.tar.gz /mnt/code/code.tar.gz && nohup helpers/start.sh "' . $command . '"';
|
||||
$executionResponse = $executor->createExecution(
|
||||
projectId: $project->getId(),
|
||||
deploymentId: $deployment->getId(),
|
||||
body: \strlen($body) > 0 ? $body : null,
|
||||
variables: $vars,
|
||||
timeout: $function->getAttribute('timeout', 0),
|
||||
image: $runtime['image'],
|
||||
source: $build->getAttribute('path', ''),
|
||||
entrypoint: $deployment->getAttribute('entrypoint', ''),
|
||||
version: $version,
|
||||
path: $path,
|
||||
method: $method,
|
||||
headers: $headers,
|
||||
runtimeEntrypoint: $command,
|
||||
requestTimeout: 30
|
||||
);
|
||||
|
||||
$headersFiltered = [];
|
||||
foreach ($executionResponse['headers'] as $key => $value) {
|
||||
if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_RESPONSE)) {
|
||||
$headersFiltered[] = ['name' => $key, 'value' => $value];
|
||||
}
|
||||
}
|
||||
|
||||
/** Update execution status */
|
||||
$status = $executionResponse['statusCode'] >= 400 ? 'failed' : 'completed';
|
||||
$execution->setAttribute('status', $status);
|
||||
$execution->setAttribute('responseStatusCode', $executionResponse['statusCode']);
|
||||
$execution->setAttribute('responseHeaders', $headersFiltered);
|
||||
$execution->setAttribute('logs', $executionResponse['logs']);
|
||||
$execution->setAttribute('errors', $executionResponse['errors']);
|
||||
$execution->setAttribute('duration', $executionResponse['duration']);
|
||||
} catch (\Throwable $th) {
|
||||
$durationEnd = \microtime(true);
|
||||
|
||||
$execution
|
||||
->setAttribute('duration', $durationEnd - $durationStart)
|
||||
->setAttribute('status', 'failed')
|
||||
->setAttribute('responseStatusCode', 500)
|
||||
->setAttribute('errors', $th->getMessage() . '\nError Code: ' . $th->getCode());
|
||||
Console::error($th->getMessage());
|
||||
} finally {
|
||||
$queueForUsage
|
||||
->addMetric(METRIC_EXECUTIONS, 1)
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1)
|
||||
->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project
|
||||
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
|
||||
;
|
||||
}
|
||||
|
||||
if ($function->getAttribute('logging')) {
|
||||
/** @var Document $execution */
|
||||
$execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', $execution));
|
||||
}
|
||||
|
||||
$execution->setAttribute('logs', '');
|
||||
$execution->setAttribute('errors', '');
|
||||
|
||||
$headers = [];
|
||||
foreach (($executionResponse['headers'] ?? []) as $key => $value) {
|
||||
$headers[] = ['name' => $key, 'value' => $value];
|
||||
}
|
||||
|
||||
$execution->setAttribute('responseBody', $executionResponse['body'] ?? '');
|
||||
$execution->setAttribute('responseHeaders', $headers);
|
||||
|
||||
$body = $execution['responseBody'] ?? '';
|
||||
|
||||
$encodingKey = \array_search('x-open-runtimes-encoding', \array_column($execution['responseHeaders'], 'name'));
|
||||
if ($encodingKey !== false) {
|
||||
if (($execution['responseHeaders'][$encodingKey]['value'] ?? '') === 'base64') {
|
||||
$body = \base64_decode($body);
|
||||
}
|
||||
}
|
||||
$execution = \json_decode($executionResponse, true);
|
||||
|
||||
$contentType = 'text/plain';
|
||||
foreach ($execution['responseHeaders'] as $header) {
|
||||
@@ -350,6 +170,15 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo
|
||||
$response->setHeader($header['name'], $header['value']);
|
||||
}
|
||||
|
||||
$body = $execution['responseBody'] ?? '';
|
||||
|
||||
$encodingKey = \array_search('x-open-runtimes-encoding', \array_column($execution['responseHeaders'], 'name'));
|
||||
if ($encodingKey !== false) {
|
||||
if (($execution['responseHeaders'][$encodingKey]['value'] ?? '') === 'base64') {
|
||||
$body = \base64_decode($body);
|
||||
}
|
||||
}
|
||||
|
||||
$response
|
||||
->setContentType($contentType)
|
||||
->setStatusCode($execution['responseStatusCode'] ?? 200)
|
||||
@@ -376,28 +205,22 @@ App::init()
|
||||
->inject('console')
|
||||
->inject('project')
|
||||
->inject('dbForConsole')
|
||||
->inject('getProjectDB')
|
||||
->inject('user')
|
||||
->inject('locale')
|
||||
->inject('localeCodes')
|
||||
->inject('clients')
|
||||
->inject('servers')
|
||||
->inject('queueForCertificates')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForUsage')
|
||||
->inject('geodb')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, callable $getProjectDB, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates, Event $queueForEvents, Usage $queueForUsage, Reader $geodb, float $startTime, Log $log) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Document $console, Document $project, Database $dbForConsole, Document $user, Locale $locale, array $localeCodes, array $clients, array $servers, Certificate $queueForCertificates) {
|
||||
/*
|
||||
* Appwrite Router
|
||||
*/
|
||||
$log->addExtra('generalInitStart', \strval(\microtime(true)));
|
||||
|
||||
$host = $request->getHostname() ?? '';
|
||||
$mainDomain = App::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if ($host !== $mainDomain) {
|
||||
if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) {
|
||||
if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -740,8 +563,6 @@ App::init()
|
||||
if ($user->getAttribute('reset')) {
|
||||
throw new AppwriteException(AppwriteException::USER_PASSWORD_RESET_REQUIRED);
|
||||
}
|
||||
|
||||
$log->addExtra('generalInitEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
App::options()
|
||||
@@ -750,11 +571,7 @@ App::options()
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->inject('getProjectDB')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForUsage')
|
||||
->inject('geodb')
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole, callable $getProjectDB, Event $queueForEvents, Usage $queueForUsage, Reader $geodb) {
|
||||
->action(function (App $utopia, SwooleRequest $swooleRequest, Request $request, Response $response, Database $dbForConsole) {
|
||||
/*
|
||||
* Appwrite Router
|
||||
*/
|
||||
@@ -762,7 +579,7 @@ App::options()
|
||||
$mainDomain = App::getEnv('_APP_DOMAIN', '');
|
||||
// Only run Router when external domain
|
||||
if ($host !== $mainDomain) {
|
||||
if (router($utopia, $dbForConsole, $getProjectDB, $swooleRequest, $request, $response, $queueForEvents, $queueForUsage, $geodb)) {
|
||||
if (router($utopia, $dbForConsole, $swooleRequest, $request, $response)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -790,28 +607,10 @@ App::error()
|
||||
->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log) {
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
$route = $utopia->getRoute();
|
||||
$publish = true;
|
||||
|
||||
if ($error instanceof AppwriteException) {
|
||||
$publish = $error->isPublishable();
|
||||
} else {
|
||||
$publish = $error->getCode() === 0 || $error->getCode() >= 500;
|
||||
}
|
||||
|
||||
if ($error->getCode() >= 400 && $error->getCode() < 500) {
|
||||
// Register error logger
|
||||
$providerName = App::getEnv('_APP_EXPERIMENT_LOGGING_PROVIDER', '');
|
||||
$providerConfig = App::getEnv('_APP_EXPERIMENT_LOGGING_CONFIG', '');
|
||||
|
||||
if (!(empty($providerName) || empty($providerConfig))) {
|
||||
if (!Logger::hasProvider($providerName)) {
|
||||
throw new Exception("Logging provider not supported. Logging is disabled");
|
||||
}
|
||||
|
||||
$classname = '\\Utopia\\Logger\\Adapter\\' . \ucfirst($providerName);
|
||||
$adapter = new $classname($providerConfig);
|
||||
$logger = new Logger($adapter);
|
||||
$publish = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ($logger && ($publish || $error->getCode() === 0)) {
|
||||
@@ -957,10 +756,10 @@ App::error()
|
||||
->setParam('development', App::isDevelopment())
|
||||
->setParam('projectName', $project->getAttribute('name'))
|
||||
->setParam('projectURL', $project->getAttribute('url'))
|
||||
->setParam('message', $output['message'] ?? '')
|
||||
->setParam('type', $output['type'] ?? '')
|
||||
->setParam('code', $output['code'] ?? '')
|
||||
->setParam('trace', $output['trace'] ?? []);
|
||||
->setParam('message', $error->getMessage())
|
||||
->setParam('type', $type)
|
||||
->setParam('code', $code)
|
||||
->setParam('trace', $trace);
|
||||
|
||||
$response->html($layout->render());
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ use Utopia\Database\Validator\UID;
|
||||
use Utopia\VCS\Adapter\Git\GitHub;
|
||||
use Utopia\Database\Helpers\Permission;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
App::get('/v1/mock/tests/general/oauth2')
|
||||
->desc('OAuth Login')
|
||||
@@ -219,11 +218,8 @@ App::shutdown()
|
||||
->inject('utopia')
|
||||
->inject('response')
|
||||
->inject('request')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (App $utopia, Response $response, Request $request, float $startTime, Log $log) {
|
||||
->action(function (App $utopia, Response $response, Request $request) {
|
||||
|
||||
$log->addExtra('MockShutdownStart', \strval(\microtime(true)));
|
||||
$result = [];
|
||||
$route = $utopia->getRoute();
|
||||
$path = APP_STORAGE_CACHE . '/tests.json';
|
||||
@@ -241,7 +237,5 @@ App::shutdown()
|
||||
throw new Exception(Exception::GENERAL_MOCK, 'Failed to save results', 500);
|
||||
}
|
||||
|
||||
$log->addExtra('MockShutdownEnd', \strval(\microtime(true)));
|
||||
|
||||
$response->dynamic(new Document(['result' => $route->getMethod() . ':' . $route->getPath() . ':passed']), Response::MODEL_MOCK);
|
||||
});
|
||||
|
||||
@@ -21,7 +21,6 @@ use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
$parseLabel = function (string $label, array $responsePayload, array $requestParams, Document $user) {
|
||||
preg_match_all('/{(.*?)}/', $label, $matches);
|
||||
@@ -157,11 +156,8 @@ App::init()
|
||||
->inject('mode')
|
||||
->inject('queueForMails')
|
||||
->inject('queueForUsage')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Database $dbForProject, string $mode, Mail $queueForMails, Usage $queueForUsage, float $startTime, Log $log) use ($databaseListener) {
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Database $dbForProject, string $mode, Mail $queueForMails, Usage $queueForUsage) use ($databaseListener) {
|
||||
|
||||
$log->addExtra('apiInitStart', \strval(\microtime(true)));
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
if ($project->isEmpty() && $route->getLabel('abuse-limit', 0) > 0) { // Abuse limit requires an active project scope
|
||||
@@ -313,7 +309,6 @@ App::init()
|
||||
$response->addHeader('X-Appwrite-Cache', 'miss');
|
||||
}
|
||||
}
|
||||
$log->addExtra('apiInitEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
App::init()
|
||||
@@ -321,10 +316,8 @@ App::init()
|
||||
->inject('utopia')
|
||||
->inject('request')
|
||||
->inject('project')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (App $utopia, Request $request, Document $project, float $startTime, Log $log) {
|
||||
$log->addExtra('APIInitStart2', \strval(\microtime(true)));
|
||||
->action(function (App $utopia, Request $request, Document $project) {
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
@@ -376,7 +369,6 @@ App::init()
|
||||
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Unsupported authentication type: ' . $route->getLabel('auth.type', ''));
|
||||
break;
|
||||
}
|
||||
$log->addExtra('APIInitEnd2', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -392,10 +384,7 @@ App::shutdown()
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Database $dbForProject, float $startTime, Log $log) {
|
||||
$log->addExtra('APIShutdownStart1', \strval(\microtime(true)));
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Database $dbForProject) {
|
||||
$sessionLimit = $project->getAttribute('auths', [])['maxSessions'] ?? APP_LIMIT_USER_SESSIONS_DEFAULT;
|
||||
$session = $response->getPayload();
|
||||
$userId = $session['userId'] ?? '';
|
||||
@@ -419,8 +408,6 @@ App::shutdown()
|
||||
$dbForProject->deleteDocument('sessions', $session->getId());
|
||||
}
|
||||
$dbForProject->deleteCachedDocument('users', $userId);
|
||||
|
||||
$log->addExtra('APIShutdownStart2', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
App::shutdown()
|
||||
@@ -439,11 +426,8 @@ App::shutdown()
|
||||
->inject('queueForFunctions')
|
||||
->inject('mode')
|
||||
->inject('dbForConsole')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsole, float $startTime, Log $log) use ($parseLabel) {
|
||||
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Event $queueForEvents, Audit $queueForAudits, Usage $queueForUsage, Delete $queueForDeletes, EventDatabase $queueForDatabase, Database $dbForProject, Func $queueForFunctions, string $mode, Database $dbForConsole) use ($parseLabel) {
|
||||
|
||||
$log->addExtra('APIShutdownStart2', \strval(\microtime(true)));
|
||||
$responsePayload = $response->getPayload();
|
||||
|
||||
if (!empty($queueForEvents->getEvent())) {
|
||||
@@ -631,17 +615,12 @@ App::shutdown()
|
||||
}
|
||||
}
|
||||
}
|
||||
$log->addExtra('APIShutdownEnd2', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
App::init()
|
||||
->groups(['usage'])
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (float $startTime, Log $log) {
|
||||
$log->addExtra('APIInitStart3', \strval(\microtime(true)));
|
||||
->action(function () {
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') !== 'enabled') {
|
||||
throw new Exception(Exception::GENERAL_USAGE_DISABLED);
|
||||
}
|
||||
$log->addExtra('APIInitEnd3', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
@@ -6,17 +6,14 @@ use Utopia\App;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
App::init()
|
||||
->groups(['auth'])
|
||||
->inject('utopia')
|
||||
->inject('request')
|
||||
->inject('project')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (App $utopia, Request $request, Document $project, float $startTime, Log $log) {
|
||||
$log->addExtra('AuthInitStart', \strval(\microtime(true)));
|
||||
->action(function (App $utopia, Request $request, Document $project) {
|
||||
|
||||
$route = $utopia->match($request);
|
||||
|
||||
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
|
||||
@@ -68,5 +65,4 @@ App::init()
|
||||
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Unsupported authentication route');
|
||||
break;
|
||||
}
|
||||
$log->addExtra('AuthInitEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
@@ -3,22 +3,17 @@
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Logger\Log;
|
||||
|
||||
App::init()
|
||||
->groups(['web'])
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->action(function (Request $request, Response $response, float $startTime, Log $log) {
|
||||
$log->addExtra('ConsoleWebInitStart', \strval(\microtime(true)));
|
||||
->action(function (Request $request, Response $response) {
|
||||
$response
|
||||
->addHeader('X-Frame-Options', 'SAMEORIGIN') // Avoid console and homepage from showing in iframes
|
||||
->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url=' . \urlencode($request->getURI()))
|
||||
->addHeader('X-UA-Compatible', 'IE=Edge') // Deny IE browsers from going into quirks mode
|
||||
;
|
||||
$log->addExtra('ConsoleWebInitEnd', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
App::get('/console/*')
|
||||
|
||||
+1
-49
@@ -2,7 +2,6 @@
|
||||
|
||||
require_once __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Swoole\Process;
|
||||
use Swoole\Http\Server;
|
||||
@@ -27,24 +26,6 @@ use Utopia\Pools\Group;
|
||||
|
||||
$http = new Server("0.0.0.0", App::getEnv('PORT', 80));
|
||||
|
||||
App::setResource('startTime', function() {
|
||||
return \microtime(true);
|
||||
});
|
||||
|
||||
App::init()
|
||||
->inject('startTime')
|
||||
->inject('log')
|
||||
->inject('http')
|
||||
->action(function(float $startTime, Log $log, mixed $http) {
|
||||
$stats = $http->stats();
|
||||
$workersIdle = $stats['idle_worker_num'] ?? -1;
|
||||
$workersTotal = $stats['worker_num'] ?? -1;
|
||||
|
||||
$log->addExtra('workersIdle', \strval($workersIdle));
|
||||
$log->addExtra('workersTotal', \strval($workersTotal));
|
||||
$log->addExtra('veryFirstInit', \strval(\microtime(true)));
|
||||
});
|
||||
|
||||
$payloadSize = 6 * (1024 * 1024); // 6MB
|
||||
$workerNumber = swoole_cpu_num() * intval(App::getEnv('_APP_WORKER_PER_CORE', 6));
|
||||
|
||||
@@ -241,10 +222,9 @@ $http->on('start', function (Server $http) use ($payloadSize, $register) {
|
||||
});
|
||||
});
|
||||
|
||||
$http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) use ($register, $http) {
|
||||
$http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swooleResponse) use ($register) {
|
||||
App::setResource('swooleRequest', fn () => $swooleRequest);
|
||||
App::setResource('swooleResponse', fn () => $swooleResponse);
|
||||
App::setResource('http', fn () => $http);
|
||||
|
||||
$request = new Request($swooleRequest);
|
||||
$response = new Response($swooleResponse);
|
||||
@@ -263,23 +243,9 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
|
||||
|
||||
$app = new App('UTC');
|
||||
|
||||
$l = new Log();
|
||||
|
||||
$fd = $swooleRequest->fd;
|
||||
$fd_info = $http->getClientInfo($fd);
|
||||
$packetTimeStart = $fd_info['last_time'];
|
||||
$l->addExtra('packetTimeStart', \strval($packetTimeStart));
|
||||
|
||||
App::setResource('log', fn() => $l);
|
||||
App::setResource('swooleStartTime', fn() => \floatval($packetTimeStart));
|
||||
|
||||
$l->addExtra('GetPoolsStart', \strval(\microtime(true)));
|
||||
|
||||
$pools = $register->get('pools');
|
||||
App::setResource('pools', fn () => $pools);
|
||||
|
||||
$l->addExtra('GetPoolsEnd', \strval(\microtime(true)));
|
||||
|
||||
try {
|
||||
Authorization::cleanRoles();
|
||||
Authorization::setRole(Role::any()->toString());
|
||||
@@ -361,18 +327,4 @@ $http->on('request', function (SwooleRequest $swooleRequest, SwooleResponse $swo
|
||||
}
|
||||
});
|
||||
|
||||
App::shutdown()
|
||||
->inject('swooleStartTime')
|
||||
->inject('log')
|
||||
->action(function(float $swooleStartTime, Log $log) {
|
||||
$endTime = \microtime(true);
|
||||
|
||||
$log->addExtra('veryLastShutdown', \strval(\microtime(true)));
|
||||
$log->addExtra('durationSwoole', \strval($endTime - $swooleStartTime));
|
||||
|
||||
if($endTime - $swooleStartTime > 10) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Our amazing timeout.');
|
||||
}
|
||||
});
|
||||
|
||||
$http->start();
|
||||
|
||||
+2
-2
@@ -112,7 +112,7 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return
|
||||
const APP_KEY_ACCCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_USER_ACCCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_BUSTER = 331;
|
||||
const APP_CACHE_BUSTER = 329;
|
||||
const APP_VERSION_STABLE = '1.4.13';
|
||||
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
|
||||
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
|
||||
@@ -195,7 +195,6 @@ const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length'];
|
||||
// Usage metrics
|
||||
const METRIC_TEAMS = 'teams';
|
||||
const METRIC_USERS = 'users';
|
||||
const METRIC_MESSAGES = 'messages';
|
||||
const METRIC_SESSIONS = 'sessions';
|
||||
const METRIC_DATABASES = 'databases';
|
||||
const METRIC_COLLECTIONS = 'collections';
|
||||
@@ -866,6 +865,7 @@ foreach ($locales as $locale) {
|
||||
]);
|
||||
|
||||
// Runtime Execution
|
||||
App::setResource('log', fn() => new Log());
|
||||
App::setResource('logger', function ($register) {
|
||||
return $register->get('logger');
|
||||
}, ['register']);
|
||||
|
||||
@@ -143,7 +143,6 @@ services:
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_MAINTENANCE_INTERVAL
|
||||
- _APP_MAINTENANCE_DELAY
|
||||
- _APP_MAINTENANCE_RETENTION_EXECUTION
|
||||
- _APP_MAINTENANCE_RETENTION_CACHE
|
||||
- _APP_MAINTENANCE_RETENTION_ABUSE
|
||||
|
||||
+9
-11
@@ -14,7 +14,6 @@ use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Migration;
|
||||
use Appwrite\Event\Phone;
|
||||
use Appwrite\Event\Usage;
|
||||
use Appwrite\Event\UsageDump;
|
||||
use Appwrite\Platform\Appwrite;
|
||||
use Swoole\Runtime;
|
||||
use Utopia\App;
|
||||
@@ -147,9 +146,6 @@ Server::setResource('log', fn() => new Log());
|
||||
Server::setResource('queueForUsage', function (Connection $queue) {
|
||||
return new Usage($queue);
|
||||
}, ['queue']);
|
||||
Server::setResource('queueForUsageDump', function (Connection $queue) {
|
||||
return new UsageDump($queue);
|
||||
}, ['queue']);
|
||||
Server::setResource('queue', function (Group $pools) {
|
||||
return $pools->get('queue')->pop()->getResource();
|
||||
}, ['pools']);
|
||||
@@ -253,6 +249,7 @@ try {
|
||||
Console::error($e->getMessage() . ', File: ' . $e->getFile() . ', Line: ' . $e->getLine());
|
||||
}
|
||||
|
||||
|
||||
$worker = $platform->getWorker();
|
||||
|
||||
$worker
|
||||
@@ -267,8 +264,7 @@ $worker
|
||||
->inject('error')
|
||||
->inject('logger')
|
||||
->inject('log')
|
||||
->inject('project')
|
||||
->action(function (Throwable $error, ?Logger $logger, Log $log, Document $project) {
|
||||
->action(function (Throwable $error, ?Logger $logger, Log $log) {
|
||||
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
||||
if ($error instanceof PDOException) {
|
||||
@@ -284,7 +280,6 @@ $worker
|
||||
$log->setAction('appwrite-queue-' . App::getEnv('QUEUE'));
|
||||
$log->addTag('verboseType', get_class($error));
|
||||
$log->addTag('code', $error->getCode());
|
||||
$log->addTag('projectId', $project->getId() ?? 'n/a');
|
||||
$log->addExtra('file', $error->getFile());
|
||||
$log->addExtra('line', $error->getLine());
|
||||
$log->addExtra('trace', $error->getTraceAsString());
|
||||
@@ -304,9 +299,12 @@ $worker
|
||||
Console::error('[Error] Line: ' . $error->getLine());
|
||||
});
|
||||
|
||||
$worker->workerStart()
|
||||
->action(function () use ($workerName) {
|
||||
Console::info("Worker $workerName started");
|
||||
});
|
||||
try {
|
||||
$workerStart = $worker->getWorkerStart();
|
||||
} catch (\Throwable $error) {
|
||||
$worker->workerStart();
|
||||
} finally {
|
||||
Console::info("Worker $workerName started");
|
||||
}
|
||||
|
||||
$worker->start();
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php calc-tier-stats $@
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php calc-users-stats $@
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php clear-card-cache $@
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php delete-orphaned-projects $@
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php get-migration-stats $@
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php hamster $@
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php hamster $@
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php usage-dump $@
|
||||
+3
-4
@@ -1,5 +1,4 @@
|
||||
{
|
||||
|
||||
"name": "appwrite/server-ce",
|
||||
"description": "End to end backend server for frontend and mobile apps.",
|
||||
"type": "project",
|
||||
@@ -51,13 +50,13 @@
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "0.2.*",
|
||||
"utopia-php/database": "0.45.*",
|
||||
"utopia-php/domains": "0.5.*",
|
||||
"utopia-php/domains": "0.3.*",
|
||||
"utopia-php/dsn": "0.1.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/image": "0.6.*",
|
||||
"utopia-php/image": "0.5.*",
|
||||
"utopia-php/locale": "0.4.*",
|
||||
"utopia-php/logger": "0.3.*",
|
||||
"utopia-php/messaging": "0.3.*",
|
||||
"utopia-php/messaging": "0.2.*",
|
||||
"utopia-php/migration": "0.3.*",
|
||||
"utopia-php/orchestration": "0.9.*",
|
||||
"utopia-php/platform": "0.5.*",
|
||||
|
||||
Generated
+111
-98
@@ -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": "f7a4173bb5adeea3518f949fa883a282",
|
||||
"content-hash": "35dcde03d0eb9a0d27de653b9fa038d4",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -156,11 +156,11 @@
|
||||
},
|
||||
{
|
||||
"name": "appwrite/php-runtimes",
|
||||
"version": "0.13.3",
|
||||
"version": "0.13.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/runtimes.git",
|
||||
"reference": "5d93fc578a9a543bcdc9b2c0562d80a51d56c73d"
|
||||
"reference": "214a37c2c66e0f2bc9c30fdfde66955d9fd084a1"
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
@@ -195,7 +195,7 @@
|
||||
"php",
|
||||
"runtimes"
|
||||
],
|
||||
"time": "2024-03-01T14:47:47+00:00"
|
||||
"time": "2023-11-22T15:36:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "chillerlan/php-qrcode",
|
||||
@@ -815,16 +815,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-php80",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-php80.git",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
|
||||
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
|
||||
"reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -832,6 +832,9 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@@ -875,7 +878,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -891,7 +894,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/abuse",
|
||||
@@ -1187,16 +1190,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "0.45.6",
|
||||
"version": "0.45.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "c7cc6d57683a4c13d9772dbeea343adb72c443fd"
|
||||
"reference": "0b66a017f817a910acb83e6aea92bccea9571fe6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/c7cc6d57683a4c13d9772dbeea343adb72c443fd",
|
||||
"reference": "c7cc6d57683a4c13d9772dbeea343adb72c443fd",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/0b66a017f817a910acb83e6aea92bccea9571fe6",
|
||||
"reference": "0b66a017f817a910acb83e6aea92bccea9571fe6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1237,22 +1240,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/0.45.6"
|
||||
"source": "https://github.com/utopia-php/database/tree/0.45.5"
|
||||
},
|
||||
"time": "2024-02-01T02:33:43+00:00"
|
||||
"time": "2024-01-08T17:08:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
"version": "0.5.0",
|
||||
"version": "0.3.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/domains.git",
|
||||
"reference": "bf07f60326f8389f378ddf6fcde86217e5cfe18c"
|
||||
"reference": "aaa8c9a96c69ccb397997b1f4f2299c66f77eefb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/domains/zipball/bf07f60326f8389f378ddf6fcde86217e5cfe18c",
|
||||
"reference": "bf07f60326f8389f378ddf6fcde86217e5cfe18c",
|
||||
"url": "https://api.github.com/repos/utopia-php/domains/zipball/aaa8c9a96c69ccb397997b1f4f2299c66f77eefb",
|
||||
"reference": "aaa8c9a96c69ccb397997b1f4f2299c66f77eefb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1297,9 +1300,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/domains/issues",
|
||||
"source": "https://github.com/utopia-php/domains/tree/0.5.0"
|
||||
"source": "https://github.com/utopia-php/domains/tree/0.3.2"
|
||||
},
|
||||
"time": "2024-01-03T22:04:27+00:00"
|
||||
"time": "2023-07-19T16:39:24+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/dsn",
|
||||
@@ -1350,16 +1353,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.33.2",
|
||||
"version": "0.33.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3"
|
||||
"reference": "b745607aa1875554a0ad52e28f6db918da1ce11c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/b1423ca3e3b61c6c4c2e619d2cb80672809a19f3",
|
||||
"reference": "b1423ca3e3b61c6c4c2e619d2cb80672809a19f3",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/b745607aa1875554a0ad52e28f6db918da1ce11c",
|
||||
"reference": "b745607aa1875554a0ad52e28f6db918da1ce11c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1389,22 +1392,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.2"
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.1"
|
||||
},
|
||||
"time": "2024-01-31T10:35:59+00:00"
|
||||
"time": "2024-01-17T16:48:32+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
"version": "0.6.1",
|
||||
"version": "0.5.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/image.git",
|
||||
"reference": "2d74c27e69e65a93cf94a16586598a04fe435bf0"
|
||||
"reference": "ca5f436f9aa22dedaa6648f24f3687733808e336"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/2d74c27e69e65a93cf94a16586598a04fe435bf0",
|
||||
"reference": "2d74c27e69e65a93cf94a16586598a04fe435bf0",
|
||||
"url": "https://api.github.com/repos/utopia-php/image/zipball/ca5f436f9aa22dedaa6648f24f3687733808e336",
|
||||
"reference": "ca5f436f9aa22dedaa6648f24f3687733808e336",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1412,8 +1415,6 @@
|
||||
"php": ">=8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
"phpstan/phpstan": "1.9.x-dev",
|
||||
"phpunit/phpunit": "^9.3",
|
||||
"vimeo/psalm": "4.13.1"
|
||||
},
|
||||
@@ -1427,6 +1428,12 @@
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Eldad Fux",
|
||||
"email": "eldad@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "A simple Image manipulation library",
|
||||
"keywords": [
|
||||
"framework",
|
||||
@@ -1437,9 +1444,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/image/issues",
|
||||
"source": "https://github.com/utopia-php/image/tree/0.6.1"
|
||||
"source": "https://github.com/utopia-php/image/tree/0.5.4"
|
||||
},
|
||||
"time": "2024-02-05T13:31:44+00:00"
|
||||
"time": "2022-05-11T12:30:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/locale",
|
||||
@@ -1547,16 +1554,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/messaging",
|
||||
"version": "0.3.0",
|
||||
"version": "0.2.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/messaging.git",
|
||||
"reference": "d488223876f88f97bb76fd6681fed0df80558f62"
|
||||
"reference": "2d0f474a106bb1da285f85e105c29b46085d3a43"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/d488223876f88f97bb76fd6681fed0df80558f62",
|
||||
"reference": "d488223876f88f97bb76fd6681fed0df80558f62",
|
||||
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/2d0f474a106bb1da285f85e105c29b46085d3a43",
|
||||
"reference": "2d0f474a106bb1da285f85e105c29b46085d3a43",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1589,9 +1596,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/messaging/issues",
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.3.0"
|
||||
"source": "https://github.com/utopia-php/messaging/tree/0.2.0"
|
||||
},
|
||||
"time": "2023-11-14T21:02:37+00:00"
|
||||
"time": "2023-09-14T20:48:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
@@ -2413,16 +2420,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.36.4",
|
||||
"version": "0.36.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "8d932098009d62d37dda73cfe4ebc11f83e21405"
|
||||
"reference": "0aa67479d75f0e0cb7b60454031534d7f0abaece"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/8d932098009d62d37dda73cfe4ebc11f83e21405",
|
||||
"reference": "8d932098009d62d37dda73cfe4ebc11f83e21405",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0aa67479d75f0e0cb7b60454031534d7f0abaece",
|
||||
"reference": "0aa67479d75f0e0cb7b60454031534d7f0abaece",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2458,22 +2465,22 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.36.4"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.36.2"
|
||||
},
|
||||
"time": "2024-02-20T16:36:15+00:00"
|
||||
"time": "2024-01-19T01:04:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/deprecations",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/deprecations.git",
|
||||
"reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
|
||||
"reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
|
||||
"reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
|
||||
"url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
|
||||
"reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2505,9 +2512,9 @@
|
||||
"homepage": "https://www.doctrine-project.org/",
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/deprecations/issues",
|
||||
"source": "https://github.com/doctrine/deprecations/tree/1.1.3"
|
||||
"source": "https://github.com/doctrine/deprecations/tree/1.1.2"
|
||||
},
|
||||
"time": "2024-01-30T19:34:25+00:00"
|
||||
"time": "2023-09-27T20:04:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/instantiator",
|
||||
@@ -2764,16 +2771,16 @@
|
||||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v5.0.1",
|
||||
"version": "v5.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "2218c2252c874a4624ab2f613d86ac32d227bc69"
|
||||
"reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/2218c2252c874a4624ab2f613d86ac32d227bc69",
|
||||
"reference": "2218c2252c874a4624ab2f613d86ac32d227bc69",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
|
||||
"reference": "4a21235f7e56e713259a6f76bf4b5ea08502b9dc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -2816,9 +2823,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.0.1"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v5.0.0"
|
||||
},
|
||||
"time": "2024-02-21T19:24:10+00:00"
|
||||
"time": "2024-01-07T17:17:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
@@ -3043,21 +3050,21 @@
|
||||
},
|
||||
{
|
||||
"name": "phpdocumentor/type-resolver",
|
||||
"version": "1.8.2",
|
||||
"version": "1.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpDocumentor/TypeResolver.git",
|
||||
"reference": "153ae662783729388a584b4361f2545e4d841e3c"
|
||||
"reference": "fad452781b3d774e3337b0c0b245dd8e5a4455fc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
|
||||
"reference": "153ae662783729388a584b4361f2545e4d841e3c",
|
||||
"url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/fad452781b3d774e3337b0c0b245dd8e5a4455fc",
|
||||
"reference": "fad452781b3d774e3337b0c0b245dd8e5a4455fc",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/deprecations": "^1.0",
|
||||
"php": "^7.3 || ^8.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"phpdocumentor/reflection-common": "^2.0",
|
||||
"phpstan/phpdoc-parser": "^1.13"
|
||||
},
|
||||
@@ -3095,30 +3102,30 @@
|
||||
"description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpDocumentor/TypeResolver/issues",
|
||||
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
|
||||
"source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.0"
|
||||
},
|
||||
"time": "2024-02-23T11:10:43+00:00"
|
||||
"time": "2024-01-11T11:49:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpspec/prophecy",
|
||||
"version": "v1.19.0",
|
||||
"version": "v1.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpspec/prophecy.git",
|
||||
"reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87"
|
||||
"reference": "d4f454f7e1193933f04e6500de3e79191648ed0c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/67a759e7d8746d501c41536ba40cd9c0a07d6a87",
|
||||
"reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87",
|
||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/d4f454f7e1193933f04e6500de3e79191648ed0c",
|
||||
"reference": "d4f454f7e1193933f04e6500de3e79191648ed0c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/instantiator": "^1.2 || ^2.0",
|
||||
"php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.*",
|
||||
"phpdocumentor/reflection-docblock": "^5.2",
|
||||
"sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0",
|
||||
"sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0 || ^6.0"
|
||||
"sebastian/comparator": "^3.0 || ^4.0 || ^5.0",
|
||||
"sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpspec/phpspec": "^6.0 || ^7.0",
|
||||
@@ -3164,22 +3171,22 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phpspec/prophecy/issues",
|
||||
"source": "https://github.com/phpspec/prophecy/tree/v1.19.0"
|
||||
"source": "https://github.com/phpspec/prophecy/tree/v1.18.0"
|
||||
},
|
||||
"time": "2024-02-29T11:52:51+00:00"
|
||||
"time": "2023-12-07T16:22:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpstan/phpdoc-parser",
|
||||
"version": "1.26.0",
|
||||
"version": "1.25.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phpstan/phpdoc-parser.git",
|
||||
"reference": "231e3186624c03d7e7c890ec662b81e6b0405227"
|
||||
"reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/231e3186624c03d7e7c890ec662b81e6b0405227",
|
||||
"reference": "231e3186624c03d7e7c890ec662b81e6b0405227",
|
||||
"url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/bd84b629c8de41aa2ae82c067c955e06f1b00240",
|
||||
"reference": "bd84b629c8de41aa2ae82c067c955e06f1b00240",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3211,9 +3218,9 @@
|
||||
"description": "PHPDoc parser with support for nullable, intersection and generic types",
|
||||
"support": {
|
||||
"issues": "https://github.com/phpstan/phpdoc-parser/issues",
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.26.0"
|
||||
"source": "https://github.com/phpstan/phpdoc-parser/tree/1.25.0"
|
||||
},
|
||||
"time": "2024-02-23T16:05:55+00:00"
|
||||
"time": "2024-01-04T17:06:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpunit/php-code-coverage",
|
||||
@@ -4653,16 +4660,16 @@
|
||||
},
|
||||
{
|
||||
"name": "squizlabs/php_codesniffer",
|
||||
"version": "3.9.0",
|
||||
"version": "3.8.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git",
|
||||
"reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b"
|
||||
"reference": "14f5fff1e64118595db5408e946f3a22c75807f7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
|
||||
"reference": "d63cee4890a8afaf86a22e51ad4d97c91dd4579b",
|
||||
"url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/14f5fff1e64118595db5408e946f3a22c75807f7",
|
||||
"reference": "14f5fff1e64118595db5408e946f3a22c75807f7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4729,7 +4736,7 @@
|
||||
"type": "open_collective"
|
||||
}
|
||||
],
|
||||
"time": "2024-02-16T15:06:51+00:00"
|
||||
"time": "2024-01-11T20:47:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swoole/ide-helper",
|
||||
@@ -4765,16 +4772,16 @@
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-ctype.git",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
|
||||
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||
"reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4788,6 +4795,9 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@@ -4824,7 +4834,7 @@
|
||||
"portable"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4840,20 +4850,20 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2023-01-26T09:26:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-mbstring",
|
||||
"version": "v1.29.0",
|
||||
"version": "v1.28.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/polyfill-mbstring.git",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec"
|
||||
"reference": "42292d99c55abe617799667f454222c54c60e229"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec",
|
||||
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229",
|
||||
"reference": "42292d99c55abe617799667f454222c54c60e229",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4867,6 +4877,9 @@
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "1.28-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/polyfill",
|
||||
"url": "https://github.com/symfony/polyfill"
|
||||
@@ -4904,7 +4917,7 @@
|
||||
"shim"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0"
|
||||
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
@@ -4920,7 +4933,7 @@
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-01-29T20:11:03+00:00"
|
||||
"time": "2023-07-28T09:04:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
|
||||
+25
-110
@@ -5,12 +5,12 @@
|
||||
|
||||
x-logging: &x-logging
|
||||
logging:
|
||||
driver: "json-file"
|
||||
driver: 'json-file'
|
||||
options:
|
||||
max-file: "5"
|
||||
max-size: "10m"
|
||||
max-file: '5'
|
||||
max-size: '10m'
|
||||
|
||||
version: "3"
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
traefik:
|
||||
@@ -185,8 +185,6 @@ services:
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
|
||||
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
- _APP_EXPERIMENT_LOGGING_PROVIDER
|
||||
- _APP_EXPERIMENT_LOGGING_CONFIG
|
||||
|
||||
appwrite-realtime:
|
||||
entrypoint: realtime
|
||||
@@ -647,7 +645,6 @@ services:
|
||||
- _APP_MAINTENANCE_RETENTION_AUDIT
|
||||
- _APP_MAINTENANCE_RETENTION_USAGE_HOURLY
|
||||
- _APP_MAINTENANCE_RETENTION_SCHEDULES
|
||||
- _APP_MAINTENANCE_DELAY
|
||||
|
||||
appwrite-worker-usage:
|
||||
entrypoint: worker-usage
|
||||
@@ -680,37 +677,6 @@ services:
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
|
||||
appwrite-worker-usage-dump:
|
||||
entrypoint: worker-usage-dump
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-usage-dump
|
||||
image: appwrite-dev
|
||||
networks:
|
||||
- appwrite
|
||||
volumes:
|
||||
- ./app:/usr/src/code/app
|
||||
- ./src:/usr/src/code/src
|
||||
depends_on:
|
||||
- redis
|
||||
- mariadb
|
||||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DB_HOST
|
||||
- _APP_DB_PORT
|
||||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
- _APP_REDIS_USER
|
||||
- _APP_REDIS_PASS
|
||||
- _APP_USAGE_STATS
|
||||
- _APP_LOGGING_PROVIDER
|
||||
- _APP_LOGGING_CONFIG
|
||||
- _APP_USAGE_AGGREGATION_INTERVAL
|
||||
|
||||
appwrite-schedule:
|
||||
entrypoint: schedule
|
||||
<<: *x-logging
|
||||
@@ -746,63 +712,6 @@ services:
|
||||
environment:
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
|
||||
appwrite-worker-hamster:
|
||||
entrypoint: worker-hamster
|
||||
<<: *x-logging
|
||||
container_name: appwrite-worker-hamster
|
||||
image: appwrite-dev
|
||||
networks:
|
||||
- appwrite
|
||||
volumes:
|
||||
- ./app:/usr/src/code/app
|
||||
- ./src:/usr/src/code/src
|
||||
depends_on:
|
||||
- redis
|
||||
- mariadb
|
||||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_DB_HOST
|
||||
- _APP_DB_PORT
|
||||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
- _APP_REDIS_USER
|
||||
- _APP_REDIS_PASS
|
||||
- _APP_MIXPANEL_TOKEN
|
||||
|
||||
appwrite-hamster-scheduler:
|
||||
entrypoint: hamster
|
||||
<<: *x-logging
|
||||
container_name: appwrite-hamster-scheduler
|
||||
image: appwrite-dev
|
||||
networks:
|
||||
- appwrite
|
||||
volumes:
|
||||
- ./app:/usr/src/code/app
|
||||
- ./src:/usr/src/code/src
|
||||
depends_on:
|
||||
- redis
|
||||
- mariadb
|
||||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_OPENSSL_KEY_V1
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
- _APP_REDIS_USER
|
||||
- _APP_REDIS_PASS
|
||||
- _APP_DB_HOST
|
||||
- _APP_DB_PORT
|
||||
- _APP_DB_SCHEMA
|
||||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
- _APP_HAMSTER_TIME
|
||||
- _APP_HAMSTER_INTERVAL
|
||||
|
||||
openruntimes-executor:
|
||||
container_name: openruntimes-executor
|
||||
hostname: appwrite-executor
|
||||
@@ -891,7 +800,7 @@ services:
|
||||
- MYSQL_DATABASE=${_APP_DB_SCHEMA}
|
||||
- MYSQL_USER=${_APP_DB_USER}
|
||||
- MYSQL_PASSWORD=${_APP_DB_PASS}
|
||||
command: "mysqld --innodb-flush-method=fsync" # add ' --query_cache_size=0' for DB tests
|
||||
command: 'mysqld --innodb-flush-method=fsync' # add ' --query_cache_size=0' for DB tests
|
||||
# command: mv /var/lib/mysql/ib_logfile0 /var/lib/mysql/ib_logfile0.bu && mv /var/lib/mysql/ib_logfile1 /var/lib/mysql/ib_logfile1.bu
|
||||
|
||||
# smtp:
|
||||
@@ -937,16 +846,15 @@ services:
|
||||
#
|
||||
# MailCatcher - An SMTP server. Catches all system emails and displays them in a nice UI.
|
||||
# RequestCatcher - An HTTP server. Catches all system https calls and displays them using a simple HTTP API. Used to debug & tests webhooks and HTTP tasks
|
||||
# Redis Insight - A nice UI for exploring Redis data
|
||||
# Adminer - A nice UI for exploring MariaDB data
|
||||
# GraphQl Explorer - A nice UI for exploring GraphQL API
|
||||
# RedisCommander - A nice UI for exploring Redis data
|
||||
# Webgrind - A nice UI for exploring and debugging code-level stuff
|
||||
|
||||
maildev: # used mainly for dev tests
|
||||
image: appwrite/mailcatcher:1.0.0
|
||||
container_name: appwrite-mailcatcher
|
||||
<<: *x-logging
|
||||
ports:
|
||||
- "9503:1080"
|
||||
- '9503:1080'
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
@@ -955,7 +863,7 @@ services:
|
||||
container_name: appwrite-requestcatcher
|
||||
<<: *x-logging
|
||||
ports:
|
||||
- "9504:5000"
|
||||
- '9504:5000'
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
@@ -969,15 +877,21 @@ services:
|
||||
networks:
|
||||
- appwrite
|
||||
|
||||
redis-insight:
|
||||
image: redis/redisinsight:latest
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
environment:
|
||||
- REDIS_HOSTS=redis
|
||||
ports:
|
||||
- "8081:5540"
|
||||
# redis-commander:
|
||||
# image: rediscommander/redis-commander:latest
|
||||
# restart: unless-stopped
|
||||
# networks:
|
||||
# - appwrite
|
||||
# environment:
|
||||
# - REDIS_HOSTS=redis
|
||||
# ports:
|
||||
# - "8081:8081"
|
||||
# webgrind:
|
||||
# image: 'jokkedk/webgrind:latest'
|
||||
# volumes:
|
||||
# - './debug:/tmp'
|
||||
# ports:
|
||||
# - '3001:80'
|
||||
|
||||
graphql-explorer:
|
||||
container_name: appwrite-graphql-explorer
|
||||
@@ -990,6 +904,7 @@ services:
|
||||
environment:
|
||||
- SERVER_URL=http://localhost/v1/graphql
|
||||
|
||||
|
||||
# Dev Tools End ------------------------------------------------------------------------------------------
|
||||
|
||||
networks:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.create_phone_verification()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.create_recovery(email: 'email@example.com', url: 'https://example.com')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.create_verification(url: 'https://example.com')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.delete_identity(identity_id: '[IDENTITY_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.delete_session(session_id: '[SESSION_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.delete_sessions()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.get_prefs()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.get_session(session_id: '[SESSION_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.get()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.list_identities()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.list_logs()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.list_sessions()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_email(email: 'email@example.com', password: 'password')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_name(name: '[NAME]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_password(password: '')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_phone_verification(user_id: '[USER_ID]', secret: '[SECRET]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_phone(phone: '+12065550100', password: 'password')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_prefs(prefs: {})
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_recovery(user_id: '[USER_ID]', secret: '[SECRET]', password: 'password', password_again: 'password')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_session(session_id: '[SESSION_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_status()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ account = Account.new(client)
|
||||
|
||||
response = account.update_verification(user_id: '[USER_ID]', secret: '[SECRET]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ avatars = Avatars.new(client)
|
||||
|
||||
response = avatars.get_browser(code: 'aa')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ avatars = Avatars.new(client)
|
||||
|
||||
response = avatars.get_credit_card(code: 'amex')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ avatars = Avatars.new(client)
|
||||
|
||||
response = avatars.get_favicon(url: 'https://example.com')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ avatars = Avatars.new(client)
|
||||
|
||||
response = avatars.get_flag(code: 'af')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ avatars = Avatars.new(client)
|
||||
|
||||
response = avatars.get_image(url: 'https://example.com')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ avatars = Avatars.new(client)
|
||||
|
||||
response = avatars.get_initials()
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ avatars = Avatars.new(client)
|
||||
|
||||
response = avatars.get_qr(text: '[TEXT]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_boolean_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_collection(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', name: '[NAME]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_datetime_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_document(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', document_id: '[DOCUMENT_ID]', data: {})
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_email_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_enum_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', elements: [], required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_float_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_index(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', type: 'key', attributes: [])
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_integer_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_ip_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_relationship_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', related_collection_id: '[RELATED_COLLECTION_ID]', type: 'oneToOne')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_string_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', size: 1, required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create_url_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '', required: false)
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.create(database_id: '[DATABASE_ID]', name: '[NAME]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.delete_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.delete_collection(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.delete_document(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', document_id: '[DOCUMENT_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.delete_index(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.delete(database_id: '[DATABASE_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.get_attribute(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.get_collection(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.get_document(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', document_id: '[DOCUMENT_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.get_index(database_id: '[DATABASE_ID]', collection_id: '[COLLECTION_ID]', key: '')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
@@ -1,4 +1,4 @@
|
||||
require 'appwrite'
|
||||
require 'Appwrite'
|
||||
|
||||
include Appwrite
|
||||
|
||||
@@ -11,4 +11,4 @@ databases = Databases.new(client)
|
||||
|
||||
response = databases.get(database_id: '[DATABASE_ID]')
|
||||
|
||||
puts response.inspect
|
||||
puts response.inspect
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user