commit
91fe8b7a8b
6
.env
6
.env
|
@ -1,4 +1,5 @@
|
|||
_APP_ENV=development
|
||||
_APP_EDITION=self-hosted
|
||||
_APP_LOCALE=en
|
||||
_APP_WORKER_PER_CORE=6
|
||||
_APP_CONSOLE_WHITELIST_ROOT=disabled
|
||||
|
@ -8,14 +9,15 @@ _APP_CONSOLE_COUNTRIES_DENYLIST=AQ
|
|||
_APP_CONSOLE_HOSTNAMES=localhost,appwrite.io,*.appwrite.io
|
||||
_APP_SYSTEM_EMAIL_NAME=Appwrite
|
||||
_APP_SYSTEM_EMAIL_ADDRESS=team@appwrite.io
|
||||
_APP_SYSTEM_SECURITY_EMAIL_ADDRESS=security@appwrite.io
|
||||
_APP_EMAIL_SECURITY=security@appwrite.io
|
||||
_APP_EMAIL_CERTIFICATES=certificates@appwrite.io
|
||||
_APP_SYSTEM_RESPONSE_FORMAT=
|
||||
_APP_OPTIONS_ABUSE=disabled
|
||||
_APP_OPTIONS_ROUTER_PROTECTION=disabled
|
||||
_APP_OPTIONS_FORCE_HTTPS=disabled
|
||||
_APP_OPTIONS_FUNCTIONS_FORCE_HTTPS=disabled
|
||||
_APP_OPENSSL_KEY_V1=your-secret-key
|
||||
_APP_DOMAIN=traefik
|
||||
_APP_DOMAIN=localhost
|
||||
_APP_DOMAIN_FUNCTIONS=functions.localhost
|
||||
_APP_DOMAIN_TARGET=localhost
|
||||
_APP_REDIS_HOST=redis
|
||||
|
|
3
.github/workflows/tests.yml
vendored
3
.github/workflows/tests.yml
vendored
|
@ -145,3 +145,6 @@ jobs:
|
|||
|
||||
- name: Run ${{matrix.service}} Tests
|
||||
run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug
|
||||
|
||||
- name: Run ${{matrix.service}} Shared Tables Tests
|
||||
run: _APP_DATABASE_SHARED_TABLES=database_db_main docker compose exec -T appwrite test /usr/src/code/tests/e2e/Services/${{matrix.service}} --debug
|
||||
|
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -14,3 +14,4 @@ app/sdks
|
|||
dev/yasd_init.php
|
||||
.phpunit.result.cache
|
||||
Makefile
|
||||
appwrite.json
|
||||
|
|
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -1,4 +1,4 @@
|
|||
[submodule "app/console"]
|
||||
path = app/console
|
||||
url = https://github.com/appwrite/console
|
||||
branch = 4.0.6
|
||||
branch = 4.3.5
|
||||
|
|
118
CHANGES.md
118
CHANGES.md
|
@ -1,3 +1,121 @@
|
|||
# Version 1.5.7
|
||||
## What's Changed
|
||||
|
||||
### Fixes
|
||||
* Fix database exception wrapping by @abnegate in https://github.com/appwrite/appwrite/pull/7787
|
||||
* Fix exception wrap order by @abnegate in https://github.com/appwrite/appwrite/pull/7818
|
||||
* Fix membership query to use internalId by @lohanidamodar in https://github.com/appwrite/appwrite/pull/7834
|
||||
* Fix vcs silent mode by @vermakhushboo in https://github.com/appwrite/appwrite/pull/7683
|
||||
* Fix function domain permissions by @stnguyen90 in https://github.com/appwrite/appwrite/pull/7852
|
||||
* Fix tests required for Cloud by @lohanidamodar in https://github.com/appwrite/appwrite/pull/7777
|
||||
* Fix OAuth error code by @vermakhushboo in https://github.com/appwrite/appwrite/pull/7893
|
||||
* Fix connection reclaim logic. by @eldadfux in https://github.com/appwrite/appwrite/pull/6886
|
||||
* Fix shared queue name by @abnegate in https://github.com/appwrite/appwrite/pull/8092
|
||||
* Fix syntax error by @abnegate in https://github.com/appwrite/appwrite/pull/8093
|
||||
* Fix missing id attribute error by @abnegate in https://github.com/appwrite/appwrite/pull/8094
|
||||
* Fix tests for CL by @lohanidamodar in https://github.com/appwrite/appwrite/pull/8076
|
||||
* Fix project deletes for shared tables by @abnegate in https://github.com/appwrite/appwrite/pull/8107
|
||||
* Handle SQL error code 'HY000' in realtime by @stnguyen90 in https://github.com/appwrite/appwrite/pull/8106
|
||||
* Fix: Don't Override `robots.txt` for Other Domains by @ItzNotABug in https://github.com/appwrite/appwrite/pull/8185
|
||||
* Escape function build command by @stnguyen90 in https://github.com/appwrite/appwrite/pull/7808
|
||||
* Create failed execution from worker if deployment doesn't exist by @vermakhushboo in https://github.com/appwrite/appwrite/pull/7896
|
||||
* Fix: admin mode on console by @TorstenDittmann in https://github.com/appwrite/appwrite/pull/7951
|
||||
* Fix file size default limit by @shimonewman in https://github.com/appwrite/appwrite/pull/7843
|
||||
* Fix: Python failing builds by @Meldiron in https://github.com/appwrite/appwrite/pull/8078
|
||||
* Fix shared project delete by @abnegate in https://github.com/appwrite/appwrite/pull/8142
|
||||
* Fix TextMagic class name by @stnguyen90 in https://github.com/appwrite/appwrite/pull/8132
|
||||
* Prevent functions domain and subdomain to be added as custom domain by @lohanidamodar in https://github.com/appwrite/appwrite/pull/7933
|
||||
* Fix don't publish max users exceed by @vermakhushboo in https://github.com/appwrite/appwrite/pull/8067
|
||||
* Fix invalid cache document id by @stnguyen90 in https://github.com/appwrite/appwrite/pull/8183
|
||||
* Fix not hiding tokens for clients via realtime by @abnegate in https://github.com/appwrite/appwrite/pull/7870
|
||||
|
||||
### Miscellaneous
|
||||
* Upload 400s to separate error logger by @PineappleIOnic in https://github.com/appwrite/appwrite/pull/7784
|
||||
* Admin mode use teamInternalId by @lohanidamodar in https://github.com/appwrite/appwrite/pull/7835
|
||||
* Chore: update avatars API by @christyjacob4 in https://github.com/appwrite/appwrite/pull/7840
|
||||
* Use internal ids for query by @lohanidamodar in https://github.com/appwrite/appwrite/pull/7838
|
||||
* Remove cloud related scripts by @shimonewman in https://github.com/appwrite/appwrite/pull/7414
|
||||
* Update VCS Comment by @vermakhushboo in https://github.com/appwrite/appwrite/pull/7854
|
||||
* Transaction and reconnection fixes by @fogelito in https://github.com/appwrite/appwrite/pull/7877
|
||||
* Feat configurable collections by @christyjacob4 in https://github.com/appwrite/appwrite/pull/7882
|
||||
* Remove var_dump calls by @stnguyen90 in https://github.com/appwrite/appwrite/pull/7884
|
||||
* Storage DO adapter http version by @lohanidamodar in https://github.com/appwrite/appwrite/pull/7905
|
||||
* Update executor version by @vermakhushboo in https://github.com/appwrite/appwrite/pull/7910
|
||||
* Comment timer tick by @vermakhushboo in https://github.com/appwrite/appwrite/pull/7911
|
||||
* Update db for relationships and object as array attributes fixes by @abnegate in https://github.com/appwrite/appwrite/pull/7917
|
||||
* Bump executor version to 0.5.1 by @vermakhushboo in https://github.com/appwrite/appwrite/pull/7925
|
||||
* Update database by @abnegate in https://github.com/appwrite/appwrite/pull/7937
|
||||
* Reclaim only current connection by @abnegate in https://github.com/appwrite/appwrite/pull/7941
|
||||
* Match memberships on internal ID by @abnegate in https://github.com/appwrite/appwrite/pull/7953
|
||||
* Chore: queue retry update by @shimonewman in https://github.com/appwrite/appwrite/pull/7991
|
||||
* Chore task addition by @shimonewman in https://github.com/appwrite/appwrite/pull/7992
|
||||
* Databases.php collection not found by @fogelito in https://github.com/appwrite/appwrite/pull/7341
|
||||
* Update database by @abnegate in https://github.com/appwrite/appwrite/pull/8036
|
||||
* Feat upgrade db by @abnegate in https://github.com/appwrite/appwrite/pull/8050
|
||||
* Handle string error codes by @fogelito in https://github.com/appwrite/appwrite/pull/7878
|
||||
* Migration Logging Improvements by @PineappleIOnic in https://github.com/appwrite/appwrite/pull/8057
|
||||
* Remove logger code from avatars.php by @vermakhushboo in https://github.com/appwrite/appwrite/pull/8065
|
||||
* Update chunk size to 7 MB by @vermakhushboo in https://github.com/appwrite/appwrite/pull/8060
|
||||
* Shared tables support by @abnegate in https://github.com/appwrite/appwrite/pull/7206
|
||||
* Ensure namespace is set if override equals shared tables by @abnegate in https://github.com/appwrite/appwrite/pull/8091
|
||||
* Update database by @abnegate in https://github.com/appwrite/appwrite/pull/8095
|
||||
* Disable sending realtime stats by @stnguyen90 in https://github.com/appwrite/appwrite/pull/8104
|
||||
* Increase chunk size to 10 MB by @vermakhushboo in https://github.com/appwrite/appwrite/pull/8099
|
||||
* Update db by @abnegate in https://github.com/appwrite/appwrite/pull/8113
|
||||
* Update executor image name to exc-1 by @vermakhushboo in https://github.com/appwrite/appwrite/pull/8123
|
||||
* Catch DB errors on delete by @abnegate in https://github.com/appwrite/appwrite/pull/8143
|
||||
* Update Logger and migrations, implement sampler. by @PineappleIOnic in https://github.com/appwrite/appwrite/pull/8146
|
||||
* Increase shared tables projects by @abnegate in https://github.com/appwrite/appwrite/pull/8161
|
||||
* Feat: improve cold start error, merge to cloud by @loks0n in https://github.com/appwrite/appwrite/pull/8165
|
||||
* Add tests for scheduled functions by @vermakhushboo in https://github.com/appwrite/appwrite/pull/8164
|
||||
* Remove throw PdoException in Error hook by @fogelito in https://github.com/appwrite/appwrite/pull/8169
|
||||
* Refactor localdevice injection by @byawitz in https://github.com/appwrite/appwrite/pull/8173
|
||||
* Usage sms per country code count by @shimonewman in https://github.com/appwrite/appwrite/pull/7592
|
||||
* GetEnv on worker.php by @shimonewman in https://github.com/appwrite/appwrite/pull/8026
|
||||
* Feat get env by @shimonewman in https://github.com/appwrite/appwrite/pull/8180
|
||||
* Chore: remove compose version by @loks0n in https://github.com/appwrite/appwrite/pull/8148
|
||||
* Chore update executor host default var by @abnegate in https://github.com/appwrite/appwrite/pull/8190
|
||||
* Wrap realtime stats in an edition check by @abnegate in https://github.com/appwrite/appwrite/pull/8192
|
||||
* Update executor image name by @vermakhushboo in https://github.com/appwrite/appwrite/pull/8147
|
||||
* Feat: improve header demo values by @loks0n in https://github.com/appwrite/appwrite/pull/8089
|
||||
* Feat: add warning header by @loks0n in https://github.com/appwrite/appwrite/pull/8063
|
||||
|
||||
# Version 1.5.6
|
||||
## What's Changed
|
||||
|
||||
### Notable Changes
|
||||
|
||||
* Prevent functions domain to be used as custom domain in [#7934](https://github.com/appwrite/appwrite/pull/7934)
|
||||
|
||||
### Fixes
|
||||
|
||||
* Fix auth mode check in [#7980](https://github.com/appwrite/appwrite/pull/7980)
|
||||
* Fix templates not copying hidden files in [#7610](https://github.com/appwrite/appwrite/pull/7610)
|
||||
* Use `resourceInternalId` for Querying Function Deployments in [#8038](https://github.com/appwrite/appwrite/pull/8038)
|
||||
* Fix Email OTP not verifying account in [#8084](https://github.com/appwrite/appwrite/pull/8084)
|
||||
* Fix MFA email verification code font in [#8082](https://github.com/appwrite/appwrite/pull/8082)
|
||||
* Don't kick user and require verification after enabling MFA in [#8081](https://github.com/appwrite/appwrite/pull/8081)
|
||||
* Fix typo in credit-cards.php credit card image filename in [#8074](https://github.com/appwrite/appwrite/pull/8074)
|
||||
* Fix Deprecated Warning in Doctor.php in [#8105](https://github.com/appwrite/appwrite/pull/8105)
|
||||
* Set limit to retrieve all stats for the usage range in [#8117](https://github.com/appwrite/appwrite/pull/8117)
|
||||
* Fix email used for name when user is created via Apple OAuth2 in [#8102](https://github.com/appwrite/appwrite/pull/8102)
|
||||
|
||||
### Miscellaneous
|
||||
|
||||
* Add GitHub action to close stale issues in [#7927](https://github.com/appwrite/appwrite/pull/7927)
|
||||
* Document the standard we follow for country codes in [#8014](https://github.com/appwrite/appwrite/pull/8014)
|
||||
* Add OSV Scanner for vulnerability scans in [#6506](https://github.com/appwrite/appwrite/pull/6506)
|
||||
* Fix stale action close reason in [#8046](https://github.com/appwrite/appwrite/pull/8046)
|
||||
* Add OSV Scanner for vulnerability scans in [#8021](https://github.com/appwrite/appwrite/pull/8021)
|
||||
* Fix some typos in comments in [#7993](https://github.com/appwrite/appwrite/pull/7993)
|
||||
* Replace missing domain paths in README.md in [#8049](https://github.com/appwrite/appwrite/pull/8049)
|
||||
* Add the React Native SDK in [#7776](https://github.com/appwrite/appwrite/pull/7776)
|
||||
* Bump database in [#8080](https://github.com/appwrite/appwrite/pull/8080)
|
||||
* Add documentation for metrics in [#8088](https://github.com/appwrite/appwrite/pull/8088)
|
||||
* Add new country Palestine with its translations in [#8031](https://github.com/appwrite/appwrite/pull/8031)
|
||||
* Update users create token description in [#8129](https://github.com/appwrite/appwrite/pull/8129)
|
||||
* Bump dependencies in [#8130](https://github.com/appwrite/appwrite/pull/8130)
|
||||
|
||||
# Version 1.5.5
|
||||
## What's Changed
|
||||
### Notable changes
|
||||
|
|
|
@ -29,7 +29,7 @@ ENV VITE_APPWRITE_GROWTH_ENDPOINT=$VITE_APPWRITE_GROWTH_ENDPOINT
|
|||
RUN npm ci
|
||||
RUN npm run build
|
||||
|
||||
FROM appwrite/base:0.9.0 as final
|
||||
FROM appwrite/base:0.9.1 as final
|
||||
|
||||
LABEL maintainer="team@appwrite.io"
|
||||
|
||||
|
|
|
@ -67,7 +67,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.5.5
|
||||
appwrite/appwrite:1.5.7
|
||||
```
|
||||
|
||||
### Windows
|
||||
|
@ -79,7 +79,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.5.5
|
||||
appwrite/appwrite:1.5.7
|
||||
```
|
||||
|
||||
#### PowerShell
|
||||
|
@ -89,7 +89,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.5.5
|
||||
appwrite/appwrite:1.5.7
|
||||
```
|
||||
|
||||
运行后,可以在浏览器上访问 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.5.5
|
||||
appwrite/appwrite:1.5.7
|
||||
```
|
||||
|
||||
### 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.5.5
|
||||
appwrite/appwrite:1.5.7
|
||||
```
|
||||
|
||||
#### 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.5.5
|
||||
appwrite/appwrite:1.5.7
|
||||
```
|
||||
|
||||
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.
|
||||
|
|
45
app/cli.php
45
app/cli.php
|
@ -15,6 +15,7 @@ use Utopia\Config\Config;
|
|||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\DSN\DSN;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Platform\Service;
|
||||
use Utopia\Pools\Group;
|
||||
|
@ -98,25 +99,53 @@ CLI::setResource('getProjectDB', function (Group $pools, Database $dbForConsole,
|
|||
return $dbForConsole;
|
||||
}
|
||||
|
||||
$databaseName = $project->getAttribute('database');
|
||||
try {
|
||||
$dsn = new DSN($project->getAttribute('database'));
|
||||
} catch (\InvalidArgumentException) {
|
||||
// TODO: Temporary until all projects are using shared tables
|
||||
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
|
||||
}
|
||||
|
||||
if (isset($databases[$dsn->getHost()])) {
|
||||
$database = $databases[$dsn->getHost()];
|
||||
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
if (isset($databases[$databaseName])) {
|
||||
$database = $databases[$databaseName];
|
||||
$database->setNamespace('_' . $project->getInternalId());
|
||||
return $database;
|
||||
}
|
||||
|
||||
$dbAdapter = $pools
|
||||
->get($databaseName)
|
||||
->get($dsn->getHost())
|
||||
->pop()
|
||||
->getResource();
|
||||
|
||||
$database = new Database($dbAdapter, $cache);
|
||||
|
||||
$databases[$databaseName] = $database;
|
||||
$databases[$dsn->getHost()] = $database;
|
||||
|
||||
if ($dsn->getHost() === System::getEnv('_APP_DATABASE_SHARED_TABLES', '')) {
|
||||
$database
|
||||
->setSharedTables(true)
|
||||
->setTenant($project->getInternalId())
|
||||
->setNamespace($dsn->getParam('namespace'));
|
||||
} else {
|
||||
$database
|
||||
->setSharedTables(false)
|
||||
->setTenant(null)
|
||||
->setNamespace('_' . $project->getInternalId());
|
||||
}
|
||||
|
||||
$database
|
||||
->setNamespace('_' . $project->getInternalId())
|
||||
->setMetadata('host', \gethostname())
|
||||
->setMetadata('project', $project->getId());
|
||||
|
||||
|
@ -173,7 +202,7 @@ CLI::setResource('logError', function (Registry $register) {
|
|||
}, ['register']);
|
||||
|
||||
$platform = new Appwrite();
|
||||
$platform->init(Service::TYPE_CLI);
|
||||
$platform->init(Service::TYPE_TASK);
|
||||
|
||||
$cli = $platform->getCli();
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ $commonCollections = [
|
|||
'$id' => ID::custom('_key_email'),
|
||||
'type' => Database::INDEX_UNIQUE,
|
||||
'attributes' => ['email'],
|
||||
'lengths' => [320],
|
||||
'lengths' => [256],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
@ -996,7 +996,7 @@ $commonCollections = [
|
|||
'$id' => ID::custom('_key_provider_providerUid'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['provider', 'providerUid'],
|
||||
'lengths' => [100, 100],
|
||||
'lengths' => [128, 128],
|
||||
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
@ -1120,14 +1120,14 @@ $commonCollections = [
|
|||
'$id' => ID::custom('_key_userInternalId_provider_providerUid'),
|
||||
'type' => Database::INDEX_UNIQUE,
|
||||
'attributes' => ['userInternalId', 'provider', 'providerUid'],
|
||||
'lengths' => [Database::LENGTH_KEY, 100, 385],
|
||||
'lengths' => [11, 128, 128],
|
||||
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_provider_providerUid'),
|
||||
'type' => Database::INDEX_UNIQUE,
|
||||
'attributes' => ['provider', 'providerUid'],
|
||||
'lengths' => [100, 640],
|
||||
'lengths' => [128, 128],
|
||||
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
@ -1148,7 +1148,7 @@ $commonCollections = [
|
|||
'$id' => ID::custom('_key_provider'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['provider'],
|
||||
'lengths' => [100],
|
||||
'lengths' => [128],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
@ -3079,7 +3079,7 @@ $projectCollections = array_merge([
|
|||
'$id' => ID::custom('_key_name'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [768],
|
||||
'lengths' => [256],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
@ -3128,7 +3128,7 @@ $projectCollections = array_merge([
|
|||
'$id' => ID::custom('_key_runtime'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['runtime'],
|
||||
'lengths' => [768],
|
||||
'lengths' => [64],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
@ -3868,14 +3868,14 @@ $projectCollections = array_merge([
|
|||
'$id' => ID::custom('_key_trigger'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['trigger'],
|
||||
'lengths' => [128],
|
||||
'lengths' => [32],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_status'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['status'],
|
||||
'lengths' => [128],
|
||||
'lengths' => [32],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
@ -5865,14 +5865,14 @@ $bucketCollections = [
|
|||
'$id' => ID::custom('_key_name'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['name'],
|
||||
'lengths' => [768],
|
||||
'lengths' => [256],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('_key_signature'),
|
||||
'type' => Database::INDEX_KEY,
|
||||
'attributes' => ['signature'],
|
||||
'lengths' => [768],
|
||||
'lengths' => [256],
|
||||
'orders' => [Database::ORDER_ASC],
|
||||
],
|
||||
[
|
||||
|
|
|
@ -134,7 +134,7 @@ return [
|
|||
Exception::USER_COUNT_EXCEEDED => [
|
||||
'name' => Exception::USER_COUNT_EXCEEDED,
|
||||
'description' => 'The current project has exceeded the maximum number of users. Please check your user limit in the Appwrite console.',
|
||||
'code' => 501,
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::USER_CONSOLE_COUNT_EXCEEDED => [
|
||||
'name' => Exception::USER_CONSOLE_COUNT_EXCEEDED,
|
||||
|
@ -524,6 +524,11 @@ return [
|
|||
'description' => 'Entrypoint for your Appwrite Function is missing. Please specify it when making deployment or update the entrypoint under your function\'s "Settings" > "Configuration" > "Entrypoint".',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::FUNCTION_SYNCHRONOUS_TIMEOUT => [
|
||||
'name' => Exception::FUNCTION_SYNCHRONOUS_TIMEOUT,
|
||||
'description' => 'Synchronous function execution timed out. Use asynchronous execution instead, or ensure the execution duration doesn\'t exceed 30 seconds.',
|
||||
'code' => 408,
|
||||
],
|
||||
|
||||
/** Builds */
|
||||
Exception::BUILD_NOT_FOUND => [
|
||||
|
@ -678,6 +683,11 @@ return [
|
|||
'description' => 'The attribute type is invalid.',
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::RELATIONSHIP_VALUE_INVALID => [
|
||||
'name' => Exception::RELATIONSHIP_VALUE_INVALID,
|
||||
'description' => 'The relationship value is invalid.',
|
||||
'code' => 400,
|
||||
],
|
||||
|
||||
/** Indexes */
|
||||
Exception::INDEX_NOT_FOUND => [
|
||||
|
@ -720,7 +730,7 @@ return [
|
|||
Exception::PROJECT_PROVIDER_UNSUPPORTED => [
|
||||
'name' => Exception::PROJECT_PROVIDER_UNSUPPORTED,
|
||||
'description' => 'The chosen OAuth provider is unsupported. Please check the <a href="/docs/client/account?sdk=web-default#accountCreateOAuth2Session">Create OAuth2 Session docs</a> for the complete list of supported OAuth providers.',
|
||||
'code' => 501,
|
||||
'code' => 400,
|
||||
],
|
||||
Exception::PROJECT_INVALID_SUCCESS_URL => [
|
||||
'name' => Exception::PROJECT_INVALID_SUCCESS_URL,
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<table border="0" cellspacing="0" cellpadding="0" style="padding-top: 10px; padding-bottom: 10px; display: inline-block;">
|
||||
<tr>
|
||||
<td align="center" style="border-radius: 8px; background-color: #ffffff;">
|
||||
<p style="font-size: 24px; text-indent: 18px; letter-spacing: 18px; font-family: Inter; color: #414146; text-decoration: none; border-radius: 8px; padding: 24px 12px; border: 1px solid #EDEDF0; display: inline-block; font-weight: bold; ">{{otp}}</p>
|
||||
<p style="font-size: 24px; text-indent: 18px; letter-spacing: 18px; font-family: 'Inter', sans-serif; color: #414146; text-decoration: none; border-radius: 8px; padding: 24px 12px; border: 1px solid #EDEDF0; display: inline-block; font-weight: bold; ">{{otp}}</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroasië",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "غرينادا",
|
||||
"countries.gt": "غواتيمالا",
|
||||
"countries.gy": "غيانا",
|
||||
"countries.hk": "هونغ كونغ",
|
||||
"countries.hn": "هندوراس",
|
||||
"countries.hr": "كرواتيا",
|
||||
"countries.ht": "هايتي",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "গ্ৰেনাডা",
|
||||
"countries.gt": "গুয়াতেমালা",
|
||||
"countries.gy": "গায়ানা",
|
||||
"countries.hk": "হং কং",
|
||||
"countries.hn": "হণ্ডুৰাছ",
|
||||
"countries.hr": "ক্ৰোৱেছিয়া",
|
||||
"countries.ht": "হাইতি",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Qrenada",
|
||||
"countries.gt": "Qvatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Honq Konq",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Xorvatiya",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Грэнада",
|
||||
"countries.gt": "Гватэмала",
|
||||
"countries.gy": "Гаяна",
|
||||
"countries.hk": "Гонконг",
|
||||
"countries.hn": "Гандурас",
|
||||
"countries.hr": "Харватыя",
|
||||
"countries.ht": "Гаіці",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Гренада",
|
||||
"countries.gt": "Гватемала",
|
||||
"countries.gy": "Гвиана",
|
||||
"countries.hk": "Хонг Конг",
|
||||
"countries.hn": "Хондурас",
|
||||
"countries.hr": "Хърватия",
|
||||
"countries.ht": "Хаити",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ग्रेनाडा",
|
||||
"countries.gt": "ग्वाटेमाला",
|
||||
"countries.gy": "गयाना",
|
||||
"countries.hk": "हांगकांग",
|
||||
"countries.hn": "होंडुरस",
|
||||
"countries.hr": "क्रोएशिया",
|
||||
"countries.ht": "हैती",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "গ্রেনাডা",
|
||||
"countries.gt": "গুয়াতেমালা",
|
||||
"countries.gy": "গায়ানা",
|
||||
"countries.hk": "হংকং",
|
||||
"countries.hn": "হন্ডুরাস",
|
||||
"countries.hr": "ক্রোয়েশিয়া",
|
||||
"countries.ht": "হাইতি",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Gvajana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Hrvatska",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Granada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guaiana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Hondures",
|
||||
"countries.hr": "Croàcia",
|
||||
"countries.ht": "Haití",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorvatsko",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatien",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatien",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Γρενάδα",
|
||||
"countries.gt": "Γουατεμάλα",
|
||||
"countries.gy": "Γουιάνα",
|
||||
"countries.hk": "Χονγκ Κονγκ",
|
||||
"countries.hn": "Ονδούρα",
|
||||
"countries.hr": "Κροατία",
|
||||
"countries.ht": "Αϊτή",
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Granada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guayana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croacia",
|
||||
"countries.ht": "Haití",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "گرنادا",
|
||||
"countries.gt": "گواتمالا",
|
||||
"countries.gy": "گویان",
|
||||
"countries.hk": "هنگ کنگ",
|
||||
"countries.hn": "هندوراس",
|
||||
"countries.hr": "کرواسی",
|
||||
"countries.ht": "هائیتی",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Gujana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenade",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyane",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatie",
|
||||
"countries.ht": "Haïti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Greanáda",
|
||||
"countries.gt": "Guatamala",
|
||||
"countries.gy": "An Ghuáin",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Hondúras",
|
||||
"countries.hr": "An Chróit",
|
||||
"countries.ht": "Háítí",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ગ્રેનાડા",
|
||||
"countries.gt": "ગ્વાટેમાલા",
|
||||
"countries.gy": "ગુયાના",
|
||||
"countries.hk": "હોંગ કોંગ",
|
||||
"countries.hn": "હોન્ડુરાસ",
|
||||
"countries.hr": "ક્રોએશિયા",
|
||||
"countries.ht": "હૈતી",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "גרנדה",
|
||||
"countries.gt": "גואטמלה",
|
||||
"countries.gy": "גיאנה",
|
||||
"countries.hk": "הונג קונג",
|
||||
"countries.hn": "הונדורס",
|
||||
"countries.hr": "קרואטיה",
|
||||
"countries.ht": "האיטי",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ग्रेनाडा",
|
||||
"countries.gt": "ग्वाटेमाला",
|
||||
"countries.gy": "गयाना",
|
||||
"countries.hk": "हांग कांग",
|
||||
"countries.hn": "होंडुरस",
|
||||
"countries.hr": "क्रोएशिया",
|
||||
"countries.ht": "हैती",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gvatemala",
|
||||
"countries.gy": "Gvajana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Hrvatska",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Horvátország",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Գրենադա",
|
||||
"countries.gt": "Գվատեմալա",
|
||||
"countries.gy": "Գայանա",
|
||||
"countries.hk": "Հոնգ Կոնգ",
|
||||
"countries.hn": "Գոնդուրաս",
|
||||
"countries.hr": "Խորվաթիա",
|
||||
"countries.ht": "Հաիթի",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroasia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gvatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Hondúras",
|
||||
"countries.hr": "Króatía",
|
||||
"countries.ht": "Haítí",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croazia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "グレナダ",
|
||||
"countries.gt": "グアテマラ",
|
||||
"countries.gy": "ガイアナ",
|
||||
"countries.hk": "香港",
|
||||
"countries.hn": "ホンジュラス",
|
||||
"countries.hr": "クロアチア",
|
||||
"countries.ht": "ハイチ",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ហ្គ្រេណាដា",
|
||||
"countries.gt": "ហ្គាតេម៉ាឡា",
|
||||
"countries.gy": "ហ្គីយ៉ាណា",
|
||||
"countries.hk": "ហុងកុង",
|
||||
"countries.hn": "ហុងឌូរ៉ាស",
|
||||
"countries.hr": "ក្រូអាត",
|
||||
"countries.ht": "ហៃទី",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ಗ್ರೆನಡಾ",
|
||||
"countries.gt": "ಗ್ವಾಟೆಮಾಲಾ",
|
||||
"countries.gy": "ಗಯಾನಾ",
|
||||
"countries.hk": "ಹಾಂಗ್ ಕಾಂಗ್",
|
||||
"countries.hn": "ಹೊಂಡುರಾಸ್",
|
||||
"countries.hr": "ಕ್ರೊಯೇಷಿಯಾ",
|
||||
"countries.ht": "ಹೈಟಿ",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "그레나다",
|
||||
"countries.gt": "과테말라",
|
||||
"countries.gy": "기아나",
|
||||
"countries.hk": "홍콩",
|
||||
"countries.hn": "온두라스",
|
||||
"countries.hr": "크로아티아",
|
||||
"countries.ht": "아이티",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
@ -250,4 +251,4 @@
|
|||
"emails.certificate.thanks": "Gratias",
|
||||
"emails.certificate.signature": "team {{project}}",
|
||||
"sms.verification.body": "{{secret}}"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gvatemala",
|
||||
"countries.gy": "Gajana",
|
||||
"countries.hk": "Honkongas",
|
||||
"countries.hn": "Hondūras",
|
||||
"countries.hr": "Kroatija",
|
||||
"countries.ht": "Haitis",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gvatemala",
|
||||
"countries.gy": "Gajāna",
|
||||
"countries.hk": "Honkonga",
|
||||
"countries.hn": "Hondurasa",
|
||||
"countries.hr": "Horvātija",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ഗ്രെനാഡ",
|
||||
"countries.gt": "ഗ്വാട്ടിമാല",
|
||||
"countries.gy": "ഗയാന",
|
||||
"countries.hk": "ഹോങ്കോങ്",
|
||||
"countries.hn": "ഹോണ്ടുറാസ്",
|
||||
"countries.hr": "ക്രോയേഷ്യ",
|
||||
"countries.ht": "ഹെയ്തി",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ग्रेनाडा",
|
||||
"countries.gt": "ग्वाटेमाला",
|
||||
"countries.gy": "गुयाना",
|
||||
"countries.hk": "हाँगकांग",
|
||||
"countries.hn": "होंडुरास",
|
||||
"countries.hr": "क्रोएशिया",
|
||||
"countries.ht": "हैती",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Granada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ग्रेनेडा",
|
||||
"countries.gt": "ग्वाटेमाला",
|
||||
"countries.gy": "गुयाना",
|
||||
"countries.hk": "हाँगकाँग",
|
||||
"countries.hn": "होन्डुरस",
|
||||
"countries.hr": "क्रोएशिया",
|
||||
"countries.ht": "हैती",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hongkong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatië",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ଗ୍ରେନାଡା",
|
||||
"countries.gt": "ଗୁଆଟେମାଲା",
|
||||
"countries.gy": "ଗୁଇନ୍ଦା",
|
||||
"countries.hk": "ହଂ କଙ୍ଗ",
|
||||
"countries.hn": "ହୋଣ୍ଡୁରାସ୍",
|
||||
"countries.hr": "କ୍ରୋଏସିଆ",
|
||||
"countries.ht": "ହାଇତି",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ਗ੍ਰੇਨਾਡਾ",
|
||||
"countries.gt": "ਗੁਆਟੇਮਾਲਾ",
|
||||
"countries.gy": "ਗੇਆਨਾ",
|
||||
"countries.hk": "ਹਾਂਗ ਕਾਂਗ",
|
||||
"countries.hn": "ਹੌਂਡੂਰਸ",
|
||||
"countries.hr": "ਕਰੋਸ਼ੀਆ",
|
||||
"countries.ht": "ਹੈਤੀ",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gwatemala",
|
||||
"countries.gy": "Gujana",
|
||||
"countries.hk": "Hongkong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorwacja",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Granada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guiana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croácia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Granada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guiana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croácia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croația",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Гренада",
|
||||
"countries.gt": "Гватемала",
|
||||
"countries.gy": "Гайана",
|
||||
"countries.hk": "Гонконг",
|
||||
"countries.hn": "Гондурас",
|
||||
"countries.hr": "Хорватия",
|
||||
"countries.ht": "Гаити",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ग्रेनेडा",
|
||||
"countries.gt": "ग्वाटेमाला",
|
||||
"countries.gy": "गुयाना",
|
||||
"countries.hk": "हांगकांग",
|
||||
"countries.hn": "होंडुरस्",
|
||||
"countries.hr": "क्रोएशिया",
|
||||
"countries.ht": "हैती",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "گرينڊا",
|
||||
"countries.gt": "گٽيمالا",
|
||||
"countries.gy": "گيانا",
|
||||
"countries.hk": "هانگ کانگ",
|
||||
"countries.hn": "هونڊرس",
|
||||
"countries.hr": "ڪوريٽيا",
|
||||
"countries.ht": "هيٽي",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "ග්රෙනාඩා",
|
||||
"countries.gt": "ග්වාතමාලාව",
|
||||
"countries.gy": "ගයනා",
|
||||
"countries.hk": "හොංකොං",
|
||||
"countries.hn": "හොන්ඩුරාස්",
|
||||
"countries.hr": "ක්රොඒෂියාව",
|
||||
"countries.ht": "හයිටි",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hongkong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Chorvátsko",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Gvatemala",
|
||||
"countries.gy": "Gvajana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Hrvaška",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guajana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroacia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroatien",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "கிரெனடா",
|
||||
"countries.gt": "குவாத்தமாலா",
|
||||
"countries.gy": "கயானா",
|
||||
"countries.hk": "ஹாங்காங்",
|
||||
"countries.hn": "ஹொண்டூராஸ்",
|
||||
"countries.hr": "குரோவாசியா",
|
||||
"countries.ht": "ஹைத்தி",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "గ్రెనడా",
|
||||
"countries.gt": "గ్వాటెమాల",
|
||||
"countries.gy": "గయానా",
|
||||
"countries.hk": "హాంగ్ కొంగ",
|
||||
"countries.hn": "హోండురాస్",
|
||||
"countries.hr": "క్రొయేషియా",
|
||||
"countries.ht": "హైతీ",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "เกรเนดา",
|
||||
"countries.gt": "กัวเตมาลา",
|
||||
"countries.gy": "กายอานา",
|
||||
"countries.hk": "ฮ่องกง",
|
||||
"countries.hn": "ฮอนดูรัส",
|
||||
"countries.hr": "โครเอเชีย",
|
||||
"countries.ht": "ไฮติ",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guwatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Kroasya",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Hırvatistan",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Гренада",
|
||||
"countries.gt": "Гватемала",
|
||||
"countries.gy": "Гайана",
|
||||
"countries.hk": "Гонконг",
|
||||
"countries.hn": "Гондурас",
|
||||
"countries.hr": "Хорватія",
|
||||
"countries.ht": "Гаїті",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "گریناڈا",
|
||||
"countries.gt": "گوئٹے مالا",
|
||||
"countries.gy": "گیانا",
|
||||
"countries.hk": "ہانگ کانگ",
|
||||
"countries.hn": "ہونڈوراس",
|
||||
"countries.hr": "کروشیا",
|
||||
"countries.ht": "ہیٹی",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "Grenada",
|
||||
"countries.gt": "Guatemala",
|
||||
"countries.gy": "Guyana",
|
||||
"countries.hk": "Hong Kong",
|
||||
"countries.hn": "Honduras",
|
||||
"countries.hr": "Croatia",
|
||||
"countries.ht": "Haiti",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "格林纳达",
|
||||
"countries.gt": "危地马拉",
|
||||
"countries.gy": "圭亚那",
|
||||
"countries.hk": "香港",
|
||||
"countries.hn": "洪都拉斯",
|
||||
"countries.hr": "克罗地亚",
|
||||
"countries.ht": "海地",
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"countries.gd": "格瑞那達",
|
||||
"countries.gt": "瓜地馬拉",
|
||||
"countries.gy": "蓋亞那",
|
||||
"countries.hk": "香港",
|
||||
"countries.hn": "宏都拉斯",
|
||||
"countries.hr": "克羅埃西亞",
|
||||
"countries.ht": "海地",
|
||||
|
|
|
@ -15,7 +15,7 @@ return [
|
|||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Web',
|
||||
'version' => '14.0.0',
|
||||
'version' => '15.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-web',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -63,7 +63,7 @@ return [
|
|||
[
|
||||
'key' => 'flutter',
|
||||
'name' => 'Flutter',
|
||||
'version' => '12.0.3',
|
||||
'version' => '12.0.4',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-flutter',
|
||||
'package' => 'https://pub.dev/packages/appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -81,7 +81,7 @@ return [
|
|||
[
|
||||
'key' => 'apple',
|
||||
'name' => 'Apple',
|
||||
'version' => '5.0.0',
|
||||
'version' => '6.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-apple',
|
||||
'enabled' => true,
|
||||
|
@ -116,7 +116,7 @@ return [
|
|||
[
|
||||
'key' => 'android',
|
||||
'name' => 'Android',
|
||||
'version' => '5.0.0',
|
||||
'version' => '5.1.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-android',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-android',
|
||||
'enabled' => true,
|
||||
|
@ -135,6 +135,24 @@ return [
|
|||
'Java' => 'java',
|
||||
],
|
||||
],
|
||||
[
|
||||
'key' => 'react-native',
|
||||
'name' => 'React Native',
|
||||
'version' => '0.4.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-react-native',
|
||||
'package' => 'https://npmjs.com/package/react-native-appwrite',
|
||||
'enabled' => true,
|
||||
'beta' => true,
|
||||
'dev' => false,
|
||||
'hidden' => false,
|
||||
'family' => APP_PLATFORM_CLIENT,
|
||||
'prism' => 'javascript',
|
||||
'source' => \realpath(__DIR__ . '/../sdks/client-react-native'),
|
||||
'gitUrl' => 'git@github.com:appwrite/sdk-for-react-native.git',
|
||||
'gitRepoName' => 'sdk-for-react-native',
|
||||
'gitUserName' => 'appwrite',
|
||||
'gitBranch' => 'dev',
|
||||
],
|
||||
[
|
||||
'key' => 'graphql',
|
||||
'name' => 'GraphQL',
|
||||
|
@ -185,7 +203,7 @@ return [
|
|||
[
|
||||
'key' => 'web',
|
||||
'name' => 'Console',
|
||||
'version' => '0.6.1',
|
||||
'version' => '0.6.3',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-console',
|
||||
'package' => '',
|
||||
'enabled' => true,
|
||||
|
@ -203,7 +221,7 @@ return [
|
|||
[
|
||||
'key' => 'cli',
|
||||
'name' => 'Command Line',
|
||||
'version' => '5.0.2',
|
||||
'version' => '5.0.5',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-cli',
|
||||
'package' => 'https://www.npmjs.com/package/appwrite-cli',
|
||||
'enabled' => true,
|
||||
|
@ -231,7 +249,7 @@ return [
|
|||
[
|
||||
'key' => 'nodejs',
|
||||
'name' => 'Node.js',
|
||||
'version' => '12.0.1',
|
||||
'version' => '13.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-node',
|
||||
'package' => 'https://www.npmjs.com/package/node-appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -249,7 +267,7 @@ return [
|
|||
[
|
||||
'key' => 'deno',
|
||||
'name' => 'Deno',
|
||||
'version' => '10.0.1',
|
||||
'version' => '11.0.0',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-deno',
|
||||
'package' => 'https://deno.land/x/appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -267,7 +285,7 @@ return [
|
|||
[
|
||||
'key' => 'php',
|
||||
'name' => 'PHP',
|
||||
'version' => '11.0.1',
|
||||
'version' => '11.0.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-php',
|
||||
'package' => 'https://packagist.org/packages/appwrite/appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -285,7 +303,7 @@ return [
|
|||
[
|
||||
'key' => 'python',
|
||||
'name' => 'Python',
|
||||
'version' => '5.0.2',
|
||||
'version' => '5.0.3',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-python',
|
||||
'package' => 'https://pypi.org/project/appwrite/',
|
||||
'enabled' => true,
|
||||
|
@ -303,7 +321,7 @@ return [
|
|||
[
|
||||
'key' => 'ruby',
|
||||
'name' => 'Ruby',
|
||||
'version' => '11.0.1',
|
||||
'version' => '11.0.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-ruby',
|
||||
'package' => 'https://rubygems.org/gems/appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -321,7 +339,7 @@ return [
|
|||
[
|
||||
'key' => 'go',
|
||||
'name' => 'Go',
|
||||
'version' => '4.0.0',
|
||||
'version' => '4.0.1',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-go',
|
||||
'package' => '',
|
||||
'enabled' => false,
|
||||
|
@ -339,7 +357,7 @@ return [
|
|||
[
|
||||
'key' => 'java',
|
||||
'name' => 'Java',
|
||||
'version' => '4.0.1',
|
||||
'version' => '4.0.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-java',
|
||||
'package' => '',
|
||||
'enabled' => false,
|
||||
|
@ -357,7 +375,7 @@ return [
|
|||
[
|
||||
'key' => 'dotnet',
|
||||
'name' => '.NET',
|
||||
'version' => '0.8.1',
|
||||
'version' => '0.8.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
|
||||
'package' => 'https://www.nuget.org/packages/Appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -375,7 +393,7 @@ return [
|
|||
[
|
||||
'key' => 'dart',
|
||||
'name' => 'Dart',
|
||||
'version' => '11.0.2',
|
||||
'version' => '11.0.3',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-dart',
|
||||
'package' => 'https://pub.dev/packages/dart_appwrite',
|
||||
'enabled' => true,
|
||||
|
@ -393,7 +411,7 @@ return [
|
|||
[
|
||||
'key' => 'kotlin',
|
||||
'name' => 'Kotlin',
|
||||
'version' => '5.0.1',
|
||||
'version' => '5.0.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-kotlin',
|
||||
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin',
|
||||
'enabled' => true,
|
||||
|
@ -415,7 +433,7 @@ return [
|
|||
[
|
||||
'key' => 'swift',
|
||||
'name' => 'Swift',
|
||||
'version' => '5.0.1',
|
||||
'version' => '5.0.2',
|
||||
'url' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'package' => 'https://github.com/appwrite/sdk-for-swift',
|
||||
'enabled' => true,
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -162,13 +162,31 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_SYSTEM_SECURITY_EMAIL_ADDRESS',
|
||||
'description' => 'This is the email address used to issue SSL certificates for custom domains or the user agent in your webhooks payload.',
|
||||
'description' => 'Deprecated since 1.5.1 use _APP_EMAIL_SECURITY and _APP_EMAIL_CERTIFICATES instead',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => 'certs@appwrite.io',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_EMAIL_SECURITY',
|
||||
'description' => 'This is the email address used as the user agent in your webhooks payload.',
|
||||
'introduction' => '1.5.1',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_EMAIL_CERTIFICATES',
|
||||
'description' => 'This is the email address used to issue SSL certificates for custom domains',
|
||||
'introduction' => '1.5.1',
|
||||
'default' => '',
|
||||
'required' => true,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_USAGE_STATS',
|
||||
'description' => 'This variable allows you to disable the collection and displaying of usage stats. This value is set to \'enabled\' by default, to disable the usage stats set the value to \'disabled\'. When disabled, it\'s recommended to turn off the Worker Usage container to reduce resource usage.',
|
||||
|
@ -450,7 +468,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_SMS_FROM',
|
||||
'description' => 'Phone number used for sending out messages. Must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789).',
|
||||
'description' => 'Phone number used for sending out messages. If using Twilio, this may be a Messaging Service SID, starting with MG. Otherwise, the number must start with a leading \'+\' and maximum of 15 digits without spaces (+123456789). ',
|
||||
'introduction' => '0.15.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
|
@ -756,7 +774,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_EXECUTOR_SECRET',
|
||||
'description' => 'The secret key used by Appwrite to communicate with the function executor. Make sure to change this!',
|
||||
'description' => 'The secret key used by Appwrite to communicate with the function executor. Make sure to change this.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'your-secret-key',
|
||||
'required' => false,
|
||||
|
@ -765,9 +783,9 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_EXECUTOR_HOST',
|
||||
'description' => 'The host used by Appwrite to communicate with the function executor!',
|
||||
'description' => 'The host used by Appwrite to communicate with the function executor.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'http://appwrite-executor/v1',
|
||||
'default' => 'http://exc1/v1',
|
||||
'required' => false,
|
||||
'overwrite' => true,
|
||||
'question' => '',
|
||||
|
@ -775,7 +793,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_EXECUTOR_RUNTIME_NETWORK',
|
||||
'description' => 'Deprecated with 0.14.0, use \'OPEN_RUNTIMES_NETWORK\' instead!',
|
||||
'description' => 'Deprecated with 0.14.0, use \'OPEN_RUNTIMES_NETWORK\' instead.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'appwrite_runtimes',
|
||||
'required' => false,
|
||||
|
@ -784,7 +802,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => '_APP_FUNCTIONS_ENVS',
|
||||
'description' => 'Deprecated with 0.8.0, use \'_APP_FUNCTIONS_RUNTIMES\' instead!',
|
||||
'description' => 'Deprecated with 0.8.0, use \'_APP_FUNCTIONS_RUNTIMES\' instead.',
|
||||
'introduction' => '0.7.0',
|
||||
'default' => 'node-16.0,php-7.4,python-3.9,ruby-3.0',
|
||||
'required' => false,
|
||||
|
@ -802,7 +820,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => 'DOCKERHUB_PULL_USERNAME',
|
||||
'description' => 'Deprecated with 1.2.0, use \'_APP_DOCKER_HUB_USERNAME\' instead!',
|
||||
'description' => 'Deprecated with 1.2.0, use \'_APP_DOCKER_HUB_USERNAME\' instead.',
|
||||
'introduction' => '0.10.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
|
@ -811,7 +829,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => 'DOCKERHUB_PULL_PASSWORD',
|
||||
'description' => 'Deprecated with 1.2.0, use \'_APP_DOCKER_HUB_PASSWORD\' instead!',
|
||||
'description' => 'Deprecated with 1.2.0, use \'_APP_DOCKER_HUB_PASSWORD\' instead.',
|
||||
'introduction' => '0.10.0',
|
||||
'default' => '',
|
||||
'required' => false,
|
||||
|
@ -829,7 +847,7 @@ return [
|
|||
],
|
||||
[
|
||||
'name' => 'OPEN_RUNTIMES_NETWORK',
|
||||
'description' => 'Deprecated with 1.2.0, use \'_APP_FUNCTIONS_RUNTIMES_NETWORK\' instead!',
|
||||
'description' => 'Deprecated with 1.2.0, use \'_APP_FUNCTIONS_RUNTIMES_NETWORK\' instead.',
|
||||
'introduction' => '0.13.0',
|
||||
'default' => 'appwrite_runtimes',
|
||||
'required' => false,
|
||||
|
|
|
@ -86,8 +86,8 @@ $createSession = function (string $userId, string $secret, Request $request, Res
|
|||
$factor = (match ($verifiedToken->getAttribute('type')) {
|
||||
Auth::TOKEN_TYPE_MAGIC_URL,
|
||||
Auth::TOKEN_TYPE_OAUTH2,
|
||||
Auth::TOKEN_TYPE_EMAIL => 'email',
|
||||
Auth::TOKEN_TYPE_PHONE => 'phone',
|
||||
Auth::TOKEN_TYPE_EMAIL => Type::EMAIL,
|
||||
Auth::TOKEN_TYPE_PHONE => Type::PHONE,
|
||||
Auth::TOKEN_TYPE_GENERIC => 'token',
|
||||
default => throw new Exception(Exception::USER_INVALID_TOKEN)
|
||||
});
|
||||
|
@ -290,7 +290,9 @@ App::post('/v1/account')
|
|||
$existingTarget = $dbForProject->findOne('targets', [
|
||||
Query::equal('identifier', [$email]),
|
||||
]);
|
||||
$user->setAttribute('targets', [...$user->getAttribute('targets', []), $existingTarget]);
|
||||
if($existingTarget) {
|
||||
$user->setAttribute('targets', $existingTarget, Document::SET_TYPE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
@ -1070,17 +1072,15 @@ App::get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
|||
$domain = $request->getHostname();
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$params = $request->getParams();
|
||||
$params['project'] = $projectId;
|
||||
unset($params['projectId']);
|
||||
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->addHeader('Pragma', 'no-cache')
|
||||
->redirect($protocol . '://' . $domain . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
|
||||
. \http_build_query([
|
||||
'project' => $projectId,
|
||||
'code' => $code,
|
||||
'state' => $state,
|
||||
'error' => $error,
|
||||
'error_description' => $error_description
|
||||
]));
|
||||
. \http_build_query($params));
|
||||
});
|
||||
|
||||
App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
||||
|
@ -1103,17 +1103,15 @@ App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
|||
$domain = $request->getHostname();
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$params = $request->getParams();
|
||||
$params['project'] = $projectId;
|
||||
unset($params['projectId']);
|
||||
|
||||
$response
|
||||
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
|
||||
->addHeader('Pragma', 'no-cache')
|
||||
->redirect($protocol . '://' . $domain . '/v1/account/sessions/oauth2/' . $provider . '/redirect?'
|
||||
. \http_build_query([
|
||||
'project' => $projectId,
|
||||
'code' => $code,
|
||||
'state' => $state,
|
||||
'error' => $error,
|
||||
'error_description' => $error_description
|
||||
]));
|
||||
. \http_build_query($params));
|
||||
});
|
||||
|
||||
App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||
|
@ -1240,7 +1238,17 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$failureRedirect(Exception::USER_MISSING_ID);
|
||||
}
|
||||
|
||||
$name = $oauth2->getUserName($accessToken);
|
||||
$name = '';
|
||||
$nameOAuth = $oauth2->getUserName($accessToken);
|
||||
$userParam = \json_decode($request->getParam('user'), true);
|
||||
if (!empty($nameOAuth)) {
|
||||
$name = $nameOAuth;
|
||||
} elseif (is_array($userParam)) {
|
||||
$nameParam = $userParam['name'];
|
||||
if (is_array($nameParam) && isset($nameParam['firstName']) && isset($nameParam['lastName'])) {
|
||||
$name = $nameParam['firstName'] . ' ' . $nameParam['lastName'];
|
||||
}
|
||||
}
|
||||
$email = $oauth2->getUserEmail($accessToken);
|
||||
|
||||
// Check if this identity is connected to a different user
|
||||
|
@ -1500,7 +1508,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
'secret' => Auth::hash($secret), // One way hash encryption to protect DB leak
|
||||
'userAgent' => $request->getUserAgent('UNKNOWN'),
|
||||
'ip' => $request->getIP(),
|
||||
'factors' => ['email'],
|
||||
'factors' => [TYPE::EMAIL, 'oauth2'], // include a special oauth2 factor to bypass MFA checks
|
||||
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
|
||||
'expire' => DateTime::addSeconds(new \DateTime(), $duration)
|
||||
], $detector->getOS(), $detector->getClient(), $detector->getDevice()));
|
||||
|
@ -1544,7 +1552,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
|
||||
$target
|
||||
->setAttribute('sessionId', $session->getId())
|
||||
->setAttrubte('sessionInternalId', $session->getInternalId());
|
||||
->setAttribute('sessionInternalId', $session->getInternalId());
|
||||
|
||||
$dbForProject->updateDocument('targets', $target->getId(), $target);
|
||||
}
|
||||
|
@ -1857,15 +1865,16 @@ App::post('/v1/account/tokens/magic-url')
|
|||
->setRecipient($email)
|
||||
->trigger();
|
||||
|
||||
$queueForEvents->setPayload(
|
||||
$response->output(
|
||||
$token->setAttribute('secret', $tokenSecret),
|
||||
Response::MODEL_TOKEN
|
||||
)
|
||||
);
|
||||
// Set to unhashed secret for events and server responses
|
||||
$token->setAttribute('secret', $tokenSecret);
|
||||
|
||||
$queueForEvents
|
||||
->setPayload($response->output($token, Response::MODEL_TOKEN), sensitive: ['secret']);
|
||||
|
||||
// Hide secret for clients
|
||||
$token->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $tokenSecret : '');
|
||||
if (!$isPrivilegedUser && !$isAppUser) {
|
||||
$token->setAttribute('secret', '');
|
||||
}
|
||||
|
||||
if (!empty($phrase)) {
|
||||
$token->setAttribute('phrase', $phrase);
|
||||
|
@ -1873,8 +1882,7 @@ App::post('/v1/account/tokens/magic-url')
|
|||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($token, Response::MODEL_TOKEN)
|
||||
;
|
||||
->dynamic($token, Response::MODEL_TOKEN);
|
||||
});
|
||||
|
||||
App::post('/v1/account/tokens/email')
|
||||
|
@ -2086,15 +2094,16 @@ App::post('/v1/account/tokens/email')
|
|||
->setRecipient($email)
|
||||
->trigger();
|
||||
|
||||
$queueForEvents->setPayload(
|
||||
$response->output(
|
||||
$token->setAttribute('secret', $tokenSecret),
|
||||
Response::MODEL_TOKEN
|
||||
)
|
||||
);
|
||||
// Set to unhashed secret for events and server responses
|
||||
$token->setAttribute('secret', $tokenSecret);
|
||||
|
||||
$queueForEvents
|
||||
->setPayload($response->output($token, Response::MODEL_TOKEN), sensitive: ['secret']);
|
||||
|
||||
// Hide secret for clients
|
||||
$token->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $tokenSecret : '');
|
||||
if (!$isPrivilegedUser && !$isAppUser) {
|
||||
$token->setAttribute('secret', '');
|
||||
}
|
||||
|
||||
if (!empty($phrase)) {
|
||||
$token->setAttribute('phrase', $phrase);
|
||||
|
@ -2102,8 +2111,7 @@ App::post('/v1/account/tokens/email')
|
|||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($token, Response::MODEL_TOKEN)
|
||||
;
|
||||
->dynamic($token, Response::MODEL_TOKEN);
|
||||
});
|
||||
|
||||
App::put('/v1/account/sessions/magic-url')
|
||||
|
@ -2320,20 +2328,18 @@ App::post('/v1/account/tokens/phone')
|
|||
->setRecipients([$phone])
|
||||
->setProviderType(MESSAGE_TYPE_SMS);
|
||||
|
||||
$queueForEvents->setPayload(
|
||||
$response->output(
|
||||
$token->setAttribute('secret', $secret),
|
||||
Response::MODEL_TOKEN
|
||||
)
|
||||
);
|
||||
// Set to unhashed secret for events and server responses
|
||||
$token->setAttribute('secret', $secret);
|
||||
|
||||
$queueForEvents
|
||||
->setPayload($response->output($token, Response::MODEL_TOKEN), sensitive: ['secret']);
|
||||
|
||||
// Hide secret for clients
|
||||
$token->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? Auth::encodeSession($user->getId(), $secret) : '');
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($token, Response::MODEL_TOKEN)
|
||||
;
|
||||
->dynamic($token, Response::MODEL_TOKEN);
|
||||
});
|
||||
|
||||
App::post('/v1/account/jwts')
|
||||
|
@ -2517,6 +2523,7 @@ App::patch('/v1/account/password')
|
|||
->label('sdk.response.model', Response::MODEL_USER)
|
||||
->label('sdk.offline.model', '/account')
|
||||
->label('sdk.offline.key', 'current')
|
||||
->label('abuse-limit', 10)
|
||||
->param('password', '', fn ($project, $passwordsDictionary) => new PasswordDictionary($passwordsDictionary, $project->getAttribute('auths', [])['passwordDictionary'] ?? false), 'New user password. Must be at least 8 chars.', false, ['project', 'passwordsDictionary'])
|
||||
->param('oldPassword', '', new Password(), 'Current user password. Must be at least 8 chars.', true)
|
||||
->inject('requestTimestamp')
|
||||
|
@ -2614,7 +2621,7 @@ App::patch('/v1/account/email')
|
|||
// Makes sure this email is not already used in another identity
|
||||
$identityWithMatchingEmail = $dbForProject->findOne('identities', [
|
||||
Query::equal('providerEmail', [$email]),
|
||||
Query::notEqual('userId', $user->getId()),
|
||||
Query::notEqual('userInternalId', $user->getInternalId()),
|
||||
]);
|
||||
if ($identityWithMatchingEmail !== false && !$identityWithMatchingEmail->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_BAD_REQUEST); /** Return a generic bad request to prevent exposing existing accounts */
|
||||
|
@ -2978,18 +2985,19 @@ App::post('/v1/account/recovery')
|
|||
->setSubject($subject)
|
||||
->trigger();
|
||||
|
||||
// Set to unhashed secret for events and server responses
|
||||
$recovery->setAttribute('secret', $secret);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('tokenId', $recovery->getId())
|
||||
->setUser($profile)
|
||||
->setPayload($response->output(
|
||||
$recovery->setAttribute('secret', $secret),
|
||||
Response::MODEL_TOKEN
|
||||
))
|
||||
;
|
||||
->setPayload($response->output($recovery, Response::MODEL_TOKEN), sensitive: ['secret']);
|
||||
|
||||
// Hide secret for clients
|
||||
$recovery->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $secret : '');
|
||||
if (!$isPrivilegedUser && !$isAppUser) {
|
||||
$recovery->setAttribute('secret', '');
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
@ -3160,6 +3168,7 @@ App::post('/v1/account/verification')
|
|||
->setParam('{{footer}}', $locale->getText("emails.verification.footer"))
|
||||
->setParam('{{thanks}}', $locale->getText("emails.verification.thanks"))
|
||||
->setParam('{{signature}}', $locale->getText("emails.verification.signature"));
|
||||
|
||||
$body = $message->render();
|
||||
|
||||
$smtp = $project->getAttribute('smtp', []);
|
||||
|
@ -3226,16 +3235,18 @@ App::post('/v1/account/verification')
|
|||
->setName($user->getAttribute('name') ?? '')
|
||||
->trigger();
|
||||
|
||||
// Set to unhashed secret for events and server responses
|
||||
$verification->setAttribute('secret', $verificationSecret);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('tokenId', $verification->getId())
|
||||
->setPayload($response->output(
|
||||
$verification->setAttribute('secret', $verificationSecret),
|
||||
Response::MODEL_TOKEN
|
||||
));
|
||||
->setPayload($response->output($verification, Response::MODEL_TOKEN), sensitive: ['secret']);
|
||||
|
||||
// Hide secret for clients
|
||||
$verification->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $verificationSecret : '');
|
||||
if (!$isPrivilegedUser && !$isAppUser) {
|
||||
$verification->setAttribute('secret', '');
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
@ -3285,7 +3296,7 @@ App::put('/v1/account/verification')
|
|||
|
||||
$user->setAttributes($profile->getArrayCopy());
|
||||
|
||||
$verificationDocument = $dbForProject->getDocument('tokens', $verifiedToken->getId());
|
||||
$verification = $dbForProject->getDocument('tokens', $verifiedToken->getId());
|
||||
|
||||
/**
|
||||
* We act like we're updating and validating
|
||||
|
@ -3296,10 +3307,9 @@ App::put('/v1/account/verification')
|
|||
|
||||
$queueForEvents
|
||||
->setParam('userId', $userId)
|
||||
->setParam('tokenId', $verificationDocument->getId())
|
||||
;
|
||||
->setParam('tokenId', $verification->getId());
|
||||
|
||||
$response->dynamic($verificationDocument, Response::MODEL_TOKEN);
|
||||
$response->dynamic($verification, Response::MODEL_TOKEN);
|
||||
});
|
||||
|
||||
App::post('/v1/account/verification/phone')
|
||||
|
@ -3397,17 +3407,18 @@ App::post('/v1/account/verification/phone')
|
|||
->setRecipients([$user->getAttribute('phone')])
|
||||
->setProviderType(MESSAGE_TYPE_SMS);
|
||||
|
||||
// Set to unhashed secret for events and server responses
|
||||
$verification->setAttribute('secret', $secret);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('tokenId', $verification->getId())
|
||||
->setPayload($response->output(
|
||||
$verification->setAttribute('secret', $secret),
|
||||
Response::MODEL_TOKEN
|
||||
))
|
||||
;
|
||||
->setPayload($response->output($verification, Response::MODEL_TOKEN), sensitive: ['secret']);
|
||||
|
||||
// Hide secret for clients
|
||||
$verification->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $secret : '');
|
||||
if (!$isPrivilegedUser && !$isAppUser) {
|
||||
$verification->setAttribute('secret', '');
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
@ -3493,14 +3504,33 @@ App::patch('/v1/account/mfa')
|
|||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('session')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (bool $mfa, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (bool $mfa, ?\DateTime $requestTimestamp, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$user->setAttribute('mfa', $mfa);
|
||||
|
||||
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
|
||||
|
||||
if ($mfa) {
|
||||
$factors = $session->getAttribute('factors', []);
|
||||
$totp = TOTP::getAuthenticatorFromUser($user);
|
||||
if ($totp !== null && $totp->getAttribute('verified', false)) {
|
||||
$factors[] = Type::TOTP;
|
||||
}
|
||||
if ($user->getAttribute('email', false) && $user->getAttribute('emailVerification', false)) {
|
||||
$factors[] = Type::EMAIL;
|
||||
}
|
||||
if ($user->getAttribute('phone', false) && $user->getAttribute('phoneVerification', false)) {
|
||||
$factors[] = Type::PHONE;
|
||||
}
|
||||
$factors = \array_unique($factors);
|
||||
|
||||
$session->setAttribute('factors', $factors);
|
||||
$dbForProject->updateDocument('sessions', $session->getId(), $session);
|
||||
}
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
$response->dynamic($user, Response::MODEL_ACCOUNT);
|
||||
|
@ -3631,10 +3661,10 @@ App::put('/v1/account/mfa/authenticators/:type')
|
|||
->param('otp', '', new Text(256), 'Valid verification token.')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('project')
|
||||
->inject('session')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (string $type, string $otp, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$authenticator = (match ($type) {
|
||||
Type::TOTP => TOTP::getAuthenticatorFromUser($user),
|
||||
|
@ -3663,10 +3693,12 @@ App::put('/v1/account/mfa/authenticators/:type')
|
|||
$dbForProject->updateDocument('authenticators', $authenticator->getId(), $authenticator);
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration);
|
||||
$session = $dbForProject->getDocument('sessions', $sessionId);
|
||||
$dbForProject->updateDocument('sessions', $sessionId, $session->setAttribute('factors', $type, Document::SET_TYPE_APPEND));
|
||||
$factors = $session->getAttribute('factors', []);
|
||||
$factors[] = $type;
|
||||
$factors = \array_unique($factors);
|
||||
|
||||
$session->setAttribute('factors', $factors);
|
||||
$dbForProject->updateDocument('sessions', $session->getId(), $session);
|
||||
|
||||
$queueForEvents->setParam('userId', $user->getId());
|
||||
|
||||
|
@ -4055,9 +4087,10 @@ App::put('/v1/account/mfa/challenge')
|
|||
->inject('project')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('session')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->action(function (string $challengeId, string $otp, Document $project, Response $response, Document $user, Database $dbForProject, Event $queueForEvents) {
|
||||
->action(function (string $challengeId, string $otp, Document $project, Response $response, Document $user, Document $session, Database $dbForProject, Event $queueForEvents) {
|
||||
|
||||
$challenge = $dbForProject->getDocument('challenges', $challengeId);
|
||||
|
||||
|
@ -4103,15 +4136,15 @@ App::put('/v1/account/mfa/challenge')
|
|||
$dbForProject->deleteDocument('challenges', $challengeId);
|
||||
$dbForProject->purgeCachedDocument('users', $user->getId());
|
||||
|
||||
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$sessionId = Auth::sessionVerify($user->getAttribute('sessions', []), Auth::$secret, $authDuration);
|
||||
$session = $dbForProject->getDocument('sessions', $sessionId);
|
||||
$factors = $session->getAttribute('factors', []);
|
||||
$factors[] = $type;
|
||||
$factors = \array_unique($factors);
|
||||
|
||||
$session = $session
|
||||
->setAttribute('factors', $type, Document::SET_TYPE_APPEND)
|
||||
$session
|
||||
->setAttribute('factors', $factors)
|
||||
->setAttribute('mfaUpdatedAt', DateTime::now());
|
||||
|
||||
$dbForProject->updateDocument('sessions', $sessionId, $session);
|
||||
$dbForProject->updateDocument('sessions', $session->getId(), $session);
|
||||
|
||||
$queueForEvents
|
||||
->setParam('userId', $user->getId())
|
||||
|
|
|
@ -6,7 +6,6 @@ use Appwrite\Utopia\Response;
|
|||
use chillerlan\QRCode\QRCode;
|
||||
use chillerlan\QRCode\QROptions;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
|
@ -14,8 +13,8 @@ use Utopia\Database\Document;
|
|||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Domains\Domain;
|
||||
use Utopia\Fetch\Client;
|
||||
use Utopia\Image\Image;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Logger\Logger;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Boolean;
|
||||
|
@ -155,40 +154,8 @@ $getUserGitHub = function (string $userId, Document $project, Database $dbForPro
|
|||
'id' => $githubId
|
||||
];
|
||||
} catch (Exception $error) {
|
||||
if ($logger) {
|
||||
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
|
||||
|
||||
$log = new Log();
|
||||
$log->setNamespace('console');
|
||||
$log->setServer(\gethostname());
|
||||
$log->setVersion($version);
|
||||
$log->setType(Log::TYPE_ERROR);
|
||||
$log->setMessage($error->getMessage());
|
||||
|
||||
$log->addTag('code', $error->getCode());
|
||||
$log->addTag('verboseType', get_class($error));
|
||||
|
||||
$log->addExtra('file', $error->getFile());
|
||||
$log->addExtra('line', $error->getLine());
|
||||
$log->addExtra('trace', $error->getTraceAsString());
|
||||
$log->addExtra('detailedTrace', $error->getTrace());
|
||||
|
||||
$log->setAction('avatarsGetGitHub');
|
||||
|
||||
$isProduction = System::getEnv('_APP_ENV', 'development') === 'production';
|
||||
$log->setEnvironment($isProduction ? Log::ENVIRONMENT_PRODUCTION : Log::ENVIRONMENT_STAGING);
|
||||
|
||||
$responseCode = $logger->addLog($log);
|
||||
Console::info('GitHub error log pushed with status code: ' . $responseCode);
|
||||
}
|
||||
|
||||
Console::warning("Failed: {$error->getMessage()}");
|
||||
Console::warning($error->getTraceAsString());
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
return [];
|
||||
};
|
||||
|
||||
App::get('/v1/avatars/credit-cards/:code')
|
||||
|
@ -284,14 +251,21 @@ App::get('/v1/avatars/image')
|
|||
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
$fetch = @\file_get_contents($url);
|
||||
$client = new Client();
|
||||
try {
|
||||
$res = $client
|
||||
->setAllowRedirects(false)
|
||||
->fetch($url);
|
||||
} catch (\Throwable) {
|
||||
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
if (!$fetch) {
|
||||
if ($res->getStatusCode() !== 200) {
|
||||
throw new Exception(Exception::AVATAR_IMAGE_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$image = new Image($fetch);
|
||||
$image = new Image($res->getBody());
|
||||
} catch (\Throwable $exception) {
|
||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Unable to parse image');
|
||||
}
|
||||
|
@ -340,31 +314,27 @@ App::get('/v1/avatars/favicon')
|
|||
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
$curl = \curl_init();
|
||||
$client = new Client();
|
||||
try {
|
||||
$res = $client
|
||||
->setAllowRedirects(false)
|
||||
->setUserAgent(\sprintf(
|
||||
APP_USERAGENT,
|
||||
System::getEnv('_APP_VERSION', 'UNKNOWN'),
|
||||
System::getEnv('_APP_EMAIL_SECURITY', System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY))
|
||||
))
|
||||
->fetch($url);
|
||||
} catch (\Throwable) {
|
||||
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
\curl_setopt_array($curl, [
|
||||
CURLOPT_RETURNTRANSFER => 1,
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 3,
|
||||
CURLOPT_URL => $url,
|
||||
CURLOPT_USERAGENT => \sprintf(
|
||||
APP_USERAGENT,
|
||||
System::getEnv('_APP_VERSION', 'UNKNOWN'),
|
||||
System::getEnv('_APP_SYSTEM_SECURITY_EMAIL_ADDRESS', APP_EMAIL_SECURITY)
|
||||
),
|
||||
]);
|
||||
|
||||
$html = \curl_exec($curl);
|
||||
|
||||
\curl_close($curl);
|
||||
|
||||
if (!$html) {
|
||||
if ($res->getStatusCode() !== 200) {
|
||||
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
$doc = new DOMDocument();
|
||||
$doc->strictErrorChecking = false;
|
||||
@$doc->loadHTML($html);
|
||||
@$doc->loadHTML($res->getBody());
|
||||
|
||||
$links = $doc->getElementsByTagName('link');
|
||||
$outputHref = '';
|
||||
|
@ -419,9 +389,22 @@ App::get('/v1/avatars/favicon')
|
|||
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
if ('ico' == $outputExt) { // Skip crop, Imagick isn\'t supporting icon files
|
||||
$data = @\file_get_contents($outputHref, false);
|
||||
$client = new Client();
|
||||
try {
|
||||
$res = $client
|
||||
->setAllowRedirects(false)
|
||||
->fetch($outputHref);
|
||||
} catch (\Throwable) {
|
||||
throw new Exception(Exception::AVATAR_REMOTE_URL_FAILED);
|
||||
}
|
||||
|
||||
if ($res->getStatusCode() !== 200) {
|
||||
throw new Exception(Exception::AVATAR_ICON_NOT_FOUND);
|
||||
}
|
||||
|
||||
$data = $res->getBody();
|
||||
|
||||
if ('ico' == $outputExt) { // Skip crop, Imagick isn\'t supporting icon files
|
||||
if (empty($data) || (\mb_substr($data, 0, 5) === '<html') || \mb_substr($data, 0, 5) === '<!doc') {
|
||||
throw new Exception(Exception::AVATAR_ICON_NOT_FOUND, 'Favicon not found');
|
||||
}
|
||||
|
@ -431,13 +414,7 @@ App::get('/v1/avatars/favicon')
|
|||
->file($data);
|
||||
}
|
||||
|
||||
$fetch = @\file_get_contents($outputHref, false);
|
||||
|
||||
if (!$fetch) {
|
||||
throw new Exception(Exception::AVATAR_ICON_NOT_FOUND);
|
||||
}
|
||||
|
||||
$image = new Image($fetch);
|
||||
$image = new Image($data);
|
||||
$image->crop((int) $width, (int) $height);
|
||||
$output = (empty($output)) ? $type : $output;
|
||||
$data = $image->output($output, $quality);
|
||||
|
|
|
@ -24,7 +24,6 @@ use Utopia\Database\Exception\Authorization as AuthorizationException;
|
|||
use Utopia\Database\Exception\Conflict as ConflictException;
|
||||
use Utopia\Database\Exception\Duplicate as DuplicateException;
|
||||
use Utopia\Database\Exception\Limit as LimitException;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Exception\Restricted as RestrictedException;
|
||||
use Utopia\Database\Exception\Structure as StructureException;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
|
@ -666,16 +665,10 @@ App::put('/v1/databases/:databaseId')
|
|||
throw new Exception(Exception::DATABASE_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$database = $dbForProject->updateDocument('databases', $databaseId, $database
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('enabled', $enabled)
|
||||
->setAttribute('search', implode(' ', [$databaseId, $name])));
|
||||
} catch (AuthorizationException) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
} catch (StructureException $exception) {
|
||||
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, 'Bad structure. ' . $exception->getMessage());
|
||||
}
|
||||
$database = $dbForProject->updateDocument('databases', $databaseId, $database
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('enabled', $enabled)
|
||||
->setAttribute('search', implode(' ', [$databaseId, $name])));
|
||||
|
||||
$queueForEvents->setParam('databaseId', $database->getId());
|
||||
|
||||
|
@ -1036,19 +1029,14 @@ App::put('/v1/databases/:databaseId/collections/:collectionId')
|
|||
|
||||
$enabled ??= $collection->getAttribute('enabled', true);
|
||||
|
||||
try {
|
||||
$collection = $dbForProject->updateDocument('database_' . $database->getInternalId(), $collectionId, $collection
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('$permissions', $permissions)
|
||||
->setAttribute('documentSecurity', $documentSecurity)
|
||||
->setAttribute('enabled', $enabled)
|
||||
->setAttribute('search', implode(' ', [$collectionId, $name])));
|
||||
$dbForProject->updateCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $permissions, $documentSecurity);
|
||||
} catch (AuthorizationException) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
} catch (StructureException $exception) {
|
||||
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, 'Bad structure. ' . $exception->getMessage());
|
||||
}
|
||||
$collection = $dbForProject->updateDocument('database_' . $database->getInternalId(), $collectionId, $collection
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('$permissions', $permissions)
|
||||
->setAttribute('documentSecurity', $documentSecurity)
|
||||
->setAttribute('enabled', $enabled)
|
||||
->setAttribute('search', implode(' ', [$collectionId, $name])));
|
||||
|
||||
$dbForProject->updateCollection('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $permissions, $documentSecurity);
|
||||
|
||||
$queueForEvents
|
||||
->setContext('database', $database)
|
||||
|
@ -3599,16 +3587,10 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
|
|||
}
|
||||
|
||||
$dbForProject->withRequestTimestamp($requestTimestamp, function () use ($dbForProject, $database, $collection, $documentId) {
|
||||
try {
|
||||
$dbForProject->deleteDocument(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
$documentId
|
||||
);
|
||||
} catch (AuthorizationException) {
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED);
|
||||
} catch (RestrictedException) {
|
||||
throw new Exception(Exception::DOCUMENT_DELETE_RESTRICTED);
|
||||
}
|
||||
$dbForProject->deleteDocument(
|
||||
'database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(),
|
||||
$documentId
|
||||
);
|
||||
});
|
||||
|
||||
// Add $collectionId and $databaseId for all documents
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue