Merge remote-tracking branch 'origin/1.8.x' into feat-txn

# Conflicts:
#	src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php
#	src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php
#	src/Appwrite/Utopia/Response.php
This commit is contained in:
Jake Barnby
2025-09-02 23:31:47 +12:00
3722 changed files with 100199 additions and 67749 deletions
+81 -5
View File
@@ -8,7 +8,15 @@ env:
IMAGE: appwrite-dev
CACHE_KEY: appwrite-dev-${{ github.event.pull_request.head.sha }}
on: [ pull_request ]
on:
pull_request:
workflow_dispatch:
inputs:
response_format:
description: 'Response format version to test (e.g., 1.5.0, 1.4.0)'
required: false
type: string
default: ''
jobs:
check_database_changes:
@@ -100,7 +108,10 @@ jobs:
run: docker compose exec -T appwrite vars
- name: Run Unit Tests
run: docker compose exec appwrite test /usr/src/code/tests/unit
run: |
docker compose exec \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/unit
e2e_general_test:
name: E2E General Test
@@ -132,7 +143,18 @@ jobs:
done
- name: Run General Tests
run: docker compose exec -T appwrite test /usr/src/code/tests/e2e/General --debug
run: |
docker compose exec -T \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/e2e/General --debug
- name: Failure Logs
if: failure()
run: |
echo "=== Appwrite Worker Builds Logs ==="
docker compose logs appwrite-worker-builds
echo "=== OpenRuntimes Executor Logs ==="
docker compose logs openruntimes-executor
e2e_service_test:
name: E2E Service Test
@@ -146,7 +168,7 @@ jobs:
Avatars,
Console,
Databases/Legacy,
Databases/Grids,
Databases/TablesDB,
Functions,
FunctionsSchedule,
GraphQL,
@@ -200,8 +222,17 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys,screenshots
- name: Failure Logs
if: failure()
run: |
echo "=== Appwrite Worker Builds Logs ==="
docker compose logs appwrite-worker-builds
echo "=== OpenRuntimes Executor Logs ==="
docker compose logs openruntimes-executor
e2e_shared_mode_test:
name: E2E Shared Mode Service Test
runs-on: ubuntu-latest
@@ -216,7 +247,7 @@ jobs:
Avatars,
Console,
Databases/Legacy,
Databases/Grids,
Databases/TablesDB,
Functions,
FunctionsSchedule,
GraphQL,
@@ -280,8 +311,17 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/e2e/Services/${{ matrix.service }} --debug --exclude-group devKeys,screenshots
- name: Failure Logs
if: failure()
run: |
echo "=== Appwrite Worker Builds Logs ==="
docker compose logs appwrite-worker-builds
echo "=== OpenRuntimes Executor Logs ==="
docker compose logs openruntimes-executor
e2e_dev_keys:
name: E2E Service Test (Dev Keys)
runs-on: ubuntu-latest
@@ -313,8 +353,17 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys
- name: Failure Logs
if: failure()
run: |
echo "=== Appwrite Worker Builds Logs ==="
docker compose logs appwrite-worker-builds
echo "=== OpenRuntimes Executor Logs ==="
docker compose logs openruntimes-executor
e2e_dev_keys_shared_mode:
name: E2E Shared Mode Service Test (Dev Keys)
runs-on: ubuntu-latest
@@ -360,8 +409,17 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/e2e/Services/Projects --debug --group=devKeys
- name: Failure Logs
if: failure()
run: |
echo "=== Appwrite Worker Builds Logs ==="
docker compose logs appwrite-worker-builds
echo "=== OpenRuntimes Executor Logs ==="
docker compose logs openruntimes-executor
e2e_screenshots_keys:
name: E2E Service Test (Site Screenshots)
runs-on: ubuntu-latest
@@ -394,8 +452,17 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/e2e/Services/Sites --debug --group=screenshots
- name: Failure Logs
if: failure()
run: |
echo "=== Appwrite Worker Builds Logs ==="
docker compose logs appwrite-worker-builds
echo "=== OpenRuntimes Executor Logs ==="
docker compose logs openruntimes-executor
e2e_screenshots_shared_mode:
name: E2E Shared Mode Service Test (Site Screenshots)
runs-on: ubuntu-latest
@@ -442,4 +509,13 @@ jobs:
docker compose exec -T \
-e _APP_DATABASE_SHARED_TABLES \
-e _APP_DATABASE_SHARED_TABLES_V1 \
-e _APP_E2E_RESPONSE_FORMAT="${{ github.event.inputs.response_format }}" \
appwrite test /usr/src/code/tests/e2e/Services/Sites --debug --group=screenshots
- name: Failure Logs
if: failure()
run: |
echo "=== Appwrite Worker Builds Logs ==="
docker compose logs appwrite-worker-builds
echo "=== OpenRuntimes Executor Logs ==="
docker compose logs openruntimes-executor
+1 -1
View File
@@ -12,7 +12,7 @@ RUN composer install --ignore-platform-reqs --optimize-autoloader \
--no-plugins --no-scripts --prefer-dist \
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
FROM appwrite/base:0.10.3 AS final
FROM appwrite/base:0.10.4 AS final
LABEL maintainer="team@appwrite.io"
+2 -1
View File
@@ -1,5 +1,6 @@
> We just announced Timestamp Overrides for Appwrite Databases - [Learn more](https://appwrite.io/blog/post/announcing-timestamp-overrides)
> We just announced Auto-increment support for Appwrite Databases - [Learn more](https://appwrite.io/blog/post/announcing-auto-increment-support)
> Appwrite Cloud is now Generally Available - [Learn more](https://appwrite.io/cloud-ga)
> [Get started with Appwrite](https://apwr.dev/appcloud)
+6
View File
@@ -194,12 +194,18 @@ CLI::setResource('publisher', function (Group $pools) {
CLI::setResource('publisherDatabases', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
CLI::setResource('publisherFunctions', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
CLI::setResource('publisherMigrations', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
CLI::setResource('publisherStatsUsage', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
CLI::setResource('publisherMessaging', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
CLI::setResource('queueForStatsUsage', function (Publisher $publisher) {
return new StatsUsage($publisher);
}, ['publisher']);
+1 -1
View File
@@ -13,7 +13,7 @@ return [
'mastercard' => ['name' => 'Mastercard', 'path' => __DIR__ . '/credit-cards/mastercard.png'],
'naranja' => ['name' => 'Naranja', 'path' => __DIR__ . '/credit-cards/naranja.png'],
'targeta-shopping' => ['name' => 'Tarjeta Shopping', 'path' => __DIR__ . '/credit-cards/tarjeta-shopping.png'],
'union-china-pay' => ['name' => 'Union China Pay', 'path' => __DIR__ . '/credit-cards/union-china-pay.png'],
'unionpay' => ['name' => 'Union Pay', 'path' => __DIR__ . '/credit-cards/unionpay.png'],
'visa' => ['name' => 'Visa', 'path' => __DIR__ . '/credit-cards/visa.png'],
'mir' => ['name' => 'MIR', 'path' => __DIR__ . '/credit-cards/mir.png'],
'maestro' => ['name' => 'Maestro', 'path' => __DIR__ . '/credit-cards/maestro.png'],

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 78 KiB

+3 -3
View File
@@ -56,7 +56,7 @@ return [
'type' => Database::VAR_STRING,
'size' => 128,
'required' => false,
'default' => 'grids',
'default' => 'tablesdb',
'signed' => true,
'array' => false,
'filters' => [],
@@ -1927,7 +1927,7 @@ return [
'$id' => ID::custom('errors'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 1000000,
'size' => APP_FUNCTION_ERROR_LENGTH_LIMIT,
'signed' => true,
'required' => false,
'default' => null,
@@ -1938,7 +1938,7 @@ return [
'$id' => ID::custom('logs'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 1000000,
'size' => APP_FUNCTION_LOG_LENGTH_LIMIT,
'signed' => true,
'required' => false,
'default' => null,
+5
View File
@@ -435,6 +435,11 @@ return [
'description' => 'The requested favicon could not be found.',
'code' => 404,
],
Exception::AVATAR_SVG_SANITIZATION_FAILED => [
'name' => Exception::AVATAR_SVG_SANITIZATION_FAILED,
'description' => 'SVG sanitization failed.',
'code' => 400,
],
/** Storage */
Exception::STORAGE_FILE_ALREADY_EXISTS => [
@@ -1,9 +1,24 @@
<!doctype html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Poppins:wght@500;600&display=swap">
<link rel="preconnect" href="https://assets.appwrite.io/" crossorigin>
<style>
@font-face {
font-family: 'Inter';
src: url('https://assets.appwrite.io/fonts/inter/Inter-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'DM Sans';
src: url('https://assets.appwrite.io/fonts/dm-sans/dm-sans-v16-latin-600.woff2') format('woff2');
font-weight: 600;
font-style: normal;
font-display: swap;
}
</style>
<style>
@media (max-width:500px) {
.mobile-full-width {
+34 -52
View File
@@ -1,9 +1,32 @@
<!doctype html>
<html>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Poppins:wght@500;600&display=swap">
<link rel="preconnect" href="https://assets.appwrite.io/" crossorigin>
<style>
@font-face {
font-family: 'Inter';
src: url('https://assets.appwrite.io/fonts/inter/Inter-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'DM Sans';
src: url('https://assets.appwrite.io/fonts/dm-sans/dm-sans-v16-latin-600.woff2') format('woff2');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Poppins';
src: url('https://assets.appwrite.io/fonts/poppins/poppins-v23-latin-regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
</style>
<style>
body {
padding: 32px;
@@ -15,6 +38,7 @@
background-color: #ffffff;
margin: 0;
padding: 0;
line-height: 150%;
}
a {
color: currentColor;
@@ -67,58 +91,16 @@
border: none;
border-top: 1px solid #e8e9f0;
}
h* {
font-family: 'Poppins', sans-serif;
}
p {
margin-bottom: 10px;
}
</style>
</head>
<head>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&family=Poppins:wght@500;600&display=swap"
rel="stylesheet">
<style>
a { color:currentColor; word-break: break-all; }
body {
background-color: #ffffff;
padding: 32px;
color: #616B7C;
font-size: 15px;
font-family: 'Inter', sans-serif;
line-height: 150%;
}
table {
width: 100%;
border-spacing: 0 !important;
}
table,
tr,
th,
td {
margin: 0;
padding: 0;
}
td {
vertical-align: top;
}
h* {
font-family: 'Poppins', sans-serif;
}
hr {
border: none;
border-top: 1px solid #E8E9F0;
}
p {
margin-bottom: 10px;
}
</style>
</head>
<body style="direction: {{direction}}">
<div style="display: none; overflow: hidden; max-height: 0; max-width: 0; opacity: 0; line-height: 1px;">
+16 -16
View File
@@ -11,7 +11,7 @@ return [
[
'key' => 'web',
'name' => 'Web',
'version' => '18.2.0',
'version' => '19.0.0',
'url' => 'https://github.com/appwrite/sdk-for-web',
'package' => 'https://www.npmjs.com/package/appwrite',
'enabled' => true,
@@ -60,7 +60,7 @@ return [
[
'key' => 'flutter',
'name' => 'Flutter',
'version' => '17.1.0',
'version' => '18.0.0',
'url' => 'https://github.com/appwrite/sdk-for-flutter',
'package' => 'https://pub.dev/packages/appwrite',
'enabled' => true,
@@ -79,7 +79,7 @@ return [
[
'key' => 'apple',
'name' => 'Apple',
'version' => '10.2.0',
'version' => '11.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' => '8.2.2',
'version' => '9.0.0',
'url' => 'https://github.com/appwrite/sdk-for-android',
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-android',
'enabled' => true,
@@ -139,7 +139,7 @@ return [
[
'key' => 'react-native',
'name' => 'React Native',
'version' => '0.11.0',
'version' => '0.12.0',
'url' => 'https://github.com/appwrite/sdk-for-react-native',
'package' => 'https://npmjs.com/package/react-native-appwrite',
'enabled' => true,
@@ -226,7 +226,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '8.3.0',
'version' => '9.0.2',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://www.npmjs.com/package/appwrite-cli',
'enabled' => true,
@@ -261,7 +261,7 @@ return [
[
'key' => 'nodejs',
'name' => 'Node.js',
'version' => '17.2.0',
'version' => '18.0.0',
'url' => 'https://github.com/appwrite/sdk-for-node',
'package' => 'https://www.npmjs.com/package/node-appwrite',
'enabled' => true,
@@ -280,7 +280,7 @@ return [
[
'key' => 'deno',
'name' => 'Deno',
'version' => '15.1.0',
'version' => '16.0.0',
'url' => 'https://github.com/appwrite/sdk-for-deno',
'package' => 'https://deno.land/x/appwrite',
'enabled' => true,
@@ -299,7 +299,7 @@ return [
[
'key' => 'php',
'name' => 'PHP',
'version' => '15.1.0',
'version' => '16.0.0',
'url' => 'https://github.com/appwrite/sdk-for-php',
'package' => 'https://packagist.org/packages/appwrite/appwrite',
'enabled' => true,
@@ -318,7 +318,7 @@ return [
[
'key' => 'python',
'name' => 'Python',
'version' => '11.1.0',
'version' => '12.0.0',
'url' => 'https://github.com/appwrite/sdk-for-python',
'package' => 'https://pypi.org/project/appwrite/',
'enabled' => true,
@@ -337,7 +337,7 @@ return [
[
'key' => 'ruby',
'name' => 'Ruby',
'version' => '16.1.0',
'version' => '17.0.0',
'url' => 'https://github.com/appwrite/sdk-for-ruby',
'package' => 'https://rubygems.org/gems/appwrite',
'enabled' => true,
@@ -356,7 +356,7 @@ return [
[
'key' => 'go',
'name' => 'Go',
'version' => '0.9.0',
'version' => '0.10.0',
'url' => 'https://github.com/appwrite/sdk-for-go',
'package' => 'https://github.com/appwrite/sdk-for-go',
'enabled' => true,
@@ -375,7 +375,7 @@ return [
[
'key' => 'dotnet',
'name' => '.NET',
'version' => '0.15.0',
'version' => '0.16.0',
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
'package' => 'https://www.nuget.org/packages/Appwrite',
'enabled' => true,
@@ -394,7 +394,7 @@ return [
[
'key' => 'dart',
'name' => 'Dart',
'version' => '16.2.0',
'version' => '17.0.0',
'url' => 'https://github.com/appwrite/sdk-for-dart',
'package' => 'https://pub.dev/packages/dart_appwrite',
'enabled' => true,
@@ -413,7 +413,7 @@ return [
[
'key' => 'kotlin',
'name' => 'Kotlin',
'version' => '9.1.2',
'version' => '10.0.0',
'url' => 'https://github.com/appwrite/sdk-for-kotlin',
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin',
'enabled' => true,
@@ -436,7 +436,7 @@ return [
[
'key' => 'swift',
'name' => 'Swift',
'version' => '10.2.0',
'version' => '11.0.0',
'url' => 'https://github.com/appwrite/sdk-for-swift',
'package' => 'https://github.com/appwrite/sdk-for-swift',
'enabled' => true,
+6 -6
View File
@@ -66,15 +66,15 @@ return [
'optional' => true,
'icon' => '/images/services/databases.png',
],
'tables' => [
'key' => 'tables',
'name' => 'Tables',
'subtitle' => 'The Tables service allows you to create structured tables of rows, query and filter lists of rows',
'description' => '/docs/services/tables.md',
'tablesdb' => [
'key' => 'tablesdb',
'name' => 'TablesDB',
'subtitle' => 'The TablesDB service allows you to create structured tables of columns, query and filter lists of rows',
'description' => '/docs/services/tablesdb.md',
'controller' => '', // Uses modules
'sdk' => true,
'docs' => true,
'docsUrl' => 'https://appwrite.io/docs/client/tables',
'docsUrl' => 'https://appwrite.io/docs/client/tablesdb',
'tests' => false,
'optional' => true,
'icon' => '/images/services/databases.png',
+14 -7
View File
@@ -2622,7 +2622,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).",
"description": "Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n",
"responses": {
"201": {
"description": "Token",
@@ -2673,7 +2673,7 @@
"properties": {
"userId": {
"type": "string",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"email": {
@@ -2755,7 +2755,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"email": {
@@ -2977,7 +2977,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"phone": {
@@ -3440,7 +3440,7 @@
"parameters": [
{
"name": "code",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, unionpay, visa, mir, maestro, rupay.",
"required": true,
"schema": {
"type": "string",
@@ -3458,7 +3458,7 @@
"mastercard",
"naranja",
"targeta-shopping",
"union-china-pay",
"unionpay",
"visa",
"mir",
"maestro",
@@ -3478,7 +3478,7 @@
"Mastercard",
"Naranja",
"Tarjeta Shopping",
"Union China Pay",
"Union Pay",
"Visa",
"MIR",
"Maestro",
@@ -9847,6 +9847,11 @@
"description": "Function ID.",
"x-example": "5e5ea6g16897e"
},
"deploymentId": {
"type": "string",
"description": "Function's deployment ID used to create the execution.",
"x-example": "5e5ea5c16897e"
},
"trigger": {
"type": "string",
"description": "The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.",
@@ -9931,6 +9936,7 @@
"$updatedAt",
"$permissions",
"functionId",
"deploymentId",
"trigger",
"status",
"requestMethod",
@@ -9951,6 +9957,7 @@
"any"
],
"functionId": "5e5ea6g16897e",
"deploymentId": "5e5ea5c16897e",
"trigger": "http",
"status": "processing",
"requestMethod": "GET",
+14 -7
View File
@@ -2631,7 +2631,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).",
"description": "Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n",
"responses": {
"201": {
"description": "Token",
@@ -2682,7 +2682,7 @@
"properties": {
"userId": {
"type": "string",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"email": {
@@ -2764,7 +2764,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"email": {
@@ -2986,7 +2986,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"phone": {
@@ -3445,7 +3445,7 @@
"parameters": [
{
"name": "code",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, unionpay, visa, mir, maestro, rupay.",
"required": true,
"schema": {
"type": "string",
@@ -3463,7 +3463,7 @@
"mastercard",
"naranja",
"targeta-shopping",
"union-china-pay",
"unionpay",
"visa",
"mir",
"maestro",
@@ -3483,7 +3483,7 @@
"Mastercard",
"Naranja",
"Tarjeta Shopping",
"Union China Pay",
"Union Pay",
"Visa",
"MIR",
"Maestro",
@@ -41133,6 +41133,11 @@
"description": "Function ID.",
"x-example": "5e5ea6g16897e"
},
"deploymentId": {
"type": "string",
"description": "Function's deployment ID used to create the execution.",
"x-example": "5e5ea5c16897e"
},
"trigger": {
"type": "string",
"description": "The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.",
@@ -41217,6 +41222,7 @@
"$updatedAt",
"$permissions",
"functionId",
"deploymentId",
"trigger",
"status",
"requestMethod",
@@ -41237,6 +41243,7 @@
"any"
],
"functionId": "5e5ea6g16897e",
"deploymentId": "5e5ea5c16897e",
"trigger": "http",
"status": "processing",
"requestMethod": "GET",
+14 -7
View File
@@ -2303,7 +2303,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).",
"description": "Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n",
"responses": {
"201": {
"description": "Token",
@@ -2354,7 +2354,7 @@
"properties": {
"userId": {
"type": "string",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"email": {
@@ -2436,7 +2436,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"email": {
@@ -2658,7 +2658,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored.",
"x-example": "<USER_ID>"
},
"phone": {
@@ -3129,7 +3129,7 @@
"parameters": [
{
"name": "code",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, unionpay, visa, mir, maestro, rupay.",
"required": true,
"schema": {
"type": "string",
@@ -3147,7 +3147,7 @@
"mastercard",
"naranja",
"targeta-shopping",
"union-china-pay",
"unionpay",
"visa",
"mir",
"maestro",
@@ -3167,7 +3167,7 @@
"Mastercard",
"Naranja",
"Tarjeta Shopping",
"Union China Pay",
"Union Pay",
"Visa",
"MIR",
"Maestro",
@@ -30230,6 +30230,11 @@
"description": "Function ID.",
"x-example": "5e5ea6g16897e"
},
"deploymentId": {
"type": "string",
"description": "Function's deployment ID used to create the execution.",
"x-example": "5e5ea5c16897e"
},
"trigger": {
"type": "string",
"description": "The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.",
@@ -30314,6 +30319,7 @@
"$updatedAt",
"$permissions",
"functionId",
"deploymentId",
"trigger",
"status",
"requestMethod",
@@ -30334,6 +30340,7 @@
"any"
],
"functionId": "5e5ea6g16897e",
"deploymentId": "5e5ea5c16897e",
"trigger": "http",
"status": "processing",
"requestMethod": "GET",
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
+14 -7
View File
@@ -2751,7 +2751,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).",
"description": "Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n",
"responses": {
"201": {
"description": "Token",
@@ -2799,7 +2799,7 @@
"properties": {
"userId": {
"type": "string",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -2886,7 +2886,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -3111,7 +3111,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -3592,7 +3592,7 @@
"parameters": [
{
"name": "code",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, unionpay, visa, mir, maestro, rupay.",
"required": true,
"type": "string",
"x-example": "amex",
@@ -3609,7 +3609,7 @@
"mastercard",
"naranja",
"targeta-shopping",
"union-china-pay",
"unionpay",
"visa",
"mir",
"maestro",
@@ -3629,7 +3629,7 @@
"Mastercard",
"Naranja",
"Tarjeta Shopping",
"Union China Pay",
"Union Pay",
"Visa",
"MIR",
"Maestro",
@@ -9885,6 +9885,11 @@
"description": "Function ID.",
"x-example": "5e5ea6g16897e"
},
"deploymentId": {
"type": "string",
"description": "Function's deployment ID used to create the execution.",
"x-example": "5e5ea5c16897e"
},
"trigger": {
"type": "string",
"description": "The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.",
@@ -9971,6 +9976,7 @@
"$updatedAt",
"$permissions",
"functionId",
"deploymentId",
"trigger",
"status",
"requestMethod",
@@ -9991,6 +9997,7 @@
"any"
],
"functionId": "5e5ea6g16897e",
"deploymentId": "5e5ea5c16897e",
"trigger": "http",
"status": "processing",
"requestMethod": "GET",
+14 -7
View File
@@ -2770,7 +2770,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).",
"description": "Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n",
"responses": {
"201": {
"description": "Token",
@@ -2818,7 +2818,7 @@
"properties": {
"userId": {
"type": "string",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -2905,7 +2905,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -3130,7 +3130,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -3607,7 +3607,7 @@
"parameters": [
{
"name": "code",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, unionpay, visa, mir, maestro, rupay.",
"required": true,
"type": "string",
"x-example": "amex",
@@ -3624,7 +3624,7 @@
"mastercard",
"naranja",
"targeta-shopping",
"union-china-pay",
"unionpay",
"visa",
"mir",
"maestro",
@@ -3644,7 +3644,7 @@
"Mastercard",
"Naranja",
"Tarjeta Shopping",
"Union China Pay",
"Union Pay",
"Visa",
"MIR",
"Maestro",
@@ -41300,6 +41300,11 @@
"description": "Function ID.",
"x-example": "5e5ea6g16897e"
},
"deploymentId": {
"type": "string",
"description": "Function's deployment ID used to create the execution.",
"x-example": "5e5ea5c16897e"
},
"trigger": {
"type": "string",
"description": "The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.",
@@ -41386,6 +41391,7 @@
"$updatedAt",
"$permissions",
"functionId",
"deploymentId",
"trigger",
"status",
"requestMethod",
@@ -41406,6 +41412,7 @@
"any"
],
"functionId": "5e5ea6g16897e",
"deploymentId": "5e5ea5c16897e",
"trigger": "http",
"status": "processing",
"requestMethod": "GET",
+14 -7
View File
@@ -2438,7 +2438,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).",
"description": "Sends the user an email with a secret key for creating a session. If the email address has never been used, a **new account is created** using the provided `userId`. Otherwise, if the email address is already attached to an account, the **user ID is ignored**. Then, the user will receive an email with the one-time password. Use the returned user ID and secret and submit a request to the [POST \/v1\/account\/sessions\/token](https:\/\/appwrite.io\/docs\/references\/cloud\/client-web\/account#createSession) endpoint to complete the login process. The secret sent to the user's email is valid for 15 minutes.\n\nA user is limited to 10 active sessions at a time by default. [Learn more about session limits](https:\/\/appwrite.io\/docs\/authentication-security#limits).\n",
"responses": {
"201": {
"description": "Token",
@@ -2486,7 +2486,7 @@
"properties": {
"userId": {
"type": "string",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -2573,7 +2573,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -2798,7 +2798,7 @@
"properties": {
"userId": {
"type": "string",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars.",
"description": "Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can't start with a special char. Max length is 36 chars. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored.",
"default": null,
"x-example": "<USER_ID>"
},
@@ -3287,7 +3287,7 @@
"parameters": [
{
"name": "code",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, union-china-pay, visa, mir, maestro, rupay.",
"description": "Credit Card Code. Possible values: amex, argencard, cabal, cencosud, diners, discover, elo, hipercard, jcb, mastercard, naranja, targeta-shopping, unionpay, visa, mir, maestro, rupay.",
"required": true,
"type": "string",
"x-example": "amex",
@@ -3304,7 +3304,7 @@
"mastercard",
"naranja",
"targeta-shopping",
"union-china-pay",
"unionpay",
"visa",
"mir",
"maestro",
@@ -3324,7 +3324,7 @@
"Mastercard",
"Naranja",
"Tarjeta Shopping",
"Union China Pay",
"Union Pay",
"Visa",
"MIR",
"Maestro",
@@ -30460,6 +30460,11 @@
"description": "Function ID.",
"x-example": "5e5ea6g16897e"
},
"deploymentId": {
"type": "string",
"description": "Function's deployment ID used to create the execution.",
"x-example": "5e5ea5c16897e"
},
"trigger": {
"type": "string",
"description": "The trigger that caused the function to execute. Possible values can be: `http`, `schedule`, or `event`.",
@@ -30546,6 +30551,7 @@
"$updatedAt",
"$permissions",
"functionId",
"deploymentId",
"trigger",
"status",
"requestMethod",
@@ -30566,6 +30572,7 @@
"any"
],
"functionId": "5e5ea6g16897e",
"deploymentId": "5e5ea5c16897e",
"trigger": "http",
"status": "processing",
"requestMethod": "GET",
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
+55
View File
@@ -2080,6 +2080,61 @@ return [
'type' => 'text'
]
],
'scopes' => ['databases.read', 'databases.write', 'collections.write', 'attributes.write', 'documents.read', 'documents.write']
],
[
'icon' => 'icon-apple',
'id' => 'sign-in-with-apple',
'name' => 'Sign in with Apple',
'score' => 6,
'tagline' => 'Use native Apple sign-in APIs on Apple devices with Appwrite Auth',
'permissions' => ['any'],
'events' => [],
'cron' => '',
'timeout' => 15,
'useCases' => ['auth'],
'runtimes' => [
...getRuntimes($templateRuntimes['DART'], 'dart pub get', 'lib/main.dart', 'dart/sign_in_with_apple')
],
'instructions' => 'For documentation and instructions, check out <a target="_blank" rel="noopener noreferrer" class="link" href="https://github.com/appwrite/templates/tree/main/dart/sign_in_with_apple">file</a>.',
'vcsProvider' => 'github',
'providerRepositoryId' => 'templates',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [
[
'name' => 'BUNDLE_ID',
'description' => 'Bundle ID of the app. <a class="u-bold" target="_blank" href="https://developer.apple.com/documentation/xcode/preparing-your-app-for-distribution/#Set-the-bundle-ID">Learn more</a>.',
'value' => '',
'placeholder' => 'com.companyname.appname',
'required' => true,
'type' => 'text'
],
[
'name' => 'TEAM_ID',
'description' => 'Team ID of the Apple Developer account.',
'value' => '',
'placeholder' => '6K3...5PH',
'required' => true,
'type' => 'text'
],
[
'name' => 'KEY_ID',
'description' => 'Key ID required to communicate with Apple Developer services. <a class="u-bold" target="_blank" href="https://developer.apple.com/help/account/keys/get-a-key-identifier/">Learn more</a>.',
'value' => '',
'placeholder' => '9G8...6YF',
'required' => true,
'type' => 'text'
],
[
'name' => 'KEY_CONTENTS_ENCODED',
'description' => 'Contents of Key required to communicated with Apple Developer services, encoded in Base64. <a class="u-bold" target="_blank" href="https://developer.apple.com/help/account/keys/revoke-edit-and-download-keys">Learn more</a>.',
'value' => '',
'placeholder' => '7x8aA...Ab7c',
'required' => true,
'type' => 'password'
]
],
'scopes' => ['users.read', 'users.write']
]
];
+3 -3
View File
@@ -1006,7 +1006,7 @@ return [
getFramework('NEXTJS', [
'providerRootDirectory' => './',
'installCommand' => 'pnpm install',
'buildCommand' => 'npm run build',
'buildCommand' => 'pnpm build',
]),
],
'vcsProvider' => 'github',
@@ -1015,7 +1015,7 @@ return [
'providerVersion' => '0.1.*',
'variables' => [
[
'name' => 'NEXT_PUBLIC_APPWRITE_FUNCTION_PROJECT_ID',
'name' => 'NEXT_PUBLIC_APPWRITE_FUNCTION_API_ENDPOINT',
'description' => 'Endpoint of Appwrite server',
'value' => '{apiEndpoint}',
'placeholder' => '{apiEndpoint}',
@@ -1023,7 +1023,7 @@ return [
'type' => 'text'
],
[
'name' => 'NEXT_PUBLIC_APPWRITE_FUNCTION_API_ENDPOINT',
'name' => 'NEXT_PUBLIC_APPWRITE_FUNCTION_PROJECT_ID',
'description' => 'Your Appwrite project ID',
'value' => '{projectId}',
'placeholder' => '{projectId}',
+318 -131
View File
@@ -25,6 +25,7 @@ use Appwrite\Network\Validator\Redirect;
use Appwrite\OpenSSL\OpenSSL;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Deprecated;
use Appwrite\SDK\Method;
use Appwrite\SDK\MethodType;
use Appwrite\SDK\Response as SDKResponse;
@@ -1917,7 +1918,7 @@ App::post('/v1/account/tokens/magic-url')
))
->label('abuse-limit', 60)
->label('abuse-key', ['url:{url},email:{param-email}', 'url:{url},ip:{ip}'])
->param('userId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('userId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.')
->param('email', '', new Email(), 'User email.')
->param('url', '', fn ($platforms, $devKey) => $devKey->isEmpty() ? new Redirect($platforms) : new URL(), 'URL to redirect the user back to your app from the magic URL login. Only URLs from hostnames in your project platform list are allowed. This requirement helps to prevent an [open redirect](https://cheatsheetseries.owasp.org/cheatsheets/Unvalidated_Redirects_and_Forwards_Cheat_Sheet.html) attack against your project API.', true, ['platforms', 'devKey'])
->param('phrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow.', true)
@@ -2170,7 +2171,7 @@ App::post('/v1/account/tokens/email')
))
->label('abuse-limit', 10)
->label('abuse-key', ['url:{url},email:{param-email}', 'url:{url},ip:{ip}'])
->param('userId', '', new CustomId(), 'User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('userId', '', new CustomId(), 'User ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars. If the email address has never been used, a new account is created using the provided userId. Otherwise, if the email address is already attached to an account, the user ID is ignored.')
->param('email', '', new Email(), 'User email.')
->param('phrase', false, new Boolean(), 'Toggle for security phrase. If enabled, email will be send with a randomly generated phrase and the phrase will also be included in the response. Confirming phrases match increases the security of your authentication flow.', true)
->inject('request')
@@ -2418,7 +2419,10 @@ App::put('/v1/account/sessions/magic-url')
)
],
contentType: ContentType::JSON,
deprecated: true,
deprecated: new Deprecated(
since: '1.6.0',
replaceWith: 'account.createSession'
),
))
->label('abuse-limit', 10)
->label('abuse-key', 'ip:{ip},userId:{param-userId}')
@@ -2456,7 +2460,10 @@ App::put('/v1/account/sessions/phone')
)
],
contentType: ContentType::JSON,
deprecated: true,
deprecated: new Deprecated(
since: '1.6.0',
replaceWith: 'account.createSession'
),
))
->label('abuse-limit', 10)
->label('abuse-key', 'ip:{ip},userId:{param-userId}')
@@ -2498,7 +2505,7 @@ App::post('/v1/account/tokens/phone')
))
->label('abuse-limit', 10)
->label('abuse-key', ['url:{url},phone:{param-phone}', 'url:{url},ip:{ip}'])
->param('userId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('userId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars. If the phone number has never been used, a new account is created using the provided userId. Otherwise, if the phone number is already attached to an account, the user ID is ignored.')
->param('phone', '', new Phone(), 'Phone number. Format this number with a leading \'+\' and a country code, e.g., +16175551212.')
->inject('request')
->inject('response')
@@ -4008,20 +4015,40 @@ App::get('/v1/account/mfa/factors')
->desc('List factors')
->groups(['api', 'account', 'mfa'])
->label('scope', 'account')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'listMfaFactors',
description: '/docs/references/account/list-mfa-factors.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_FACTORS,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'listMfaFactors',
description: '/docs/references/account/list-mfa-factors.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_FACTORS,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.listMFAFactors',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'listMFAFactors',
description: '/docs/references/account/list-mfa-factors.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_FACTORS,
)
],
contentType: ContentType::JSON
)
])
->inject('response')
->inject('user')
->action(function (Response $response, Document $user) {
@@ -4049,20 +4076,40 @@ App::post('/v1/account/mfa/authenticators/:type')
->label('audits.event', 'user.update')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'createMfaAuthenticator',
description: '/docs/references/account/create-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_TYPE,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'createMfaAuthenticator',
description: '/docs/references/account/create-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_TYPE,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.createMFAAuthenticator',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'createMFAAuthenticator',
description: '/docs/references/account/create-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_TYPE,
)
],
contentType: ContentType::JSON
)
])
->param('type', null, new WhiteList([Type::TOTP]), 'Type of authenticator. Must be `' . Type::TOTP . '`')
->inject('requestTimestamp')
->inject('response')
@@ -4126,20 +4173,40 @@ App::put('/v1/account/mfa/authenticators/:type')
->label('audits.event', 'user.update')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMfaAuthenticator',
description: '/docs/references/account/update-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_USER,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMfaAuthenticator',
description: '/docs/references/account/update-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_USER,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.updateMFAAuthenticator',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMFAAuthenticator',
description: '/docs/references/account/update-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_USER,
)
],
contentType: ContentType::JSON
)
])
->param('type', null, new WhiteList([Type::TOTP]), 'Type of authenticator.')
->param('otp', '', new Text(256), 'Valid verification token.')
->inject('response')
@@ -4196,20 +4263,40 @@ App::post('/v1/account/mfa/recovery-codes')
->label('audits.event', 'user.update')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'createMfaRecoveryCodes',
description: '/docs/references/account/create-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'createMfaRecoveryCodes',
description: '/docs/references/account/create-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.createMFARecoveryCodes',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'createMFARecoveryCodes',
description: '/docs/references/account/create-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON
)
])
->inject('response')
->inject('user')
->inject('dbForProject')
@@ -4243,20 +4330,40 @@ App::patch('/v1/account/mfa/recovery-codes')
->label('audits.event', 'user.update')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMfaRecoveryCodes',
description: '/docs/references/account/update-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMfaRecoveryCodes',
description: '/docs/references/account/update-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.updateMFARecoveryCodes',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMFARecoveryCodes',
description: '/docs/references/account/update-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON
)
])
->inject('dbForProject')
->inject('response')
->inject('user')
@@ -4285,20 +4392,40 @@ App::get('/v1/account/mfa/recovery-codes')
->desc('List MFA recovery codes')
->groups(['api', 'account', 'mfaProtected'])
->label('scope', 'account')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'getMfaRecoveryCodes',
description: '/docs/references/account/get-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'getMfaRecoveryCodes',
description: '/docs/references/account/get-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.getMFARecoveryCodes',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'getMFARecoveryCodes',
description: '/docs/references/account/get-mfa-recovery-codes.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
contentType: ContentType::JSON
)
])
->inject('response')
->inject('user')
->action(function (Response $response, Document $user) {
@@ -4324,20 +4451,40 @@ App::delete('/v1/account/mfa/authenticators/:type')
->label('audits.event', 'user.update')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'deleteMfaAuthenticator',
description: '/docs/references/account/delete-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
contentType: ContentType::NONE
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'deleteMfaAuthenticator',
description: '/docs/references/account/delete-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
contentType: ContentType::NONE,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.deleteMFAAuthenticator',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'deleteMFAAuthenticator',
description: '/docs/references/account/delete-mfa-authenticator.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
contentType: ContentType::NONE
)
])
->param('type', null, new WhiteList([Type::TOTP]), 'Type of authenticator.')
->inject('response')
->inject('user')
@@ -4370,20 +4517,40 @@ App::post('/v1/account/mfa/challenge')
->label('audits.event', 'challenge.create')
->label('audits.resource', 'user/{response.userId}')
->label('audits.userId', '{response.userId}')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'createMfaChallenge',
description: '/docs/references/account/create-mfa-challenge.md',
auth: [],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_CHALLENGE,
)
],
contentType: ContentType::JSON,
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'createMfaChallenge',
description: '/docs/references/account/create-mfa-challenge.md',
auth: [],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_CHALLENGE,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.createMFAChallenge',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'createMFAChallenge',
description: '/docs/references/account/create-mfa-challenge.md',
auth: [],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_CHALLENGE,
)
],
contentType: ContentType::JSON
)
])
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},userId:{userId}')
->param('factor', '', new WhiteList([Type::EMAIL, Type::PHONE, Type::TOTP, Type::RECOVERY_CODE]), 'Factor used for verification. Must be one of following: `' . Type::EMAIL . '`, `' . Type::PHONE . '`, `' . Type::TOTP . '`, `' . Type::RECOVERY_CODE . '`.')
@@ -4592,20 +4759,40 @@ App::put('/v1/account/mfa/challenge')
->label('audits.event', 'challenges.update')
->label('audits.resource', 'user/{response.userId}')
->label('audits.userId', '{response.userId}')
->label('sdk', new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMfaChallenge',
description: '/docs/references/account/update-mfa-challenge.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SESSION,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMfaChallenge',
description: '/docs/references/account/update-mfa-challenge.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SESSION,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'account.updateMFAChallenge',
),
),
new Method(
namespace: 'account',
group: 'mfa',
name: 'updateMFAChallenge',
description: '/docs/references/account/update-mfa-challenge.md',
auth: [AuthType::SESSION, AuthType::JWT],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SESSION,
)
],
contentType: ContentType::JSON
)
])
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},challengeId:{param-challengeId}')
->param('challengeId', '', new Text(256), 'ID of the challenge.')
+1 -1
View File
@@ -474,7 +474,7 @@ App::get('/v1/avatars/favicon')
$sanitizer->minify(true);
$cleanSvg = $sanitizer->sanitize($data);
if ($cleanSvg === false) {
throw new \Exception('SVG sanitization failed');
throw new Exception(Exception::AVATAR_SVG_SANITIZATION_FAILED);
}
$response
->addHeader('Cache-Control', 'private, max-age=2592000') // 30 days
+15 -13
View File
@@ -23,10 +23,12 @@ use Utopia\Storage\Device;
use Utopia\Storage\Device\Local;
use Utopia\Storage\Storage;
use Utopia\System\System;
use Utopia\Validator\AnyOf;
use Utopia\Validator\Domain;
use Utopia\Validator\Integer;
use Utopia\Validator\Multiple;
use Utopia\Validator\Text;
use Utopia\Validator\URL;
use Utopia\Validator\WhiteList;
App::get('/v1/health')
@@ -397,7 +399,7 @@ App::get('/v1/health/certificate')
],
contentType: ContentType::JSON
))
->param('domain', null, new Multiple([new Domain(), new PublicDomain()]), Multiple::TYPE_STRING, 'Domain name')
->param('domain', null, new Multiple([new AnyOf([new URL(), new Domain()]), new PublicDomain()]), Multiple::TYPE_STRING, 'Domain name')
->inject('response')
->action(function (string $domain, Response $response) {
if (filter_var($domain, FILTER_VALIDATE_URL)) {
@@ -554,12 +556,12 @@ App::get('/v1/health/queue/deletes')
contentType: ContentType::JSON
))
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('publisher')
->inject('publisherDeletes')
->inject('response')
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
->action(function (int|string $threshold, Publisher $publisherDeletes, Response $response) {
$threshold = \intval($threshold);
$size = $publisher->getQueueSize(new Queue(Event::DELETE_QUEUE_NAME));
$size = $publisherDeletes->getQueueSize(new Queue(Event::DELETE_QUEUE_NAME));
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
@@ -587,12 +589,12 @@ App::get('/v1/health/queue/mails')
contentType: ContentType::JSON
))
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('publisher')
->inject('publisherMails')
->inject('response')
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
->action(function (int|string $threshold, Publisher $publisherMails, Response $response) {
$threshold = \intval($threshold);
$size = $publisher->getQueueSize(new Queue(Event::MAILS_QUEUE_NAME));
$size = $publisherMails->getQueueSize(new Queue(Event::MAILS_QUEUE_NAME));
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
@@ -620,12 +622,12 @@ App::get('/v1/health/queue/messaging')
contentType: ContentType::JSON
))
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('publisher')
->inject('publisherMessaging')
->inject('response')
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
->action(function (int|string $threshold, Publisher $publisherMessaging, Response $response) {
$threshold = \intval($threshold);
$size = $publisher->getQueueSize(new Queue(Event::MESSAGING_QUEUE_NAME));
$size = $publisherMessaging->getQueueSize(new Queue(Event::MESSAGING_QUEUE_NAME));
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
@@ -686,12 +688,12 @@ App::get('/v1/health/queue/functions')
contentType: ContentType::JSON
))
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('publisher')
->inject('publisherFunctions')
->inject('response')
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
->action(function (int|string $threshold, Publisher $publisherFunctions, Response $response) {
$threshold = \intval($threshold);
$size = $publisher->getQueueSize(new Queue(Event::FUNCTIONS_QUEUE_NAME));
$size = $publisherFunctions->getQueueSize(new Queue(Event::FUNCTIONS_QUEUE_NAME));
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
+260 -107
View File
@@ -13,6 +13,7 @@ use Appwrite\Permission;
use Appwrite\Role;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Deprecated;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Database\Validator\CompoundUID;
@@ -238,19 +239,38 @@ App::post('/v1/messaging/providers/smtp')
->label('event', 'providers.[providerId].create')
->label('scope', 'providers.write')
->label('resourceType', RESOURCE_TYPE_PROVIDERS)
->label('sdk', new Method(
namespace: 'messaging',
group: 'providers',
name: 'createSmtpProvider',
description: '/docs/references/messaging/create-smtp-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'providers',
name: 'createSmtpProvider',
description: '/docs/references/messaging/create-smtp-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.createSMTPProvider',
),
),
new Method(
namespace: 'messaging',
group: 'providers',
name: 'createSMTPProvider',
description: '/docs/references/messaging/create-smtp-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
]
)
])
->param('providerId', '', new CustomId(), 'Provider ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('name', '', new Text(128), 'Provider name.')
->param('host', '', new Text(0), 'SMTP hosts. Either a single hostname or multiple semicolon-delimited hostnames. You can also specify a different port for each host such as `smtp1.example.com:25;smtp2.example.com`. You can also specify encryption type, for example: `tls://smtp1.example.com:587;ssl://smtp2.example.com:465"`. Hosts will be tried in order.')
@@ -752,19 +772,38 @@ App::post('/v1/messaging/providers/fcm')
->label('event', 'providers.[providerId].create')
->label('scope', 'providers.write')
->label('resourceType', RESOURCE_TYPE_PROVIDERS)
->label('sdk', new Method(
namespace: 'messaging',
group: 'providers',
name: 'createFcmProvider',
description: '/docs/references/messaging/create-fcm-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'providers',
name: 'createFcmProvider',
description: '/docs/references/messaging/create-fcm-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.createFCMProvider',
),
),
new Method(
namespace: 'messaging',
group: 'providers',
name: 'createFCMProvider',
description: '/docs/references/messaging/create-fcm-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
]
)
])
->param('providerId', '', new CustomId(), 'Provider ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('name', '', new Text(128), 'Provider name.')
->param('serviceAccountJSON', null, new JSON(), 'FCM service account JSON.', true)
@@ -822,19 +861,38 @@ App::post('/v1/messaging/providers/apns')
->label('event', 'providers.[providerId].create')
->label('scope', 'providers.write')
->label('resourceType', RESOURCE_TYPE_PROVIDERS)
->label('sdk', new Method(
namespace: 'messaging',
group: 'providers',
name: 'createApnsProvider',
description: '/docs/references/messaging/create-apns-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'providers',
name: 'createApnsProvider',
description: '/docs/references/messaging/create-apns-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.createAPNSProvider',
),
),
new Method(
namespace: 'messaging',
group: 'providers',
name: 'createAPNSProvider',
description: '/docs/references/messaging/create-apns-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_PROVIDER,
)
]
)
])
->param('providerId', '', new CustomId(), 'Provider ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('name', '', new Text(128), 'Provider name.')
->param('authKey', '', new Text(0), 'APNS authentication key.', true)
@@ -1322,19 +1380,38 @@ App::patch('/v1/messaging/providers/smtp/:providerId')
->label('event', 'providers.[providerId].update')
->label('scope', 'providers.write')
->label('resourceType', RESOURCE_TYPE_PROVIDERS)
->label('sdk', new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateSmtpProvider',
description: '/docs/references/messaging/update-smtp-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateSmtpProvider',
description: '/docs/references/messaging/update-smtp-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.updateSMTPProvider',
),
),
new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateSMTPProvider',
description: '/docs/references/messaging/update-smtp-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
]
)
])
->param('providerId', '', new UID(), 'Provider ID.')
->param('name', '', new Text(128), 'Provider name.', true)
->param('host', '', new Text(0), 'SMTP hosts. Either a single hostname or multiple semicolon-delimited hostnames. You can also specify a different port for each host such as `smtp1.example.com:25;smtp2.example.com`. You can also specify encryption type, for example: `tls://smtp1.example.com:587;ssl://smtp2.example.com:465"`. Hosts will be tried in order.', true)
@@ -1894,19 +1971,38 @@ App::patch('/v1/messaging/providers/fcm/:providerId')
->label('event', 'providers.[providerId].update')
->label('scope', 'providers.write')
->label('resourceType', RESOURCE_TYPE_PROVIDERS)
->label('sdk', new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateFcmProvider',
description: '/docs/references/messaging/update-fcm-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateFcmProvider',
description: '/docs/references/messaging/update-fcm-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.updateFCMProvider',
),
),
new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateFCMProvider',
description: '/docs/references/messaging/update-fcm-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
]
)
])
->param('providerId', '', new UID(), 'Provider ID.')
->param('name', '', new Text(128), 'Provider name.', true)
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
@@ -1970,19 +2066,38 @@ App::patch('/v1/messaging/providers/apns/:providerId')
->label('event', 'providers.[providerId].update')
->label('scope', 'providers.write')
->label('resourceType', RESOURCE_TYPE_PROVIDERS)
->label('sdk', new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateApnsProvider',
description: '/docs/references/messaging/update-apns-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateApnsProvider',
description: '/docs/references/messaging/update-apns-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.updateAPNSProvider',
),
),
new Method(
namespace: 'messaging',
group: 'providers',
name: 'updateAPNSProvider',
description: '/docs/references/messaging/update-apns-provider.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROVIDER,
)
]
)
])
->param('providerId', '', new UID(), 'Provider ID.')
->param('name', '', new Text(128), 'Provider name.', true)
->param('enabled', null, new Boolean(), 'Set as enabled.', true)
@@ -2896,7 +3011,7 @@ App::post('/v1/messaging/messages/email')
->inject('project')
->inject('queueForMessaging')
->inject('response')
->action(function (string $messageId, string $subject, string $content, array $topics, array $users, array $targets, array $cc, array $bcc, array $attachments, bool $draft, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
->action(function (string $messageId, string $subject, string $content, ?array $topics, ?array $users, ?array $targets, ?array $cc, ?array $bcc, ?array $attachments, bool $draft, bool $html, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
$messageId = $messageId == 'unique()'
? ID::unique()
: $messageId;
@@ -3024,19 +3139,38 @@ App::post('/v1/messaging/messages/sms')
->label('event', 'messages.[messageId].create')
->label('scope', 'messages.write')
->label('resourceType', RESOURCE_TYPE_MESSAGES)
->label('sdk', new Method(
namespace: 'messaging',
group: 'messages',
name: 'createSms',
description: '/docs/references/messaging/create-sms.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MESSAGE,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'messages',
name: 'createSms',
description: '/docs/references/messaging/create-sms.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MESSAGE,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.createSMS',
),
),
new Method(
namespace: 'messaging',
group: 'messages',
name: 'createSMS',
description: '/docs/references/messaging/create-sms.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MESSAGE,
)
]
)
])
->param('messageId', '', new CustomId(), 'Message ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('content', '', new Text(64230), 'SMS Content.')
->param('topics', [], new ArrayList(new UID()), 'List of Topic IDs.', true)
@@ -3050,7 +3184,7 @@ App::post('/v1/messaging/messages/sms')
->inject('project')
->inject('queueForMessaging')
->inject('response')
->action(function (string $messageId, string $content, array $topics, array $users, array $targets, bool $draft, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
->action(function (string $messageId, string $content, ?array $topics, ?array $users, ?array $targets, bool $draft, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
$messageId = $messageId == 'unique()'
? ID::unique()
: $messageId;
@@ -3185,7 +3319,7 @@ App::post('/v1/messaging/messages/push')
->inject('project')
->inject('queueForMessaging')
->inject('response')
->action(function (string $messageId, string $title, string $body, array $topics, array $users, array $targets, ?array $data, string $action, string $image, string $icon, string $sound, string $color, string $tag, int $badge, bool $draft, ?string $scheduledAt, bool $contentAvailable, bool $critical, string $priority, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
->action(function (string $messageId, string $title, string $body, ?array $topics, ?array $users, ?array $targets, ?array $data, string $action, string $image, string $icon, string $sound, string $color, string $tag, int $badge, bool $draft, ?string $scheduledAt, bool $contentAvailable, bool $critical, string $priority, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
$messageId = $messageId == 'unique()'
? ID::unique()
: $messageId;
@@ -3851,19 +3985,38 @@ App::patch('/v1/messaging/messages/sms/:messageId')
->label('event', 'messages.[messageId].update')
->label('scope', 'messages.write')
->label('resourceType', RESOURCE_TYPE_MESSAGES)
->label('sdk', new Method(
namespace: 'messaging',
group: 'messages',
name: 'updateSms',
description: '/docs/references/messaging/update-sms.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MESSAGE,
)
]
))
->label('sdk', [
new Method(
namespace: 'messaging',
group: 'messages',
name: 'updateSms',
description: '/docs/references/messaging/update-sms.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MESSAGE,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'messaging.updateSMS',
),
),
new Method(
namespace: 'messaging',
group: 'messages',
name: 'updateSMS',
description: '/docs/references/messaging/update-sms.md',
auth: [AuthType::ADMIN, AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MESSAGE,
)
]
)
])
->param('messageId', '', new UID(), 'Message ID.')
->param('topics', null, new ArrayList(new UID()), 'List of Topic IDs.', true)
->param('users', null, new ArrayList(new UID()), 'List of User IDs.', true)
+227 -92
View File
@@ -12,6 +12,7 @@ use Appwrite\Network\Platform;
use Appwrite\Network\Validator\Email;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Deprecated;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Template\Template;
@@ -619,19 +620,38 @@ App::patch('/v1/projects/:projectId/api')
->desc('Update API status')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk', new Method(
namespace: 'projects',
group: 'projects',
name: 'updateApiStatus',
description: '/docs/references/projects/update-api-status.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
))
->label('sdk', [
new Method(
namespace: 'projects',
group: 'projects',
name: 'updateApiStatus',
description: '/docs/references/projects/update-api-status.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'projects.updateAPIStatus',
),
),
new Method(
namespace: 'projects',
group: 'projects',
name: 'updateAPIStatus',
description: '/docs/references/projects/update-api-status.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
)
])
->param('projectId', '', new UID(), 'Project unique ID.')
->param('api', '', new WhiteList(array_keys(Config::getParam('apis')), true), 'API name.')
->param('status', null, new Boolean(), 'API status.')
@@ -657,19 +677,38 @@ App::patch('/v1/projects/:projectId/api/all')
->desc('Update all API status')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk', new Method(
namespace: 'projects',
group: 'projects',
name: 'updateApiStatusAll',
description: '/docs/references/projects/update-api-status-all.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
))
->label('sdk', [
new Method(
namespace: 'projects',
group: 'projects',
name: 'updateApiStatusAll',
description: '/docs/references/projects/update-api-status-all.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'projects.updateAPIStatusAll',
),
),
new Method(
namespace: 'projects',
group: 'projects',
name: 'updateAPIStatusAll',
description: '/docs/references/projects/update-api-status-all.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
)
])
->param('projectId', '', new UID(), 'Project unique ID.')
->param('status', null, new Boolean(), 'API status.')
->inject('response')
@@ -2018,19 +2057,38 @@ App::patch('/v1/projects/:projectId/smtp')
->desc('Update SMTP')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk', new Method(
namespace: 'projects',
group: 'templates',
name: 'updateSmtp',
description: '/docs/references/projects/update-smtp.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
))
->label('sdk', [
new Method(
namespace: 'projects',
group: 'templates',
name: 'updateSmtp',
description: '/docs/references/projects/update-smtp.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'projects.updateSMTP',
),
),
new Method(
namespace: 'projects',
group: 'templates',
name: 'updateSMTP',
description: '/docs/references/projects/update-smtp.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_PROJECT,
)
]
)
])
->param('projectId', '', new UID(), 'Project unique ID.')
->param('enabled', false, new Boolean(), 'Enable custom SMTP service')
->param('senderName', '', new Text(255, 0), 'Name of the email sender', true)
@@ -2115,19 +2173,38 @@ App::post('/v1/projects/:projectId/smtp/tests')
->desc('Create SMTP test')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk', new Method(
namespace: 'projects',
group: 'templates',
name: 'createSmtpTest',
description: '/docs/references/projects/create-smtp-test.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
]
))
->label('sdk', [
new Method(
namespace: 'projects',
group: 'templates',
name: 'createSmtpTest',
description: '/docs/references/projects/create-smtp-test.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'projects.createSMTPTest',
),
),
new Method(
namespace: 'projects',
group: 'templates',
name: 'createSMTPTest',
description: '/docs/references/projects/create-smtp-test.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
]
)
])
->param('projectId', '', new UID(), 'Project unique ID.')
->param('emails', [], new ArrayList(new Email(), 10), 'Array of emails to send test email to. Maximum of 10 emails are allowed.')
->param('senderName', System::getEnv('_APP_SYSTEM_EMAIL_NAME', APP_NAME . ' Server'), new Text(255, 0), 'Name of the email sender')
@@ -2190,19 +2267,38 @@ App::get('/v1/projects/:projectId/templates/sms/:type/:locale')
->desc('Get custom SMS template')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk', new Method(
namespace: 'projects',
group: 'templates',
name: 'getSmsTemplate',
description: '/docs/references/projects/get-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
]
))
->label('sdk', [
new Method(
namespace: 'projects',
group: 'templates',
name: 'getSmsTemplate',
description: '/docs/references/projects/get-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'projects.getSMSTemplate',
),
),
new Method(
namespace: 'projects',
group: 'templates',
name: 'getSMSTemplate',
description: '/docs/references/projects/get-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
]
)
])
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['sms'] ?? []), 'Template type')
->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
@@ -2337,19 +2433,38 @@ App::patch('/v1/projects/:projectId/templates/sms/:type/:locale')
->desc('Update custom SMS template')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk', new Method(
namespace: 'projects',
group: 'templates',
name: 'updateSmsTemplate',
description: '/docs/references/projects/update-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
]
))
->label('sdk', [
new Method(
namespace: 'projects',
group: 'templates',
name: 'updateSmsTemplate',
description: '/docs/references/projects/update-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'projects.updateSMSTemplate',
),
),
new Method(
namespace: 'projects',
group: 'templates',
name: 'updateSMSTemplate',
description: '/docs/references/projects/update-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
]
)
])
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['sms'] ?? []), 'Template type')
->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
@@ -2441,20 +2556,40 @@ App::delete('/v1/projects/:projectId/templates/sms/:type/:locale')
->desc('Reset custom SMS template')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('sdk', new Method(
namespace: 'projects',
group: 'templates',
name: 'deleteSmsTemplate',
description: '/docs/references/projects/delete-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
],
contentType: ContentType::JSON
))
->label('sdk', [
new Method(
namespace: 'projects',
group: 'templates',
name: 'deleteSmsTemplate',
description: '/docs/references/projects/delete-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
],
contentType: ContentType::JSON,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'projects.deleteSMSTemplate',
),
),
new Method(
namespace: 'projects',
group: 'templates',
name: 'deleteSMSTemplate',
description: '/docs/references/projects/delete-sms-template.md',
auth: [AuthType::ADMIN],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_SMS_TEMPLATE,
)
],
contentType: ContentType::JSON
)
])
->param('projectId', '', new UID(), 'Project unique ID.')
->param('type', '', new WhiteList(Config::getParam('locale-templates')['sms'] ?? []), 'Template type')
->param('locale', '', fn ($localeCodes) => new WhiteList($localeCodes), 'Template locale', false, ['localeCodes'])
+195 -79
View File
@@ -19,6 +19,7 @@ use Appwrite\Hooks\Hooks;
use Appwrite\Network\Validator\Email;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Deprecated;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Database\Validator\CustomId;
@@ -1756,19 +1757,38 @@ App::patch('/v1/users/:userId/mfa')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('usage.metric', 'users.{scope}.requests.update')
->label('sdk', new Method(
namespace: 'users',
group: 'users',
name: 'updateMfa',
description: '/docs/references/users/update-user-mfa.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_USER,
)
]
))
->label('sdk', [
new Method(
namespace: 'users',
group: 'users',
name: 'updateMfa',
description: '/docs/references/users/update-user-mfa.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_USER,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'users.updateMFA',
),
),
new Method(
namespace: 'users',
group: 'users',
name: 'updateMFA',
description: '/docs/references/users/update-user-mfa.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_USER,
)
]
)
])
->param('userId', '', new UID(), 'User ID.')
->param('mfa', null, new Boolean(), 'Enable or disable MFA.')
->inject('response')
@@ -1796,19 +1816,38 @@ App::get('/v1/users/:userId/mfa/factors')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('usage.metric', 'users.{scope}.requests.read')
->label('sdk', new Method(
namespace: 'users',
group: 'mfa',
name: 'listMfaFactors',
description: '/docs/references/users/list-mfa-factors.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_FACTORS,
)
]
))
->label('sdk', [
new Method(
namespace: 'users',
group: 'mfa',
name: 'listMfaFactors',
description: '/docs/references/users/list-mfa-factors.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_FACTORS,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'users.listMFAFactors',
),
),
new Method(
namespace: 'users',
group: 'mfa',
name: 'listMFAFactors',
description: '/docs/references/users/list-mfa-factors.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_FACTORS,
)
]
)
])
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForProject')
@@ -1835,19 +1874,38 @@ App::get('/v1/users/:userId/mfa/recovery-codes')
->groups(['api', 'users'])
->label('scope', 'users.read')
->label('usage.metric', 'users.{scope}.requests.read')
->label('sdk', new Method(
namespace: 'users',
group: 'mfa',
name: 'getMfaRecoveryCodes',
description: '/docs/references/users/get-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
]
))
->label('sdk', [
new Method(
namespace: 'users',
group: 'mfa',
name: 'getMfaRecoveryCodes',
description: '/docs/references/users/get-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'users.getMFARecoveryCodes',
),
),
new Method(
namespace: 'users',
group: 'mfa',
name: 'getMFARecoveryCodes',
description: '/docs/references/users/get-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
]
)
])
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForProject')
@@ -1880,19 +1938,38 @@ App::patch('/v1/users/:userId/mfa/recovery-codes')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('usage.metric', 'users.{scope}.requests.update')
->label('sdk', new Method(
namespace: 'users',
group: 'mfa',
name: 'createMfaRecoveryCodes',
description: '/docs/references/users/create-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
]
))
->label('sdk', [
new Method(
namespace: 'users',
group: 'mfa',
name: 'createMfaRecoveryCodes',
description: '/docs/references/users/create-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'users.createMFARecoveryCodes',
),
),
new Method(
namespace: 'users',
group: 'mfa',
name: 'createMFARecoveryCodes',
description: '/docs/references/users/create-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_CREATED,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
]
)
])
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForProject')
@@ -1932,19 +2009,38 @@ App::put('/v1/users/:userId/mfa/recovery-codes')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('usage.metric', 'users.{scope}.requests.update')
->label('sdk', new Method(
namespace: 'users',
group: 'mfa',
name: 'updateMfaRecoveryCodes',
description: '/docs/references/users/update-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
]
))
->label('sdk', [
new Method(
namespace: 'users',
group: 'mfa',
name: 'updateMfaRecoveryCodes',
description: '/docs/references/users/update-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
],
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'users.updateMFARecoveryCodes',
),
),
new Method(
namespace: 'users',
group: 'mfa',
name: 'updateMFARecoveryCodes',
description: '/docs/references/users/update-mfa-recovery-codes.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_MFA_RECOVERY_CODES,
)
]
)
])
->param('userId', '', new UID(), 'User ID.')
->inject('response')
->inject('dbForProject')
@@ -1983,20 +2079,40 @@ App::delete('/v1/users/:userId/mfa/authenticators/:type')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('usage.metric', 'users.{scope}.requests.update')
->label('sdk', new Method(
namespace: 'users',
group: 'mfa',
name: 'deleteMfaAuthenticator',
description: '/docs/references/users/delete-mfa-authenticator.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
contentType: ContentType::NONE
))
->label('sdk', [
new Method(
namespace: 'users',
group: 'mfa',
name: 'deleteMfaAuthenticator',
description: '/docs/references/users/delete-mfa-authenticator.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
contentType: ContentType::NONE,
deprecated: new Deprecated(
since: '1.8.0',
replaceWith: 'users.deleteMFAAuthenticator',
),
),
new Method(
namespace: 'users',
group: 'mfa',
name: 'deleteMFAAuthenticator',
description: '/docs/references/users/delete-mfa-authenticator.md',
auth: [AuthType::KEY],
responses: [
new SDKResponse(
code: Response::STATUS_CODE_NOCONTENT,
model: Response::MODEL_NONE,
)
],
contentType: ContentType::NONE
)
])
->param('userId', '', new UID(), 'User ID.')
->param('type', null, new WhiteList([Type::TOTP]), 'Type of authenticator.')
->inject('response')
+35 -30
View File
@@ -28,7 +28,6 @@ use Appwrite\Utopia\Response\Filters\V16 as ResponseV16;
use Appwrite\Utopia\Response\Filters\V17 as ResponseV17;
use Appwrite\Utopia\Response\Filters\V18 as ResponseV18;
use Appwrite\Utopia\Response\Filters\V19 as ResponseV19;
use Appwrite\Utopia\Response\Filters\V20 as ResponseV20;
use Appwrite\Utopia\View;
use Executor\Executor;
use MaxMind\Db\Reader;
@@ -357,11 +356,16 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
}
$executionId = ID::unique();
$headers = \array_merge([], $requestHeaders);
$headers['x-appwrite-execution-id'] = $executionId ?? '';
$headers['x-appwrite-user-id'] = '';
$headers['x-appwrite-country-code'] = '';
$headers['x-appwrite-continent-code'] = '';
$headers['x-appwrite-continent-eu'] = 'false';
$ip = $request->getIP();
$headers['x-appwrite-client-ip'] = $ip;
$jwtExpiry = $resource->getAttribute('timeout', 900) + 60; // 1min extra to account for possible cold-starts
$jwtObj = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', $jwtExpiry, 0);
@@ -373,7 +377,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$headers['x-appwrite-trigger'] = 'http';
$headers['x-appwrite-user-jwt'] = '';
$ip = $headers['x-real-ip'] ?? '';
if (!empty($ip)) {
$record = $geodb->get($ip);
@@ -393,8 +396,6 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
}
$executionId = ID::unique();
$execution = new Document([
'$id' => $executionId,
'$permissions' => [],
@@ -610,6 +611,12 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
}
if ($deployment->getAttribute('resourceType') === 'functions') {
$executionResponse['headers']['x-appwrite-execution-id'] = $execution->getId();
} elseif ($deployment->getAttribute('resourceType') === 'sites') {
$executionResponse['headers']['x-appwrite-log-id'] = $execution->getId();
}
$headersFiltered = [];
foreach ($executionResponse['headers'] as $key => $value) {
if (\in_array(\strtolower($key), FUNCTION_ALLOWLIST_HEADERS_RESPONSE)) {
@@ -617,11 +624,32 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
}
}
// Truncate logs if they exceed the limit
$maxLogLength = APP_FUNCTION_LOG_LENGTH_LIMIT;
$logs = $executionResponse['logs'] ?? '';
if (\is_string($logs) && \strlen($logs) > $maxLogLength) {
$warningMessage = "[WARNING] Logs truncated. The output exceeded {$maxLogLength} characters.\n";
$warningLength = \strlen($warningMessage);
$maxContentLength = max(0, $maxLogLength - $warningLength);
$logs = $warningMessage . ($maxContentLength > 0 ? \substr($logs, -$maxContentLength) : '');
}
// Truncate errors if they exceed the limit
$maxErrorLength = APP_FUNCTION_ERROR_LENGTH_LIMIT;
$errors = $executionResponse['errors'] ?? '';
if (\is_string($errors) && \strlen($errors) > $maxErrorLength) {
$warningMessage = "[WARNING] Errors truncated. The output exceeded {$maxErrorLength} characters.\n";
$warningLength = \strlen($warningMessage);
$maxContentLength = max(0, $maxErrorLength - $warningLength);
$errors = $warningMessage . ($maxContentLength > 0 ? \substr($errors, -$maxContentLength) : '');
}
/** Update execution status */
$status = $executionResponse['statusCode'] >= 500 ? 'failed' : 'completed';
$execution->setAttribute('status', $status);
$execution->setAttribute('logs', $executionResponse['logs']);
$execution->setAttribute('errors', $executionResponse['errors']);
$execution->setAttribute('logs', $logs);
$execution->setAttribute('errors', $errors);
$execution->setAttribute('responseStatusCode', $executionResponse['statusCode']);
$execution->setAttribute('responseHeaders', $headersFiltered);
$execution->setAttribute('duration', $executionResponse['duration']);
@@ -854,7 +882,7 @@ App::init()
}
if (version_compare($requestFormat, '1.8.0', '<')) {
$dbForProject = $getProjectDB($project);
$request->addFilter(new RequestV20($dbForProject, $request->getParams()));
$request->addFilter(new RequestV20($dbForProject, $route->getPathValues($request)));
}
}
@@ -994,9 +1022,6 @@ App::init()
if (version_compare($responseFormat, '1.7.0', '<')) {
$response->addFilter(new ResponseV19());
}
if (version_compare($responseFormat, '1.8.0', '<')) {
$response->addFilter(new ResponseV20());
}
if (version_compare($responseFormat, APP_VERSION_STABLE, '>')) {
$warnings[] = "The current SDK is built for Appwrite " . $responseFormat . ". However, the current Appwrite server version is " . APP_VERSION_STABLE . ". Please downgrade your SDK to match the Appwrite version: https://appwrite.io/docs/sdks";
}
@@ -1035,26 +1060,6 @@ App::init()
$response->addHeader('Access-Control-Allow-Origin', '*');
}
/**
* Deprecation Warning
*/
/** @var \Appwrite\SDK\Method $sdk */
$sdk = $route->getLabel('sdk', false);
$deprecationWarning = 'This route is deprecated. See the updated documentation for improved compatibility and migration details.';
$sdkItems = is_array($sdk) ? $sdk : (!empty($sdk) ? [$sdk] : []);
if (!empty($sdkItems) && count($sdkItems) > 0) {
$allDeprecated = true;
foreach ($sdkItems as $sdkItem) {
if (!$sdkItem->isDeprecated()) {
$allDeprecated = false;
break;
}
}
if ($allDeprecated) {
$warnings[] = $deprecationWarning;
}
}
if (!empty($warnings)) {
$response->addHeader('X-Appwrite-Warning', implode(';', $warnings));
}
+14 -12
View File
@@ -60,6 +60,12 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
return $label;
};
/**
* This isolated event handling for `users.*.create` which is based on a `Database::EVENT_DOCUMENT_CREATE` listener may look odd, but it is **intentional**.
*
* Accounts can be created in many ways beyond `createAccount`
* (anonymous, OAuth, phone, etc.), and those flows are probably not covered in event tests; so we handle this here.
*/
$eventDatabaseListener = function (Document $project, Document $document, Response $response, Event $queueForEvents, Func $queueForFunctions, Webhook $queueForWebhooks, Realtime $queueForRealtime) {
// Only trigger events for user creation with the database listener.
if ($document->getCollection() !== 'users') {
@@ -372,9 +378,9 @@ App::init()
}
// Do now allow access if scope is not allowed
$scope = $route->getLabel('scope', 'none');
if (!\in_array($scope, $scopes)) {
throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE, $user->getAttribute('email', 'User') . ' (role: ' . \strtolower($roles[$role]['label']) . ') missing scope (' . $scope . ')');
$allowed = (array)$route->getLabel('scope', 'none');
if (empty(\array_intersect($allowed, $scopes))) {
throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE, $user->getAttribute('email', 'User') . ' (role: ' . \strtolower($roles[$role]['label']) . ') missing scopes (' . \json_encode($allowed) . ')');
}
// Do not allow access to blocked accounts
@@ -408,6 +414,8 @@ App::init()
->inject('project')
->inject('user')
->inject('publisher')
->inject('publisherFunctions')
->inject('publisherWebhooks')
->inject('queueForEvents')
->inject('queueForMessaging')
->inject('queueForAudits')
@@ -423,7 +431,7 @@ App::init()
->inject('plan')
->inject('devKey')
->inject('telemetry')
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry) use ($usageDatabaseListener, $eventDatabaseListener) {
->action(function (App $utopia, Request $request, Response $response, Document $project, Document $user, Publisher $publisher, Publisher $publisherFunctions, Publisher $publisherWebhooks, Event $queueForEvents, Messaging $queueForMessaging, Audit $queueForAudits, Delete $queueForDeletes, EventDatabase $queueForDatabase, Build $queueForBuilds, StatsUsage $queueForStatsUsage, Database $dbForProject, callable $timelimit, Document $resourceToken, string $mode, ?Key $apiKey, array $plan, Document $devKey, Telemetry $telemetry) use ($usageDatabaseListener, $eventDatabaseListener) {
$route = $utopia->getRoute();
@@ -535,8 +543,8 @@ App::init()
// Clone the queues, to prevent events triggered by the database listener
// from overwriting the events that are supposed to be triggered in the shutdown hook.
$queueForEventsClone = new Event($publisher);
$queueForFunctions = new Func($publisher);
$queueForWebhooks = new Webhook($publisher);
$queueForFunctions = new Func($publisherFunctions);
$queueForWebhooks = new Webhook($publisherWebhooks);
$queueForRealtime = new Realtime();
$dbForProject
@@ -802,12 +810,6 @@ App::shutdown()
}
if (!empty($queueForDatabase->getType())) {
Console::info("Triggering database event: \n" . \json_encode([
'projectId' => $project->getId(),
'databaseId' => $queueForDatabase->getDatabase()?->getId(),
'tableId' => $queueForDatabase->getTable()?->getId() ?? $queueForDatabase->getCollection()?->getId(),
'rowId' => $queueForDatabase->getRow()?->getId() ?? $queueForDatabase->getDocument()?->getId(),
]));
$queueForDatabase->trigger();
}
+3 -1
View File
@@ -149,8 +149,10 @@ const APP_AUTH_TYPE_KEY = 'Key';
const APP_AUTH_TYPE_ADMIN = 'Admin';
// Response related
const MAX_OUTPUT_CHUNK_SIZE = 10 * 1024 * 1024; // 10MB
const APP_FUNCTION_LOG_LENGTH_LIMIT = 1000000;
const APP_FUNCTION_ERROR_LENGTH_LIMIT = 1000000;
// Function headers
const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host'];
const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host', 'x-appwrite-client-ip'];
const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length'];
// Message types
const MESSAGE_TYPE_EMAIL = 'email';
+18 -15
View File
@@ -84,27 +84,30 @@ App::setResource('localeCodes', function () {
App::setResource('publisher', function (Group $pools) {
return new BrokerPool(publisher: $pools->get('publisher'));
}, ['pools']);
App::setResource('publisherDatabases', function (BrokerPool $publisher) {
App::setResource('publisherDatabases', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('publisherMigrations', function (BrokerPool $publisher) {
App::setResource('publisherFunctions', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('publisherStatsUsage', function (BrokerPool $publisher) {
App::setResource('publisherMigrations', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('publisherStatsUsage', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('publisherMails', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('publisherDeletes', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('publisherMessaging', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('publisherWebhooks', function (Publisher $publisher) {
return $publisher;
}, ['publisher']);
App::setResource('consumer', function (Group $pools) {
return new BrokerPool(consumer: $pools->get('consumer'));
}, ['pools']);
App::setResource('consumerDatabases', function (BrokerPool $consumer) {
return $consumer;
}, ['consumer']);
App::setResource('consumerMigrations', function (BrokerPool $consumer) {
return $consumer;
}, ['consumer']);
App::setResource('consumerStatsUsage', function (BrokerPool $consumer) {
return $consumer;
}, ['consumer']);
App::setResource('queueForMessaging', function (Publisher $publisher) {
return new Messaging($publisher);
}, ['publisher']);
+25 -2
View File
@@ -6,9 +6,32 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>404 Not Found</title>
<link rel="preconnect" href="https://assets.appwrite.io/" crossorigin>
<style>
@font-face {
font-family: 'Inter';
src: url('https://assets.appwrite.io/fonts/inter/Inter-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('https://assets.appwrite.io/fonts/inter/Inter-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Fira Code';
src: url('https://assets.appwrite.io/fonts/fira-code/FiraCode-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
</style>
<style>
@import url(https://fonts.bunny.net/css?family=fira-code:400|inter:400);
* {
margin: 0;
padding: 0;
+43 -20
View File
@@ -104,26 +104,38 @@ switch ($type) {
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.x.x/dist/alpine.min.js" defer></script>
<link rel="icon" type="image/svg+xml" href="<?php echo $url; ?>/images/logos/appwrite-icon.svg" />
<link rel="mask-icon" type="image/png" href="<?php echo $url; ?>/images/logos/appwrite-icon.png" />
<link
rel="preload"
href="/fonts/inter/inter-v8-latin-600.woff2"
as="font"
type="font/woff2"
crossorigin />
<link
rel="preload"
href="/fonts/inter/inter-v8-latin-regular.woff2"
as="font"
type="font/woff2"
crossorigin />
<link rel="preconnect" href="https://assets.appwrite.io/" crossorigin>
<style>
@font-face {
font-family: 'Inter';
src: url('https://assets.appwrite.io/fonts/inter/Inter-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Inter';
src: url('https://assets.appwrite.io/fonts/inter/Inter-Medium.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Fira Code';
src: url('https://assets.appwrite.io/fonts/fira-code/FiraCode-Regular.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
</style>
<title><?php echo $this->print($title); ?></title>
<style>
@import url(https://fonts.bunny.net/css?family=fira-code:400|inter:400);
* {
margin: 0;
padding: 0;
@@ -452,9 +464,9 @@ switch ($type) {
</style>
</head>
<body x-data="{ page: 'error' }">
<body>
<div class="main">
<div x-show="page === 'error'" class="content <?php echo $isSimpleMessage ? 'large-error' : 'small-error' ?>">
<div id="views-error" class="content <?php echo $isSimpleMessage ? 'large-error' : 'small-error' ?>">
<div class="center"><span class="<?php echo $this->print($labelClass); ?>"><?php echo $this->print($label); ?></span></div>
<h1><?php echo $this->print($message); ?></h1>
<?php if (!empty($type)): ?>
@@ -474,14 +486,14 @@ switch ($type) {
<?php endif; ?>
<?php if ($development) : ?>
<button class="<?php echo count($buttons) === 0 ? 'bordered-button' : 'button' ?>" x-on:click="page = 'trace'">View error trace</button>
<button class="<?php echo count($buttons) === 0 ? 'bordered-button' : 'button' ?>" onclick="openTraceView()">View error trace</button>
<?php endif; ?>
</div>
</div>
<?php if ($development) : ?>
<div x-show="page === 'trace'" class="error-trace">
<button class="back-button" x-on:click="page = 'error'">
<div id="views-trace" style="display: none;" class="error-trace">
<button class="back-button" onclick="openErrorView()">
Back
</button>
<div class="trace-grid-header">Error trace</div>
@@ -512,6 +524,17 @@ switch ($type) {
<?php endif; ?>
</div>
<script>
function openErrorView() {
document.getElementById('views-trace').style.display = 'none';
document.getElementById('views-error').style.display = 'block';
}
function openTraceView() {
document.getElementById('views-trace').style.display = 'block';
document.getElementById('views-error').style.display = 'none';
}
</script>
</body>
</html>
+1 -1
View File
@@ -179,7 +179,7 @@ $image = $this->getParam('image', '');
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: <?php echo $organization; ?>/console:6.2.0
image: <?php echo $organization; ?>/console:7.0.2
restart: unless-stopped
networks:
- appwrite
+8
View File
@@ -251,6 +251,10 @@ Server::setResource('publisherDatabases', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
Server::setResource('publisherFunctions', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
Server::setResource('publisherMigrations', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
@@ -259,6 +263,10 @@ Server::setResource('publisherStatsUsage', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
Server::setResource('publisherMessaging', function (BrokerPool $publisher) {
return $publisher;
}, ['publisher']);
Server::setResource('consumer', function (Group $pools) {
return new BrokerPool(consumer: $pools->get('consumer'));
}, ['pools']);
Generated
+77 -57
View File
@@ -486,16 +486,16 @@
},
{
"name": "composer/semver",
"version": "3.4.3",
"version": "3.4.4",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12"
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
"url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95",
"reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95",
"shasum": ""
},
"require": {
@@ -547,7 +547,7 @@
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.4.3"
"source": "https://github.com/composer/semver/tree/3.4.4"
},
"funding": [
{
@@ -557,13 +557,9 @@
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2024-09-19T14:15:21+00:00"
"time": "2025-08-20T19:15:30+00:00"
},
{
"name": "dragonmantank/cron-expression",
@@ -898,16 +894,16 @@
},
{
"name": "matomo/device-detector",
"version": "6.4.6",
"version": "6.4.7",
"source": {
"type": "git",
"url": "https://github.com/matomo-org/device-detector.git",
"reference": "6f07f615199851548db47a900815d2ea2cdcde08"
"reference": "e53eed31bb1530851feebe52bd64c3451da19e77"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/6f07f615199851548db47a900815d2ea2cdcde08",
"reference": "6f07f615199851548db47a900815d2ea2cdcde08",
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/e53eed31bb1530851feebe52bd64c3451da19e77",
"reference": "e53eed31bb1530851feebe52bd64c3451da19e77",
"shasum": ""
},
"require": {
@@ -964,7 +960,7 @@
"source": "https://github.com/matomo-org/matomo",
"wiki": "https://dev.matomo.org/"
},
"time": "2025-06-10T10:00:59+00:00"
"time": "2025-08-20T17:20:16+00:00"
},
{
"name": "mustangostang/spyc",
@@ -2780,7 +2776,7 @@
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.32.0",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
@@ -2841,7 +2837,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.32.0"
"source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0"
},
"funding": [
{
@@ -2852,6 +2848,10 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
@@ -2861,7 +2861,7 @@
},
{
"name": "symfony/polyfill-php82",
"version": "v1.32.0",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php82.git",
@@ -2917,7 +2917,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php82/tree/v1.32.0"
"source": "https://github.com/symfony/polyfill-php82/tree/v1.33.0"
},
"funding": [
{
@@ -2928,6 +2928,10 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
@@ -3553,16 +3557,16 @@
},
{
"name": "utopia-php/database",
"version": "1.0.2",
"version": "1.2.3",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "e194da3ff803c51486d343c88156619fec9d1531"
"reference": "8a536fead840d9da6ee819fe6b80e0f047997f69"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/e194da3ff803c51486d343c88156619fec9d1531",
"reference": "e194da3ff803c51486d343c88156619fec9d1531",
"url": "https://api.github.com/repos/utopia-php/database/zipball/8a536fead840d9da6ee819fe6b80e0f047997f69",
"reference": "8a536fead840d9da6ee819fe6b80e0f047997f69",
"shasum": ""
},
"require": {
@@ -3603,9 +3607,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/1.0.2"
"source": "https://github.com/utopia-php/database/tree/1.2.3"
},
"time": "2025-08-15T07:11:01+00:00"
"time": "2025-08-27T11:47:04+00:00"
},
{
"name": "utopia-php/detector",
@@ -3857,16 +3861,16 @@
},
{
"name": "utopia-php/framework",
"version": "0.33.20",
"version": "0.33.22",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/http.git",
"reference": "e1c7ab4e0b5b0a9a70256b1e00912e101e76a131"
"reference": "c01a815cb976c9255e045fc3bcc3f5fcf477e0bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/http/zipball/e1c7ab4e0b5b0a9a70256b1e00912e101e76a131",
"reference": "e1c7ab4e0b5b0a9a70256b1e00912e101e76a131",
"url": "https://api.github.com/repos/utopia-php/http/zipball/c01a815cb976c9255e045fc3bcc3f5fcf477e0bc",
"reference": "c01a815cb976c9255e045fc3bcc3f5fcf477e0bc",
"shasum": ""
},
"require": {
@@ -3898,9 +3902,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/http/issues",
"source": "https://github.com/utopia-php/http/tree/0.33.20"
"source": "https://github.com/utopia-php/http/tree/0.33.22"
},
"time": "2025-05-18T23:51:21+00:00"
"time": "2025-08-26T10:29:50+00:00"
},
{
"name": "utopia-php/image",
@@ -4922,16 +4926,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.41.29",
"version": "1.1.15",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "4af563f3b0879747efc8434eb8ed8bf97e75039f"
"reference": "8e8e39634ba7558704522959d88f3542563a5444"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/4af563f3b0879747efc8434eb8ed8bf97e75039f",
"reference": "4af563f3b0879747efc8434eb8ed8bf97e75039f",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/8e8e39634ba7558704522959d88f3542563a5444",
"reference": "8e8e39634ba7558704522959d88f3542563a5444",
"shasum": ""
},
"require": {
@@ -4967,9 +4971,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": {
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/0.41.29"
"source": "https://github.com/appwrite/sdk-generator/tree/1.1.15"
},
"time": "2025-08-04T04:34:45+00:00"
"time": "2025-08-27T04:59:35+00:00"
},
{
"name": "doctrine/annotations",
@@ -6151,16 +6155,16 @@
},
{
"name": "phpunit/phpunit",
"version": "9.6.24",
"version": "9.6.25",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
"reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701"
"reference": "049c011e01be805202d8eebedef49f769a8ec7b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea49afa29aeea25ea7bf9de9fdd7cab163cc0701",
"reference": "ea49afa29aeea25ea7bf9de9fdd7cab163cc0701",
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/049c011e01be805202d8eebedef49f769a8ec7b7",
"reference": "049c011e01be805202d8eebedef49f769a8ec7b7",
"shasum": ""
},
"require": {
@@ -6234,7 +6238,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
"security": "https://github.com/sebastianbergmann/phpunit/security/policy",
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.24"
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.25"
},
"funding": [
{
@@ -6258,7 +6262,7 @@
"type": "tidelift"
}
],
"time": "2025-08-10T08:32:42+00:00"
"time": "2025-08-20T14:38:31+00:00"
},
{
"name": "psr/cache",
@@ -7713,7 +7717,7 @@
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.32.0",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
@@ -7772,7 +7776,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.32.0"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0"
},
"funding": [
{
@@ -7783,6 +7787,10 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
@@ -7792,16 +7800,16 @@
},
{
"name": "symfony/polyfill-intl-grapheme",
"version": "v1.32.0",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe"
"reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
"reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70",
"reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70",
"shasum": ""
},
"require": {
@@ -7850,7 +7858,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.32.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0"
},
"funding": [
{
@@ -7861,16 +7869,20 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-09-09T11:45:10+00:00"
"time": "2025-06-27T09:58:17+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
"version": "v1.32.0",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
@@ -7931,7 +7943,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.32.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0"
},
"funding": [
{
@@ -7942,6 +7954,10 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
@@ -7951,7 +7967,7 @@
},
{
"name": "symfony/polyfill-php81",
"version": "v1.32.0",
"version": "v1.33.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php81.git",
@@ -8007,7 +8023,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php81/tree/v1.32.0"
"source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0"
},
"funding": [
{
@@ -8018,6 +8034,10 @@
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://github.com/nicolas-grekas",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
@@ -8407,7 +8427,7 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
@@ -8431,5 +8451,5 @@
"platform-overrides": {
"php": "8.3"
},
"plugin-api-version": "2.3.0"
"plugin-api-version": "2.6.0"
}
+4 -1
View File
@@ -71,6 +71,9 @@ services:
- traefik.http.routers.appwrite_api_https.service=appwrite_api
- traefik.http.routers.appwrite_api_https.tls=true
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Only needed for tests
- ./docker-compose.yml:/usr/src/code/docker-compose.yml # Only needed for tests
- ./.env:/usr/src/code/.env # Only needed for tests
- appwrite-uploads:/storage/uploads:rw
- appwrite-imports:/storage/imports:rw
- appwrite-cache:/storage/cache:rw
@@ -216,7 +219,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:7.0.0-qa.8
image: appwrite/console:7.0.2
restart: unless-stopped
networks:
- appwrite
@@ -9,7 +9,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.createMfaAuthenticator(
account.createMFAAuthenticator(
AuthenticatorType.TOTP, // type
new CoroutineCallback<>((result, error) -> {
if (error != null) {
@@ -9,7 +9,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.createMfaChallenge(
account.createMFAChallenge(
AuthenticationFactor.EMAIL, // factor
new CoroutineCallback<>((result, error) -> {
if (error != null) {
@@ -8,7 +8,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.createMfaRecoveryCodes(new CoroutineCallback<>((result, error) -> {
account.createMFARecoveryCodes(new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
@@ -9,7 +9,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.deleteMfaAuthenticator(
account.deleteMFAAuthenticator(
AuthenticatorType.TOTP, // type
new CoroutineCallback<>((result, error) -> {
if (error != null) {
@@ -8,7 +8,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.getMfaRecoveryCodes(new CoroutineCallback<>((result, error) -> {
account.getMFARecoveryCodes(new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
@@ -8,7 +8,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.listMfaFactors(new CoroutineCallback<>((result, error) -> {
account.listMFAFactors(new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
@@ -9,7 +9,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.updateMfaAuthenticator(
account.updateMFAAuthenticator(
AuthenticatorType.TOTP, // type
"<OTP>", // otp
new CoroutineCallback<>((result, error) -> {
@@ -8,7 +8,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.updateMfaChallenge(
account.updateMFAChallenge(
"<CHALLENGE_ID>", // challengeId
"<OTP>", // otp
new CoroutineCallback<>((result, error) -> {
@@ -8,7 +8,7 @@ Client client = new Client(context)
Account account = new Account(client);
account.updateMfaRecoveryCodes(new CoroutineCallback<>((result, error) -> {
account.updateMFARecoveryCodes(new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
@@ -4,15 +4,17 @@ import io.appwrite.services.Databases;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setAdmin("") //
.setKey(""); //
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Databases databases = new Databases(client);
databases.createDocuments(
databases.decrementDocumentAttribute(
"<DATABASE_ID>", // databaseId
"<COLLECTION_ID>", // collectionId
listOf(), // documents
"<DOCUMENT_ID>", // documentId
"", // attribute
0, // value (optional)
0, // min (optional)
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
@@ -0,0 +1,27 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Databases;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Databases databases = new Databases(client);
databases.incrementDocumentAttribute(
"<DATABASE_ID>", // databaseId
"<COLLECTION_ID>", // collectionId
"<DOCUMENT_ID>", // documentId
"", // attribute
0, // value (optional)
0, // max (optional)
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
}
Log.d("Appwrite", result.toString());
})
);
@@ -1,14 +1,14 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Grids;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Grids grids = new Grids(client);
TablesDB tablesDB = new TablesDB(client);
grids.createRow(
tablesDB.createRow(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
@@ -0,0 +1,27 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
TablesDB tablesDB = new TablesDB(client);
tablesDB.decrementRowColumn(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
"", // column
0, // value (optional)
0, // min (optional)
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
}
Log.d("Appwrite", result.toString());
})
);
@@ -1,14 +1,14 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Grids;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Grids grids = new Grids(client);
TablesDB tablesDB = new TablesDB(client);
grids.deleteRow(
tablesDB.deleteRow(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
@@ -1,14 +1,14 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Grids;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Grids grids = new Grids(client);
TablesDB tablesDB = new TablesDB(client);
grids.getRow(
tablesDB.getRow(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
@@ -0,0 +1,27 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
TablesDB tablesDB = new TablesDB(client);
tablesDB.incrementRowColumn(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
"", // column
0, // value (optional)
0, // max (optional)
new CoroutineCallback<>((result, error) -> {
if (error != null) {
error.printStackTrace();
return;
}
Log.d("Appwrite", result.toString());
})
);
@@ -1,14 +1,14 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Grids;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Grids grids = new Grids(client);
TablesDB tablesDB = new TablesDB(client);
grids.listRows(
tablesDB.listRows(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
listOf(), // queries (optional)
@@ -1,14 +1,14 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Grids;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Grids grids = new Grids(client);
TablesDB tablesDB = new TablesDB(client);
grids.updateRow(
tablesDB.updateRow(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
@@ -1,14 +1,14 @@
import io.appwrite.Client;
import io.appwrite.coroutines.CoroutineCallback;
import io.appwrite.services.Grids;
import io.appwrite.services.TablesDB;
Client client = new Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>"); // Your project ID
Grids grids = new Grids(client);
TablesDB tablesDB = new TablesDB(client);
grids.upsertRow(
tablesDB.upsertRow(
"<DATABASE_ID>", // databaseId
"<TABLE_ID>", // tableId
"<ROW_ID>", // rowId
@@ -9,6 +9,6 @@ val client = Client(context)
val account = Account(client)
val result = account.createMfaAuthenticator(
val result = account.createMFAAuthenticator(
type = AuthenticatorType.TOTP,
)
@@ -9,6 +9,6 @@ val client = Client(context)
val account = Account(client)
val result = account.createMfaChallenge(
val result = account.createMFAChallenge(
factor = AuthenticationFactor.EMAIL,
)
@@ -8,4 +8,4 @@ val client = Client(context)
val account = Account(client)
val result = account.createMfaRecoveryCodes()
val result = account.createMFARecoveryCodes()
@@ -9,6 +9,6 @@ val client = Client(context)
val account = Account(client)
val result = account.deleteMfaAuthenticator(
val result = account.deleteMFAAuthenticator(
type = AuthenticatorType.TOTP,
)
@@ -8,4 +8,4 @@ val client = Client(context)
val account = Account(client)
val result = account.getMfaRecoveryCodes()
val result = account.getMFARecoveryCodes()
@@ -8,4 +8,4 @@ val client = Client(context)
val account = Account(client)
val result = account.listMfaFactors()
val result = account.listMFAFactors()
@@ -9,7 +9,7 @@ val client = Client(context)
val account = Account(client)
val result = account.updateMfaAuthenticator(
val result = account.updateMFAAuthenticator(
type = AuthenticatorType.TOTP,
otp = "<OTP>",
)
@@ -8,7 +8,7 @@ val client = Client(context)
val account = Account(client)
val result = account.updateMfaChallenge(
val result = account.updateMFAChallenge(
challengeId = "<CHALLENGE_ID>",
otp = "<OTP>",
)
@@ -8,4 +8,4 @@ val client = Client(context)
val account = Account(client)
val result = account.updateMfaRecoveryCodes()
val result = account.updateMFARecoveryCodes()
@@ -4,13 +4,15 @@ import io.appwrite.services.Databases
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setAdmin("") //
.setKey("") //
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val databases = Databases(client)
val result = databases.createDocuments(
val result = databases.decrementDocumentAttribute(
databaseId = "<DATABASE_ID>",
collectionId = "<COLLECTION_ID>",
documents = listOf(),
documentId = "<DOCUMENT_ID>",
attribute = "",
value = 0, // (optional)
min = 0, // (optional)
)
@@ -0,0 +1,18 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Databases
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val databases = Databases(client)
val result = databases.incrementDocumentAttribute(
databaseId = "<DATABASE_ID>",
collectionId = "<COLLECTION_ID>",
documentId = "<DOCUMENT_ID>",
attribute = "",
value = 0, // (optional)
max = 0, // (optional)
)
@@ -1,14 +1,14 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Grids
import io.appwrite.services.TablesDB
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val grids = Grids(client)
val tablesDB = TablesDB(client)
val result = grids.createRow(
val result = tablesDB.createRow(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
rowId = "<ROW_ID>",
@@ -0,0 +1,18 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.TablesDB
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val tablesDB = TablesDB(client)
val result = tablesDB.decrementRowColumn(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
rowId = "<ROW_ID>",
column = "",
value = 0, // (optional)
min = 0, // (optional)
)
@@ -1,14 +1,14 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Grids
import io.appwrite.services.TablesDB
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val grids = Grids(client)
val tablesDB = TablesDB(client)
val result = grids.deleteRow(
val result = tablesDB.deleteRow(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
rowId = "<ROW_ID>",
@@ -1,14 +1,14 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Grids
import io.appwrite.services.TablesDB
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val grids = Grids(client)
val tablesDB = TablesDB(client)
val result = grids.getRow(
val result = tablesDB.getRow(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
rowId = "<ROW_ID>",
@@ -0,0 +1,18 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.TablesDB
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val tablesDB = TablesDB(client)
val result = tablesDB.incrementRowColumn(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
rowId = "<ROW_ID>",
column = "",
value = 0, // (optional)
max = 0, // (optional)
)
@@ -1,14 +1,14 @@
import io.appwrite.Client
import io.appwrite.coroutines.CoroutineCallback
import io.appwrite.services.Grids
import io.appwrite.services.TablesDB
val client = Client(context)
.setEndpoint("https://<REGION>.cloud.appwrite.io/v1") // Your API Endpoint
.setProject("<YOUR_PROJECT_ID>") // Your project ID
val grids = Grids(client)
val tablesDB = TablesDB(client)
val result = grids.listRows(
val result = tablesDB.listRows(
databaseId = "<DATABASE_ID>",
tableId = "<TABLE_ID>",
queries = listOf(), // (optional)

Some files were not shown because too many files have changed in this diff Show More