mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 17:08:45 +00:00
Merge branch '1.8.x' of github.com:appwrite/appwrite into add-webhooks-and-functions-events
This commit is contained in:
commit
2dfb386b12
156 changed files with 9279 additions and 7247 deletions
1
.env
1
.env
|
|
@ -101,6 +101,7 @@ _APP_USAGE_AGGREGATION_INTERVAL=30
|
|||
_APP_STATS_RESOURCES_INTERVAL=30
|
||||
_APP_MAINTENANCE_RETENTION_USAGE_HOURLY=8640000
|
||||
_APP_MAINTENANCE_RETENTION_SCHEDULES=86400
|
||||
_APP_INTERVAL_DOMAIN_VERIFICATION=60
|
||||
_APP_USAGE_STATS=enabled
|
||||
_APP_LOGGING_CONFIG=
|
||||
_APP_LOGGING_CONFIG_REALTIME=
|
||||
|
|
|
|||
|
|
@ -58,6 +58,10 @@ Examples:
|
|||
|
||||
Avoid introducing new dependencies other than utopia-php.
|
||||
|
||||
## Adding new endpoints
|
||||
|
||||
When adding new endpoints, make sure to use modules and follow its patterns. Find instruction in [Modules AGENTS.md](src/Appwrite/Platform/AGENTS.md) file.
|
||||
|
||||
## Pull Request Guidelines
|
||||
### Before Submitting
|
||||
|
||||
|
|
|
|||
98
CHANGES.md
98
CHANGES.md
|
|
@ -1,3 +1,101 @@
|
|||
# Version 1.8.1
|
||||
|
||||
## What's Changed
|
||||
|
||||
### Notable changes
|
||||
|
||||
* Add branch deployments support in [#10486](https://github.com/appwrite/appwrite/pull/10486)
|
||||
* Add TanStack Start sites support in [#10681](https://github.com/appwrite/appwrite/pull/10681)
|
||||
* Add Next.js standalone support in [#10747](https://github.com/appwrite/appwrite/pull/10747)
|
||||
* Add Resend integration in [#10690](https://github.com/appwrite/appwrite/pull/10690)
|
||||
* Add option to enable/disable image transformations per-bucket in [#10722](https://github.com/appwrite/appwrite/pull/10722)
|
||||
* Add operators support in [#10735](https://github.com/appwrite/appwrite/pull/10735) and [#10800](https://github.com/appwrite/appwrite/pull/10800)
|
||||
* Add function and sites stats in [#10786](https://github.com/appwrite/appwrite/pull/10786)
|
||||
* Add disable count feature in [#10668](https://github.com/appwrite/appwrite/pull/10668)
|
||||
* Add ElevenLabs site template in [#10782](https://github.com/appwrite/appwrite/pull/10782)
|
||||
* Add suggested environment variables in [#10795](https://github.com/appwrite/appwrite/pull/10795)
|
||||
* Update GeoDB database in [#10890](https://github.com/appwrite/appwrite/pull/10890)
|
||||
* Update Flutter default build runtime in [#10807](https://github.com/appwrite/appwrite/pull/10807)
|
||||
* Upgrade runtimes in [#10804](https://github.com/appwrite/appwrite/pull/10804)
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix duplicate document error while creating file in [#10891](https://github.com/appwrite/appwrite/pull/10891)
|
||||
* Fix "Update external deployment (authorize)" throwing 500 error due to invalid query in [#10888](https://github.com/appwrite/appwrite/pull/10888)
|
||||
* Fix error setting user password in [#10889](https://github.com/appwrite/appwrite/pull/10889)
|
||||
* Fix error generating email MFA challenges in [#10884](https://github.com/appwrite/appwrite/pull/10884)
|
||||
* Fix file token expiry in [#10877](https://github.com/appwrite/appwrite/pull/10877)
|
||||
* Fix TanStack Nitro default in [#10860](https://github.com/appwrite/appwrite/pull/10860)
|
||||
* Fix TanStack builds in [#10767](https://github.com/appwrite/appwrite/pull/10767)
|
||||
* Fix nullable validation in [#10819](https://github.com/appwrite/appwrite/pull/10819) and [#10778](https://github.com/appwrite/appwrite/pull/10778)
|
||||
* Fix WebP library in [#10738](https://github.com/appwrite/appwrite/pull/10738)
|
||||
* Fix batch writes in [#10812](https://github.com/appwrite/appwrite/pull/10812)
|
||||
* Fix error handler error in [#10719](https://github.com/appwrite/appwrite/pull/10719)
|
||||
* Fix Next 16 compatibility in [#10713](https://github.com/appwrite/appwrite/pull/10713)
|
||||
* Fix stats usage memory leak in [#10683](https://github.com/appwrite/appwrite/pull/10683)
|
||||
* Fix author URL in template deployments in [#10535](https://github.com/appwrite/appwrite/pull/10535)
|
||||
* Fix VCS lock deletion in [#10691](https://github.com/appwrite/appwrite/pull/10691)
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* Add CSV export functionality in [#10546](https://github.com/appwrite/appwrite/pull/10546), [#10750](https://github.com/appwrite/appwrite/pull/10750), [#10813](https://github.com/appwrite/appwrite/pull/10813), and [#10847](https://github.com/appwrite/appwrite/pull/10847)
|
||||
* Add JWT disposition in [#10867](https://github.com/appwrite/appwrite/pull/10867)
|
||||
* Add screenshots endpoint in [#10675](https://github.com/appwrite/appwrite/pull/10675)
|
||||
* Add screenshot endpoint stats in [#10706](https://github.com/appwrite/appwrite/pull/10706)
|
||||
* Add users attributes in [#10688](https://github.com/appwrite/appwrite/pull/10688)
|
||||
* Add max build duration environment variable in [#10674](https://github.com/appwrite/appwrite/pull/10674)
|
||||
* Add custom realtime logger in [#10871](https://github.com/appwrite/appwrite/pull/10871)
|
||||
* Add logs in [#10869](https://github.com/appwrite/appwrite/pull/10869)
|
||||
* Improve MFA docs endpoint order in [#10793](https://github.com/appwrite/appwrite/pull/10793)
|
||||
* Auth refactor in [#10758](https://github.com/appwrite/appwrite/pull/10758), [#10837](https://github.com/appwrite/appwrite/pull/10837), [#10682](https://github.com/appwrite/appwrite/pull/10682), and [#10667](https://github.com/appwrite/appwrite/pull/10667)
|
||||
* Bump assistant to 0.8.4 in [#10887](https://github.com/appwrite/appwrite/pull/10887)
|
||||
* Bump database to 3.1.5 in [#10766](https://github.com/appwrite/appwrite/pull/10766)
|
||||
* Bump Utopia DNS in [#10761](https://github.com/appwrite/appwrite/pull/10761)
|
||||
* Update domains to 0.8.3 in [#10658](https://github.com/appwrite/appwrite/pull/10658)
|
||||
* Update domains to 0.9.1 in [#10678](https://github.com/appwrite/appwrite/pull/10678)
|
||||
* Update Apple Swift to 13.3.0 in [#10679](https://github.com/appwrite/appwrite/pull/10679)
|
||||
* Update Apple Swift in [#10663](https://github.com/appwrite/appwrite/pull/10663)
|
||||
* Update CLI to 10.2.2 in [#10672](https://github.com/appwrite/appwrite/pull/10672)
|
||||
* Update to CLI 12.0.0 in [#10853](https://github.com/appwrite/appwrite/pull/10853)
|
||||
* Update docs examples to use Permission class in [#10707](https://github.com/appwrite/appwrite/pull/10707)
|
||||
* Update SDK examples docs in [#10855](https://github.com/appwrite/appwrite/pull/10855)
|
||||
* Release Python SDK in [#10762](https://github.com/appwrite/appwrite/pull/10762)
|
||||
* Release Flutter 20.3.2 in [#10838](https://github.com/appwrite/appwrite/pull/10838)
|
||||
* Release Flutter/Dart add screenshot examples in [#10811](https://github.com/appwrite/appwrite/pull/10811)
|
||||
* Release PHP CLI in [#10791](https://github.com/appwrite/appwrite/pull/10791)
|
||||
* Release SDKs in [#10817](https://github.com/appwrite/appwrite/pull/10817)
|
||||
* Update SDKs in [#10694](https://github.com/appwrite/appwrite/pull/10694), [#10729](https://github.com/appwrite/appwrite/pull/10729), and [#10744](https://github.com/appwrite/appwrite/pull/10744)
|
||||
* Update SDK generator in [#10743](https://github.com/appwrite/appwrite/pull/10743)
|
||||
* Update database in [#10664](https://github.com/appwrite/appwrite/pull/10664)
|
||||
* Update README file in [#10763](https://github.com/appwrite/appwrite/pull/10763)
|
||||
* SDK release documentation in [#10745](https://github.com/appwrite/appwrite/pull/10745)
|
||||
* SDK release runtime config in [#10765](https://github.com/appwrite/appwrite/pull/10765)
|
||||
* Sync specs in [#10789](https://github.com/appwrite/appwrite/pull/10789)
|
||||
* Sync 1.8.0 in [#10677](https://github.com/appwrite/appwrite/pull/10677)
|
||||
* Add workflow for issue triage in [#10718](https://github.com/appwrite/appwrite/pull/10718)
|
||||
* Add issue auto-labeler in [#10700](https://github.com/appwrite/appwrite/pull/10700)
|
||||
* Add AI moderator repo in [#10717](https://github.com/appwrite/appwrite/pull/10717)
|
||||
* Browser bump in [#10850](https://github.com/appwrite/appwrite/pull/10850)
|
||||
* Template type enum override in [#10848](https://github.com/appwrite/appwrite/pull/10848)
|
||||
* VCS reference type in [#10852](https://github.com/appwrite/appwrite/pull/10852)
|
||||
* Index scope description in [#10851](https://github.com/appwrite/appwrite/pull/10851)
|
||||
* Config for environment in [#10833](https://github.com/appwrite/appwrite/pull/10833)
|
||||
* Format instance in [#10830](https://github.com/appwrite/appwrite/pull/10830)
|
||||
* Replace sleep in webhooks service in [#10656](https://github.com/appwrite/appwrite/pull/10656)
|
||||
* Update email composer in [#10720](https://github.com/appwrite/appwrite/pull/10720)
|
||||
* Update facts on GitHub sites and functions in [#10593](https://github.com/appwrite/appwrite/pull/10593) and [#10771](https://github.com/appwrite/appwrite/pull/10771)
|
||||
* Fix wrong user type in [#10875](https://github.com/appwrite/appwrite/pull/10875)
|
||||
* Fix limit and offset computation in [#10880](https://github.com/appwrite/appwrite/pull/10880)
|
||||
* Fix enum examples in [#10828](https://github.com/appwrite/appwrite/pull/10828)
|
||||
* Fix response models multi-methods in [#10815](https://github.com/appwrite/appwrite/pull/10815)
|
||||
* Fix undefined variable in [#10654](https://github.com/appwrite/appwrite/pull/10654)
|
||||
* Fix undefined sequence in [#10652](https://github.com/appwrite/appwrite/pull/10652)
|
||||
* Fix description in [#10702](https://github.com/appwrite/appwrite/pull/10702)
|
||||
* Fix warning in builds worker in [#10705](https://github.com/appwrite/appwrite/pull/10705)
|
||||
* Fix sites create deployment docs in [#10566](https://github.com/appwrite/appwrite/pull/10566)
|
||||
* Fix test dependencies projects in [#10655](https://github.com/appwrite/appwrite/pull/10655)
|
||||
* Fix list sites test in [#10726](https://github.com/appwrite/appwrite/pull/10726)
|
||||
|
||||
# Version 1.8.0
|
||||
|
||||
## What's Changed
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ RUN mkdir -p /storage/uploads && \
|
|||
# Executables
|
||||
RUN chmod +x /usr/local/bin/doctor && \
|
||||
chmod +x /usr/local/bin/install && \
|
||||
chmod +x /usr/local/bin/interval && \
|
||||
chmod +x /usr/local/bin/maintenance && \
|
||||
chmod +x /usr/local/bin/migrate && \
|
||||
chmod +x /usr/local/bin/realtime && \
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ docker run -it --rm \
|
|||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
|
||||
--entrypoint="install" \
|
||||
appwrite/appwrite:1.8.0
|
||||
appwrite/appwrite:1.8.1
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
|
@ -84,7 +84,7 @@ docker run -it --rm ^
|
|||
--volume //var/run/docker.sock:/var/run/docker.sock ^
|
||||
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
|
||||
--entrypoint="install" ^
|
||||
appwrite/appwrite:1.8.0
|
||||
appwrite/appwrite:1.8.1
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
|
@ -94,7 +94,7 @@ docker run -it --rm `
|
|||
--volume /var/run/docker.sock:/var/run/docker.sock `
|
||||
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
|
||||
--entrypoint="install" `
|
||||
appwrite/appwrite:1.8.0
|
||||
appwrite/appwrite:1.8.1
|
||||
```
|
||||
|
||||
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ docker run -it --rm \
|
|||
--volume /var/run/docker.sock:/var/run/docker.sock \
|
||||
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
|
||||
--entrypoint="install" \
|
||||
appwrite/appwrite:1.8.0
|
||||
appwrite/appwrite:1.8.1
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
|
@ -87,7 +87,7 @@ docker run -it --rm ^
|
|||
--volume //var/run/docker.sock:/var/run/docker.sock ^
|
||||
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
|
||||
--entrypoint="install" ^
|
||||
appwrite/appwrite:1.8.0
|
||||
appwrite/appwrite:1.8.1
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
|
@ -97,7 +97,7 @@ docker run -it --rm `
|
|||
--volume /var/run/docker.sock:/var/run/docker.sock `
|
||||
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
|
||||
--entrypoint="install" `
|
||||
appwrite/appwrite:1.8.0
|
||||
appwrite/appwrite:1.8.1
|
||||
```
|
||||
|
||||
Once the Docker installation is complete, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after completing the installation.
|
||||
|
|
|
|||
|
|
@ -257,6 +257,14 @@ CLI::setResource('logError', function (Registry $register) {
|
|||
$log->addExtra('trace', $error->getTraceAsString());
|
||||
$log->addExtra('detailedTrace', $error->getTrace());
|
||||
|
||||
if ($error->getPrevious() !== null) {
|
||||
if ($error->getPrevious()->getMessage() != $error->getMessage()) {
|
||||
$log->addExtra('previousMessage', $error->getPrevious()->getMessage());
|
||||
}
|
||||
$log->addExtra('previousFile', $error->getPrevious()->getFile());
|
||||
$log->addExtra('previousLine', $error->getPrevious()->getLine());
|
||||
}
|
||||
|
||||
$log->setAction($action);
|
||||
|
||||
$isProduction = System::getEnv('_APP_ENV', 'development') === 'production';
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use Utopia\Database\Helpers\ID;
|
|||
|
||||
$providers = Config::getParam('oAuthProviders', []);
|
||||
|
||||
return [
|
||||
$platformCollections = [
|
||||
'projects' => [
|
||||
'$collection' => ID::custom(Database::METADATA),
|
||||
'$id' => ID::custom('projects'),
|
||||
|
|
@ -643,6 +643,39 @@ return [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'resourceType',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'resourceId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => 'resourceInternalId',
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => Database::LENGTH_KEY,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('name'),
|
||||
'type' => Database::VAR_STRING,
|
||||
|
|
@ -718,6 +751,13 @@ return [
|
|||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_resource',
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['resourceType', 'resourceInternalId'],
|
||||
'lengths' => [Database::LENGTH_KEY],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => '_key_accessedAt',
|
||||
'type' => Database::INDEX_KEY,
|
||||
|
|
@ -1903,3 +1943,31 @@ return [
|
|||
'indexes' => []
|
||||
],
|
||||
];
|
||||
|
||||
// Organization API keys subquery
|
||||
$platformCollections['teams']['attributes'][] = [
|
||||
'$id' => ID::custom('keys'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => ['subQueryOrganizationKeys'],
|
||||
];
|
||||
|
||||
// Account API keys subquery
|
||||
$platformCollections['users']['attributes'][] = [
|
||||
'$id' => ID::custom('keys'),
|
||||
'type' => Database::VAR_STRING,
|
||||
'format' => '',
|
||||
'size' => 16384,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => null,
|
||||
'array' => false,
|
||||
'filters' => ['subQueryAccountKeys'],
|
||||
];
|
||||
|
||||
return $platformCollections;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ return [
|
|||
'name' => 'Console',
|
||||
'subtitle' => '',
|
||||
'description' => '',
|
||||
'controller' => 'web/console.php',
|
||||
'controller' => '', // Uses modules
|
||||
'sdk' => false,
|
||||
'docs' => false,
|
||||
'docsUrl' => '',
|
||||
|
|
@ -146,7 +146,7 @@ return [
|
|||
'name' => 'Storage',
|
||||
'subtitle' => 'The Storage service allows you to manage your project files.',
|
||||
'description' => '/docs/services/storage.md',
|
||||
'controller' => 'api/storage.php',
|
||||
'controller' => '',
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => 'https://appwrite.io/docs/client/storage',
|
||||
|
|
@ -270,9 +270,9 @@ return [
|
|||
'console' => [
|
||||
'key' => 'console',
|
||||
'name' => 'Console',
|
||||
'subtitle' => 'The Console service allows you to interact with console relevant informations.',
|
||||
'subtitle' => 'The Console service allows you to interact with console relevant information.',
|
||||
'description' => '',
|
||||
'controller' => 'api/console.php',
|
||||
'controller' => '', // Uses modules
|
||||
'sdk' => true,
|
||||
'docs' => true,
|
||||
'docsUrl' => '',
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -37,7 +37,7 @@ use libphonenumber\PhoneNumberUtil;
|
|||
use MaxMind\Db\Reader;
|
||||
use Utopia\Abuse\Abuse;
|
||||
use Utopia\App;
|
||||
use Utopia\Audit\Audit as EventAudit;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Auth\Hashes\Sha;
|
||||
use Utopia\Auth\Proofs\Code as ProofsCode;
|
||||
use Utopia\Auth\Proofs\Password as ProofsPassword;
|
||||
|
|
@ -3033,7 +3033,8 @@ App::get('/v1/account/logs')
|
|||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('dbForProject')
|
||||
->action(function (array $queries, bool $includeTotal, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject) {
|
||||
->inject('audit')
|
||||
->action(function (array $queries, bool $includeTotal, Response $response, Document $user, Locale $locale, Reader $geodb, Database $dbForProject, Audit $audit) {
|
||||
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
|
|
@ -3041,9 +3042,10 @@ App::get('/v1/account/logs')
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new EventAudit($dbForProject);
|
||||
|
||||
$logs = $audit->getLogsByUser($user->getSequence(), $queries);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
$logs = $audit->getLogsByUser($user->getSequence(), offset: $offset, limit: $limit);
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
@ -3072,7 +3074,7 @@ App::get('/v1/account/logs')
|
|||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence(), $queries) : 0,
|
||||
'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence()) : 0,
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,147 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Domains\Domain;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\IP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
App::init()
|
||||
->groups(['console'])
|
||||
->inject('project')
|
||||
->action(function (Document $project) {
|
||||
if ($project->getId() !== 'console') {
|
||||
throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
App::get('/v1/console/variables')
|
||||
->desc('Get variables')
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'projects.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'console',
|
||||
group: 'console',
|
||||
name: 'variables',
|
||||
description: '/docs/references/console/variables.md',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_CONSOLE_VARIABLES,
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->inject('response')
|
||||
->action(function (Response $response) {
|
||||
$validator = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME'));
|
||||
$isCNAMEValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_CNAME', '')) && $validator->isKnown() && !$validator->isTest();
|
||||
|
||||
$validator = new IP(IP::V4);
|
||||
$isAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_A', '')) && ($validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_A')));
|
||||
|
||||
$validator = new IP(IP::V6);
|
||||
$isAAAAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_AAAA', '')) && $validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA'));
|
||||
|
||||
$isDomainEnabled = $isAAAAValid || $isAValid || $isCNAMEValid;
|
||||
|
||||
$isVcsEnabled = !empty(System::getEnv('_APP_VCS_GITHUB_APP_NAME', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_APP_ID', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_CLIENT_ID', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_CLIENT_SECRET', ''));
|
||||
|
||||
$isAssistantEnabled = !empty(System::getEnv('_APP_ASSISTANT_OPENAI_API_KEY', ''));
|
||||
|
||||
$variables = new Document([
|
||||
'_APP_DOMAIN_TARGET_CNAME' => System::getEnv('_APP_DOMAIN_TARGET_CNAME'),
|
||||
'_APP_DOMAIN_TARGET_AAAA' => System::getEnv('_APP_DOMAIN_TARGET_AAAA'),
|
||||
'_APP_DOMAIN_TARGET_A' => System::getEnv('_APP_DOMAIN_TARGET_A'),
|
||||
// Combine CAA domain with most common flags and tag (no parameters)
|
||||
'_APP_DOMAIN_TARGET_CAA' => '0 issue "' . System::getEnv('_APP_DOMAIN_TARGET_CAA') . '"',
|
||||
'_APP_STORAGE_LIMIT' => +System::getEnv('_APP_STORAGE_LIMIT'),
|
||||
'_APP_COMPUTE_BUILD_TIMEOUT' => +System::getEnv('_APP_COMPUTE_BUILD_TIMEOUT'),
|
||||
'_APP_COMPUTE_SIZE_LIMIT' => +System::getEnv('_APP_COMPUTE_SIZE_LIMIT'),
|
||||
'_APP_USAGE_STATS' => System::getEnv('_APP_USAGE_STATS'),
|
||||
'_APP_VCS_ENABLED' => $isVcsEnabled,
|
||||
'_APP_DOMAIN_ENABLED' => $isDomainEnabled,
|
||||
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled,
|
||||
'_APP_DOMAIN_SITES' => System::getEnv('_APP_DOMAIN_SITES'),
|
||||
'_APP_DOMAIN_FUNCTIONS' => System::getEnv('_APP_DOMAIN_FUNCTIONS'),
|
||||
'_APP_OPTIONS_FORCE_HTTPS' => System::getEnv('_APP_OPTIONS_FORCE_HTTPS'),
|
||||
'_APP_DOMAINS_NAMESERVERS' => System::getEnv('_APP_DOMAINS_NAMESERVERS'),
|
||||
]);
|
||||
|
||||
$response->dynamic($variables, Response::MODEL_CONSOLE_VARIABLES);
|
||||
});
|
||||
|
||||
App::post('/v1/console/assistant')
|
||||
->desc('Create assistant query')
|
||||
->groups(['api', 'assistant'])
|
||||
->label('scope', 'assistant.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'assistant',
|
||||
group: 'console',
|
||||
name: 'chat',
|
||||
description: '/docs/references/assistant/chat.md',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_NONE,
|
||||
)
|
||||
],
|
||||
contentType: ContentType::TEXT
|
||||
))
|
||||
->label('abuse-limit', 15)
|
||||
->label('abuse-key', 'userId:{userId}')
|
||||
->param('prompt', '', new Text(2000), 'Prompt. A string containing questions asked to the AI assistant.')
|
||||
->inject('response')
|
||||
->action(function (string $prompt, Response $response) {
|
||||
$ch = curl_init('http://appwrite-assistant:3003/v1/models/assistant/prompt');
|
||||
$responseHeaders = [];
|
||||
$query = json_encode(['prompt' => $prompt]);
|
||||
$headers = ['accept: text/event-stream'];
|
||||
$handleEvent = function ($ch, $data) use ($response) {
|
||||
$response->chunk($data);
|
||||
|
||||
return \strlen($data);
|
||||
};
|
||||
|
||||
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $handleEvent);
|
||||
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 9000);
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) {
|
||||
$len = strlen($header);
|
||||
$header = explode(':', $header, 2);
|
||||
|
||||
if (count($header) < 2) { // ignore invalid headers
|
||||
return $len;
|
||||
}
|
||||
|
||||
$responseHeaders[strtolower(trim($header[0]))] = trim($header[1]);
|
||||
|
||||
return $len;
|
||||
});
|
||||
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
|
||||
|
||||
curl_exec($ch);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$response->chunk('', true);
|
||||
});
|
||||
|
|
@ -1145,7 +1145,8 @@ App::get('/v1/messaging/providers/:providerId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function (string $providerId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
|
||||
->inject('audit')
|
||||
->action(function (string $providerId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) {
|
||||
$provider = $dbForProject->getDocument('providers', $providerId);
|
||||
|
||||
if ($provider->isEmpty()) {
|
||||
|
|
@ -1158,9 +1159,12 @@ App::get('/v1/messaging/providers/:providerId/logs')
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$resource = 'provider/' . $providerId;
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit);
|
||||
$output = [];
|
||||
|
||||
foreach ($logs as $i => &$log) {
|
||||
|
|
@ -1207,7 +1211,7 @@ App::get('/v1/messaging/providers/:providerId/logs')
|
|||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0,
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
|
@ -2549,7 +2553,8 @@ App::get('/v1/messaging/topics/:topicId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function (string $topicId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
|
||||
->inject('audit')
|
||||
->action(function (string $topicId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) {
|
||||
$topic = $dbForProject->getDocument('topics', $topicId);
|
||||
|
||||
if ($topic->isEmpty()) {
|
||||
|
|
@ -2562,9 +2567,12 @@ App::get('/v1/messaging/topics/:topicId/logs')
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$resource = 'topic/' . $topicId;
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit);
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
@ -2612,7 +2620,7 @@ App::get('/v1/messaging/topics/:topicId/logs')
|
|||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0,
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
|
@ -2966,7 +2974,8 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function (string $subscriberId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
|
||||
->inject('audit')
|
||||
->action(function (string $subscriberId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) {
|
||||
$subscriber = $dbForProject->getDocument('subscribers', $subscriberId);
|
||||
|
||||
if ($subscriber->isEmpty()) {
|
||||
|
|
@ -2979,9 +2988,12 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs')
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$resource = 'subscriber/' . $subscriberId;
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
@ -3029,7 +3041,7 @@ App::get('/v1/messaging/subscribers/:subscriberId/logs')
|
|||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0,
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
|
@ -3762,7 +3774,8 @@ App::get('/v1/messaging/messages/:messageId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function (string $messageId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
|
||||
->inject('audit')
|
||||
->action(function (string $messageId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) {
|
||||
$message = $dbForProject->getDocument('messages', $messageId);
|
||||
|
||||
if ($message->isEmpty()) {
|
||||
|
|
@ -3775,9 +3788,12 @@ App::get('/v1/messaging/messages/:messageId/logs')
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$resource = 'message/' . $messageId;
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
@ -3825,7 +3841,7 @@ App::get('/v1/messaging/messages/:messageId/logs')
|
|||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0,
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ use Appwrite\Utopia\Request;
|
|||
use Appwrite\Utopia\Response;
|
||||
use PHPMailer\PHPMailer\PHPMailer;
|
||||
use Utopia\App;
|
||||
use Utopia\Audit\Adapter\Database as AdapterDatabase;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Cache\Cache;
|
||||
use Utopia\Config\Config;
|
||||
|
|
@ -247,13 +248,15 @@ App::post('/v1/projects')
|
|||
}
|
||||
|
||||
if ($create || $projectTables) {
|
||||
$audit = new Audit($dbForProject);
|
||||
$adapter = new AdapterDatabase($dbForProject);
|
||||
$audit = new Audit($adapter);
|
||||
$audit->setup();
|
||||
}
|
||||
|
||||
if (!$create && $sharedTablesV1) {
|
||||
$attributes = \array_map(fn ($attribute) => new Document($attribute), Audit::ATTRIBUTES);
|
||||
$indexes = \array_map(fn (array $index) => new Document($index), Audit::INDEXES);
|
||||
$adapter = new AdapterDatabase($dbForProject);
|
||||
$attributes = $adapter->getAttributeDocuments();
|
||||
$indexes = $adapter->getIndexDocuments();
|
||||
$dbForProject->createDocument(Database::METADATA, new Document([
|
||||
'$id' => ID::custom('audit'),
|
||||
'$permissions' => [Permission::create(Role::any())],
|
||||
|
|
@ -1499,6 +1502,9 @@ App::post('/v1/projects/:projectId/keys')
|
|||
],
|
||||
'projectInternalId' => $project->getSequence(),
|
||||
'projectId' => $project->getId(),
|
||||
'resourceInternalId' => $project->getSequence(),
|
||||
'resourceId' => $project->getId(),
|
||||
'resourceType' => 'projects',
|
||||
'name' => $name,
|
||||
'scopes' => $scopes,
|
||||
'expire' => $expire,
|
||||
|
|
@ -1546,7 +1552,13 @@ App::get('/v1/projects/:projectId/keys')
|
|||
}
|
||||
|
||||
$keys = $dbForPlatform->find('keys', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::or([
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::and([
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$project->getSequence()]),
|
||||
])
|
||||
]),
|
||||
Query::limit(5000),
|
||||
]);
|
||||
|
||||
|
|
@ -1587,7 +1599,13 @@ App::get('/v1/projects/:projectId/keys/:keyId')
|
|||
|
||||
$key = $dbForPlatform->findOne('keys', [
|
||||
Query::equal('$id', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::or([
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::and([
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$project->getSequence()]),
|
||||
])
|
||||
])
|
||||
]);
|
||||
|
||||
if ($key->isEmpty()) {
|
||||
|
|
@ -1631,7 +1649,13 @@ App::put('/v1/projects/:projectId/keys/:keyId')
|
|||
|
||||
$key = $dbForPlatform->findOne('keys', [
|
||||
Query::equal('$id', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::or([
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::and([
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$project->getSequence()]),
|
||||
])
|
||||
])
|
||||
]);
|
||||
|
||||
if ($key->isEmpty()) {
|
||||
|
|
@ -1682,7 +1706,13 @@ App::delete('/v1/projects/:projectId/keys/:keyId')
|
|||
|
||||
$key = $dbForPlatform->findOne('keys', [
|
||||
Query::equal('$id', [$keyId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::or([
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::and([
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$project->getSequence()]),
|
||||
])
|
||||
])
|
||||
]);
|
||||
|
||||
if ($key->isEmpty()) {
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1464,7 +1464,8 @@ App::get('/v1/teams/:teamId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function (string $teamId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
|
||||
->inject('audit')
|
||||
->action(function (string $teamId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) {
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
|
||||
|
|
@ -1478,9 +1479,12 @@ App::get('/v1/teams/:teamId/logs')
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$resource = 'team/' . $team->getId();
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, offset: $offset, limit: $limit);
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
@ -1527,7 +1531,7 @@ App::get('/v1/teams/:teamId/logs')
|
|||
}
|
||||
}
|
||||
$response->dynamic(new Document([
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource, $queries) : 0,
|
||||
'total' => $includeTotal ? $audit->countLogsByResource($resource) : 0,
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -945,7 +945,8 @@ App::get('/v1/users/:userId/logs')
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->action(function (string $userId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb) {
|
||||
->inject('audit')
|
||||
->action(function (string $userId, array $queries, bool $includeTotal, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit) {
|
||||
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
||||
|
|
@ -958,8 +959,11 @@ App::get('/v1/users/:userId/logs')
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$logs = $audit->getLogsByUser($user->getSequence(), $queries);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$logs = $audit->getLogsByUser($user->getSequence(), limit: $limit, offset: $offset);
|
||||
$output = [];
|
||||
foreach ($logs as $i => &$log) {
|
||||
$log['userAgent'] = (!empty($log['userAgent'])) ? $log['userAgent'] : 'UNKNOWN';
|
||||
|
|
@ -999,7 +1003,7 @@ App::get('/v1/users/:userId/logs')
|
|||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence(), $queries) : 0,
|
||||
'total' => $includeTotal ? $audit->countLogsByUser($user->getSequence()) : 0,
|
||||
'logs' => $output,
|
||||
]), Response::MODEL_LOG_LIST);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\App;
|
||||
|
||||
App::init()
|
||||
->groups(['web'])
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->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
|
||||
;
|
||||
});
|
||||
|
||||
App::get('/')
|
||||
->alias('auth/*')
|
||||
->alias('/invite')
|
||||
->alias('/login')
|
||||
->alias('/mfa')
|
||||
->alias('/card/*')
|
||||
->alias('/recover')
|
||||
->alias('/register/*')
|
||||
->groups(['web'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->action(function (Request $request, Response $response) {
|
||||
$url = parse_url($request->getURI());
|
||||
$target = "/console{$url['path']}";
|
||||
$params = $request->getParams();
|
||||
if (!empty($params)) {
|
||||
$target .= "?" . \http_build_query($params);
|
||||
}
|
||||
if ($url['fragment'] ?? false) {
|
||||
$target .= "#{$url['fragment']}";
|
||||
}
|
||||
$response->redirect($target);
|
||||
});
|
||||
12
app/http.php
12
app/http.php
|
|
@ -12,6 +12,8 @@ use Swoole\Process;
|
|||
use Swoole\Table;
|
||||
use Swoole\Timer;
|
||||
use Utopia\App;
|
||||
use Utopia\Audit\Adapter\Database as AdapterDatabase;
|
||||
use Utopia\Audit\Adapter\SQL as AuditAdapterSQL;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Compression\Compression;
|
||||
|
|
@ -260,8 +262,9 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
|
||||
// create appwrite database, `dbForPlatform` is a direct access call.
|
||||
createDatabase($app, 'dbForPlatform', 'appwrite', $collections['console'], $pools, function (Database $dbForPlatform) use ($collections) {
|
||||
if ($dbForPlatform->getCollection(Audit::COLLECTION)->isEmpty()) {
|
||||
$audit = new Audit($dbForPlatform);
|
||||
if ($dbForPlatform->getCollection(AuditAdapterSQL::COLLECTION)->isEmpty()) {
|
||||
$adapter = new AdapterDatabase($dbForPlatform);
|
||||
$audit = new Audit($adapter);
|
||||
$audit->setup();
|
||||
}
|
||||
|
||||
|
|
@ -389,8 +392,9 @@ $http->on(Constant::EVENT_START, function (Server $http) use ($payloadSize, $reg
|
|||
Console::success('[Setup] - Skip: metadata table already exists');
|
||||
}
|
||||
|
||||
if ($dbForProject->getCollection(Audit::COLLECTION)->isEmpty()) {
|
||||
$audit = new Audit($dbForProject);
|
||||
if ($dbForProject->getCollection(AuditAdapterSQL::COLLECTION)->isEmpty()) {
|
||||
$adapter = new AdapterDatabase($dbForProject);
|
||||
$audit = new Audit($adapter);
|
||||
$audit->setup();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ require_once __DIR__ . '/init/database/filters.php';
|
|||
require_once __DIR__ . '/init/database/formats.php';
|
||||
require_once __DIR__ . '/init/locales.php';
|
||||
require_once __DIR__ . '/init/registers.php';
|
||||
require_once __DIR__ . '/init/models.php';
|
||||
require_once __DIR__ . '/init/resources.php';
|
||||
|
||||
\stream_context_set_default([ // Set global user agent and http settings
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ const APP_RESOURCE_TOKEN_ACCESS = 24 * 60 * 60; // 24 hours
|
|||
const APP_FILE_ACCESS = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours
|
||||
const APP_CACHE_BUSTER = 4321;
|
||||
const APP_VERSION_STABLE = '1.8.0';
|
||||
const APP_VERSION_STABLE = '1.8.1';
|
||||
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
|
||||
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
|
||||
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
|
||||
|
|
|
|||
|
|
@ -136,7 +136,13 @@ Database::addFilter(
|
|||
function (mixed $value, Document $document, Database $database) {
|
||||
return $database
|
||||
->find('keys', [
|
||||
Query::equal('projectInternalId', [$document->getSequence()]),
|
||||
Query::or([
|
||||
Query::equal('projectInternalId', [$document->getSequence()]),
|
||||
Query::and([
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$document->getSequence()]),
|
||||
])
|
||||
]),
|
||||
Query::limit(APP_LIMIT_SUBQUERY),
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
344
app/init/models.php
Normal file
344
app/init/models.php
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
<?php
|
||||
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Utopia\Response\Model\Account;
|
||||
use Appwrite\Utopia\Response\Model\AlgoArgon2;
|
||||
use Appwrite\Utopia\Response\Model\AlgoBcrypt;
|
||||
use Appwrite\Utopia\Response\Model\AlgoMd5;
|
||||
use Appwrite\Utopia\Response\Model\AlgoPhpass;
|
||||
use Appwrite\Utopia\Response\Model\AlgoScrypt;
|
||||
use Appwrite\Utopia\Response\Model\AlgoScryptModified;
|
||||
use Appwrite\Utopia\Response\Model\AlgoSha;
|
||||
use Appwrite\Utopia\Response\Model\Any;
|
||||
use Appwrite\Utopia\Response\Model\Attribute;
|
||||
use Appwrite\Utopia\Response\Model\AttributeBoolean;
|
||||
use Appwrite\Utopia\Response\Model\AttributeDatetime;
|
||||
use Appwrite\Utopia\Response\Model\AttributeEmail;
|
||||
use Appwrite\Utopia\Response\Model\AttributeEnum;
|
||||
use Appwrite\Utopia\Response\Model\AttributeFloat;
|
||||
use Appwrite\Utopia\Response\Model\AttributeInteger;
|
||||
use Appwrite\Utopia\Response\Model\AttributeIP;
|
||||
use Appwrite\Utopia\Response\Model\AttributeLine;
|
||||
use Appwrite\Utopia\Response\Model\AttributeList;
|
||||
use Appwrite\Utopia\Response\Model\AttributePoint;
|
||||
use Appwrite\Utopia\Response\Model\AttributePolygon;
|
||||
use Appwrite\Utopia\Response\Model\AttributeRelationship;
|
||||
use Appwrite\Utopia\Response\Model\AttributeString;
|
||||
use Appwrite\Utopia\Response\Model\AttributeURL;
|
||||
use Appwrite\Utopia\Response\Model\AuthProvider;
|
||||
use Appwrite\Utopia\Response\Model\BaseList;
|
||||
use Appwrite\Utopia\Response\Model\Branch;
|
||||
use Appwrite\Utopia\Response\Model\Bucket;
|
||||
use Appwrite\Utopia\Response\Model\Collection;
|
||||
use Appwrite\Utopia\Response\Model\Column;
|
||||
use Appwrite\Utopia\Response\Model\ColumnBoolean;
|
||||
use Appwrite\Utopia\Response\Model\ColumnDatetime;
|
||||
use Appwrite\Utopia\Response\Model\ColumnEmail;
|
||||
use Appwrite\Utopia\Response\Model\ColumnEnum;
|
||||
use Appwrite\Utopia\Response\Model\ColumnFloat;
|
||||
use Appwrite\Utopia\Response\Model\ColumnIndex;
|
||||
use Appwrite\Utopia\Response\Model\ColumnInteger;
|
||||
use Appwrite\Utopia\Response\Model\ColumnIP;
|
||||
use Appwrite\Utopia\Response\Model\ColumnLine;
|
||||
use Appwrite\Utopia\Response\Model\ColumnList;
|
||||
use Appwrite\Utopia\Response\Model\ColumnPoint;
|
||||
use Appwrite\Utopia\Response\Model\ColumnPolygon;
|
||||
use Appwrite\Utopia\Response\Model\ColumnRelationship;
|
||||
use Appwrite\Utopia\Response\Model\ColumnString;
|
||||
use Appwrite\Utopia\Response\Model\ColumnURL;
|
||||
use Appwrite\Utopia\Response\Model\ConsoleVariables;
|
||||
use Appwrite\Utopia\Response\Model\Continent;
|
||||
use Appwrite\Utopia\Response\Model\Country;
|
||||
use Appwrite\Utopia\Response\Model\Currency;
|
||||
use Appwrite\Utopia\Response\Model\Database;
|
||||
use Appwrite\Utopia\Response\Model\Deployment;
|
||||
use Appwrite\Utopia\Response\Model\DetectionFramework;
|
||||
use Appwrite\Utopia\Response\Model\DetectionRuntime;
|
||||
use Appwrite\Utopia\Response\Model\DetectionVariable;
|
||||
use Appwrite\Utopia\Response\Model\DevKey;
|
||||
use Appwrite\Utopia\Response\Model\Document as ModelDocument;
|
||||
use Appwrite\Utopia\Response\Model\Error;
|
||||
use Appwrite\Utopia\Response\Model\ErrorDev;
|
||||
use Appwrite\Utopia\Response\Model\Execution;
|
||||
use Appwrite\Utopia\Response\Model\File;
|
||||
use Appwrite\Utopia\Response\Model\Framework;
|
||||
use Appwrite\Utopia\Response\Model\FrameworkAdapter;
|
||||
use Appwrite\Utopia\Response\Model\Func;
|
||||
use Appwrite\Utopia\Response\Model\Headers;
|
||||
use Appwrite\Utopia\Response\Model\HealthAntivirus;
|
||||
use Appwrite\Utopia\Response\Model\HealthCertificate;
|
||||
use Appwrite\Utopia\Response\Model\HealthQueue;
|
||||
use Appwrite\Utopia\Response\Model\HealthStatus;
|
||||
use Appwrite\Utopia\Response\Model\HealthTime;
|
||||
use Appwrite\Utopia\Response\Model\HealthVersion;
|
||||
use Appwrite\Utopia\Response\Model\Identity;
|
||||
use Appwrite\Utopia\Response\Model\Index;
|
||||
use Appwrite\Utopia\Response\Model\Installation;
|
||||
use Appwrite\Utopia\Response\Model\JWT;
|
||||
use Appwrite\Utopia\Response\Model\Key;
|
||||
use Appwrite\Utopia\Response\Model\Language;
|
||||
use Appwrite\Utopia\Response\Model\Locale;
|
||||
use Appwrite\Utopia\Response\Model\LocaleCode;
|
||||
use Appwrite\Utopia\Response\Model\Log;
|
||||
use Appwrite\Utopia\Response\Model\Membership;
|
||||
use Appwrite\Utopia\Response\Model\Message;
|
||||
use Appwrite\Utopia\Response\Model\Metric;
|
||||
use Appwrite\Utopia\Response\Model\MetricBreakdown;
|
||||
use Appwrite\Utopia\Response\Model\MFAChallenge;
|
||||
use Appwrite\Utopia\Response\Model\MFAFactors;
|
||||
use Appwrite\Utopia\Response\Model\MFARecoveryCodes;
|
||||
use Appwrite\Utopia\Response\Model\MFAType;
|
||||
use Appwrite\Utopia\Response\Model\Migration;
|
||||
use Appwrite\Utopia\Response\Model\MigrationFirebaseProject;
|
||||
use Appwrite\Utopia\Response\Model\MigrationReport;
|
||||
use Appwrite\Utopia\Response\Model\Mock;
|
||||
use Appwrite\Utopia\Response\Model\MockNumber;
|
||||
use Appwrite\Utopia\Response\Model\None;
|
||||
use Appwrite\Utopia\Response\Model\Phone;
|
||||
use Appwrite\Utopia\Response\Model\Platform;
|
||||
use Appwrite\Utopia\Response\Model\Preferences;
|
||||
use Appwrite\Utopia\Response\Model\Project;
|
||||
use Appwrite\Utopia\Response\Model\Provider;
|
||||
use Appwrite\Utopia\Response\Model\ProviderRepository;
|
||||
use Appwrite\Utopia\Response\Model\ProviderRepositoryFramework;
|
||||
use Appwrite\Utopia\Response\Model\ProviderRepositoryRuntime;
|
||||
use Appwrite\Utopia\Response\Model\ResourceToken;
|
||||
use Appwrite\Utopia\Response\Model\Row;
|
||||
use Appwrite\Utopia\Response\Model\Rule;
|
||||
use Appwrite\Utopia\Response\Model\Runtime;
|
||||
use Appwrite\Utopia\Response\Model\Session;
|
||||
use Appwrite\Utopia\Response\Model\Site;
|
||||
use Appwrite\Utopia\Response\Model\Specification;
|
||||
use Appwrite\Utopia\Response\Model\Subscriber;
|
||||
use Appwrite\Utopia\Response\Model\Table;
|
||||
use Appwrite\Utopia\Response\Model\Target;
|
||||
use Appwrite\Utopia\Response\Model\Team;
|
||||
use Appwrite\Utopia\Response\Model\TemplateEmail;
|
||||
use Appwrite\Utopia\Response\Model\TemplateFramework;
|
||||
use Appwrite\Utopia\Response\Model\TemplateFunction;
|
||||
use Appwrite\Utopia\Response\Model\TemplateRuntime;
|
||||
use Appwrite\Utopia\Response\Model\TemplateSite;
|
||||
use Appwrite\Utopia\Response\Model\TemplateSMS;
|
||||
use Appwrite\Utopia\Response\Model\TemplateVariable;
|
||||
use Appwrite\Utopia\Response\Model\Token;
|
||||
use Appwrite\Utopia\Response\Model\Topic;
|
||||
use Appwrite\Utopia\Response\Model\Transaction;
|
||||
use Appwrite\Utopia\Response\Model\UsageBuckets;
|
||||
use Appwrite\Utopia\Response\Model\UsageCollection;
|
||||
use Appwrite\Utopia\Response\Model\UsageDatabase;
|
||||
use Appwrite\Utopia\Response\Model\UsageDatabases;
|
||||
use Appwrite\Utopia\Response\Model\UsageFunction;
|
||||
use Appwrite\Utopia\Response\Model\UsageFunctions;
|
||||
use Appwrite\Utopia\Response\Model\UsageProject;
|
||||
use Appwrite\Utopia\Response\Model\UsageSite;
|
||||
use Appwrite\Utopia\Response\Model\UsageSites;
|
||||
use Appwrite\Utopia\Response\Model\UsageStorage;
|
||||
use Appwrite\Utopia\Response\Model\UsageTable;
|
||||
use Appwrite\Utopia\Response\Model\UsageUsers;
|
||||
use Appwrite\Utopia\Response\Model\User;
|
||||
use Appwrite\Utopia\Response\Model\Variable;
|
||||
use Appwrite\Utopia\Response\Model\VcsContent;
|
||||
use Appwrite\Utopia\Response\Model\Webhook;
|
||||
|
||||
// General
|
||||
Response::setModel(new None());
|
||||
Response::setModel(new Any());
|
||||
Response::setModel(new Error());
|
||||
Response::setModel(new ErrorDev());
|
||||
|
||||
// Lists
|
||||
Response::setModel(new BaseList('Rows List', Response::MODEL_ROW_LIST, 'rows', Response::MODEL_ROW));
|
||||
Response::setModel(new BaseList('Documents List', Response::MODEL_DOCUMENT_LIST, 'documents', Response::MODEL_DOCUMENT));
|
||||
Response::setModel(new BaseList('Tables List', Response::MODEL_TABLE_LIST, 'tables', Response::MODEL_TABLE));
|
||||
Response::setModel(new BaseList('Collections List', Response::MODEL_COLLECTION_LIST, 'collections', Response::MODEL_COLLECTION));
|
||||
Response::setModel(new BaseList('Databases List', Response::MODEL_DATABASE_LIST, 'databases', Response::MODEL_DATABASE));
|
||||
Response::setModel(new BaseList('Indexes List', Response::MODEL_INDEX_LIST, 'indexes', Response::MODEL_INDEX));
|
||||
Response::setModel(new BaseList('Column Indexes List', Response::MODEL_COLUMN_INDEX_LIST, 'indexes', Response::MODEL_COLUMN_INDEX));
|
||||
Response::setModel(new BaseList('Users List', Response::MODEL_USER_LIST, 'users', Response::MODEL_USER));
|
||||
Response::setModel(new BaseList('Sessions List', Response::MODEL_SESSION_LIST, 'sessions', Response::MODEL_SESSION));
|
||||
Response::setModel(new BaseList('Identities List', Response::MODEL_IDENTITY_LIST, 'identities', Response::MODEL_IDENTITY));
|
||||
Response::setModel(new BaseList('Logs List', Response::MODEL_LOG_LIST, 'logs', Response::MODEL_LOG));
|
||||
Response::setModel(new BaseList('Files List', Response::MODEL_FILE_LIST, 'files', Response::MODEL_FILE));
|
||||
Response::setModel(new BaseList('Buckets List', Response::MODEL_BUCKET_LIST, 'buckets', Response::MODEL_BUCKET));
|
||||
Response::setModel(new BaseList('Resource Tokens List', Response::MODEL_RESOURCE_TOKEN_LIST, 'tokens', Response::MODEL_RESOURCE_TOKEN));
|
||||
Response::setModel(new BaseList('Teams List', Response::MODEL_TEAM_LIST, 'teams', Response::MODEL_TEAM));
|
||||
Response::setModel(new BaseList('Memberships List', Response::MODEL_MEMBERSHIP_LIST, 'memberships', Response::MODEL_MEMBERSHIP));
|
||||
Response::setModel(new BaseList('Sites List', Response::MODEL_SITE_LIST, 'sites', Response::MODEL_SITE));
|
||||
Response::setModel(new BaseList('Site Templates List', Response::MODEL_TEMPLATE_SITE_LIST, 'templates', Response::MODEL_TEMPLATE_SITE));
|
||||
Response::setModel(new BaseList('Functions List', Response::MODEL_FUNCTION_LIST, 'functions', Response::MODEL_FUNCTION));
|
||||
Response::setModel(new BaseList('Function Templates List', Response::MODEL_TEMPLATE_FUNCTION_LIST, 'templates', Response::MODEL_TEMPLATE_FUNCTION));
|
||||
Response::setModel(new BaseList('Installations List', Response::MODEL_INSTALLATION_LIST, 'installations', Response::MODEL_INSTALLATION));
|
||||
Response::setModel(new BaseList('Framework Provider Repositories List', Response::MODEL_PROVIDER_REPOSITORY_FRAMEWORK_LIST, 'frameworkProviderRepositories', Response::MODEL_PROVIDER_REPOSITORY_FRAMEWORK));
|
||||
Response::setModel(new BaseList('Runtime Provider Repositories List', Response::MODEL_PROVIDER_REPOSITORY_RUNTIME_LIST, 'runtimeProviderRepositories', Response::MODEL_PROVIDER_REPOSITORY_RUNTIME));
|
||||
Response::setModel(new BaseList('Branches List', Response::MODEL_BRANCH_LIST, 'branches', Response::MODEL_BRANCH));
|
||||
Response::setModel(new BaseList('Frameworks List', Response::MODEL_FRAMEWORK_LIST, 'frameworks', Response::MODEL_FRAMEWORK));
|
||||
Response::setModel(new BaseList('Runtimes List', Response::MODEL_RUNTIME_LIST, 'runtimes', Response::MODEL_RUNTIME));
|
||||
Response::setModel(new BaseList('Deployments List', Response::MODEL_DEPLOYMENT_LIST, 'deployments', Response::MODEL_DEPLOYMENT));
|
||||
Response::setModel(new BaseList('Executions List', Response::MODEL_EXECUTION_LIST, 'executions', Response::MODEL_EXECUTION));
|
||||
Response::setModel(new BaseList('Projects List', Response::MODEL_PROJECT_LIST, 'projects', Response::MODEL_PROJECT, true, false));
|
||||
Response::setModel(new BaseList('Webhooks List', Response::MODEL_WEBHOOK_LIST, 'webhooks', Response::MODEL_WEBHOOK, true, false));
|
||||
Response::setModel(new BaseList('API Keys List', Response::MODEL_KEY_LIST, 'keys', Response::MODEL_KEY, true, false));
|
||||
Response::setModel(new BaseList('Dev Keys List', Response::MODEL_DEV_KEY_LIST, 'devKeys', Response::MODEL_DEV_KEY, true, false));
|
||||
Response::setModel(new BaseList('Auth Providers List', Response::MODEL_AUTH_PROVIDER_LIST, 'platforms', Response::MODEL_AUTH_PROVIDER, true, false));
|
||||
Response::setModel(new BaseList('Platforms List', Response::MODEL_PLATFORM_LIST, 'platforms', Response::MODEL_PLATFORM, true, false));
|
||||
Response::setModel(new BaseList('Countries List', Response::MODEL_COUNTRY_LIST, 'countries', Response::MODEL_COUNTRY));
|
||||
Response::setModel(new BaseList('Continents List', Response::MODEL_CONTINENT_LIST, 'continents', Response::MODEL_CONTINENT));
|
||||
Response::setModel(new BaseList('Languages List', Response::MODEL_LANGUAGE_LIST, 'languages', Response::MODEL_LANGUAGE));
|
||||
Response::setModel(new BaseList('Currencies List', Response::MODEL_CURRENCY_LIST, 'currencies', Response::MODEL_CURRENCY));
|
||||
Response::setModel(new BaseList('Phones List', Response::MODEL_PHONE_LIST, 'phones', Response::MODEL_PHONE));
|
||||
Response::setModel(new BaseList('Metric List', Response::MODEL_METRIC_LIST, 'metrics', Response::MODEL_METRIC, true, false));
|
||||
Response::setModel(new BaseList('Variables List', Response::MODEL_VARIABLE_LIST, 'variables', Response::MODEL_VARIABLE));
|
||||
Response::setModel(new BaseList('Status List', Response::MODEL_HEALTH_STATUS_LIST, 'statuses', Response::MODEL_HEALTH_STATUS));
|
||||
Response::setModel(new BaseList('Rule List', Response::MODEL_PROXY_RULE_LIST, 'rules', Response::MODEL_PROXY_RULE));
|
||||
Response::setModel(new BaseList('Locale codes list', Response::MODEL_LOCALE_CODE_LIST, 'localeCodes', Response::MODEL_LOCALE_CODE));
|
||||
Response::setModel(new BaseList('Provider list', Response::MODEL_PROVIDER_LIST, 'providers', Response::MODEL_PROVIDER));
|
||||
Response::setModel(new BaseList('Message list', Response::MODEL_MESSAGE_LIST, 'messages', Response::MODEL_MESSAGE));
|
||||
Response::setModel(new BaseList('Topic list', Response::MODEL_TOPIC_LIST, 'topics', Response::MODEL_TOPIC));
|
||||
Response::setModel(new BaseList('Subscriber list', Response::MODEL_SUBSCRIBER_LIST, 'subscribers', Response::MODEL_SUBSCRIBER));
|
||||
Response::setModel(new BaseList('Target list', Response::MODEL_TARGET_LIST, 'targets', Response::MODEL_TARGET));
|
||||
Response::setModel(new BaseList('Transaction List', Response::MODEL_TRANSACTION_LIST, 'transactions', Response::MODEL_TRANSACTION));
|
||||
Response::setModel(new BaseList('Migrations List', Response::MODEL_MIGRATION_LIST, 'migrations', Response::MODEL_MIGRATION));
|
||||
Response::setModel(new BaseList('Migrations Firebase Projects List', Response::MODEL_MIGRATION_FIREBASE_PROJECT_LIST, 'projects', Response::MODEL_MIGRATION_FIREBASE_PROJECT));
|
||||
Response::setModel(new BaseList('Specifications List', Response::MODEL_SPECIFICATION_LIST, 'specifications', Response::MODEL_SPECIFICATION));
|
||||
Response::setModel(new BaseList('VCS Content List', Response::MODEL_VCS_CONTENT_LIST, 'contents', Response::MODEL_VCS_CONTENT));
|
||||
|
||||
// Entities
|
||||
Response::setModel(new Database());
|
||||
|
||||
// Collection API Models
|
||||
Response::setModel(new Collection());
|
||||
Response::setModel(new Attribute());
|
||||
Response::setModel(new AttributeList());
|
||||
Response::setModel(new AttributeString());
|
||||
Response::setModel(new AttributeInteger());
|
||||
Response::setModel(new AttributeFloat());
|
||||
Response::setModel(new AttributeBoolean());
|
||||
Response::setModel(new AttributeEmail());
|
||||
Response::setModel(new AttributeEnum());
|
||||
Response::setModel(new AttributeIP());
|
||||
Response::setModel(new AttributeURL());
|
||||
Response::setModel(new AttributeDatetime());
|
||||
Response::setModel(new AttributeRelationship());
|
||||
Response::setModel(new AttributePoint());
|
||||
Response::setModel(new AttributeLine());
|
||||
Response::setModel(new AttributePolygon());
|
||||
|
||||
// Table API Models
|
||||
Response::setModel(new Table());
|
||||
Response::setModel(new Column());
|
||||
Response::setModel(new ColumnList());
|
||||
Response::setModel(new ColumnString());
|
||||
Response::setModel(new ColumnInteger());
|
||||
Response::setModel(new ColumnFloat());
|
||||
Response::setModel(new ColumnBoolean());
|
||||
Response::setModel(new ColumnEmail());
|
||||
Response::setModel(new ColumnEnum());
|
||||
Response::setModel(new ColumnIP());
|
||||
Response::setModel(new ColumnURL());
|
||||
Response::setModel(new ColumnDatetime());
|
||||
Response::setModel(new ColumnRelationship());
|
||||
Response::setModel(new ColumnPoint());
|
||||
Response::setModel(new ColumnLine());
|
||||
Response::setModel(new ColumnPolygon());
|
||||
Response::setModel(new Index());
|
||||
Response::setModel(new ColumnIndex());
|
||||
Response::setModel(new Row());
|
||||
Response::setModel(new ModelDocument());
|
||||
Response::setModel(new Log());
|
||||
Response::setModel(new User());
|
||||
Response::setModel(new AlgoMd5());
|
||||
Response::setModel(new AlgoSha());
|
||||
Response::setModel(new AlgoPhpass());
|
||||
Response::setModel(new AlgoBcrypt());
|
||||
Response::setModel(new AlgoScrypt());
|
||||
Response::setModel(new AlgoScryptModified());
|
||||
Response::setModel(new AlgoArgon2());
|
||||
Response::setModel(new Account());
|
||||
Response::setModel(new Preferences());
|
||||
Response::setModel(new Session());
|
||||
Response::setModel(new Identity());
|
||||
Response::setModel(new Token());
|
||||
Response::setModel(new JWT());
|
||||
Response::setModel(new Locale());
|
||||
Response::setModel(new LocaleCode());
|
||||
Response::setModel(new File());
|
||||
Response::setModel(new Bucket());
|
||||
Response::setModel(new ResourceToken());
|
||||
Response::setModel(new Team());
|
||||
Response::setModel(new Membership());
|
||||
Response::setModel(new Site());
|
||||
Response::setModel(new TemplateSite());
|
||||
Response::setModel(new TemplateFramework());
|
||||
Response::setModel(new Func());
|
||||
Response::setModel(new TemplateFunction());
|
||||
Response::setModel(new TemplateRuntime());
|
||||
Response::setModel(new TemplateVariable());
|
||||
Response::setModel(new Installation());
|
||||
Response::setModel(new ProviderRepository());
|
||||
Response::setModel(new ProviderRepositoryFramework());
|
||||
Response::setModel(new ProviderRepositoryRuntime());
|
||||
Response::setModel(new DetectionFramework());
|
||||
Response::setModel(new DetectionRuntime());
|
||||
Response::setModel(new DetectionVariable());
|
||||
Response::setModel(new VcsContent());
|
||||
Response::setModel(new Branch());
|
||||
Response::setModel(new Runtime());
|
||||
Response::setModel(new Framework());
|
||||
Response::setModel(new FrameworkAdapter());
|
||||
Response::setModel(new Deployment());
|
||||
Response::setModel(new Execution());
|
||||
Response::setModel(new Project());
|
||||
Response::setModel(new Webhook());
|
||||
Response::setModel(new Key());
|
||||
Response::setModel(new DevKey());
|
||||
Response::setModel(new MockNumber());
|
||||
Response::setModel(new AuthProvider());
|
||||
Response::setModel(new Platform());
|
||||
Response::setModel(new Variable());
|
||||
Response::setModel(new Country());
|
||||
Response::setModel(new Continent());
|
||||
Response::setModel(new Language());
|
||||
Response::setModel(new Currency());
|
||||
Response::setModel(new Phone());
|
||||
Response::setModel(new HealthAntivirus());
|
||||
Response::setModel(new HealthQueue());
|
||||
Response::setModel(new HealthStatus());
|
||||
Response::setModel(new HealthCertificate());
|
||||
Response::setModel(new HealthTime());
|
||||
Response::setModel(new HealthVersion());
|
||||
Response::setModel(new Metric());
|
||||
Response::setModel(new MetricBreakdown());
|
||||
Response::setModel(new UsageDatabases());
|
||||
Response::setModel(new UsageDatabase());
|
||||
Response::setModel(new UsageTable());
|
||||
Response::setModel(new UsageCollection());
|
||||
Response::setModel(new UsageUsers());
|
||||
Response::setModel(new UsageStorage());
|
||||
Response::setModel(new UsageBuckets());
|
||||
Response::setModel(new UsageFunctions());
|
||||
Response::setModel(new UsageFunction());
|
||||
Response::setModel(new UsageSites());
|
||||
Response::setModel(new UsageSite());
|
||||
Response::setModel(new UsageProject());
|
||||
Response::setModel(new Headers());
|
||||
Response::setModel(new Specification());
|
||||
Response::setModel(new Rule());
|
||||
Response::setModel(new TemplateSMS());
|
||||
Response::setModel(new TemplateEmail());
|
||||
Response::setModel(new ConsoleVariables());
|
||||
Response::setModel(new MFAChallenge());
|
||||
Response::setModel(new MFARecoveryCodes());
|
||||
Response::setModel(new MFAType());
|
||||
Response::setModel(new MFAFactors());
|
||||
Response::setModel(new Provider());
|
||||
Response::setModel(new Message());
|
||||
Response::setModel(new Topic());
|
||||
Response::setModel(new Transaction());
|
||||
Response::setModel(new Subscriber());
|
||||
Response::setModel(new Target());
|
||||
Response::setModel(new Migration());
|
||||
Response::setModel(new MigrationReport());
|
||||
Response::setModel(new MigrationFirebaseProject());
|
||||
|
||||
// Tests (keep last)
|
||||
Response::setModel(new Mock());
|
||||
|
|
@ -4,7 +4,7 @@ use Ahc\Jwt\JWT;
|
|||
use Ahc\Jwt\JWTException;
|
||||
use Appwrite\Auth\Key;
|
||||
use Appwrite\Databases\TransactionState;
|
||||
use Appwrite\Event\Audit;
|
||||
use Appwrite\Event\Audit as AuditEvent;
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
|
|
@ -30,6 +30,8 @@ use Appwrite\Utopia\Response;
|
|||
use Executor\Executor;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
|
||||
use Utopia\App;
|
||||
use Utopia\Audit\Adapter\Database as AdapterDatabase;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Auth\Hashes\Argon2;
|
||||
use Utopia\Auth\Hashes\Sha;
|
||||
use Utopia\Auth\Proofs\Code;
|
||||
|
|
@ -146,7 +148,7 @@ App::setResource('queueForStatsUsage', function (Publisher $publisher) {
|
|||
return new StatsUsage($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForAudits', function (Publisher $publisher) {
|
||||
return new Audit($publisher);
|
||||
return new AuditEvent($publisher);
|
||||
}, ['publisher']);
|
||||
App::setResource('queueForFunctions', function (Publisher $publisher) {
|
||||
return new Func($publisher);
|
||||
|
|
@ -642,6 +644,11 @@ App::setResource('getLogsDB', function (Group $pools, Cache $cache) {
|
|||
};
|
||||
}, ['pools', 'cache']);
|
||||
|
||||
App::setResource('audit', function ($dbForProject) {
|
||||
$adapter = new AdapterDatabase($dbForProject);
|
||||
return new Audit($adapter);
|
||||
}, ['dbForProject']);
|
||||
|
||||
App::setResource('telemetry', fn () => new NoTelemetry());
|
||||
|
||||
App::setResource('cache', function (Group $pools, Telemetry $telemetry) {
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ $httpsPort = $this->getParam('httpsPort', '');
|
|||
$version = $this->getParam('version', '');
|
||||
$organization = $this->getParam('organization', '');
|
||||
$image = $this->getParam('image', '');
|
||||
$enableAssistant = $this->getParam('enableAssistant', false);
|
||||
?>services:
|
||||
traefik:
|
||||
image: traefik:2.11
|
||||
|
|
@ -179,7 +180,7 @@ $image = $this->getParam('image', '');
|
|||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: <?php echo $organization; ?>/console:7.4.7
|
||||
image: <?php echo $organization; ?>/console:7.5.7
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
|
@ -848,6 +849,7 @@ $image = $this->getParam('image', '');
|
|||
- _APP_DB_USER
|
||||
- _APP_DB_PASS
|
||||
|
||||
<?php if ($enableAssistant): ?>
|
||||
appwrite-assistant:
|
||||
image: appwrite/assistant:0.8.4
|
||||
container_name: appwrite-assistant
|
||||
|
|
@ -857,6 +859,7 @@ $image = $this->getParam('image', '');
|
|||
- appwrite
|
||||
environment:
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
<?php endif; ?>
|
||||
|
||||
appwrite-browser:
|
||||
image: appwrite/browser:0.3.2
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ use Appwrite\Utopia\Database\Documents\User;
|
|||
use Executor\Executor;
|
||||
use Swoole\Runtime;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
|
||||
use Utopia\Audit\Adapter\Database as AdapterDatabase;
|
||||
use Utopia\Audit\Audit as UtopiaAudit;
|
||||
use Utopia\Cache\Adapter\Pool as CachePool;
|
||||
use Utopia\Cache\Adapter\Sharding;
|
||||
use Utopia\Cache\Cache;
|
||||
|
|
@ -450,6 +452,19 @@ Server::setResource('logError', function (Registry $register, Document $project)
|
|||
|
||||
Server::setResource('executor', fn () => new Executor());
|
||||
|
||||
Server::setResource('getAudit', function (Database $dbForPlatform, callable $getProjectDB) {
|
||||
return function (Document $project) use ($dbForPlatform, $getProjectDB) {
|
||||
if ($project->isEmpty() || $project->getId() === 'console') {
|
||||
$adapter = new AdapterDatabase($dbForPlatform);
|
||||
return new UtopiaAudit($adapter);
|
||||
}
|
||||
|
||||
$dbForProject = $getProjectDB($project);
|
||||
$adapter = new AdapterDatabase($dbForProject);
|
||||
return new UtopiaAudit($adapter);
|
||||
};
|
||||
}, ['dbForPlatform', 'getProjectDB']);
|
||||
|
||||
$pools = $register->get('pools');
|
||||
$platform = new Appwrite();
|
||||
$args = $platform->getEnv('argv');
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php doctor $@
|
||||
exec php /usr/src/code/app/cli.php doctor "$@"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php install $@
|
||||
exec php /usr/src/code/app/cli.php install "$@"
|
||||
3
bin/interval
Normal file
3
bin/interval
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
exec php /usr/src/code/app/cli.php interval "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php maintenance $@
|
||||
exec php /usr/src/code/app/cli.php maintenance "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php migrate $@
|
||||
exec php /usr/src/code/app/cli.php migrate "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php queue-count --type=failed $@
|
||||
exec php /usr/src/code/app/cli.php queue-count --type=failed "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php queue-count --type=processing $@
|
||||
exec php /usr/src/code/app/cli.php queue-count --type=processing "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php queue-count --type=success $@
|
||||
exec php /usr/src/code/app/cli.php queue-count --type=success "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php queue-retry $@
|
||||
exec php /usr/src/code/app/cli.php queue-retry "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/realtime.php $@
|
||||
exec php /usr/src/code/app/realtime.php "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php schedule-executions $@
|
||||
exec php /usr/src/code/app/cli.php schedule-executions "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php schedule-functions $@
|
||||
exec php /usr/src/code/app/cli.php schedule-functions "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php schedule-messages $@
|
||||
exec php /usr/src/code/app/cli.php schedule-messages "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php screenshot $@
|
||||
exec php /usr/src/code/app/cli.php screenshot "$@"
|
||||
2
bin/sdks
2
bin/sdks
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php sdks $@
|
||||
exec php /usr/src/code/app/cli.php sdks "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php specs $@
|
||||
exec php /usr/src/code/app/cli.php specs "$@"
|
||||
2
bin/ssl
2
bin/ssl
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php ssl $@
|
||||
exec php /usr/src/code/app/cli.php ssl "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php stats-resources $@
|
||||
exec php /usr/src/code/app/cli.php stats-resources "$@"
|
||||
2
bin/test
2
bin/test
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
/usr/src/code/vendor/bin/phpunit --configuration /usr/src/code/phpunit.xml $@
|
||||
exec /usr/src/code/vendor/bin/phpunit --configuration /usr/src/code/phpunit.xml "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php upgrade $@
|
||||
exec php /usr/src/code/app/cli.php upgrade "$@"
|
||||
2
bin/vars
2
bin/vars
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/cli.php vars $@
|
||||
exec php /usr/src/code/app/cli.php vars "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php audits $@
|
||||
exec php /usr/src/code/app/worker.php audits "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php builds $@
|
||||
exec php /usr/src/code/app/worker.php builds "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php certificates $@
|
||||
exec php /usr/src/code/app/worker.php certificates "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php databases $@
|
||||
exec php /usr/src/code/app/worker.php databases "$@"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php deletes $@
|
||||
exec php /usr/src/code/app/worker.php deletes "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php functions $@
|
||||
exec php /usr/src/code/app/worker.php functions "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php mails $@
|
||||
exec php /usr/src/code/app/worker.php mails "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php messaging $@
|
||||
exec php /usr/src/code/app/worker.php messaging "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php migrations $@
|
||||
exec php /usr/src/code/app/worker.php migrations "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php stats-resources $@
|
||||
exec php /usr/src/code/app/worker.php stats-resources "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php stats-usage $@
|
||||
exec php /usr/src/code/app/worker.php stats-usage "$@"
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
php /usr/src/code/app/worker.php webhooks $@
|
||||
exec php /usr/src/code/app/worker.php webhooks "$@"
|
||||
|
|
@ -47,12 +47,12 @@
|
|||
"appwrite/php-clamav": "2.0.*",
|
||||
"utopia-php/abuse": "1.*",
|
||||
"utopia-php/analytics": "0.10.*",
|
||||
"utopia-php/audit": "1.*",
|
||||
"utopia-php/audit": "2.0.2-rc1",
|
||||
"utopia-php/auth": "0.5.*",
|
||||
"utopia-php/cache": "0.13.*",
|
||||
"utopia-php/cli": "0.15.*",
|
||||
"utopia-php/config": "1.*.*",
|
||||
"utopia-php/database": "3.*",
|
||||
"utopia-php/database": "3.*.*",
|
||||
"utopia-php/detector": "0.2.*",
|
||||
"utopia-php/domains": "0.9.*",
|
||||
"utopia-php/emails": "0.6.*",
|
||||
|
|
@ -109,4 +109,4 @@
|
|||
"tbachert/spi": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
154
composer.lock
generated
154
composer.lock
generated
|
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "7c9cb03eb5267f1e7a3ffc037ae22b6a",
|
||||
"content-hash": "b873febd2b03c32ec61a57b690cc44a2",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
|
@ -2673,16 +2673,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/http-client",
|
||||
"version": "v7.4.1",
|
||||
"version": "v7.4.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-client.git",
|
||||
"reference": "26cc224ea7103dda90e9694d9e139a389092d007"
|
||||
"reference": "d01dfac1e0dc99f18da48b18101c23ce57929616"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/26cc224ea7103dda90e9694d9e139a389092d007",
|
||||
"reference": "26cc224ea7103dda90e9694d9e139a389092d007",
|
||||
"url": "https://api.github.com/repos/symfony/http-client/zipball/d01dfac1e0dc99f18da48b18101c23ce57929616",
|
||||
"reference": "d01dfac1e0dc99f18da48b18101c23ce57929616",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -2750,7 +2750,7 @@
|
|||
"http"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.4.1"
|
||||
"source": "https://github.com/symfony/http-client/tree/v7.4.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -2770,7 +2770,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-04T21:12:57+00:00"
|
||||
"time": "2025-12-23T14:50:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-client-contracts",
|
||||
|
|
@ -3552,21 +3552,23 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "1.0.2",
|
||||
"version": "2.0.2-rc1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/audit.git",
|
||||
"reference": "8c17065c2473d4ca799f65585ca74eb53e1be211"
|
||||
"reference": "7b35dab40bce66bda56eeeacd2bbcbf1e823f05f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/8c17065c2473d4ca799f65585ca74eb53e1be211",
|
||||
"reference": "8c17065c2473d4ca799f65585ca74eb53e1be211",
|
||||
"url": "https://api.github.com/repos/utopia-php/audit/zipball/7b35dab40bce66bda56eeeacd2bbcbf1e823f05f",
|
||||
"reference": "7b35dab40bce66bda56eeeacd2bbcbf1e823f05f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0",
|
||||
"utopia-php/database": "*"
|
||||
"utopia-php/database": "3.*",
|
||||
"utopia-php/fetch": "^0.4.2",
|
||||
"utopia-php/validators": "^0.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
|
|
@ -3593,9 +3595,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/audit/issues",
|
||||
"source": "https://github.com/utopia-php/audit/tree/1.0.2"
|
||||
"source": "https://github.com/utopia-php/audit/tree/2.0.2-rc1"
|
||||
},
|
||||
"time": "2025-10-20T07:14:26+00:00"
|
||||
"time": "2025-12-24T01:20:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/auth",
|
||||
|
|
@ -3654,16 +3656,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/cache",
|
||||
"version": "0.13.1",
|
||||
"version": "0.13.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/cache.git",
|
||||
"reference": "97220cb3b3822b166ee016d1646e2ae2815dc540"
|
||||
"reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/cache/zipball/97220cb3b3822b166ee016d1646e2ae2815dc540",
|
||||
"reference": "97220cb3b3822b166ee016d1646e2ae2815dc540",
|
||||
"url": "https://api.github.com/repos/utopia-php/cache/zipball/5768498c9f451482f0bf3eede4d6452ddcd4a0f6",
|
||||
"reference": "5768498c9f451482f0bf3eede4d6452ddcd4a0f6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3672,7 +3674,7 @@
|
|||
"ext-redis": "*",
|
||||
"php": ">=8.0",
|
||||
"utopia-php/pools": "0.8.*",
|
||||
"utopia-php/telemetry": "0.1.*"
|
||||
"utopia-php/telemetry": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.2.*",
|
||||
|
|
@ -3700,9 +3702,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/cache/issues",
|
||||
"source": "https://github.com/utopia-php/cache/tree/0.13.1"
|
||||
"source": "https://github.com/utopia-php/cache/tree/0.13.2"
|
||||
},
|
||||
"time": "2025-05-09T14:43:52+00:00"
|
||||
"time": "2025-12-17T08:55:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/cli",
|
||||
|
|
@ -3896,16 +3898,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "3.6.0",
|
||||
"version": "3.6.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "af15066255a5fd7bd2926de37bcbf3d8500fc155"
|
||||
"reference": "c8c1b2f5770245dd4006e2680681e3efbe8b1fa7"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/af15066255a5fd7bd2926de37bcbf3d8500fc155",
|
||||
"reference": "af15066255a5fd7bd2926de37bcbf3d8500fc155",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/c8c1b2f5770245dd4006e2680681e3efbe8b1fa7",
|
||||
"reference": "c8c1b2f5770245dd4006e2680681e3efbe8b1fa7",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -3948,9 +3950,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/3.6.0"
|
||||
"source": "https://github.com/utopia-php/database/tree/3.6.1"
|
||||
},
|
||||
"time": "2025-12-08T05:23:04+00:00"
|
||||
"time": "2025-12-16T09:55:41+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
|
|
@ -3999,23 +4001,23 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/dns",
|
||||
"version": "1.4.0",
|
||||
"version": "1.4.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/dns.git",
|
||||
"reference": "dce3453364a4524b7250db8d8eb74820b814409e"
|
||||
"reference": "5daf8b683dad877491c4df84c6be24850b2f363b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/dns/zipball/dce3453364a4524b7250db8d8eb74820b814409e",
|
||||
"reference": "dce3453364a4524b7250db8d8eb74820b814409e",
|
||||
"url": "https://api.github.com/repos/utopia-php/dns/zipball/5daf8b683dad877491c4df84c6be24850b2f363b",
|
||||
"reference": "5daf8b683dad877491c4df84c6be24850b2f363b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"utopia-php/console": "0.0.*",
|
||||
"utopia-php/domains": "0.9.*",
|
||||
"utopia-php/telemetry": "0.1.*",
|
||||
"utopia-php/telemetry": "*",
|
||||
"utopia-php/validators": "0.*"
|
||||
},
|
||||
"require-dev": {
|
||||
|
|
@ -4050,9 +4052,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/dns/issues",
|
||||
"source": "https://github.com/utopia-php/dns/tree/1.4.0"
|
||||
"source": "https://github.com/utopia-php/dns/tree/1.4.1"
|
||||
},
|
||||
"time": "2025-12-05T10:09:00+00:00"
|
||||
"time": "2025-12-17T09:09:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/domains",
|
||||
|
|
@ -4730,21 +4732,21 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
"version": "0.8.2",
|
||||
"version": "0.8.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/pools.git",
|
||||
"reference": "05c67aba42eb68ac65489cc1e7fc5db83db2dd4d"
|
||||
"reference": "ad7d6ba946376e81c603204285ce9a674b6502b8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/05c67aba42eb68ac65489cc1e7fc5db83db2dd4d",
|
||||
"reference": "05c67aba42eb68ac65489cc1e7fc5db83db2dd4d",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/ad7d6ba946376e81c603204285ce9a674b6502b8",
|
||||
"reference": "ad7d6ba946376e81c603204285ce9a674b6502b8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.3",
|
||||
"utopia-php/telemetry": "0.1.*"
|
||||
"php": ">=8.4",
|
||||
"utopia-php/telemetry": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/pint": "1.*",
|
||||
|
|
@ -4776,9 +4778,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/pools/issues",
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.8.2"
|
||||
"source": "https://github.com/utopia-php/pools/tree/0.8.3"
|
||||
},
|
||||
"time": "2025-04-17T02:04:54+00:00"
|
||||
"time": "2025-12-17T09:35:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/preloader",
|
||||
|
|
@ -4835,16 +4837,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/queue",
|
||||
"version": "0.11.1",
|
||||
"version": "0.11.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/queue.git",
|
||||
"reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6"
|
||||
"reference": "a854f7c4abc18e0eca55fc5608cd7088d71eb19f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/498bbbef418b1db71b51e1bb62f5d1d752ddd8d6",
|
||||
"reference": "498bbbef418b1db71b51e1bb62f5d1d752ddd8d6",
|
||||
"url": "https://api.github.com/repos/utopia-php/queue/zipball/a854f7c4abc18e0eca55fc5608cd7088d71eb19f",
|
||||
"reference": "a854f7c4abc18e0eca55fc5608cd7088d71eb19f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -4854,7 +4856,7 @@
|
|||
"utopia-php/fetch": "0.4.*",
|
||||
"utopia-php/framework": "0.33.*",
|
||||
"utopia-php/pools": "0.8.*",
|
||||
"utopia-php/telemetry": "0.1.*"
|
||||
"utopia-php/telemetry": "*"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-redis": "*",
|
||||
|
|
@ -4895,9 +4897,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/queue/issues",
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.11.1"
|
||||
"source": "https://github.com/utopia-php/queue/tree/0.11.2"
|
||||
},
|
||||
"time": "2025-05-30T11:50:34+00:00"
|
||||
"time": "2025-12-17T09:32:35+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/registry",
|
||||
|
|
@ -4953,16 +4955,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/storage",
|
||||
"version": "0.18.16",
|
||||
"version": "0.18.18",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/storage.git",
|
||||
"reference": "0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f"
|
||||
"reference": "acaea524f315f87b8811a2c34450fe2b502f49d8"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f",
|
||||
"reference": "0c7b8ad68de8e1eb23ccc8af9f27a30eb832930f",
|
||||
"url": "https://api.github.com/repos/utopia-php/storage/zipball/acaea524f315f87b8811a2c34450fe2b502f49d8",
|
||||
"reference": "acaea524f315f87b8811a2c34450fe2b502f49d8",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5005,9 +5007,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/storage/issues",
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.18.16"
|
||||
"source": "https://github.com/utopia-php/storage/tree/0.18.18"
|
||||
},
|
||||
"time": "2025-12-03T02:15:45+00:00"
|
||||
"time": "2025-12-17T07:33:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/swoole",
|
||||
|
|
@ -5436,16 +5438,16 @@
|
|||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "1.5.9",
|
||||
"version": "1.8.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "ee434aa00a9185380b9a39bb46bf86d7104d3a93"
|
||||
"reference": "b6cc29d3bd247e193f3c06b4168dc69d884645f0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/ee434aa00a9185380b9a39bb46bf86d7104d3a93",
|
||||
"reference": "ee434aa00a9185380b9a39bb46bf86d7104d3a93",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/b6cc29d3bd247e193f3c06b4168dc69d884645f0",
|
||||
"reference": "b6cc29d3bd247e193f3c06b4168dc69d884645f0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -5481,9 +5483,9 @@
|
|||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.5.9"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/1.8.6"
|
||||
},
|
||||
"time": "2025-11-25T05:22:25+00:00"
|
||||
"time": "2025-12-31T10:22:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
|
|
@ -7931,16 +7933,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v8.0.1",
|
||||
"version": "v8.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "fcb73f69d655b48fcb894a262f074218df08bd58"
|
||||
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/fcb73f69d655b48fcb894a262f074218df08bd58",
|
||||
"reference": "fcb73f69d655b48fcb894a262f074218df08bd58",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
|
||||
"reference": "6145b304a5c1ea0bdbd0b04d297a5864f9a7d587",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -7997,7 +7999,7 @@
|
|||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.1"
|
||||
"source": "https://github.com/symfony/console/tree/v8.0.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -8017,7 +8019,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-12-05T15:25:33+00:00"
|
||||
"time": "2025-12-23T14:52:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
|
|
@ -8091,16 +8093,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v8.0.0",
|
||||
"version": "v8.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "7598dd5770580fa3517ec83e8da0c9b9e01f4291"
|
||||
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/7598dd5770580fa3517ec83e8da0c9b9e01f4291",
|
||||
"reference": "7598dd5770580fa3517ec83e8da0c9b9e01f4291",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/dd3a2953570a283a2ba4e17063bb98c734cf5b12",
|
||||
"reference": "dd3a2953570a283a2ba4e17063bb98c734cf5b12",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
|
@ -8135,7 +8137,7 @@
|
|||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v8.0.0"
|
||||
"source": "https://github.com/symfony/finder/tree/v8.0.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
|
@ -8155,7 +8157,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-11-05T14:36:47+00:00"
|
||||
"time": "2025-12-23T14:52:06+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
|
|
@ -8943,7 +8945,9 @@
|
|||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"stability-flags": {
|
||||
"utopia-php/audit": 5
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
|
@ -8967,5 +8971,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@ services:
|
|||
appwrite-console:
|
||||
<<: *x-logging
|
||||
container_name: appwrite-console
|
||||
image: appwrite/console:7.4.11
|
||||
image: appwrite/console:7.5.7
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- appwrite
|
||||
|
|
@ -555,6 +555,7 @@ services:
|
|||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_DOMAIN_SITES
|
||||
- _APP_EMAIL_CERTIFICATES
|
||||
- _APP_REDIS_HOST
|
||||
- _APP_REDIS_PORT
|
||||
|
|
@ -753,6 +754,7 @@ services:
|
|||
- ./app:/usr/src/code/app
|
||||
- ./src:/usr/src/code/src
|
||||
depends_on:
|
||||
- mariadb
|
||||
- redis
|
||||
environment:
|
||||
- _APP_ENV
|
||||
|
|
@ -785,6 +787,43 @@ services:
|
|||
- _APP_MAINTENANCE_START_TIME
|
||||
- _APP_DATABASE_SHARED_TABLES
|
||||
|
||||
appwrite-task-interval:
|
||||
entrypoint: interval
|
||||
<<: *x-logging
|
||||
container_name: appwrite-task-interval
|
||||
image: appwrite-dev
|
||||
networks:
|
||||
- appwrite
|
||||
volumes:
|
||||
- ./app:/usr/src/code/app
|
||||
- ./src:/usr/src/code/src
|
||||
depends_on:
|
||||
- mariadb
|
||||
- redis
|
||||
environment:
|
||||
- _APP_ENV
|
||||
- _APP_WORKER_PER_CORE
|
||||
- _APP_DOMAIN
|
||||
- _APP_DOMAIN_TARGET_CNAME
|
||||
- _APP_DOMAIN_TARGET_AAAA
|
||||
- _APP_DOMAIN_TARGET_A
|
||||
- _APP_DOMAIN_TARGET_CAA
|
||||
- _APP_DNS
|
||||
- _APP_DOMAIN_FUNCTIONS
|
||||
- _APP_DOMAIN_SITES
|
||||
- _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_DATABASE_SHARED_TABLES
|
||||
- _APP_INTERVAL_DOMAIN_VERIFICATION
|
||||
|
||||
appwrite-task-stats-resources:
|
||||
container_name: appwrite-task-stats-resources
|
||||
entrypoint: stats-resources
|
||||
|
|
@ -1028,27 +1067,6 @@ services:
|
|||
- OPR_EXECUTOR_STORAGE_WASABI_REGION=$_APP_STORAGE_WASABI_REGION
|
||||
- OPR_EXECUTOR_STORAGE_WASABI_BUCKET=$_APP_STORAGE_WASABI_BUCKET
|
||||
|
||||
openruntimes-proxy:
|
||||
container_name: openruntimes-proxy
|
||||
hostname: proxy
|
||||
<<: *x-logging
|
||||
stop_signal: SIGINT
|
||||
image: openruntimes/proxy:0.5.5
|
||||
networks:
|
||||
- appwrite
|
||||
- runtimes
|
||||
environment:
|
||||
- OPR_PROXY_WORKER_PER_CORE=$_APP_WORKER_PER_CORE
|
||||
- OPR_PROXY_ENV=$_APP_ENV
|
||||
- OPR_PROXY_EXECUTOR_SECRET=$_APP_EXECUTOR_SECRET
|
||||
- OPR_PROXY_SECRET=$_APP_EXECUTOR_SECRET
|
||||
- OPR_PROXY_LOGGING_CONFIG=$_APP_LOGGING_CONFIG
|
||||
- OPR_PROXY_ALGORITHM=random
|
||||
- OPR_PROXY_EXECUTORS=exc1
|
||||
- OPR_PROXY_HEALTHCHECK_INTERVAL=10000
|
||||
- OPR_PROXY_MAX_TIMEOUT=600
|
||||
- OPR_PROXY_HEALTHCHECK=enabled
|
||||
|
||||
mariadb:
|
||||
image: mariadb:10.11 # fix issues when upgrading using: mysql_upgrade -u root -p
|
||||
container_name: appwrite-mariadb
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ interface Adapter
|
|||
{
|
||||
public function issueCertificate(string $certName, string $domain, ?string $domainType): ?string;
|
||||
|
||||
public function isInstantGeneration(string $domain, ?string $domainType): bool;
|
||||
|
||||
public function getCertificateStatus(string $domain, ?string $domainType): string;
|
||||
|
||||
public function isRenewRequired(string $domain, ?string $domainType, Log $log): bool;
|
||||
|
||||
public function deleteCertificate(string $domain): void;
|
||||
|
|
|
|||
10
src/Appwrite/Certificates/Exception/CertificateStatus.php
Normal file
10
src/Appwrite/Certificates/Exception/CertificateStatus.php
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Certificates\Exception;
|
||||
|
||||
use Exception;
|
||||
|
||||
// Exception thrown during certificate status retrieval
|
||||
class CertificateStatus extends Exception
|
||||
{
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace Appwrite\Certificates;
|
||||
|
||||
use Appwrite\Certificates\Exception\CertificateStatus as CertificateStatusException;
|
||||
use Exception;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
|
|
@ -84,6 +85,16 @@ class LetsEncrypt implements Adapter
|
|||
return DateTime::addSeconds($dt, -60 * 60 * 24 * 30);
|
||||
}
|
||||
|
||||
public function isInstantGeneration(string $domain, ?string $domainType): bool
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getCertificateStatus(string $domain, ?string $domainType): string
|
||||
{
|
||||
throw new CertificateStatusException('Certificate status retrieval is not supported for LetsEncrypt.');
|
||||
}
|
||||
|
||||
public function isRenewRequired(string $domain, ?string $domainType, Log $log): bool
|
||||
{
|
||||
$certPath = APP_STORAGE_CERTIFICATES . '/' . $domain . '/cert.pem';
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ use Utopia\System\System;
|
|||
|
||||
class Certificate extends Event
|
||||
{
|
||||
public const string ACTION_DOMAIN_VERIFICATION = 'verification';
|
||||
public const string ACTION_GENERATION = 'generation';
|
||||
protected bool $skipRenewCheck = false;
|
||||
protected string $action = self::ACTION_GENERATION;
|
||||
protected ?Document $domain = null;
|
||||
protected ?string $validationDomain = null;
|
||||
|
||||
|
|
@ -91,6 +94,28 @@ class Certificate extends Event
|
|||
return $this->skipRenewCheck;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set action for this certificate event.
|
||||
*
|
||||
* @param string $action
|
||||
* @return self
|
||||
*/
|
||||
public function setAction(string $action): self
|
||||
{
|
||||
$this->action = $action;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get action for this certificate event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getAction(): string
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Prepare the payload for the event
|
||||
|
|
@ -103,7 +128,8 @@ class Certificate extends Event
|
|||
'project' => $this->project,
|
||||
'domain' => $this->domain,
|
||||
'skipRenewCheck' => $this->skipRenewCheck,
|
||||
'validationDomain' => $this->validationDomain
|
||||
'validationDomain' => $this->validationDomain,
|
||||
'action' => $this->action
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ abstract class Migration
|
|||
'1.7.3' => 'V22',
|
||||
'1.7.4' => 'V22',
|
||||
'1.8.0' => 'V23',
|
||||
'1.8.1' => 'V23',
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -139,7 +139,7 @@ class V23 extends Migration
|
|||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to migration error attribute size in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
break;
|
||||
case 'buckets':
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->dbForProject, $id, 'transformations');
|
||||
|
|
@ -148,6 +148,21 @@ class V23 extends Migration
|
|||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'users':
|
||||
$attributes = [
|
||||
'emailCanonical',
|
||||
'emailIsFree',
|
||||
'emailIsDisposable',
|
||||
'emailIsCorporate',
|
||||
'emailIsCanonical',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
67
src/Appwrite/Platform/AGENTS.md
Normal file
67
src/Appwrite/Platform/AGENTS.md
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
# Modules AGENTS.md
|
||||
|
||||
> Before reading this file, also read Appwrite's base [AGENTS.md](../../../AGENTS.md).
|
||||
|
||||
Modules are the building blocks of the Appwrite platform. They are responsible for handling specific tasks, defining background workers, and providing API endpoints. Each module should have its own directory within the `src/Appwrite/Platform/Modules` directory.
|
||||
|
||||
Generally-speaking, each service is its own module, but there are some exceptions. The goal is to always put related code that achieves a specific goal under one roof.
|
||||
|
||||
## Structure and Naming Conventions
|
||||
|
||||
When adding a module, always add a new directory under `src/Appwrite/Platform/Modules`. The directory name should be PascalCase, and if possible, use only one word. For example, `User`, `Database`, `Storage`, etc. Avoid using shorthands, unless they are standardized, such as `DB`, `JWT`, or `SMTP`.
|
||||
|
||||
A module consists of:
|
||||
|
||||
- `Module.php` - Simple register class registering all module's services (from `Services` directory)
|
||||
- `Workers` directory - Contains behavior for module-specific workers
|
||||
- `Tasks` directory - Contains behavior for module-specific CLI tasks
|
||||
- `Http` directory - Contains HTTP endpoints for the module
|
||||
- `Services` directory - Contains register classes for all relevant types of services
|
||||
|
||||
Inside module, the `Services` directory can contain:
|
||||
|
||||
- `Http.php` - Register HTTP endpoints and hooks from `Http` directory
|
||||
- `Workers.php` - Register workers from `Workers` directory
|
||||
- `Tasks.php` - Register CLI tasks from `Tasks` directory
|
||||
|
||||
> After implementing a module, make sure to register it in `src/Appwrite/Platform/Appwrite.php`.
|
||||
|
||||
### HTTP directory structure
|
||||
|
||||
Inside module's `Http` directory, there are multiple rules to follow:
|
||||
|
||||
1. Directly in `Http` directory, there should only be directories for services (and hooks, check point number 2). If a module is a single service, it's okay to only have one directory, with the same name as the service, for example `src/Appwrite/Platform/Modules/Account/Http/Account`. An example with multiple services is `src/Appwrite/Platform/Modules/Databases/Http/Databases` and `src/Appwrite/Platform/Modules/Databases/Http/TablesDB`.
|
||||
|
||||
2. Hooks should live in `Hooks` directory, under `Init`, `Shutdown`, or `Error` directories, inside `Http` directory. For example, an init hook to prevent unauthorized access might live in `src/Appwrite/Platform/Modules/Functions/Http/Hooks/Init/Authentication.php`.
|
||||
|
||||
3. Inside `Http` directories for services, file names can only be `Get.php`, `Update.php`, `Create.php`, `Delete.php` or `XList.php`. We call it `XList`, because `List` is a reserved keyword and PHP would not like that. Never use any other words! Let's say you want a method to be `blockUser`, tempting to add `Users/Block.php`, instead, think of the resource and property it affects. Better naming would be `Users/Status/Update.php` (update user's status). Doing so also nicely reflects in the HTTP endpoint, `PATCH /v1/users/:userId/status`.
|
||||
|
||||
4. It's allowed to nest directories in `Http` service directories. For example, if you want to create a new deployment for a function based on a template, an endpoint might live in `src/Appwrite/Platform/Modules/Functions/Http/Functions/Deployments/Template/Create.php`. In this example, notice functions and deployments are resources, and template is property - both resources and properties can be nested, and have separate directories.
|
||||
|
||||
### Sample module directory structure
|
||||
|
||||
```bash
|
||||
src/Appwrite/Platform/Modules/Functions
|
||||
├── Module.php
|
||||
├── Workers
|
||||
│ └── Builds.php
|
||||
├── Tasks
|
||||
│ └── Block.php
|
||||
├── Http
|
||||
│ └── Functions
|
||||
│ ├── Create.php
|
||||
│ ├── XList.php
|
||||
│ ├── Update.php
|
||||
│ ├── Delete.php
|
||||
│ ├── Get.php
|
||||
│ └── Deployments
|
||||
│ ├── XList.php
|
||||
│ ├── Delete.php
|
||||
│ ├── Get.php
|
||||
│ └── Template
|
||||
│ └── Create.php
|
||||
└── Services
|
||||
├── Http.php
|
||||
├── Workers.php
|
||||
└── Tasks.php
|
||||
```
|
||||
|
|
@ -2,8 +2,6 @@
|
|||
|
||||
namespace Appwrite\Platform;
|
||||
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Swoole\Coroutine as Co;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
|
|
@ -22,9 +20,9 @@ class Action extends UtopiaAction
|
|||
protected mixed $logError;
|
||||
|
||||
protected array $filters = [
|
||||
'subQueryKeys', 'subQueryWebhooks', 'subQueryPlatforms', 'subQueryProjectVariables', 'subQueryBlocks', 'subQueryDevKeys', // Project
|
||||
'subQueryKeys', 'subQueryWebhooks', 'subQueryPlatforms', 'subQueryBlocks', 'subQueryDevKeys', // Project
|
||||
'subQueryAuthenticators', 'subQuerySessions', 'subQueryTokens', 'subQueryChallenges', 'subQueryMemberships', 'subQueryTargets', 'subQueryTopicTargets',// Users
|
||||
'subQueryVariables', // Sites
|
||||
'subQueryVariables', 'subQueryProjectVariables' // Sites / Functions
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
@ -161,50 +159,4 @@ class Action extends UtopiaAction
|
|||
Console::info("[" . DateTime::now() . "] " . $method . ' ' . $type . ' ' . $project->getSequence() . ' ' . $project->getId() . ' ' . $collectionId . ' ' . $log);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper to apply (request) select queries to response model.
|
||||
*
|
||||
* This prevents default values of rules to be presnet for not-selected attributes
|
||||
*
|
||||
* @param Request $request
|
||||
* @param Document $document
|
||||
* @return void
|
||||
*/
|
||||
public function applySelectQueries(Request $request, Response $response, string $model): void
|
||||
{
|
||||
$queries = $request->getParam('queries', []);
|
||||
|
||||
$queries = Query::parseQueries($queries);
|
||||
$selectQueries = Query::groupByType($queries)['selections'] ?? [];
|
||||
|
||||
// No select queries means no filtering out
|
||||
if (empty($selectQueries)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$attributes = [];
|
||||
foreach ($selectQueries as $query) {
|
||||
foreach ($query->getValues() as $attribute) {
|
||||
$attributes[] = $attribute;
|
||||
}
|
||||
}
|
||||
|
||||
// found a wildcard, return!
|
||||
if (\in_array('*', $attributes)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$responseModel = $response->getModel($model);
|
||||
foreach ($responseModel->getRules() as $ruleName => $rule) {
|
||||
if (\str_starts_with($ruleName, '$')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!\in_array($ruleName, $attributes)) {
|
||||
$responseModel->removeRule($ruleName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ use Appwrite\Platform\Modules\Functions;
|
|||
use Appwrite\Platform\Modules\Projects;
|
||||
use Appwrite\Platform\Modules\Proxy;
|
||||
use Appwrite\Platform\Modules\Sites;
|
||||
use Appwrite\Platform\Modules\Storage;
|
||||
use Appwrite\Platform\Modules\Tokens;
|
||||
use Utopia\Platform\Platform;
|
||||
|
||||
|
|
@ -26,5 +27,6 @@ class Appwrite extends Platform
|
|||
$this->addModule(new Console\Module());
|
||||
$this->addModule(new Proxy\Module());
|
||||
$this->addModule(new Tokens\Module());
|
||||
$this->addModule(new Storage\Module());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Assistant;
|
||||
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Text;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createAssistantQuery';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/console/assistant')
|
||||
->desc('Create assistant query')
|
||||
->groups(['api', 'assistant'])
|
||||
->label('scope', 'assistant.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'assistant',
|
||||
group: 'console',
|
||||
name: 'chat',
|
||||
description: '/docs/references/assistant/chat.md',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_NONE,
|
||||
)
|
||||
],
|
||||
contentType: ContentType::TEXT
|
||||
))
|
||||
->label('abuse-limit', 15)
|
||||
->label('abuse-key', 'userId:{userId}')
|
||||
->param('prompt', '', new Text(2000), 'Prompt. A string containing questions asked to the AI assistant.')
|
||||
->inject('response')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $prompt, Response $response)
|
||||
{
|
||||
$ch = curl_init('http://appwrite-assistant:3003/v1/models/assistant/prompt');
|
||||
$responseHeaders = [];
|
||||
$query = json_encode(['prompt' => $prompt]);
|
||||
$headers = ['accept: text/event-stream'];
|
||||
$handleEvent = function ($ch, $data) use ($response) {
|
||||
$response->chunk($data);
|
||||
|
||||
return \strlen($data);
|
||||
};
|
||||
|
||||
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $handleEvent);
|
||||
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 9000);
|
||||
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) {
|
||||
$len = strlen($header);
|
||||
$header = explode(':', $header, 2);
|
||||
|
||||
if (count($header) < 2) { // ignore invalid headers
|
||||
return $len;
|
||||
}
|
||||
|
||||
$responseHeaders[strtolower(trim($header[0]))] = trim($header[1]);
|
||||
|
||||
return $len;
|
||||
});
|
||||
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, $query);
|
||||
|
||||
curl_exec($ch);
|
||||
|
||||
curl_close($ch);
|
||||
|
||||
$response->chunk('', true);
|
||||
}
|
||||
}
|
||||
28
src/Appwrite/Platform/Modules/Console/Http/Init/API.php
Normal file
28
src/Appwrite/Platform/Modules/Console/Http/Init/API.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Init;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Platform\Action;
|
||||
|
||||
class API extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleAPI';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setType(Action::TYPE_INIT)
|
||||
->groups(['console'])
|
||||
->inject('project')
|
||||
->callback(function (Document $project) {
|
||||
if ($project->getId() !== 'console') {
|
||||
throw new Exception(Exception::GENERAL_ACCESS_FORBIDDEN);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
31
src/Appwrite/Platform/Modules/Console/Http/Init/Web.php
Normal file
31
src/Appwrite/Platform/Modules/Console/Http/Init/Web.php
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Init;
|
||||
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Platform\Action;
|
||||
|
||||
class Web extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleWeb';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setType(Action::TYPE_INIT)
|
||||
->groups(['web'])
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->callback(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
|
||||
;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\Auth;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectAuth';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/auth/*';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects;
|
||||
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
|
||||
abstract class Base extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
/**
|
||||
* HTTP platform trait doesn't support multiple `aliases`
|
||||
* like legacy controllers so we use independent redirects!
|
||||
*
|
||||
* This helps as a base and a small code logic for maintenance.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getPath(): string;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath($this->getPath())
|
||||
->groups(['web'])
|
||||
->label('permission', 'public')
|
||||
->label('scope', 'home')
|
||||
->inject('request')
|
||||
->inject('response')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(Request $request, Response $response): void
|
||||
{
|
||||
$url = parse_url($request->getURI());
|
||||
$target = "/console{$url['path']}";
|
||||
$params = $request->getParams();
|
||||
if (!empty($params)) {
|
||||
$target .= "?" . \http_build_query($params);
|
||||
}
|
||||
if ($url['fragment'] ?? false) {
|
||||
$target .= "#{$url['fragment']}";
|
||||
}
|
||||
|
||||
$response->redirect($target);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\Card;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectCard';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/card/*';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\Invite;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectInvite';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/invite';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\Login;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectLogin';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/login';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\MFA;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectMFA';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/mfa';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\Recover;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectRecover';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/recover';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\Register;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectRegister';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/register/*';
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Redirects\Root;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Base;
|
||||
|
||||
class Get extends Base
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'consoleRedirectRoot';
|
||||
}
|
||||
|
||||
protected function getPath(): string
|
||||
{
|
||||
return '/';
|
||||
}
|
||||
}
|
||||
93
src/Appwrite/Platform/Modules/Console/Http/Variables/Get.php
Normal file
93
src/Appwrite/Platform/Modules/Console/Http/Variables/Get.php
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Console\Http\Variables;
|
||||
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Domains\Domain;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\IP;
|
||||
|
||||
class Get extends Action
|
||||
{
|
||||
use HTTP;
|
||||
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'getVariables';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/console/variables')
|
||||
->desc('Get variables')
|
||||
->groups(['api', 'projects'])
|
||||
->label('scope', 'projects.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'console',
|
||||
group: 'console',
|
||||
name: 'variables',
|
||||
description: '/docs/references/console/variables.md',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_CONSOLE_VARIABLES,
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->inject('response')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(Response $response)
|
||||
{
|
||||
$validator = new Domain(System::getEnv('_APP_DOMAIN_TARGET_CNAME'));
|
||||
$isCNAMEValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_CNAME', '')) && $validator->isKnown() && !$validator->isTest();
|
||||
|
||||
$validator = new IP(IP::V4);
|
||||
$isAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_A', '')) && ($validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_A')));
|
||||
|
||||
$validator = new IP(IP::V6);
|
||||
$isAAAAValid = !empty(System::getEnv('_APP_DOMAIN_TARGET_AAAA', '')) && $validator->isValid(System::getEnv('_APP_DOMAIN_TARGET_AAAA'));
|
||||
|
||||
$isDomainEnabled = $isAAAAValid || $isAValid || $isCNAMEValid;
|
||||
|
||||
$isVcsEnabled = !empty(System::getEnv('_APP_VCS_GITHUB_APP_NAME', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_APP_ID', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_CLIENT_ID', ''))
|
||||
&& !empty(System::getEnv('_APP_VCS_GITHUB_CLIENT_SECRET', ''));
|
||||
|
||||
$isAssistantEnabled = !empty(System::getEnv('_APP_ASSISTANT_OPENAI_API_KEY', ''));
|
||||
|
||||
$variables = new Document([
|
||||
'_APP_DOMAIN_TARGET_CNAME' => System::getEnv('_APP_DOMAIN_TARGET_CNAME'),
|
||||
'_APP_DOMAIN_TARGET_AAAA' => System::getEnv('_APP_DOMAIN_TARGET_AAAA'),
|
||||
'_APP_DOMAIN_TARGET_A' => System::getEnv('_APP_DOMAIN_TARGET_A'),
|
||||
'_APP_DOMAIN_TARGET_CAA' => '0 issue "' . System::getEnv('_APP_DOMAIN_TARGET_CAA') . '"',
|
||||
'_APP_STORAGE_LIMIT' => +System::getEnv('_APP_STORAGE_LIMIT'),
|
||||
'_APP_COMPUTE_BUILD_TIMEOUT' => +System::getEnv('_APP_COMPUTE_BUILD_TIMEOUT'),
|
||||
'_APP_COMPUTE_SIZE_LIMIT' => +System::getEnv('_APP_COMPUTE_SIZE_LIMIT'),
|
||||
'_APP_USAGE_STATS' => System::getEnv('_APP_USAGE_STATS'),
|
||||
'_APP_VCS_ENABLED' => $isVcsEnabled,
|
||||
'_APP_DOMAIN_ENABLED' => $isDomainEnabled,
|
||||
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled,
|
||||
'_APP_DOMAIN_SITES' => System::getEnv('_APP_DOMAIN_SITES'),
|
||||
'_APP_DOMAIN_FUNCTIONS' => System::getEnv('_APP_DOMAIN_FUNCTIONS'),
|
||||
'_APP_OPTIONS_FORCE_HTTPS' => System::getEnv('_APP_OPTIONS_FORCE_HTTPS'),
|
||||
'_APP_DOMAINS_NAMESERVERS' => System::getEnv('_APP_DOMAINS_NAMESERVERS'),
|
||||
]);
|
||||
|
||||
$response->dynamic($variables, Response::MODEL_CONSOLE_VARIABLES);
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,19 @@
|
|||
|
||||
namespace Appwrite\Platform\Modules\Console\Services;
|
||||
|
||||
use Appwrite\Platform\Modules\Console\Http\Assistant\Create as CreateAssistantQuery;
|
||||
use Appwrite\Platform\Modules\Console\Http\Init\API;
|
||||
use Appwrite\Platform\Modules\Console\Http\Init\Web;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Auth\Get as RedirectAuth;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Card\Get as RedirectCard;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Invite\Get as RedirectInvite;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Login\Get as RedirectLogin;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\MFA\Get as RedirectMFA;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Recover\Get as RedirectRecover;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Register\Get as RedirectRegister;
|
||||
use Appwrite\Platform\Modules\Console\Http\Redirects\Root\Get as RedirectRoot;
|
||||
use Appwrite\Platform\Modules\Console\Http\Resources\Get as GetResourceAvailability;
|
||||
use Appwrite\Platform\Modules\Console\Http\Variables\Get as GetVariables;
|
||||
use Utopia\Platform\Service;
|
||||
|
||||
class Http extends Service
|
||||
|
|
@ -10,7 +22,23 @@ class Http extends Service
|
|||
public function __construct()
|
||||
{
|
||||
$this->type = Service::TYPE_HTTP;
|
||||
// Resources
|
||||
|
||||
// API and Web init hooks!
|
||||
$this->addAction(API::getName(), new API());
|
||||
$this->addAction(Web::getName(), new Web());
|
||||
|
||||
$this->addAction(GetVariables::getName(), new GetVariables());
|
||||
$this->addAction(CreateAssistantQuery::getName(), new CreateAssistantQuery());
|
||||
$this->addAction(GetResourceAvailability::getName(), new GetResourceAvailability());
|
||||
|
||||
// web redirects to /console
|
||||
$this->addAction(RedirectRoot::getName(), new RedirectRoot());
|
||||
$this->addAction(RedirectAuth::getName(), new RedirectAuth());
|
||||
$this->addAction(RedirectInvite::getName(), new RedirectInvite());
|
||||
$this->addAction(RedirectLogin::getName(), new RedirectLogin());
|
||||
$this->addAction(RedirectMFA::getName(), new RedirectMFA());
|
||||
$this->addAction(RedirectCard::getName(), new RedirectCard());
|
||||
$this->addAction(RedirectRecover::getName(), new RedirectRecover());
|
||||
$this->addAction(RedirectRegister::getName(), new RedirectRegister());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ class Decrement extends Action
|
|||
value: $value,
|
||||
min: $min
|
||||
);
|
||||
$document->setAttribute('$databaseId', $database->getId());
|
||||
$document->setAttribute('$' . $this->getCollectionsEventsContext() . 'Id', $collectionId);
|
||||
} catch (ConflictException) {
|
||||
throw new Exception($this->getConflictException());
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ class Increment extends Action
|
|||
value: $value,
|
||||
max: $max
|
||||
);
|
||||
$document->setAttribute('$databaseId', $database->getId());
|
||||
$document->setAttribute('$' . $this->getCollectionsEventsContext() . 'Id', $collectionId);
|
||||
} catch (ConflictException) {
|
||||
throw new Exception($this->getConflictException());
|
||||
|
|
|
|||
|
|
@ -72,10 +72,11 @@ class XList extends Action
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
|
||||
public function action(string $databaseId, string $collectionId, string $documentId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
|
||||
{
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
if ($database->isEmpty()) {
|
||||
|
|
@ -98,12 +99,16 @@ class XList extends Action
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$type = $this->getCollectionsEventsContext();
|
||||
$context = $this->getContext();
|
||||
$resource = "database/$databaseId/$type/$collectionId/$context/{$document->getId()}";
|
||||
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
@ -152,7 +157,7 @@ class XList extends Action
|
|||
|
||||
$response->dynamic(new Document([
|
||||
'logs' => $output,
|
||||
'total' => $audit->countLogsByResource($resource, $queries),
|
||||
'total' => $audit->countLogsByResource($resource),
|
||||
]), $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,10 +71,11 @@ class XList extends Action
|
|||
->inject('dbForProject')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('audit')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb): void
|
||||
public function action(string $databaseId, string $collectionId, array $queries, UtopiaResponse $response, Database $dbForProject, Locale $locale, Reader $geodb, Audit $audit): void
|
||||
{
|
||||
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
|
||||
|
||||
|
|
@ -95,10 +96,13 @@ class XList extends Action
|
|||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$audit = new Audit($dbForProject);
|
||||
$grouped = Query::groupByType($queries);
|
||||
$limit = $grouped['limit'] ?? 25;
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
|
||||
$context = $this->getContext();
|
||||
$resource = "database/$databaseId/$context/$collectionId";
|
||||
$logs = $audit->getLogsByResource($resource, $queries);
|
||||
$logs = $audit->getLogsByResource($resource, limit: $limit, offset: $offset);
|
||||
|
||||
$output = [];
|
||||
|
||||
|
|
@ -147,7 +151,7 @@ class XList extends Action
|
|||
|
||||
$response->dynamic(new Document([
|
||||
'logs' => $output,
|
||||
'total' => $audit->countLogsByResource($resource, $queries),
|
||||
'total' => $audit->countLogsByResource($resource),
|
||||
]), $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue