Merge branch '1.6.x' of https://github.com/appwrite/appwrite into multi-region-support

This commit is contained in:
shimon
2025-01-16 15:04:52 +02:00
149 changed files with 7763 additions and 7439 deletions
+2
View File
@@ -175,6 +175,8 @@ jobs:
name: Benchmark
runs-on: ubuntu-latest
needs: setup
permissions:
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
+15 -6147
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+126
View File
@@ -0,0 +1,126 @@
<?php
use Utopia\Database\Database;
use Utopia\Database\Helpers\ID;
return [
'collections' => [
'$collection' => ID::custom('databases'),
'$id' => ID::custom('collections'),
'name' => 'Collections',
'attributes' => [
[
'$id' => ID::custom('databaseInternalId'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => Database::LENGTH_KEY,
'signed' => true,
'required' => true,
'default' => null,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('databaseId'),
'type' => Database::VAR_STRING,
'signed' => true,
'size' => Database::LENGTH_KEY,
'format' => '',
'filters' => [],
'required' => true,
'default' => null,
'array' => false,
],
[
'$id' => ID::custom('name'),
'type' => Database::VAR_STRING,
'size' => 256,
'required' => true,
'signed' => true,
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('enabled'),
'type' => Database::VAR_BOOLEAN,
'signed' => true,
'size' => 0,
'format' => '',
'filters' => [],
'required' => true,
'default' => null,
'array' => false,
],
[
'$id' => ID::custom('documentSecurity'),
'type' => Database::VAR_BOOLEAN,
'signed' => true,
'size' => 0,
'format' => '',
'filters' => [],
'required' => true,
'default' => null,
'array' => false,
],
[
'$id' => ID::custom('attributes'),
'type' => Database::VAR_STRING,
'size' => 1000000,
'required' => false,
'signed' => true,
'array' => false,
'filters' => ['subQueryAttributes'],
],
[
'$id' => ID::custom('indexes'),
'type' => Database::VAR_STRING,
'size' => 1000000,
'required' => false,
'signed' => true,
'array' => false,
'filters' => ['subQueryIndexes'],
],
[
'$id' => ID::custom('search'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 16384,
'signed' => true,
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
],
],
'indexes' => [
[
'$id' => ID::custom('_fulltext_search'),
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [],
],
[
'$id' => ID::custom('_key_name'),
'type' => Database::INDEX_KEY,
'attributes' => ['name'],
'lengths' => [256],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_enabled'),
'type' => Database::INDEX_KEY,
'attributes' => ['enabled'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => ID::custom('_key_documentSecurity'),
'type' => Database::INDEX_KEY,
'attributes' => ['documentSecurity'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
],
]
];
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -1567,7 +1567,8 @@ return [
'required' => false,
'type' => 'number'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-chip',
+10 -10
View File
@@ -245,7 +245,7 @@ return [
[
'key' => 'nodejs',
'name' => 'Node.js',
'version' => '14.1.0',
'version' => '14.2.0',
'url' => 'https://github.com/appwrite/sdk-for-node',
'package' => 'https://www.npmjs.com/package/node-appwrite',
'enabled' => true,
@@ -263,7 +263,7 @@ return [
[
'key' => 'deno',
'name' => 'Deno',
'version' => '12.1.0',
'version' => '12.2.0',
'url' => 'https://github.com/appwrite/sdk-for-deno',
'package' => 'https://deno.land/x/appwrite',
'enabled' => true,
@@ -281,7 +281,7 @@ return [
[
'key' => 'php',
'name' => 'PHP',
'version' => '12.1.0',
'version' => '12.2.0',
'url' => 'https://github.com/appwrite/sdk-for-php',
'package' => 'https://packagist.org/packages/appwrite/appwrite',
'enabled' => true,
@@ -299,7 +299,7 @@ return [
[
'key' => 'python',
'name' => 'Python',
'version' => '6.1.0',
'version' => '6.2.0',
'url' => 'https://github.com/appwrite/sdk-for-python',
'package' => 'https://pypi.org/project/appwrite/',
'enabled' => true,
@@ -317,7 +317,7 @@ return [
[
'key' => 'ruby',
'name' => 'Ruby',
'version' => '12.1.1',
'version' => '12.2.0',
'url' => 'https://github.com/appwrite/sdk-for-ruby',
'package' => 'https://rubygems.org/gems/appwrite',
'enabled' => true,
@@ -335,7 +335,7 @@ return [
[
'key' => 'go',
'name' => 'Go',
'version' => '0.2.0',
'version' => '0.3.0',
'url' => 'https://github.com/appwrite/sdk-for-go',
'package' => 'https://github.com/appwrite/sdk-for-go',
'enabled' => true,
@@ -353,7 +353,7 @@ return [
[
'key' => 'dotnet',
'name' => '.NET',
'version' => '0.10.1',
'version' => '0.11.0',
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
'package' => 'https://www.nuget.org/packages/Appwrite',
'enabled' => true,
@@ -371,7 +371,7 @@ return [
[
'key' => 'dart',
'name' => 'Dart',
'version' => '12.1.0',
'version' => '12.2.0',
'url' => 'https://github.com/appwrite/sdk-for-dart',
'package' => 'https://pub.dev/packages/dart_appwrite',
'enabled' => true,
@@ -389,7 +389,7 @@ return [
[
'key' => 'kotlin',
'name' => 'Kotlin',
'version' => '6.1.0',
'version' => '6.2.0',
'url' => 'https://github.com/appwrite/sdk-for-kotlin',
'package' => 'https://search.maven.org/artifact/io.appwrite/sdk-for-kotlin',
'enabled' => true,
@@ -411,7 +411,7 @@ return [
[
'key' => 'swift',
'name' => 'Swift',
'version' => '6.1.0',
'version' => '6.2.0',
'url' => 'https://github.com/appwrite/sdk-for-swift',
'package' => 'https://github.com/appwrite/sdk-for-swift',
'enabled' => true,
+4 -4
View File
@@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.6.0",
"version": "1.6.1",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@@ -2784,7 +2784,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\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",
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour.\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",
@@ -5766,7 +5766,7 @@
},
"x-appwrite": {
"method": "createSubscriber",
"weight": 382,
"weight": 376,
"cookies": false,
"type": "",
"deprecated": false,
@@ -5851,7 +5851,7 @@
},
"x-appwrite": {
"method": "deleteSubscriber",
"weight": 386,
"weight": 380,
"cookies": false,
"type": "",
"deprecated": false,
+146 -363
View File
@@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.6.0",
"version": "1.6.1",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@@ -2795,7 +2795,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\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",
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour.\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",
@@ -9488,7 +9488,8 @@
"bun-1.0",
"bun-1.1",
"go-1.23",
"static-1"
"static-1",
"flutter-3.24"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -10145,7 +10146,8 @@
"bun-1.0",
"bun-1.1",
"go-1.23",
"static-1"
"static-1",
"flutter-3.24"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -13673,7 +13675,7 @@
},
"x-appwrite": {
"method": "listMessages",
"weight": 390,
"weight": 384,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13751,7 +13753,7 @@
},
"x-appwrite": {
"method": "createEmail",
"weight": 387,
"weight": 381,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13897,7 +13899,7 @@
},
"x-appwrite": {
"method": "updateEmail",
"weight": 394,
"weight": 388,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14045,7 +14047,7 @@
},
"x-appwrite": {
"method": "createPush",
"weight": 389,
"weight": 383,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14120,7 +14122,7 @@
},
"data": {
"type": "object",
"description": "Additional Data for push notification.",
"description": "Additional key-value pair data for push notification.",
"x-example": "{}"
},
"action": {
@@ -14140,7 +14142,7 @@
},
"sound": {
"type": "string",
"description": "Sound for push notification. Available only for Android and IOS Platform.",
"description": "Sound for push notification. Available only for Android and iOS Platform.",
"x-example": "<SOUND>"
},
"color": {
@@ -14154,9 +14156,9 @@
"x-example": "<TAG>"
},
"badge": {
"type": "string",
"description": "Badge for push notification. Available only for IOS Platform.",
"x-example": "<BADGE>"
"type": "integer",
"description": "Badge for push notification. Available only for iOS Platform.",
"x-example": null
},
"draft": {
"type": "boolean",
@@ -14167,12 +14169,31 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device state and may not deliver notifications immediately. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
},
"required": [
"messageId",
"title",
"body"
"messageId"
]
}
}
@@ -14202,7 +14223,7 @@
},
"x-appwrite": {
"method": "updatePush",
"weight": 396,
"weight": 390,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14331,6 +14352,27 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device battery state and may send notifications later. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
}
}
@@ -14361,7 +14403,7 @@
},
"x-appwrite": {
"method": "createSms",
"weight": 388,
"weight": 382,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14472,7 +14514,7 @@
},
"x-appwrite": {
"method": "updateSms",
"weight": 395,
"weight": 389,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14586,7 +14628,7 @@
},
"x-appwrite": {
"method": "getMessage",
"weight": 393,
"weight": 387,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14641,7 +14683,7 @@
},
"x-appwrite": {
"method": "delete",
"weight": 397,
"weight": 391,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14705,7 +14747,7 @@
},
"x-appwrite": {
"method": "listMessageLogs",
"weight": 391,
"weight": 385,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14782,7 +14824,7 @@
},
"x-appwrite": {
"method": "listTargets",
"weight": 392,
"weight": 386,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14859,7 +14901,7 @@
},
"x-appwrite": {
"method": "listProviders",
"weight": 362,
"weight": 356,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14937,7 +14979,7 @@
},
"x-appwrite": {
"method": "createApnsProvider",
"weight": 361,
"weight": 355,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15044,7 +15086,7 @@
},
"x-appwrite": {
"method": "updateApnsProvider",
"weight": 374,
"weight": 368,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15154,7 +15196,7 @@
},
"x-appwrite": {
"method": "createFcmProvider",
"weight": 360,
"weight": 354,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15241,7 +15283,7 @@
},
"x-appwrite": {
"method": "updateFcmProvider",
"weight": 373,
"weight": 367,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15331,7 +15373,7 @@
},
"x-appwrite": {
"method": "createMailgunProvider",
"weight": 352,
"weight": 346,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15448,7 +15490,7 @@
},
"x-appwrite": {
"method": "updateMailgunProvider",
"weight": 365,
"weight": 359,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15568,7 +15610,7 @@
},
"x-appwrite": {
"method": "createMsg91Provider",
"weight": 355,
"weight": 349,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15665,7 +15707,7 @@
},
"x-appwrite": {
"method": "updateMsg91Provider",
"weight": 368,
"weight": 362,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15765,7 +15807,7 @@
},
"x-appwrite": {
"method": "createSendgridProvider",
"weight": 353,
"weight": 347,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15872,7 +15914,7 @@
},
"x-appwrite": {
"method": "updateSendgridProvider",
"weight": 366,
"weight": 360,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15982,7 +16024,7 @@
},
"x-appwrite": {
"method": "createSmtpProvider",
"weight": 354,
"weight": 348,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16127,7 +16169,7 @@
},
"x-appwrite": {
"method": "updateSmtpProvider",
"weight": 367,
"weight": 361,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16274,7 +16316,7 @@
},
"x-appwrite": {
"method": "createTelesignProvider",
"weight": 356,
"weight": 350,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16371,7 +16413,7 @@
},
"x-appwrite": {
"method": "updateTelesignProvider",
"weight": 369,
"weight": 363,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16471,7 +16513,7 @@
},
"x-appwrite": {
"method": "createTextmagicProvider",
"weight": 357,
"weight": 351,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16568,7 +16610,7 @@
},
"x-appwrite": {
"method": "updateTextmagicProvider",
"weight": 370,
"weight": 364,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16668,7 +16710,7 @@
},
"x-appwrite": {
"method": "createTwilioProvider",
"weight": 358,
"weight": 352,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16765,7 +16807,7 @@
},
"x-appwrite": {
"method": "updateTwilioProvider",
"weight": 371,
"weight": 365,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16865,7 +16907,7 @@
},
"x-appwrite": {
"method": "createVonageProvider",
"weight": 359,
"weight": 353,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16962,7 +17004,7 @@
},
"x-appwrite": {
"method": "updateVonageProvider",
"weight": 372,
"weight": 366,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17062,7 +17104,7 @@
},
"x-appwrite": {
"method": "getProvider",
"weight": 364,
"weight": 358,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17117,7 +17159,7 @@
},
"x-appwrite": {
"method": "deleteProvider",
"weight": 375,
"weight": 369,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17181,7 +17223,7 @@
},
"x-appwrite": {
"method": "listProviderLogs",
"weight": 363,
"weight": 357,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17258,7 +17300,7 @@
},
"x-appwrite": {
"method": "listSubscriberLogs",
"weight": 384,
"weight": 378,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17335,7 +17377,7 @@
},
"x-appwrite": {
"method": "listTopics",
"weight": 377,
"weight": 371,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17411,7 +17453,7 @@
},
"x-appwrite": {
"method": "createTopic",
"weight": 376,
"weight": 370,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17496,7 +17538,7 @@
},
"x-appwrite": {
"method": "getTopic",
"weight": 379,
"weight": 373,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17558,7 +17600,7 @@
},
"x-appwrite": {
"method": "updateTopic",
"weight": 380,
"weight": 374,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17637,7 +17679,7 @@
},
"x-appwrite": {
"method": "deleteTopic",
"weight": 381,
"weight": 375,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17701,7 +17743,7 @@
},
"x-appwrite": {
"method": "listTopicLogs",
"weight": 378,
"weight": 372,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17778,7 +17820,7 @@
},
"x-appwrite": {
"method": "listSubscribers",
"weight": 383,
"weight": 377,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17864,7 +17906,7 @@
},
"x-appwrite": {
"method": "createSubscriber",
"weight": 382,
"weight": 376,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17956,7 +17998,7 @@
},
"x-appwrite": {
"method": "getSubscriber",
"weight": 385,
"weight": 379,
"cookies": false,
"type": "",
"deprecated": false,
@@ -18021,7 +18063,7 @@
},
"x-appwrite": {
"method": "deleteSubscriber",
"weight": 386,
"weight": 380,
"cookies": false,
"type": "",
"deprecated": false,
@@ -18098,7 +18140,7 @@
},
"x-appwrite": {
"method": "list",
"weight": 339,
"weight": 338,
"cookies": false,
"type": "",
"deprecated": false,
@@ -18264,7 +18306,7 @@
},
"x-appwrite": {
"method": "getAppwriteReport",
"weight": 341,
"weight": 340,
"cookies": false,
"type": "",
"deprecated": false,
@@ -18339,7 +18381,7 @@
},
"\/migrations\/firebase": {
"post": {
"summary": "Migrate Firebase data (Service Account)",
"summary": "Migrate Firebase data",
"operationId": "migrationsCreateFirebaseMigration",
"tags": [
"migrations"
@@ -18359,7 +18401,7 @@
},
"x-appwrite": {
"method": "createFirebaseMigration",
"weight": 336,
"weight": 335,
"cookies": false,
"type": "",
"deprecated": false,
@@ -18415,177 +18457,6 @@
}
}
},
"\/migrations\/firebase\/deauthorize": {
"get": {
"summary": "Revoke Appwrite's authorization to access Firebase projects",
"operationId": "migrationsDeleteFirebaseAuth",
"tags": [
"migrations"
],
"description": "",
"responses": {
"200": {
"description": "File"
}
},
"x-appwrite": {
"method": "deleteFirebaseAuth",
"weight": 347,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "migrations\/delete-firebase-auth.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
"scope": "migrations.write",
"platforms": [
"console"
],
"packaging": false,
"offline-model": "",
"offline-key": "",
"offline-response-key": "$id",
"auth": {
"Project": []
}
},
"security": [
{
"Project": []
}
]
}
},
"\/migrations\/firebase\/oauth": {
"post": {
"summary": "Migrate Firebase data (OAuth)",
"operationId": "migrationsCreateFirebaseOAuthMigration",
"tags": [
"migrations"
],
"description": "",
"responses": {
"202": {
"description": "Migration",
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/migration"
}
}
}
}
},
"x-appwrite": {
"method": "createFirebaseOAuthMigration",
"weight": 335,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "migrations\/create-firebase-o-auth-migration.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/migrations\/migration-firebase.md",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
"scope": "migrations.write",
"platforms": [
"console"
],
"packaging": false,
"offline-model": "",
"offline-key": "",
"offline-response-key": "$id",
"auth": {
"Project": []
}
},
"security": [
{
"Project": []
}
],
"requestBody": {
"content": {
"application\/json": {
"schema": {
"type": "object",
"properties": {
"resources": {
"type": "array",
"description": "List of resources to migrate",
"x-example": null,
"items": {
"type": "string"
}
},
"projectId": {
"type": "string",
"description": "Project ID of the Firebase Project",
"x-example": "<PROJECT_ID>"
}
},
"required": [
"resources",
"projectId"
]
}
}
}
}
}
},
"\/migrations\/firebase\/projects": {
"get": {
"summary": "List Firebase projects",
"operationId": "migrationsListFirebaseProjects",
"tags": [
"migrations"
],
"description": "",
"responses": {
"200": {
"description": "Migrations Firebase Projects List",
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/firebaseProjectList"
}
}
}
}
},
"x-appwrite": {
"method": "listFirebaseProjects",
"weight": 346,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "migrations\/list-firebase-projects.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
"scope": "migrations.read",
"platforms": [
"console"
],
"packaging": false,
"offline-model": "",
"offline-key": "",
"offline-response-key": "$id",
"auth": {
"Project": []
}
},
"security": [
{
"Project": []
}
]
}
},
"\/migrations\/firebase\/report": {
"get": {
"summary": "Generate a report on Firebase data",
@@ -18608,7 +18479,7 @@
},
"x-appwrite": {
"method": "getFirebaseReport",
"weight": 342,
"weight": 341,
"cookies": false,
"type": "",
"deprecated": false,
@@ -18660,80 +18531,6 @@
]
}
},
"\/migrations\/firebase\/report\/oauth": {
"get": {
"summary": "Generate a report on Firebase data using OAuth",
"operationId": "migrationsGetFirebaseReportOAuth",
"tags": [
"migrations"
],
"description": "",
"responses": {
"200": {
"description": "Migration Report",
"content": {
"application\/json": {
"schema": {
"$ref": "#\/components\/schemas\/migrationReport"
}
}
}
}
},
"x-appwrite": {
"method": "getFirebaseReportOAuth",
"weight": 343,
"cookies": false,
"type": "",
"deprecated": false,
"demo": "migrations\/get-firebase-report-o-auth.md",
"edit": "https:\/\/github.com\/appwrite\/appwrite\/edit\/master\/docs\/references\/migrations\/migration-firebase-report.md",
"rate-limit": 0,
"rate-time": 3600,
"rate-key": "url:{url},ip:{ip}",
"scope": "migrations.write",
"platforms": [
"console"
],
"packaging": false,
"offline-model": "",
"offline-key": "",
"offline-response-key": "$id",
"auth": {
"Project": []
}
},
"security": [
{
"Project": []
}
],
"parameters": [
{
"name": "resources",
"description": "List of resources to migrate",
"required": true,
"schema": {
"type": "array",
"items": {
"type": "string"
}
},
"in": "query"
},
{
"name": "projectId",
"description": "Project ID",
"required": true,
"schema": {
"type": "string",
"x-example": "<PROJECT_ID>"
},
"in": "query"
}
]
}
},
"\/migrations\/nhost": {
"post": {
"summary": "Migrate NHost data",
@@ -18756,7 +18553,7 @@
},
"x-appwrite": {
"method": "createNHostMigration",
"weight": 338,
"weight": 337,
"cookies": false,
"type": "",
"deprecated": false,
@@ -18869,7 +18666,7 @@
},
"x-appwrite": {
"method": "getNHostReport",
"weight": 349,
"weight": 343,
"cookies": false,
"type": "",
"deprecated": false,
@@ -19004,7 +18801,7 @@
},
"x-appwrite": {
"method": "createSupabaseMigration",
"weight": 337,
"weight": 336,
"cookies": false,
"type": "",
"deprecated": false,
@@ -19111,7 +18908,7 @@
},
"x-appwrite": {
"method": "getSupabaseReport",
"weight": 348,
"weight": 342,
"cookies": false,
"type": "",
"deprecated": false,
@@ -19237,7 +19034,7 @@
},
"x-appwrite": {
"method": "get",
"weight": 340,
"weight": 339,
"cookies": false,
"type": "",
"deprecated": false,
@@ -19297,7 +19094,7 @@
},
"x-appwrite": {
"method": "retry",
"weight": 350,
"weight": 344,
"cookies": false,
"type": "",
"deprecated": false,
@@ -19350,7 +19147,7 @@
},
"x-appwrite": {
"method": "delete",
"weight": 351,
"weight": 345,
"cookies": false,
"type": "",
"deprecated": false,
@@ -32749,30 +32546,6 @@
"migrations"
]
},
"firebaseProjectList": {
"description": "Migrations Firebase Projects List",
"type": "object",
"properties": {
"total": {
"type": "integer",
"description": "Total number of projects documents that matched your query.",
"x-example": 5,
"format": "int32"
},
"projects": {
"type": "array",
"description": "List of projects.",
"items": {
"$ref": "#\/components\/schemas\/firebaseProject"
},
"x-example": ""
}
},
"required": [
"total",
"projects"
]
},
"specificationList": {
"description": "Specifications List",
"type": "object",
@@ -35109,7 +34882,7 @@
},
"schedule": {
"type": "string",
"description": "Function execution schedult in CRON format.",
"description": "Function execution schedule in CRON format.",
"x-example": "5 4 * * *"
},
"timeout": {
@@ -36976,7 +36749,8 @@
"resourceId": {
"type": "string",
"description": "Resource ID.",
"x-example": "5e5ea5c16897e"
"x-example": "5e5ea5c16897e",
"nullable": true
},
"name": {
"type": "string",
@@ -36988,10 +36762,16 @@
"description": "The value of this metric at the timestamp.",
"x-example": 1,
"format": "int32"
},
"estimate": {
"type": "number",
"description": "The estimated value of this metric at the end of the period.",
"x-example": 1,
"format": "double",
"nullable": true
}
},
"required": [
"resourceId",
"name",
"value"
]
@@ -37807,6 +37587,26 @@
"$ref": "#\/components\/schemas\/metricBreakdown"
},
"x-example": []
},
"authPhoneTotal": {
"type": "integer",
"description": "Total aggregated number of phone auth.",
"x-example": 0,
"format": "int32"
},
"authPhoneEstimate": {
"type": "number",
"description": "Estimated total aggregated cost of phone auth.",
"x-example": 0,
"format": "double"
},
"authPhoneCountryBreakdown": {
"type": "array",
"description": "Aggregated breakdown in totals of phone auth by country.",
"items": {
"$ref": "#\/components\/schemas\/metricBreakdown"
},
"x-example": []
}
},
"required": [
@@ -37831,7 +37631,10 @@
"databasesStorageBreakdown",
"executionsMbSecondsBreakdown",
"buildsMbSecondsBreakdown",
"functionsStorageBreakdown"
"functionsStorageBreakdown",
"authPhoneTotal",
"authPhoneEstimate",
"authPhoneCountryBreakdown"
]
},
"headers": {
@@ -38707,26 +38510,6 @@
"size",
"version"
]
},
"firebaseProject": {
"description": "MigrationFirebaseProject",
"type": "object",
"properties": {
"projectId": {
"type": "string",
"description": "Project ID.",
"x-example": "my-project"
},
"displayName": {
"type": "string",
"description": "Project display name.",
"x-example": "My Project"
}
},
"required": [
"projectId",
"displayName"
]
}
},
"securitySchemes": {
+101 -59
View File
@@ -1,7 +1,7 @@
{
"openapi": "3.0.0",
"info": {
"version": "1.6.0",
"version": "1.6.1",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@@ -2451,7 +2451,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\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",
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour.\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",
@@ -8596,7 +8596,8 @@
"bun-1.0",
"bun-1.1",
"go-1.23",
"static-1"
"static-1",
"flutter-3.24"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -9019,7 +9020,8 @@
"bun-1.0",
"bun-1.1",
"go-1.23",
"static-1"
"static-1",
"flutter-3.24"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -12527,7 +12529,7 @@
},
"x-appwrite": {
"method": "listMessages",
"weight": 390,
"weight": 384,
"cookies": false,
"type": "",
"deprecated": false,
@@ -12606,7 +12608,7 @@
},
"x-appwrite": {
"method": "createEmail",
"weight": 387,
"weight": 381,
"cookies": false,
"type": "",
"deprecated": false,
@@ -12753,7 +12755,7 @@
},
"x-appwrite": {
"method": "updateEmail",
"weight": 394,
"weight": 388,
"cookies": false,
"type": "",
"deprecated": false,
@@ -12902,7 +12904,7 @@
},
"x-appwrite": {
"method": "createPush",
"weight": 389,
"weight": 383,
"cookies": false,
"type": "",
"deprecated": false,
@@ -12978,7 +12980,7 @@
},
"data": {
"type": "object",
"description": "Additional Data for push notification.",
"description": "Additional key-value pair data for push notification.",
"x-example": "{}"
},
"action": {
@@ -12998,7 +13000,7 @@
},
"sound": {
"type": "string",
"description": "Sound for push notification. Available only for Android and IOS Platform.",
"description": "Sound for push notification. Available only for Android and iOS Platform.",
"x-example": "<SOUND>"
},
"color": {
@@ -13012,9 +13014,9 @@
"x-example": "<TAG>"
},
"badge": {
"type": "string",
"description": "Badge for push notification. Available only for IOS Platform.",
"x-example": "<BADGE>"
"type": "integer",
"description": "Badge for push notification. Available only for iOS Platform.",
"x-example": null
},
"draft": {
"type": "boolean",
@@ -13025,12 +13027,31 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device state and may not deliver notifications immediately. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
},
"required": [
"messageId",
"title",
"body"
"messageId"
]
}
}
@@ -13060,7 +13081,7 @@
},
"x-appwrite": {
"method": "updatePush",
"weight": 396,
"weight": 390,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13190,6 +13211,27 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device battery state and may send notifications later. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
}
}
@@ -13220,7 +13262,7 @@
},
"x-appwrite": {
"method": "createSms",
"weight": 388,
"weight": 382,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13332,7 +13374,7 @@
},
"x-appwrite": {
"method": "updateSms",
"weight": 395,
"weight": 389,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13447,7 +13489,7 @@
},
"x-appwrite": {
"method": "getMessage",
"weight": 393,
"weight": 387,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13503,7 +13545,7 @@
},
"x-appwrite": {
"method": "delete",
"weight": 397,
"weight": 391,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13568,7 +13610,7 @@
},
"x-appwrite": {
"method": "listMessageLogs",
"weight": 391,
"weight": 385,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13646,7 +13688,7 @@
},
"x-appwrite": {
"method": "listTargets",
"weight": 392,
"weight": 386,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13724,7 +13766,7 @@
},
"x-appwrite": {
"method": "listProviders",
"weight": 362,
"weight": 356,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13803,7 +13845,7 @@
},
"x-appwrite": {
"method": "createApnsProvider",
"weight": 361,
"weight": 355,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13911,7 +13953,7 @@
},
"x-appwrite": {
"method": "updateApnsProvider",
"weight": 374,
"weight": 368,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14022,7 +14064,7 @@
},
"x-appwrite": {
"method": "createFcmProvider",
"weight": 360,
"weight": 354,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14110,7 +14152,7 @@
},
"x-appwrite": {
"method": "updateFcmProvider",
"weight": 373,
"weight": 367,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14201,7 +14243,7 @@
},
"x-appwrite": {
"method": "createMailgunProvider",
"weight": 352,
"weight": 346,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14319,7 +14361,7 @@
},
"x-appwrite": {
"method": "updateMailgunProvider",
"weight": 365,
"weight": 359,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14440,7 +14482,7 @@
},
"x-appwrite": {
"method": "createMsg91Provider",
"weight": 355,
"weight": 349,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14538,7 +14580,7 @@
},
"x-appwrite": {
"method": "updateMsg91Provider",
"weight": 368,
"weight": 362,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14639,7 +14681,7 @@
},
"x-appwrite": {
"method": "createSendgridProvider",
"weight": 353,
"weight": 347,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14747,7 +14789,7 @@
},
"x-appwrite": {
"method": "updateSendgridProvider",
"weight": 366,
"weight": 360,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14858,7 +14900,7 @@
},
"x-appwrite": {
"method": "createSmtpProvider",
"weight": 354,
"weight": 348,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15004,7 +15046,7 @@
},
"x-appwrite": {
"method": "updateSmtpProvider",
"weight": 367,
"weight": 361,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15152,7 +15194,7 @@
},
"x-appwrite": {
"method": "createTelesignProvider",
"weight": 356,
"weight": 350,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15250,7 +15292,7 @@
},
"x-appwrite": {
"method": "updateTelesignProvider",
"weight": 369,
"weight": 363,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15351,7 +15393,7 @@
},
"x-appwrite": {
"method": "createTextmagicProvider",
"weight": 357,
"weight": 351,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15449,7 +15491,7 @@
},
"x-appwrite": {
"method": "updateTextmagicProvider",
"weight": 370,
"weight": 364,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15550,7 +15592,7 @@
},
"x-appwrite": {
"method": "createTwilioProvider",
"weight": 358,
"weight": 352,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15648,7 +15690,7 @@
},
"x-appwrite": {
"method": "updateTwilioProvider",
"weight": 371,
"weight": 365,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15749,7 +15791,7 @@
},
"x-appwrite": {
"method": "createVonageProvider",
"weight": 359,
"weight": 353,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15847,7 +15889,7 @@
},
"x-appwrite": {
"method": "updateVonageProvider",
"weight": 372,
"weight": 366,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15948,7 +15990,7 @@
},
"x-appwrite": {
"method": "getProvider",
"weight": 364,
"weight": 358,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16004,7 +16046,7 @@
},
"x-appwrite": {
"method": "deleteProvider",
"weight": 375,
"weight": 369,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16069,7 +16111,7 @@
},
"x-appwrite": {
"method": "listProviderLogs",
"weight": 363,
"weight": 357,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16147,7 +16189,7 @@
},
"x-appwrite": {
"method": "listSubscriberLogs",
"weight": 384,
"weight": 378,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16225,7 +16267,7 @@
},
"x-appwrite": {
"method": "listTopics",
"weight": 377,
"weight": 371,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16302,7 +16344,7 @@
},
"x-appwrite": {
"method": "createTopic",
"weight": 376,
"weight": 370,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16388,7 +16430,7 @@
},
"x-appwrite": {
"method": "getTopic",
"weight": 379,
"weight": 373,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16451,7 +16493,7 @@
},
"x-appwrite": {
"method": "updateTopic",
"weight": 380,
"weight": 374,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16531,7 +16573,7 @@
},
"x-appwrite": {
"method": "deleteTopic",
"weight": 381,
"weight": 375,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16596,7 +16638,7 @@
},
"x-appwrite": {
"method": "listTopicLogs",
"weight": 378,
"weight": 372,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16674,7 +16716,7 @@
},
"x-appwrite": {
"method": "listSubscribers",
"weight": 383,
"weight": 377,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16761,7 +16803,7 @@
},
"x-appwrite": {
"method": "createSubscriber",
"weight": 382,
"weight": 376,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16855,7 +16897,7 @@
},
"x-appwrite": {
"method": "getSubscriber",
"weight": 385,
"weight": 379,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16921,7 +16963,7 @@
},
"x-appwrite": {
"method": "deleteSubscriber",
"weight": 386,
"weight": 380,
"cookies": false,
"type": "",
"deprecated": false,
@@ -25746,7 +25788,7 @@
},
"schedule": {
"type": "string",
"description": "Function execution schedult in CRON format.",
"description": "Function execution schedule in CRON format.",
"x-example": "5 4 * * *"
},
"timeout": {
+81 -11
View File
@@ -14122,7 +14122,7 @@
},
"data": {
"type": "object",
"description": "Additional Data for push notification.",
"description": "Additional key-value pair data for push notification.",
"x-example": "{}"
},
"action": {
@@ -14142,7 +14142,7 @@
},
"sound": {
"type": "string",
"description": "Sound for push notification. Available only for Android and IOS Platform.",
"description": "Sound for push notification. Available only for Android and iOS Platform.",
"x-example": "<SOUND>"
},
"color": {
@@ -14156,9 +14156,9 @@
"x-example": "<TAG>"
},
"badge": {
"type": "string",
"description": "Badge for push notification. Available only for IOS Platform.",
"x-example": "<BADGE>"
"type": "integer",
"description": "Badge for push notification. Available only for iOS Platform.",
"x-example": null
},
"draft": {
"type": "boolean",
@@ -14169,12 +14169,31 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device state and may not deliver notifications immediately. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
},
"required": [
"messageId",
"title",
"body"
"messageId"
]
}
}
@@ -14333,6 +14352,27 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device battery state and may send notifications later. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
}
}
@@ -36709,7 +36749,8 @@
"resourceId": {
"type": "string",
"description": "Resource ID.",
"x-example": "5e5ea5c16897e"
"x-example": "5e5ea5c16897e",
"nullable": true
},
"name": {
"type": "string",
@@ -36721,10 +36762,16 @@
"description": "The value of this metric at the timestamp.",
"x-example": 1,
"format": "int32"
},
"estimate": {
"type": "number",
"description": "The estimated value of this metric at the end of the period.",
"x-example": 1,
"format": "double",
"nullable": true
}
},
"required": [
"resourceId",
"name",
"value"
]
@@ -37540,6 +37587,26 @@
"$ref": "#\/components\/schemas\/metricBreakdown"
},
"x-example": []
},
"authPhoneTotal": {
"type": "integer",
"description": "Total aggregated number of phone auth.",
"x-example": 0,
"format": "int32"
},
"authPhoneEstimate": {
"type": "number",
"description": "Estimated total aggregated cost of phone auth.",
"x-example": 0,
"format": "double"
},
"authPhoneCountryBreakdown": {
"type": "array",
"description": "Aggregated breakdown in totals of phone auth by country.",
"items": {
"$ref": "#\/components\/schemas\/metricBreakdown"
},
"x-example": []
}
},
"required": [
@@ -37564,7 +37631,10 @@
"databasesStorageBreakdown",
"executionsMbSecondsBreakdown",
"buildsMbSecondsBreakdown",
"functionsStorageBreakdown"
"functionsStorageBreakdown",
"authPhoneTotal",
"authPhoneEstimate",
"authPhoneCountryBreakdown"
]
},
"headers": {
+48 -8
View File
@@ -12980,7 +12980,7 @@
},
"data": {
"type": "object",
"description": "Additional Data for push notification.",
"description": "Additional key-value pair data for push notification.",
"x-example": "{}"
},
"action": {
@@ -13000,7 +13000,7 @@
},
"sound": {
"type": "string",
"description": "Sound for push notification. Available only for Android and IOS Platform.",
"description": "Sound for push notification. Available only for Android and iOS Platform.",
"x-example": "<SOUND>"
},
"color": {
@@ -13014,9 +13014,9 @@
"x-example": "<TAG>"
},
"badge": {
"type": "string",
"description": "Badge for push notification. Available only for IOS Platform.",
"x-example": "<BADGE>"
"type": "integer",
"description": "Badge for push notification. Available only for iOS Platform.",
"x-example": null
},
"draft": {
"type": "boolean",
@@ -13027,12 +13027,31 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device state and may not deliver notifications immediately. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
},
"required": [
"messageId",
"title",
"body"
"messageId"
]
}
}
@@ -13192,6 +13211,27 @@
"type": "string",
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device battery state and may send notifications later. \"high\" will always attempt to immediately deliver the notification.",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
}
}
+4 -4
View File
@@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.6.0",
"version": "1.6.1",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@@ -2922,7 +2922,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\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",
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour.\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",
@@ -5981,7 +5981,7 @@
},
"x-appwrite": {
"method": "createSubscriber",
"weight": 382,
"weight": 376,
"cookies": false,
"type": "",
"deprecated": false,
@@ -6070,7 +6070,7 @@
},
"x-appwrite": {
"method": "deleteSubscriber",
"weight": 386,
"weight": 380,
"cookies": false,
"type": "",
"deprecated": false,
File diff suppressed because it is too large Load Diff
+110 -62
View File
@@ -1,7 +1,7 @@
{
"swagger": "2.0",
"info": {
"version": "1.6.0",
"version": "1.6.1",
"title": "Appwrite",
"description": "Appwrite backend as a service cuts up to 70% of the time and costs required for building a modern application. We abstract and simplify common development tasks behind a REST APIs, to help you develop your app in a fast and secure way. For full API documentation and tutorials go to [https:\/\/appwrite.io\/docs](https:\/\/appwrite.io\/docs)",
"termsOfService": "https:\/\/appwrite.io\/policy\/terms",
@@ -2604,7 +2604,7 @@
"tags": [
"account"
],
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour. If you are on a mobile device you can leave the URL parameter empty, so that the login completion will be handled by your Appwrite instance by default.\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",
"description": "Sends the user an email with a secret key for creating a session. If the provided user ID has not been registered, a new user will be created. When the user clicks the link in the email, the user is redirected back to the URL you provided with the secret key and userId values attached to the URL query string. Use the query string parameters to 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 link sent to the user's email address is valid for 1 hour.\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",
@@ -8720,7 +8720,8 @@
"bun-1.0",
"bun-1.1",
"go-1.23",
"static-1"
"static-1",
"flutter-3.24"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -9166,7 +9167,8 @@
"bun-1.0",
"bun-1.1",
"go-1.23",
"static-1"
"static-1",
"flutter-3.24"
],
"x-enum-name": null,
"x-enum-keys": []
@@ -12752,7 +12754,7 @@
},
"x-appwrite": {
"method": "listMessages",
"weight": 390,
"weight": 384,
"cookies": false,
"type": "",
"deprecated": false,
@@ -12830,7 +12832,7 @@
},
"x-appwrite": {
"method": "createEmail",
"weight": 387,
"weight": 381,
"cookies": false,
"type": "",
"deprecated": false,
@@ -12991,7 +12993,7 @@
},
"x-appwrite": {
"method": "updateEmail",
"weight": 394,
"weight": 388,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13149,7 +13151,7 @@
},
"x-appwrite": {
"method": "createPush",
"weight": 389,
"weight": 383,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13194,13 +13196,13 @@
"title": {
"type": "string",
"description": "Title for push notification.",
"default": null,
"default": "",
"x-example": "<TITLE>"
},
"body": {
"type": "string",
"description": "Body for push notification.",
"default": null,
"default": "",
"x-example": "<BODY>"
},
"topics": {
@@ -13232,7 +13234,7 @@
},
"data": {
"type": "object",
"description": "Additional Data for push notification.",
"description": "Additional key-value pair data for push notification.",
"default": {},
"x-example": "{}"
},
@@ -13256,7 +13258,7 @@
},
"sound": {
"type": "string",
"description": "Sound for push notification. Available only for Android and IOS Platform.",
"description": "Sound for push notification. Available only for Android and iOS Platform.",
"default": "",
"x-example": "<SOUND>"
},
@@ -13273,10 +13275,10 @@
"x-example": "<TAG>"
},
"badge": {
"type": "string",
"description": "Badge for push notification. Available only for IOS Platform.",
"default": "",
"x-example": "<BADGE>"
"type": "integer",
"description": "Badge for push notification. Available only for iOS Platform.",
"default": -1,
"x-example": null
},
"draft": {
"type": "boolean",
@@ -13289,12 +13291,34 @@
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"default": null,
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"default": false,
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"default": false,
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device state and may not deliver notifications immediately. \"high\" will always attempt to immediately deliver the notification.",
"default": "high",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
},
"required": [
"messageId",
"title",
"body"
"messageId"
]
}
}
@@ -13325,7 +13349,7 @@
},
"x-appwrite": {
"method": "updatePush",
"weight": 396,
"weight": 390,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13467,6 +13491,30 @@
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"default": null,
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"default": null,
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"default": null,
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device battery state and may send notifications later. \"high\" will always attempt to immediately deliver the notification.",
"default": null,
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
}
}
@@ -13498,7 +13546,7 @@
},
"x-appwrite": {
"method": "createSms",
"weight": 388,
"weight": 382,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13619,7 +13667,7 @@
},
"x-appwrite": {
"method": "updateSms",
"weight": 395,
"weight": 389,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13738,7 +13786,7 @@
},
"x-appwrite": {
"method": "getMessage",
"weight": 393,
"weight": 387,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13798,7 +13846,7 @@
},
"x-appwrite": {
"method": "delete",
"weight": 397,
"weight": 391,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13863,7 +13911,7 @@
},
"x-appwrite": {
"method": "listMessageLogs",
"weight": 391,
"weight": 385,
"cookies": false,
"type": "",
"deprecated": false,
@@ -13940,7 +13988,7 @@
},
"x-appwrite": {
"method": "listTargets",
"weight": 392,
"weight": 386,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14017,7 +14065,7 @@
},
"x-appwrite": {
"method": "listProviders",
"weight": 362,
"weight": 356,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14095,7 +14143,7 @@
},
"x-appwrite": {
"method": "createApnsProvider",
"weight": 361,
"weight": 355,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14213,7 +14261,7 @@
},
"x-appwrite": {
"method": "updateApnsProvider",
"weight": 374,
"weight": 368,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14329,7 +14377,7 @@
},
"x-appwrite": {
"method": "createFcmProvider",
"weight": 360,
"weight": 354,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14423,7 +14471,7 @@
},
"x-appwrite": {
"method": "updateFcmProvider",
"weight": 373,
"weight": 367,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14515,7 +14563,7 @@
},
"x-appwrite": {
"method": "createMailgunProvider",
"weight": 352,
"weight": 346,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14645,7 +14693,7 @@
},
"x-appwrite": {
"method": "updateMailgunProvider",
"weight": 365,
"weight": 359,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14773,7 +14821,7 @@
},
"x-appwrite": {
"method": "createMsg91Provider",
"weight": 355,
"weight": 349,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14879,7 +14927,7 @@
},
"x-appwrite": {
"method": "updateMsg91Provider",
"weight": 368,
"weight": 362,
"cookies": false,
"type": "",
"deprecated": false,
@@ -14983,7 +15031,7 @@
},
"x-appwrite": {
"method": "createSendgridProvider",
"weight": 353,
"weight": 347,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15101,7 +15149,7 @@
},
"x-appwrite": {
"method": "updateSendgridProvider",
"weight": 366,
"weight": 360,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15217,7 +15265,7 @@
},
"x-appwrite": {
"method": "createSmtpProvider",
"weight": 354,
"weight": 348,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15379,7 +15427,7 @@
},
"x-appwrite": {
"method": "updateSmtpProvider",
"weight": 367,
"weight": 361,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15538,7 +15586,7 @@
},
"x-appwrite": {
"method": "createTelesignProvider",
"weight": 356,
"weight": 350,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15644,7 +15692,7 @@
},
"x-appwrite": {
"method": "updateTelesignProvider",
"weight": 369,
"weight": 363,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15748,7 +15796,7 @@
},
"x-appwrite": {
"method": "createTextmagicProvider",
"weight": 357,
"weight": 351,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15854,7 +15902,7 @@
},
"x-appwrite": {
"method": "updateTextmagicProvider",
"weight": 370,
"weight": 364,
"cookies": false,
"type": "",
"deprecated": false,
@@ -15958,7 +16006,7 @@
},
"x-appwrite": {
"method": "createTwilioProvider",
"weight": 358,
"weight": 352,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16064,7 +16112,7 @@
},
"x-appwrite": {
"method": "updateTwilioProvider",
"weight": 371,
"weight": 365,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16168,7 +16216,7 @@
},
"x-appwrite": {
"method": "createVonageProvider",
"weight": 359,
"weight": 353,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16274,7 +16322,7 @@
},
"x-appwrite": {
"method": "updateVonageProvider",
"weight": 372,
"weight": 366,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16378,7 +16426,7 @@
},
"x-appwrite": {
"method": "getProvider",
"weight": 364,
"weight": 358,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16438,7 +16486,7 @@
},
"x-appwrite": {
"method": "deleteProvider",
"weight": 375,
"weight": 369,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16503,7 +16551,7 @@
},
"x-appwrite": {
"method": "listProviderLogs",
"weight": 363,
"weight": 357,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16580,7 +16628,7 @@
},
"x-appwrite": {
"method": "listSubscriberLogs",
"weight": 384,
"weight": 378,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16657,7 +16705,7 @@
},
"x-appwrite": {
"method": "listTopics",
"weight": 377,
"weight": 371,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16733,7 +16781,7 @@
},
"x-appwrite": {
"method": "createTopic",
"weight": 376,
"weight": 370,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16826,7 +16874,7 @@
},
"x-appwrite": {
"method": "getTopic",
"weight": 379,
"weight": 373,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16889,7 +16937,7 @@
},
"x-appwrite": {
"method": "updateTopic",
"weight": 380,
"weight": 374,
"cookies": false,
"type": "",
"deprecated": false,
@@ -16973,7 +17021,7 @@
},
"x-appwrite": {
"method": "deleteTopic",
"weight": 381,
"weight": 375,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17038,7 +17086,7 @@
},
"x-appwrite": {
"method": "listTopicLogs",
"weight": 378,
"weight": 372,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17115,7 +17163,7 @@
},
"x-appwrite": {
"method": "listSubscribers",
"weight": 383,
"weight": 377,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17199,7 +17247,7 @@
},
"x-appwrite": {
"method": "createSubscriber",
"weight": 382,
"weight": 376,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17293,7 +17341,7 @@
},
"x-appwrite": {
"method": "getSubscriber",
"weight": 385,
"weight": 379,
"cookies": false,
"type": "",
"deprecated": false,
@@ -17361,7 +17409,7 @@
},
"x-appwrite": {
"method": "deleteSubscriber",
"weight": 386,
"weight": 380,
"cookies": false,
"type": "",
"deprecated": false,
@@ -26233,7 +26281,7 @@
},
"schedule": {
"type": "string",
"description": "Function execution schedult in CRON format.",
"description": "Function execution schedule in CRON format.",
"x-example": "5 4 * * *"
},
"timeout": {
+91 -14
View File
@@ -14330,13 +14330,13 @@
"title": {
"type": "string",
"description": "Title for push notification.",
"default": null,
"default": "",
"x-example": "<TITLE>"
},
"body": {
"type": "string",
"description": "Body for push notification.",
"default": null,
"default": "",
"x-example": "<BODY>"
},
"topics": {
@@ -14368,7 +14368,7 @@
},
"data": {
"type": "object",
"description": "Additional Data for push notification.",
"description": "Additional key-value pair data for push notification.",
"default": {},
"x-example": "{}"
},
@@ -14392,7 +14392,7 @@
},
"sound": {
"type": "string",
"description": "Sound for push notification. Available only for Android and IOS Platform.",
"description": "Sound for push notification. Available only for Android and iOS Platform.",
"default": "",
"x-example": "<SOUND>"
},
@@ -14409,10 +14409,10 @@
"x-example": "<TAG>"
},
"badge": {
"type": "string",
"description": "Badge for push notification. Available only for IOS Platform.",
"default": "",
"x-example": "<BADGE>"
"type": "integer",
"description": "Badge for push notification. Available only for iOS Platform.",
"default": -1,
"x-example": null
},
"draft": {
"type": "boolean",
@@ -14425,12 +14425,34 @@
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"default": null,
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"default": false,
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"default": false,
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device state and may not deliver notifications immediately. \"high\" will always attempt to immediately deliver the notification.",
"default": "high",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
},
"required": [
"messageId",
"title",
"body"
"messageId"
]
}
}
@@ -14602,6 +14624,30 @@
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"default": null,
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"default": null,
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"default": null,
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device battery state and may send notifications later. \"high\" will always attempt to immediately deliver the notification.",
"default": null,
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
}
}
@@ -37212,7 +37258,8 @@
"resourceId": {
"type": "string",
"description": "Resource ID.",
"x-example": "5e5ea5c16897e"
"x-example": "5e5ea5c16897e",
"x-nullable": true
},
"name": {
"type": "string",
@@ -37224,10 +37271,16 @@
"description": "The value of this metric at the timestamp.",
"x-example": 1,
"format": "int32"
},
"estimate": {
"type": "number",
"description": "The estimated value of this metric at the end of the period.",
"x-example": 1,
"format": "double",
"x-nullable": true
}
},
"required": [
"resourceId",
"name",
"value"
]
@@ -38087,6 +38140,27 @@
"$ref": "#\/definitions\/metricBreakdown"
},
"x-example": []
},
"authPhoneTotal": {
"type": "integer",
"description": "Total aggregated number of phone auth.",
"x-example": 0,
"format": "int32"
},
"authPhoneEstimate": {
"type": "number",
"description": "Estimated total aggregated cost of phone auth.",
"x-example": 0,
"format": "double"
},
"authPhoneCountryBreakdown": {
"type": "array",
"description": "Aggregated breakdown in totals of phone auth by country.",
"items": {
"type": "object",
"$ref": "#\/definitions\/metricBreakdown"
},
"x-example": []
}
},
"required": [
@@ -38111,7 +38185,10 @@
"databasesStorageBreakdown",
"executionsMbSecondsBreakdown",
"buildsMbSecondsBreakdown",
"functionsStorageBreakdown"
"functionsStorageBreakdown",
"authPhoneTotal",
"authPhoneEstimate",
"authPhoneCountryBreakdown"
]
},
"headers": {
+57 -11
View File
@@ -13196,13 +13196,13 @@
"title": {
"type": "string",
"description": "Title for push notification.",
"default": null,
"default": "",
"x-example": "<TITLE>"
},
"body": {
"type": "string",
"description": "Body for push notification.",
"default": null,
"default": "",
"x-example": "<BODY>"
},
"topics": {
@@ -13234,7 +13234,7 @@
},
"data": {
"type": "object",
"description": "Additional Data for push notification.",
"description": "Additional key-value pair data for push notification.",
"default": {},
"x-example": "{}"
},
@@ -13258,7 +13258,7 @@
},
"sound": {
"type": "string",
"description": "Sound for push notification. Available only for Android and IOS Platform.",
"description": "Sound for push notification. Available only for Android and iOS Platform.",
"default": "",
"x-example": "<SOUND>"
},
@@ -13275,10 +13275,10 @@
"x-example": "<TAG>"
},
"badge": {
"type": "string",
"description": "Badge for push notification. Available only for IOS Platform.",
"default": "",
"x-example": "<BADGE>"
"type": "integer",
"description": "Badge for push notification. Available only for iOS Platform.",
"default": -1,
"x-example": null
},
"draft": {
"type": "boolean",
@@ -13291,12 +13291,34 @@
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"default": null,
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"default": false,
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"default": false,
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device state and may not deliver notifications immediately. \"high\" will always attempt to immediately deliver the notification.",
"default": "high",
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
},
"required": [
"messageId",
"title",
"body"
"messageId"
]
}
}
@@ -13469,6 +13491,30 @@
"description": "Scheduled delivery time for message in [ISO 8601](https:\/\/www.iso.org\/iso-8601-date-and-time-format.html) format. DateTime value must be in future.",
"default": null,
"x-example": null
},
"contentAvailable": {
"type": "boolean",
"description": "If set to true, the notification will be delivered in the background. Available only for iOS Platform.",
"default": null,
"x-example": false
},
"critical": {
"type": "boolean",
"description": "If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.",
"default": null,
"x-example": false
},
"priority": {
"type": "string",
"description": "Set the notification priority. \"normal\" will consider device battery state and may send notifications later. \"high\" will always attempt to immediately deliver the notification.",
"default": null,
"x-example": "normal",
"enum": [
"normal",
"high"
],
"x-enum-name": "MessagePriority",
"x-enum-keys": []
}
}
}
+82 -6
View File
@@ -17,6 +17,7 @@ use Appwrite\Event\Delete;
use Appwrite\Event\Event;
use Appwrite\Event\Mail;
use Appwrite\Event\Messaging;
use Appwrite\Event\Usage;
use Appwrite\Extend\Exception;
use Appwrite\Hooks\Hooks;
use Appwrite\Network\Validator\Email;
@@ -27,7 +28,9 @@ use Appwrite\Utopia\Database\Validator\CustomId;
use Appwrite\Utopia\Database\Validator\Queries\Identities;
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use libphonenumber\PhoneNumberUtil;
use MaxMind\Db\Reader;
use Utopia\Abuse\Abuse;
use Utopia\App;
use Utopia\Audit\Audit as EventAudit;
use Utopia\Config\Config;
@@ -275,7 +278,7 @@ App::post('/v1/account')
->desc('Create account')
->groups(['api', 'account', 'auth'])
->label('scope', 'sessions.write')
->label('auth.type', 'emailPassword')
->label('auth.type', 'email-password')
->label('audits.event', 'user.create')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
@@ -796,7 +799,7 @@ App::post('/v1/account/sessions/email')
->groups(['api', 'account', 'auth', 'session'])
->label('event', 'users.[userId].sessions.[sessionId].create')
->label('scope', 'sessions.write')
->label('auth.type', 'emailPassword')
->label('auth.type', 'email-password')
->label('audits.event', 'session.create')
->label('audits.resource', 'user/{response.userId}')
->label('audits.userId', '{response.userId}')
@@ -2315,7 +2318,10 @@ App::post('/v1/account/tokens/phone')
->inject('queueForEvents')
->inject('queueForMessaging')
->inject('locale')
->action(function (string $userId, string $phone, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Locale $locale) {
->inject('timelimit')
->inject('queueForUsage')
->inject('plan')
->action(function (string $userId, string $phone, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Locale $locale, callable $timelimit, Usage $queueForUsage, array $plan) {
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
}
@@ -2452,6 +2458,27 @@ App::post('/v1/account/tokens/phone')
->setMessage($messageDoc)
->setRecipients([$phone])
->setProviderType(MESSAGE_TYPE_SMS);
if (isset($plan['authPhone'])) {
$timelimit = $timelimit('organization:{organizationId}', $plan['authPhone'], 30 * 24 * 60 * 60); // 30 days
$timelimit
->setParam('{organizationId}', $project->getAttribute('teamId'));
$abuse = new Abuse($timelimit);
if ($abuse->check() && System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') {
$helper = PhoneNumberUtil::getInstance();
$countryCode = $helper->parse($phone)->getCountryCode();
if (!empty($countryCode)) {
$queueForUsage
->addMetric(str_replace('{countryCode}', $countryCode, METRIC_AUTH_METHOD_PHONE_COUNTRY_CODE), 1);
}
}
$queueForUsage
->addMetric(METRIC_AUTH_METHOD_PHONE, 1)
->setProject($project)
->trigger();
}
}
// Set to unhashed secret for events and server responses
@@ -3465,7 +3492,10 @@ App::post('/v1/account/verification/phone')
->inject('queueForMessaging')
->inject('project')
->inject('locale')
->action(function (Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Document $project, Locale $locale) {
->inject('timelimit')
->inject('queueForUsage')
->inject('plan')
->action(function (Request $request, Response $response, Document $user, Database $dbForProject, Event $queueForEvents, Messaging $queueForMessaging, Document $project, Locale $locale, callable $timelimit, Usage $queueForUsage, array $plan) {
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
}
@@ -3548,6 +3578,27 @@ App::post('/v1/account/verification/phone')
->setMessage($messageDoc)
->setRecipients([$user->getAttribute('phone')])
->setProviderType(MESSAGE_TYPE_SMS);
if (isset($plan['authPhone'])) {
$timelimit = $timelimit('organization:{organizationId}', $plan['authPhone'], 30 * 24 * 60 * 60); // 30 days
$timelimit
->setParam('{organizationId}', $project->getAttribute('teamId'));
$abuse = new Abuse($timelimit);
if ($abuse->check() && System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') {
$helper = PhoneNumberUtil::getInstance();
$countryCode = $helper->parse($phone)->getCountryCode();
if (!empty($countryCode)) {
$queueForUsage
->addMetric(str_replace('{countryCode}', $countryCode, METRIC_AUTH_METHOD_PHONE_COUNTRY_CODE), 1);
}
}
$queueForUsage
->addMetric(METRIC_AUTH_METHOD_PHONE, 1)
->setProject($project)
->trigger();
}
}
// Set to unhashed secret for events and server responses
@@ -4026,7 +4077,10 @@ App::post('/v1/account/mfa/challenge')
->inject('queueForEvents')
->inject('queueForMessaging')
->inject('queueForMails')
->action(function (string $factor, Response $response, Database $dbForProject, Document $user, Locale $locale, Document $project, Request $request, Event $queueForEvents, Messaging $queueForMessaging, Mail $queueForMails) {
->inject('timelimit')
->inject('queueForUsage')
->inject('plan')
->action(function (string $factor, Response $response, Database $dbForProject, Document $user, Locale $locale, Document $project, Request $request, Event $queueForEvents, Messaging $queueForMessaging, Mail $queueForMails, callable $timelimit, Usage $queueForUsage, array $plan) {
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM);
$code = Auth::codeGenerator();
@@ -4074,6 +4128,7 @@ App::post('/v1/account/mfa/challenge')
$message = $message->render();
$phone = $user->getAttribute('phone');
$queueForMessaging
->setType(MESSAGE_SEND_TYPE_INTERNAL)
->setMessage(new Document([
@@ -4082,8 +4137,29 @@ App::post('/v1/account/mfa/challenge')
'content' => $code,
],
]))
->setRecipients([$user->getAttribute('phone')])
->setRecipients([$phone])
->setProviderType(MESSAGE_TYPE_SMS);
if (isset($plan['authPhone'])) {
$timelimit = $timelimit('organization:{organizationId}', $plan['authPhone'], 30 * 24 * 60 * 60); // 30 days
$timelimit
->setParam('{organizationId}', $project->getAttribute('teamId'));
$abuse = new Abuse($timelimit);
if ($abuse->check() && System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') {
$helper = PhoneNumberUtil::getInstance();
$countryCode = $helper->parse($phone)->getCountryCode();
if (!empty($countryCode)) {
$queueForUsage
->addMetric(str_replace('{countryCode}', $countryCode, METRIC_AUTH_METHOD_PHONE_COUNTRY_CODE), 1);
}
}
$queueForUsage
->addMetric(METRIC_AUTH_METHOD_PHONE, 1)
->setProject($project)
->trigger();
}
break;
case Type::EMAIL:
if (empty(System::getEnv('_APP_SMTP_HOST'))) {
+63 -13
View File
@@ -2906,28 +2906,31 @@ App::post('/v1/messaging/messages/push')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.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('title', '', new Text(256), 'Title for push notification.')
->param('body', '', new Text(64230), 'Body for push notification.')
->param('title', '', new Text(256), 'Title for push notification.', true)
->param('body', '', new Text(64230), 'Body for push notification.', true)
->param('topics', [], new ArrayList(new UID()), 'List of Topic IDs.', true)
->param('users', [], new ArrayList(new UID()), 'List of User IDs.', true)
->param('targets', [], new ArrayList(new UID()), 'List of Targets IDs.', true)
->param('data', null, new JSON(), 'Additional Data for push notification.', true)
->param('data', null, new JSON(), 'Additional key-value pair data for push notification.', true)
->param('action', '', new Text(256), 'Action for push notification.', true)
->param('image', '', new CompoundUID(), 'Image for push notification. Must be a compound bucket ID to file ID of a jpeg, png, or bmp image in Appwrite Storage. It should be formatted as <BUCKET_ID>:<FILE_ID>.', true)
->param('icon', '', new Text(256), 'Icon for push notification. Available only for Android and Web Platform.', true)
->param('sound', '', new Text(256), 'Sound for push notification. Available only for Android and IOS Platform.', true)
->param('sound', '', new Text(256), 'Sound for push notification. Available only for Android and iOS Platform.', true)
->param('color', '', new Text(256), 'Color for push notification. Available only for Android Platform.', true)
->param('tag', '', new Text(256), 'Tag for push notification. Available only for Android Platform.', true)
->param('badge', '', new Text(256), 'Badge for push notification. Available only for IOS Platform.', true)
->param('badge', -1, new Integer(), 'Badge for push notification. Available only for iOS Platform.', true)
->param('draft', false, new Boolean(), 'Is message a draft', true)
->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true)
->param('contentAvailable', false, new Boolean(), 'If set to true, the notification will be delivered in the background. Available only for iOS Platform.', true)
->param('critical', false, new Boolean(), 'If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.', true)
->param('priority', 'high', new WhiteList(['normal', 'high']), 'Set the notification priority. "normal" will consider device state and may not deliver notifications immediately. "high" will always attempt to immediately deliver the notification.', true)
->inject('queueForEvents')
->inject('dbForProject')
->inject('dbForPlatform')
->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, string $badge, bool $draft, ?string $scheduledAt, 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;
@@ -3010,12 +3013,44 @@ App::post('/v1/messaging/messages/push')
$pushData = [];
$keys = ['title', 'body', 'data', 'action', 'image', 'icon', 'sound', 'color', 'tag', 'badge'];
foreach ($keys as $key) {
if (!empty($$key)) {
$pushData[$key] = $$key;
}
if (!empty($title)) {
$pushData['title'] = $title;
}
if (!empty($body)) {
$pushData['body'] = $body;
}
if (!empty($data)) {
$pushData['data'] = $data;
}
if (!empty($action)) {
$pushData['action'] = $action;
}
if (!empty($image)) {
$pushData['image'] = $image;
}
if (!empty($icon)) {
$pushData['icon'] = $icon;
}
if (!empty($sound)) {
$pushData['sound'] = $sound;
}
if (!empty($color)) {
$pushData['color'] = $color;
}
if (!empty($tag)) {
$pushData['tag'] = $tag;
}
if ($badge >= 0) {
$pushData['badge'] = $badge;
}
if ($contentAvailable) {
$pushData['contentAvailable'] = true;
}
if ($critical) {
$pushData['critical'] = true;
}
if (!empty($priority)) {
$pushData['priority'] = $priority;
}
$message = $dbForProject->createDocument('messages', new Document([
@@ -3698,13 +3733,16 @@ App::patch('/v1/messaging/messages/push/:messageId')
->param('badge', null, new Integer(), 'Badge for push notification. Available only for iOS platforms.', true)
->param('draft', null, new Boolean(), 'Is message a draft', true)
->param('scheduledAt', null, new DatetimeValidator(requireDateInFuture: true), 'Scheduled delivery time for message in [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html) format. DateTime value must be in future.', true)
->param('contentAvailable', null, new Boolean(), 'If set to true, the notification will be delivered in the background. Available only for iOS Platform.', true)
->param('critical', null, new Boolean(), 'If set to true, the notification will be marked as critical. This requires the app to have the critical notification entitlement. Available only for iOS Platform.', true)
->param('priority', null, new WhiteList(['normal', 'high']), 'Set the notification priority. "normal" will consider device battery state and may send notifications later. "high" will always attempt to immediately deliver the notification.', true)
->inject('queueForEvents')
->inject('dbForProject')
->inject('dbForPlatform')
->inject('project')
->inject('queueForMessaging')
->inject('response')
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $title, ?string $body, ?array $data, ?string $action, ?string $image, ?string $icon, ?string $sound, ?string $color, ?string $tag, ?int $badge, ?bool $draft, ?string $scheduledAt, Event $queueForEvents, Database $dbForProject, Database $dbForPlatform, Document $project, Messaging $queueForMessaging, Response $response) {
->action(function (string $messageId, ?array $topics, ?array $users, ?array $targets, ?string $title, ?string $body, ?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) {
$message = $dbForProject->getDocument('messages', $messageId);
if ($message->isEmpty()) {
@@ -3843,6 +3881,18 @@ App::patch('/v1/messaging/messages/push/:messageId')
$pushData['badge'] = $badge;
}
if (!\is_null($contentAvailable)) {
$pushData['contentAvailable'] = $contentAvailable;
}
if (!\is_null($critical)) {
$pushData['critical'] = $critical;
}
if (!\is_null($priority)) {
$pushData['priority'] = $priority;
}
if (!\is_null($image)) {
[$bucketId, $fileId] = CompoundUID::parse($image);
+45 -1
View File
@@ -31,7 +31,8 @@ App::get('/v1/project/usage')
->param('period', '1d', new WhiteList(['1h', '1d']), 'Period used', true)
->inject('response')
->inject('dbForProject')
->action(function (string $startDate, string $endDate, string $period, Response $response, Database $dbForProject) {
->inject('smsRates')
->action(function (string $startDate, string $endDate, string $period, Response $response, Database $dbForProject, array $smsRates) {
$stats = $total = $usage = [];
$format = 'Y-m-d 00:00:00';
$firstDay = (new DateTime($startDate))->format($format);
@@ -257,6 +258,46 @@ App::get('/v1/project/usage')
];
}, $dbForProject->find('functions'));
// This total is includes free and paid SMS usage
$authPhoneTotal = Authorization::skip(fn () => $dbForProject->sum('stats', 'value', [
Query::equal('metric', [METRIC_AUTH_METHOD_PHONE]),
Query::equal('period', ['1d']),
Query::greaterThanEqual('time', $firstDay),
Query::lessThan('time', $lastDay),
]));
// This estimate is only for paid SMS usage
$authPhoneMetrics = Authorization::skip(fn () => $dbForProject->find('stats', [
Query::startsWith('metric', METRIC_AUTH_METHOD_PHONE . '.'),
Query::equal('period', ['1d']),
Query::greaterThanEqual('time', $firstDay),
Query::lessThan('time', $lastDay),
]));
$authPhoneEstimate = 0.0;
$authPhoneCountryBreakdown = [];
foreach ($authPhoneMetrics as $metric) {
$parts = explode('.', $metric->getAttribute('metric'));
$countryCode = $parts[3] ?? null;
if ($countryCode === null) {
continue;
}
$value = $metric->getAttribute('value', 0);
if (isset($smsRates[$countryCode])) {
$authPhoneEstimate += $value * $smsRates[$countryCode];
}
$authPhoneCountryBreakdown[] = [
'name' => $countryCode,
'value' => $value,
'estimate' => isset($smsRates[$countryCode])
? $value * $smsRates[$countryCode]
: 0.0,
];
}
// merge network inbound + outbound
$projectBandwidth = [];
foreach ($usage[METRIC_NETWORK_INBOUND] as $item) {
@@ -303,6 +344,9 @@ App::get('/v1/project/usage')
'executionsMbSecondsBreakdown' => $executionsMbSecondsBreakdown,
'buildsMbSecondsBreakdown' => $buildsMbSecondsBreakdown,
'functionsStorageBreakdown' => $functionsStorageBreakdown,
'authPhoneTotal' => $authPhoneTotal,
'authPhoneEstimate' => $authPhoneEstimate,
'authPhoneCountryBreakdown' => $authPhoneCountryBreakdown,
]), Response::MODEL_USAGE_PROJECT);
});
+6
View File
@@ -60,6 +60,7 @@ App::post('/v1/projects')
->desc('Create project')
->groups(['api', 'projects'])
->label('audits.event', 'projects.create')
->label('audits.resource', 'project/{response.$id}')
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
@@ -375,6 +376,8 @@ App::patch('/v1/projects/:projectId')
->desc('Update project')
->groups(['api', 'projects'])
->label('scope', 'projects.write')
->label('audits.event', 'projects.update')
->label('audits.resource', 'project/{request.projectId}')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
->label('sdk.method', 'update')
@@ -989,6 +992,7 @@ App::delete('/v1/projects/:projectId')
->desc('Delete project')
->groups(['api', 'projects'])
->label('audits.event', 'projects.delete')
->label('audits.resource', 'project/{request.projectId}')
->label('scope', 'projects.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
@@ -1522,6 +1526,7 @@ App::post('/v1/projects/:projectId/platforms')
->desc('Create platform')
->groups(['api', 'projects'])
->label('audits.event', 'platforms.create')
->label('audits.resource', 'project/{request.projectId}')
->label('scope', 'platforms.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
@@ -1686,6 +1691,7 @@ App::delete('/v1/projects/:projectId/platforms/:platformId')
->desc('Delete platform')
->groups(['api', 'projects'])
->label('audits.event', 'platforms.delete')
->label('audits.resource', 'project/{request.projectId}/platform/${request.platformId}')
->label('scope', 'platforms.write')
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
->label('sdk.namespace', 'projects')
+28 -1
View File
@@ -8,6 +8,7 @@ use Appwrite\Event\Delete;
use Appwrite\Event\Event;
use Appwrite\Event\Mail;
use Appwrite\Event\Messaging;
use Appwrite\Event\Usage;
use Appwrite\Extend\Exception;
use Appwrite\Network\Validator\Email;
use Appwrite\Platform\Workers\Deletes;
@@ -17,7 +18,9 @@ use Appwrite\Utopia\Database\Validator\Queries\Memberships;
use Appwrite\Utopia\Database\Validator\Queries\Teams;
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use libphonenumber\PhoneNumberUtil;
use MaxMind\Db\Reader;
use Utopia\Abuse\Abuse;
use Utopia\App;
use Utopia\Audit\Audit;
use Utopia\Config\Config;
@@ -423,7 +426,10 @@ App::post('/v1/teams/:teamId/memberships')
->inject('queueForMails')
->inject('queueForMessaging')
->inject('queueForEvents')
->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents) {
->inject('timelimit')
->inject('queueForUsage')
->inject('plan')
->action(function (string $teamId, string $email, string $userId, string $phone, array $roles, string $url, string $name, Response $response, Document $project, Document $user, Database $dbForProject, Locale $locale, Mail $queueForMails, Messaging $queueForMessaging, Event $queueForEvents, callable $timelimit, Usage $queueForUsage, array $plan) {
$isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
@@ -691,6 +697,27 @@ App::post('/v1/teams/:teamId/memberships')
->setMessage($messageDoc)
->setRecipients([$phone])
->setProviderType('SMS');
if (isset($plan['authPhone'])) {
$timelimit = $timelimit('organization:{organizationId}', $plan['authPhone'], 30 * 24 * 60 * 60); // 30 days
$timelimit
->setParam('{organizationId}', $project->getAttribute('teamId'));
$abuse = new Abuse($timelimit);
if ($abuse->check() && System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') === 'enabled') {
$helper = PhoneNumberUtil::getInstance();
$countryCode = $helper->parse($phone)->getCountryCode();
if (!empty($countryCode)) {
$queueForUsage
->addMetric(str_replace('{countryCode}', $countryCode, METRIC_AUTH_METHOD_PHONE_COUNTRY_CODE), 1);
}
}
$queueForUsage
->addMetric(METRIC_AUTH_METHOD_PHONE, 1)
->setProject($project)
->trigger();
}
}
}
+6
View File
@@ -1814,6 +1814,12 @@ App::post('/v1/users/:userId/sessions')
$detector->getDevice()
));
$session->setAttribute('$permissions', [
Permission::read(Role::user($user->getId())),
Permission::update(Role::user($user->getId())),
Permission::delete(Role::user($user->getId())),
]);
$countryName = $locale->getText('countries.' . strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown'));
$session = $dbForProject->createDocument('sessions', $session);
+45 -64
View File
@@ -355,53 +355,6 @@ App::get('/v1/vcs/github/callback')
throw new Exception(Exception::PROJECT_NOT_FOUND, $error);
}
$personalSlug = '';
// OAuth Authroization
if (!empty($code)) {
$oauth2 = new OAuth2Github(System::getEnv('_APP_VCS_GITHUB_CLIENT_ID', ''), System::getEnv('_APP_VCS_GITHUB_CLIENT_SECRET', ''), "");
$accessToken = $oauth2->getAccessToken($code) ?? '';
$refreshToken = $oauth2->getRefreshToken($code) ?? '';
$accessTokenExpiry = $oauth2->getAccessTokenExpiry($code) ?? '';
$personalSlug = $oauth2->getUserSlug($accessToken) ?? '';
$email = $oauth2->getUserEmail($accessToken);
$oauth2ID = $oauth2->getUserID($accessToken);
// Makes sure this email is not already used in another identity
$identity = $dbForPlatform->findOne('identities', [
Query::equal('providerEmail', [$email]),
]);
if (!$identity->isEmpty()) {
if ($identity->getAttribute('userInternalId', '') !== $user->getInternalId()) {
throw new Exception(Exception::USER_EMAIL_ALREADY_EXISTS);
}
$identity = $identity
->setAttribute('providerAccessToken', $accessToken)
->setAttribute('providerRefreshToken', $refreshToken)
->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$accessTokenExpiry));
$dbForPlatform->updateDocument('identities', $identity->getId(), $identity);
} else {
$identity = $dbForPlatform->createDocument('identities', new Document([
'$id' => ID::unique(),
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::user($user->getId())),
Permission::delete(Role::user($user->getId())),
],
'userInternalId' => $user->getInternalId(),
'userId' => $user->getId(),
'provider' => 'github',
'providerUid' => $oauth2ID,
'providerEmail' => $email,
'providerAccessToken' => $accessToken,
'providerRefreshToken' => $refreshToken,
'providerAccessTokenExpiry' => DateTime::addSeconds(new \DateTime(), (int)$accessTokenExpiry),
]));
}
}
// Create / Update installation
if (!empty($providerInstallationId)) {
$privateKey = System::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY');
@@ -416,6 +369,22 @@ App::get('/v1/vcs/github/callback')
Query::equal('projectInternalId', [$projectInternalId])
]);
$personal = false;
$refreshToken = null;
$accessToken = null;
$accessTokenExpiry = null;
if (!empty($code)) {
$oauth2 = new OAuth2Github(System::getEnv('_APP_VCS_GITHUB_CLIENT_ID', ''), System::getEnv('_APP_VCS_GITHUB_CLIENT_SECRET', ''), "");
$accessToken = $oauth2->getAccessToken($code) ?? '';
$refreshToken = $oauth2->getRefreshToken($code) ?? '';
$accessTokenExpiry = DateTime::addSeconds(new \DateTime(), \intval($oauth2->getAccessTokenExpiry($code)));
$personalSlug = $oauth2->getUserSlug($accessToken) ?? '';
$personal = $personalSlug === $owner;
}
if ($installation->isEmpty()) {
$teamId = $project->getAttribute('teamId', '');
@@ -433,14 +402,20 @@ App::get('/v1/vcs/github/callback')
'projectInternalId' => $projectInternalId,
'provider' => 'github',
'organization' => $owner,
'personal' => $personalSlug === $owner
'personal' => $personal,
'personalRefreshToken' => $refreshToken,
'personalAccessToken' => $accessToken,
'personalAccessTokenExpiry' => $accessTokenExpiry,
]);
$installation = $dbForPlatform->createDocument('installations', $installation);
} else {
$installation = $installation
->setAttribute('organization', $owner)
->setAttribute('personal', $personalSlug === $owner);
->setAttribute('personal', $personal)
->setAttribute('personalRefreshToken', $refreshToken)
->setAttribute('personalAccessToken', $accessToken)
->setAttribute('personalAccessTokenExpiry', $accessTokenExpiry);
$installation = $dbForPlatform->updateDocument('installations', $installation->getId(), $installation);
}
} else {
@@ -720,17 +695,23 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories')
if ($installation->getAttribute('personal', false) === true) {
$oauth2 = new OAuth2Github(System::getEnv('_APP_VCS_GITHUB_CLIENT_ID', ''), System::getEnv('_APP_VCS_GITHUB_CLIENT_SECRET', ''), "");
$identity = $dbForPlatform->findOne('identities', [
Query::equal('provider', ['github']),
Query::equal('userInternalId', [$user->getInternalId()]),
]);
if ($identity->isEmpty()) {
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
}
$accessToken = $installation->getAttribute('personalAccessToken');
$refreshToken = $installation->getAttribute('personalRefreshToken');
$accessTokenExpiry = $installation->getAttribute('personalAccessTokenExpiry');
$accessToken = $identity->getAttribute('providerAccessToken');
$refreshToken = $identity->getAttribute('providerRefreshToken');
$accessTokenExpiry = $identity->getAttribute('providerAccessTokenExpiry');
if (empty($accessToken) || empty($refreshToken) || empty($accessTokenExpiry)) {
$identity = $dbForPlatform->findOne('identities', [
Query::equal('provider', ['github']),
Query::equal('userInternalId', [$user->getInternalId()]),
]);
if ($identity->isEmpty()) {
throw new Exception(Exception::USER_IDENTITY_NOT_FOUND);
}
$accessToken = $accessToken ?? $identity->getAttribute('providerAccessToken');
$refreshToken = $refreshToken ?? $identity->getAttribute('providerRefreshToken');
$accessTokenExpiry = $accessTokenExpiry ?? $identity->getAttribute('providerAccessTokenExpiry');
}
$isExpired = new \DateTime($accessTokenExpiry) < new \DateTime('now');
if ($isExpired) {
@@ -745,12 +726,12 @@ App::post('/v1/vcs/github/installations/:installationId/providerRepositories')
throw new Exception(Exception::GENERAL_RATE_LIMIT_EXCEEDED, "Another request is currently refreshing OAuth token. Please try again.");
}
$identity = $identity
->setAttribute('providerAccessToken', $accessToken)
->setAttribute('providerRefreshToken', $refreshToken)
->setAttribute('providerAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$oauth2->getAccessTokenExpiry('')));
$installation = $installation
->setAttribute('personalAccessToken', $accessToken)
->setAttribute('personalRefreshToken', $refreshToken)
->setAttribute('personalAccessTokenExpiry', DateTime::addSeconds(new \DateTime(), (int)$oauth2->getAccessTokenExpiry('')));
$dbForPlatform->updateDocument('identities', $identity->getId(), $identity);
$dbForPlatform->updateDocument('installations', $installation->getId(), $installation);
}
try {
+2 -14
View File
@@ -21,7 +21,6 @@ use Appwrite\Utopia\Response\Filters\V18 as ResponseV18;
use Appwrite\Utopia\View;
use Executor\Executor;
use MaxMind\Db\Reader;
use Swoole\Database\DetectsLostConnections;
use Swoole\Http\Request as SwooleRequest;
use Utopia\App;
use Utopia\CLI\Console;
@@ -29,7 +28,6 @@ use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Exception as DatabaseException;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
@@ -40,7 +38,6 @@ use Utopia\Logger\Adapter\Sentry;
use Utopia\Logger\Log;
use Utopia\Logger\Log\User;
use Utopia\Logger\Logger;
use Utopia\Pools\Connection;
use Utopia\System\System;
use Utopia\Validator\Hostname;
use Utopia\Validator\Text;
@@ -749,16 +746,7 @@ App::error()
->inject('logger')
->inject('log')
->inject('queueForUsage')
->inject('connectionForProject')
->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Usage $queueForUsage, Connection $connectionForProject) {
if (
($error instanceof PDOException || $error instanceof DatabaseException)
&& DetectsLostConnections::causedByLostConnection($error)
) {
// Mark connection as unhealthy so it will be recycled on next reclaim.
$connectionForProject->setHealthy(false);
}
->action(function (Throwable $error, App $utopia, Request $request, Response $response, Document $project, ?Logger $logger, Log $log, Usage $queueForUsage) {
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
$route = $utopia->getRoute();
$class = \get_class($error);
@@ -907,7 +895,7 @@ App::error()
$log->addTag('database', $dsn->getHost());
$log->addTag('method', $route->getMethod());
$log->addTag('url', $route->getPath());
$log->addTag('url', $request->getURI());
$log->addTag('verboseType', get_class($error));
$log->addTag('code', $error->getCode());
$log->addTag('projectId', $project->getId());
+1
View File
@@ -506,6 +506,7 @@ App::init()
->setMode($mode)
->setUserAgent($request->getUserAgent(''))
->setIP($request->getIP())
->setHostname($request->getHostname())
->setEvent($route->getLabel('audits.event', ''))
->setProject($project)
->setUser($user);
+9 -8
View File
@@ -5,6 +5,7 @@ use Appwrite\Extend\Exception;
use Appwrite\Utopia\Request;
use MaxMind\Db\Reader;
use Utopia\App;
use Utopia\Config\Config;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Validator\Authorization;
@@ -57,44 +58,44 @@ App::init()
$auths = $project->getAttribute('auths', []);
switch ($route->getLabel('auth.type', '')) {
case 'emailPassword':
if (($auths['emailPassword'] ?? true) === false) {
case 'email-password':
if (($auths[Config::getParam('auth')['email-password']['key']] ?? true) === false) {
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Email / Password authentication is disabled for this project');
}
break;
case 'magic-url':
if (($auths['usersAuthMagicURL'] ?? true) === false) {
if (($auths[Config::getParam('auth')['magic-url']['key']] ?? true) === false) {
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Magic URL authentication is disabled for this project');
}
break;
case 'anonymous':
if (($auths['anonymous'] ?? true) === false) {
if (($auths[Config::getParam('auth')['anonymous']['key']] ?? true) === false) {
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Anonymous authentication is disabled for this project');
}
break;
case 'phone':
if (($auths['phone'] ?? true) === false) {
if (($auths[Config::getParam('auth')['phone']['key']] ?? true) === false) {
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Phone authentication is disabled for this project');
}
break;
case 'invites':
if (($auths['invites'] ?? true) === false) {
if (($auths[Config::getParam('auth')['invites']['key']] ?? true) === false) {
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Invites authentication is disabled for this project');
}
break;
case 'jwt':
if (($auths['JWT'] ?? true) === false) {
if (($auths[Config::getParam('auth')['jwt']['key']] ?? true) === false) {
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'JWT authentication is disabled for this project');
}
break;
case 'email-otp':
if (($auths['emailOTP'] ?? true) === false) {
if (($auths[Config::getParam('auth')['email-otp']['key']] ?? true) === false) {
throw new Exception(Exception::USER_AUTH_METHOD_UNSUPPORTED, 'Email OTP authentication is disabled for this project');
}
break;
-11
View File
@@ -5,7 +5,6 @@ require_once __DIR__ . '/../vendor/autoload.php';
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use Swoole\Constant;
use Swoole\Database\DetectsLostConnections;
use Swoole\Http\Request as SwooleRequest;
use Swoole\Http\Response as SwooleResponse;
use Swoole\Http\Server;
@@ -18,7 +17,6 @@ use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Exception as DatabaseException;
use Utopia\Database\Exception\Duplicate;
use Utopia\Database\Helpers\ID;
use Utopia\Database\Helpers\Permission;
@@ -364,15 +362,6 @@ $http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, Swool
$app->run($request, $response);
} catch (\Throwable $th) {
if (
($th instanceof PDOException || $th instanceof DatabaseException)
&& DetectsLostConnections::causedByLostConnection($th)
) {
// Mark connection as unhealthy so it will be recycled on next reclaim.
$connectionForProject = $app->getResource('connectionForProject');
$connectionForProject->setHealthy(false);
}
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
$logger = $app->getResource("logger");
+31 -29
View File
@@ -74,7 +74,6 @@ use Utopia\Logger\Adapter\Raygun;
use Utopia\Logger\Adapter\Sentry;
use Utopia\Logger\Log;
use Utopia\Logger\Logger;
use Utopia\Pools\Connection as PoolConnection;
use Utopia\Pools\Group;
use Utopia\Pools\Pool;
use Utopia\Queue;
@@ -734,12 +733,19 @@ Database::addFilter(
$data = \json_decode($message->getAttribute('data', []), true);
$providerType = $message->getAttribute('providerType', '');
if ($providerType === MESSAGE_TYPE_EMAIL) {
$searchValues = \array_merge($searchValues, [$data['subject'], MESSAGE_TYPE_EMAIL]);
} elseif ($providerType === MESSAGE_TYPE_SMS) {
$searchValues = \array_merge($searchValues, [$data['content'], MESSAGE_TYPE_SMS]);
} else {
$searchValues = \array_merge($searchValues, [$data['title'], MESSAGE_TYPE_PUSH]);
switch ($providerType) {
case MESSAGE_TYPE_EMAIL:
$searchValues[] = $data['subject'];
$searchValues[] = MESSAGE_TYPE_EMAIL;
break;
case MESSAGE_TYPE_SMS:
$searchValues[] = $data['content'];
$searchValues[] = MESSAGE_TYPE_SMS;
break;
case MESSAGE_TYPE_PUSH:
$searchValues[] = $data['title'] ?? '';
$searchValues[] = MESSAGE_TYPE_PUSH;
break;
}
$search = \implode(' ', \array_filter($searchValues));
@@ -876,6 +882,12 @@ $register->set('pools', function () {
'multiple' => true,
'schemes' => ['mariadb', 'mysql'],
],
'logs' => [
'type' => 'database',
'dsns' => System::getEnv('_APP_CONNECTIONS_DB_LOGS', $fallbackForDB),
'multiple' => false,
'schemes' => ['mariadb', 'mysql'],
],
'queue' => [
'type' => 'queue',
'dsns' => $fallbackForRedis,
@@ -1424,26 +1436,7 @@ App::setResource('console', function () {
]);
}, []);
App::setResource('connectionForProject', function (Group $pools, Document $project) {
if ($project->isEmpty() || $project->getId() === 'console') {
return $pools
->get('console')
->pop();
}
try {
$dsn = new DSN($project->getAttribute('database'));
} catch (\InvalidArgumentException) {
// TODO: Temporary until all projects are using shared tables
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
}
return $pools
->get($dsn->getHost())
->pop();
}, ['pools', 'project']);
App::setResource('dbForProject', function (Group $pools, PoolConnection $connectionForProject, Database $dbForPlatform, Cache $cache, Document $project) {
App::setResource('dbForProject', function (Group $pools, Database $dbForPlatform, Cache $cache, Document $project) {
if ($project->isEmpty() || $project->getId() === 'console') {
return $dbForPlatform;
}
@@ -1455,7 +1448,12 @@ App::setResource('dbForProject', function (Group $pools, PoolConnection $connect
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
}
$database = new Database($connectionForProject->getResource(), $cache);
$dbAdapter = $pools
->get($dsn->getHost())
->pop()
->getResource();
$database = new Database($dbAdapter, $cache);
$database
->setMetadata('host', \gethostname())
@@ -1478,7 +1476,7 @@ App::setResource('dbForProject', function (Group $pools, PoolConnection $connect
}
return $database;
}, ['pools', 'connectionForProject', 'dbForPlatform', 'cache', 'project']);
}, ['pools', 'dbForPlatform', 'cache', 'project']);
App::setResource('dbForPlatform', function (Group $pools, Cache $cache) {
$dbAdapter = $pools
@@ -1855,6 +1853,10 @@ App::setResource('plan', function (array $plan = []) {
return [];
});
App::setResource('smsRates', function () {
return [];
});
App::setResource('team', function (Document $project, Database $dbForPlatform, App $utopia, Request $request) {
$teamInternalId = '';
if ($project->getId() !== 'console') {
+19 -31
View File
@@ -16,7 +16,6 @@ use Appwrite\Event\Migration;
use Appwrite\Event\Usage;
use Appwrite\Event\UsageDump;
use Appwrite\Platform\Appwrite;
use Swoole\Database\DetectsLostConnections;
use Swoole\Runtime;
use Utopia\Abuse\Adapters\TimeLimit\Redis as TimeLimitRedis;
use Utopia\Cache\Adapter\Sharding;
@@ -26,13 +25,11 @@ use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\DateTime;
use Utopia\Database\Document;
use Utopia\Database\Exception as DatabaseException;
use Utopia\Database\Validator\Authorization;
use Utopia\DSN\DSN;
use Utopia\Logger\Log;
use Utopia\Logger\Logger;
use Utopia\Platform\Service;
use Utopia\Pools\Connection as PoolConnection;
use Utopia\Pools\Group;
use Utopia\Queue\Connection;
use Utopia\Queue\Message;
@@ -69,13 +66,13 @@ Server::setResource('project', function (Message $message, Database $dbForPlatfo
return $dbForPlatform->getDocument('projects', $project->getId());
}, ['message', 'dbForPlatform']);
Server::setResource('connectionForProject', function (Group $pools, Document $project) {
Server::setResource('dbForProject', function (Cache $cache, Registry $register, Message $message, Document $project, Database $dbForPlatform) {
if ($project->isEmpty() || $project->getId() === 'console') {
return $pools
->get('console')
->pop();
return $dbForPlatform;
}
$pools = $register->get('pools');
try {
$dsn = new DSN($project->getAttribute('database'));
} catch (\InvalidArgumentException) {
@@ -83,17 +80,12 @@ Server::setResource('connectionForProject', function (Group $pools, Document $pr
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
}
return $pools
$adapter = $pools
->get($dsn->getHost())
->pop();
}, ['pools', 'project']);
->pop()
->getResource();
Server::setResource('dbForProject', function (PoolConnection $connectionForProject, Cache $cache, Registry $register, Message $message, Document $project, Database $dbForPlatform) {
if ($project->isEmpty() || $project->getId() === 'console') {
return $dbForPlatform;
}
$database = new Database($connectionForProject->getResource(), $cache);
$database = new Database($adapter, $cache);
try {
$dsn = new DSN($project->getAttribute('database'));
@@ -117,12 +109,12 @@ Server::setResource('dbForProject', function (PoolConnection $connectionForProje
}
return $database;
}, ['connectionForProject', 'cache', 'register', 'message', 'project', 'dbForPlatform']);
}, ['cache', 'register', 'message', 'project', 'dbForPlatform']);
Server::setResource('getProjectDB', function (Group $pools, PoolConnection $connectionForProject, Database $dbForPlatform, $cache) {
Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) {
$databases = []; // TODO: @Meldiron This should probably be responsibility of utopia-php/pools
return function (Document $project) use ($pools, $connectionForProject, $dbForPlatform, $cache, &$databases): Database {
return function (Document $project) use ($pools, $dbForPlatform, $cache, &$databases): Database {
if ($project->isEmpty() || $project->getId() === 'console') {
return $dbForPlatform;
}
@@ -154,7 +146,12 @@ Server::setResource('getProjectDB', function (Group $pools, PoolConnection $conn
return $database;
}
$database = new Database($connectionForProject->getResource(), $cache);
$dbAdapter = $pools
->get($dsn->getHost())
->pop()
->getResource();
$database = new Database($dbAdapter, $cache);
$databases[$dsn->getHost()] = $database;
@@ -174,7 +171,7 @@ Server::setResource('getProjectDB', function (Group $pools, PoolConnection $conn
return $database;
};
}, ['pools', 'connectionForProject', 'dbForPlatform', 'cache']);
}, ['pools', 'dbForPlatform', 'cache']);
Server::setResource('abuseRetention', function () {
return time() - (int) System::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', 86400);
@@ -413,16 +410,7 @@ $worker
->inject('log')
->inject('pools')
->inject('project')
->inject('connectionForProject')
->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project, PoolConnection $connectionForProject) use ($queueName) {
if (
($error instanceof PDOException || $error instanceof DatabaseException)
&& DetectsLostConnections::causedByLostConnection($error)
) {
// Mark connection as unhealthy, it will be recycled on next reclaim.
$connectionForProject->setHealthy(false);
}
->action(function (Throwable $error, ?Logger $logger, Log $log, Group $pools, Document $project) use ($queueName) {
$pools->reclaim();
$version = System::getEnv('_APP_VERSION', 'UNKNOWN');
+5 -5
View File
@@ -47,11 +47,11 @@
"appwrite/php-clamav": "2.0.*",
"utopia-php/abuse": "0.46.*",
"utopia-php/analytics": "0.10.*",
"utopia-php/audit": "0.43.*",
"utopia-php/audit": "0.46.*",
"utopia-php/cache": "0.11.*",
"utopia-php/cli": "0.15.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "0.53.200",
"utopia-php/database": "0.53.32",
"utopia-php/domains": "0.5.*",
"utopia-php/dsn": "0.2.1",
"utopia-php/framework": "0.33.*",
@@ -59,11 +59,11 @@
"utopia-php/image": "0.7.*",
"utopia-php/locale": "0.4.*",
"utopia-php/logger": "0.6.*",
"utopia-php/messaging": "0.12.*",
"utopia-php/messaging": "0.13.*",
"utopia-php/migration": "0.6.*",
"utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.7.*",
"utopia-php/pools": "0.6.*",
"utopia-php/platform": "0.7.1",
"utopia-php/pools": "0.5.*",
"utopia-php/preloader": "0.2.*",
"utopia-php/queue": "0.7.*",
"utopia-php/registry": "0.5.*",
Generated
+66 -66
View File
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "7b5b5926b452186543903eb539f59c2d",
"content-hash": "3853435a659889e86c16764046950bed",
"packages": [
{
"name": "adhocore/jwt",
@@ -709,16 +709,16 @@
},
{
"name": "google/protobuf",
"version": "v4.29.2",
"version": "v4.29.3",
"source": {
"type": "git",
"url": "https://github.com/protocolbuffers/protobuf-php.git",
"reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945"
"reference": "ab5077c2cfdd1f415f42d11fdbdf903ba8e3d9b7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/79aa5014efeeec3d137df5cdb0ae2fc163953945",
"reference": "79aa5014efeeec3d137df5cdb0ae2fc163953945",
"url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/ab5077c2cfdd1f415f42d11fdbdf903ba8e3d9b7",
"reference": "ab5077c2cfdd1f415f42d11fdbdf903ba8e3d9b7",
"shasum": ""
},
"require": {
@@ -747,9 +747,9 @@
"proto"
],
"support": {
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.2"
"source": "https://github.com/protocolbuffers/protobuf-php/tree/v4.29.3"
},
"time": "2024-12-18T14:11:12+00:00"
"time": "2025-01-08T21:00:13+00:00"
},
{
"name": "jean85/pretty-package-versions",
@@ -1237,16 +1237,16 @@
},
{
"name": "open-telemetry/api",
"version": "1.1.2",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/api.git",
"reference": "04c85a1e41a3d59fa9bdc801a5de1df6624b95ed"
"reference": "351a30baa79699de3de3a814c8ccc7b52ccdfb1d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/api/zipball/04c85a1e41a3d59fa9bdc801a5de1df6624b95ed",
"reference": "04c85a1e41a3d59fa9bdc801a5de1df6624b95ed",
"url": "https://api.github.com/repos/opentelemetry-php/api/zipball/351a30baa79699de3de3a814c8ccc7b52ccdfb1d",
"reference": "351a30baa79699de3de3a814c8ccc7b52ccdfb1d",
"shasum": ""
},
"require": {
@@ -1303,7 +1303,7 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2024-11-16T04:32:30+00:00"
"time": "2025-01-08T23:50:34+00:00"
},
{
"name": "open-telemetry/context",
@@ -1366,16 +1366,16 @@
},
{
"name": "open-telemetry/exporter-otlp",
"version": "1.1.0",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/exporter-otlp.git",
"reference": "9b6de12204f25f8ab9540b46d6e7b5151897ce18"
"reference": "243d9657c44a06f740cf384f486afe954c2b725f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/exporter-otlp/zipball/9b6de12204f25f8ab9540b46d6e7b5151897ce18",
"reference": "9b6de12204f25f8ab9540b46d6e7b5151897ce18",
"url": "https://api.github.com/repos/opentelemetry-php/exporter-otlp/zipball/243d9657c44a06f740cf384f486afe954c2b725f",
"reference": "243d9657c44a06f740cf384f486afe954c2b725f",
"shasum": ""
},
"require": {
@@ -1426,7 +1426,7 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2024-04-30T18:28:30+00:00"
"time": "2025-01-08T23:50:03+00:00"
},
{
"name": "open-telemetry/gen-otlp-protobuf",
@@ -1493,16 +1493,16 @@
},
{
"name": "open-telemetry/sdk",
"version": "1.1.2",
"version": "1.2.0",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/sdk.git",
"reference": "fb0ff8d8279a3776bd604791e2531dd0cc147e8b"
"reference": "9a1c3b866239dbff291e5cc555bb7793eab08127"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/fb0ff8d8279a3776bd604791e2531dd0cc147e8b",
"reference": "fb0ff8d8279a3776bd604791e2531dd0cc147e8b",
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/9a1c3b866239dbff291e5cc555bb7793eab08127",
"reference": "9a1c3b866239dbff291e5cc555bb7793eab08127",
"shasum": ""
},
"require": {
@@ -1579,7 +1579,7 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2024-10-18T21:01:35+00:00"
"time": "2025-01-08T23:50:34+00:00"
},
{
"name": "open-telemetry/sem-conv",
@@ -3136,16 +3136,16 @@
},
{
"name": "utopia-php/abuse",
"version": "0.46.0",
"version": "0.46.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/abuse.git",
"reference": "bef426a9a28b3e71b08216bcbe310455f588c11b"
"reference": "59749df988430b28953fb5cabfad88b0ff5b539b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/bef426a9a28b3e71b08216bcbe310455f588c11b",
"reference": "bef426a9a28b3e71b08216bcbe310455f588c11b",
"url": "https://api.github.com/repos/utopia-php/abuse/zipball/59749df988430b28953fb5cabfad88b0ff5b539b",
"reference": "59749df988430b28953fb5cabfad88b0ff5b539b",
"shasum": ""
},
"require": {
@@ -3153,7 +3153,7 @@
"ext-pdo": "*",
"ext-redis": "*",
"php": ">=8.0",
"utopia-php/database": "0.53.200"
"utopia-php/database": "0.53.32"
},
"require-dev": {
"laravel/pint": "1.5.*",
@@ -3181,9 +3181,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/abuse/issues",
"source": "https://github.com/utopia-php/abuse/tree/0.46.0"
"source": "https://github.com/utopia-php/abuse/tree/0.46.2"
},
"time": "2024-12-27T17:46:08+00:00"
"time": "2025-01-13T02:09:43+00:00"
},
{
"name": "utopia-php/analytics",
@@ -3233,21 +3233,21 @@
},
{
"name": "utopia-php/audit",
"version": "0.43.1",
"version": "0.46.1",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/audit.git",
"reference": "04a47dd1f5f92e2d50e971a06bcc9e759325d277"
"reference": "21255fa1ce66433140a43d380b2859c7f0a0bb37"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/04a47dd1f5f92e2d50e971a06bcc9e759325d277",
"reference": "04a47dd1f5f92e2d50e971a06bcc9e759325d277",
"url": "https://api.github.com/repos/utopia-php/audit/zipball/21255fa1ce66433140a43d380b2859c7f0a0bb37",
"reference": "21255fa1ce66433140a43d380b2859c7f0a0bb37",
"shasum": ""
},
"require": {
"php": ">=8.0",
"utopia-php/database": "0.53.*"
"utopia-php/database": "0.53.32"
},
"require-dev": {
"laravel/pint": "1.5.*",
@@ -3274,9 +3274,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/audit/issues",
"source": "https://github.com/utopia-php/audit/tree/0.43.1"
"source": "https://github.com/utopia-php/audit/tree/0.46.1"
},
"time": "2024-10-23T04:27:59+00:00"
"time": "2025-01-13T02:19:56+00:00"
},
{
"name": "utopia-php/cache",
@@ -3476,16 +3476,16 @@
},
{
"name": "utopia-php/database",
"version": "0.53.200",
"version": "0.53.32",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/database.git",
"reference": "570c63a3760d0e1404679ddfacd9484af40bd9fc"
"reference": "981a1241139b42dccd531511130b79137740b205"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/570c63a3760d0e1404679ddfacd9484af40bd9fc",
"reference": "570c63a3760d0e1404679ddfacd9484af40bd9fc",
"url": "https://api.github.com/repos/utopia-php/database/zipball/981a1241139b42dccd531511130b79137740b205",
"reference": "981a1241139b42dccd531511130b79137740b205",
"shasum": ""
},
"require": {
@@ -3526,9 +3526,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.53.200"
"source": "https://github.com/utopia-php/database/tree/0.53.32"
},
"time": "2024-12-01T07:59:15+00:00"
"time": "2025-01-10T08:53:47+00:00"
},
{
"name": "utopia-php/domains",
@@ -3878,16 +3878,16 @@
},
{
"name": "utopia-php/messaging",
"version": "0.12.2",
"version": "0.13.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/messaging.git",
"reference": "f6790fba1fcee12163d51c65d2c226a7856295d9"
"reference": "0e3e57351fe4fe875ef3ab9a01a7fff5f022de90"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/f6790fba1fcee12163d51c65d2c226a7856295d9",
"reference": "f6790fba1fcee12163d51c65d2c226a7856295d9",
"url": "https://api.github.com/repos/utopia-php/messaging/zipball/0e3e57351fe4fe875ef3ab9a01a7fff5f022de90",
"reference": "0e3e57351fe4fe875ef3ab9a01a7fff5f022de90",
"shasum": ""
},
"require": {
@@ -3898,9 +3898,9 @@
"phpmailer/phpmailer": "6.9.1"
},
"require-dev": {
"laravel/pint": "1.13.11",
"phpstan/phpstan": "1.10.58",
"phpunit/phpunit": "10.5.10"
"laravel/pint": "1.*",
"phpstan/phpstan": "1.*",
"phpunit/phpunit": "11.*"
},
"type": "library",
"autoload": {
@@ -3923,9 +3923,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/messaging/issues",
"source": "https://github.com/utopia-php/messaging/tree/0.12.2"
"source": "https://github.com/utopia-php/messaging/tree/0.13.0"
},
"time": "2024-10-22T01:02:20+00:00"
"time": "2024-12-05T08:36:07+00:00"
},
{
"name": "utopia-php/migration",
@@ -4145,25 +4145,25 @@
},
{
"name": "utopia-php/pools",
"version": "0.6.0",
"version": "0.5.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/pools.git",
"reference": "59414ab7b57728edfde6d5ccc5a2583b7967ac18"
"reference": "6f716a213a08db95eda1b5dddfa90983c1834817"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/pools/zipball/59414ab7b57728edfde6d5ccc5a2583b7967ac18",
"reference": "59414ab7b57728edfde6d5ccc5a2583b7967ac18",
"url": "https://api.github.com/repos/utopia-php/pools/zipball/6f716a213a08db95eda1b5dddfa90983c1834817",
"reference": "6f716a213a08db95eda1b5dddfa90983c1834817",
"shasum": ""
},
"require": {
"php": ">=8.3"
"php": ">=8.0"
},
"require-dev": {
"laravel/pint": "1.*",
"phpstan/phpstan": "1.*",
"phpunit/phpunit": "11.*"
"laravel/pint": "1.2.*",
"phpstan/phpstan": "1.8.*",
"phpunit/phpunit": "^9.3"
},
"type": "library",
"autoload": {
@@ -4190,9 +4190,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/pools/issues",
"source": "https://github.com/utopia-php/pools/tree/0.6.0"
"source": "https://github.com/utopia-php/pools/tree/0.5.0"
},
"time": "2025-01-08T07:58:42+00:00"
"time": "2024-04-19T11:11:54+00:00"
},
{
"name": "utopia-php/preloader",
@@ -5126,16 +5126,16 @@
},
{
"name": "laravel/pint",
"version": "v1.19.0",
"version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/laravel/pint.git",
"reference": "8169513746e1bac70c85d6ea1524d9225d4886f0"
"reference": "53072e8ea22213a7ed168a8a15b96fbb8b82d44b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/8169513746e1bac70c85d6ea1524d9225d4886f0",
"reference": "8169513746e1bac70c85d6ea1524d9225d4886f0",
"url": "https://api.github.com/repos/laravel/pint/zipball/53072e8ea22213a7ed168a8a15b96fbb8b82d44b",
"reference": "53072e8ea22213a7ed168a8a15b96fbb8b82d44b",
"shasum": ""
},
"require": {
@@ -5188,7 +5188,7 @@
"issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint"
},
"time": "2024-12-30T16:20:10+00:00"
"time": "2025-01-14T16:20:53+00:00"
},
{
"name": "matthiasmullie/minify",
@@ -13,6 +13,6 @@ AttributeString result = await databases.updateStringAttribute(
key: '',
xrequired: false,
xdefault: '<DEFAULT>',
size: 0, // (optional)
size: 1, // (optional)
newKey: '', // (optional)
);
@@ -9,8 +9,8 @@ Messaging messaging = Messaging(client);
Message result = await messaging.createPush(
messageId: '<MESSAGE_ID>',
title: '<TITLE>',
body: '<BODY>',
title: '<TITLE>', // (optional)
body: '<BODY>', // (optional)
topics: [], // (optional)
users: [], // (optional)
targets: [], // (optional)
@@ -21,7 +21,10 @@ Message result = await messaging.createPush(
sound: '<SOUND>', // (optional)
color: '<COLOR>', // (optional)
tag: '<TAG>', // (optional)
badge: '<BADGE>', // (optional)
badge: 0, // (optional)
draft: false, // (optional)
scheduledAt: '', // (optional)
contentAvailable: false, // (optional)
critical: false, // (optional)
priority: MessagePriority.normal, // (optional)
);
@@ -24,4 +24,7 @@ Message result = await messaging.updatePush(
badge: 0, // (optional)
draft: false, // (optional)
scheduledAt: '', // (optional)
contentAvailable: false, // (optional)
critical: false, // (optional)
priority: MessagePriority.normal, // (optional)
);
@@ -13,6 +13,6 @@ const response = await databases.updateStringAttribute(
'', // key
false, // required
'<DEFAULT>', // default
null, // size (optional)
1, // size (optional)
'' // newKey (optional)
);
@@ -1,4 +1,4 @@
import { Client, Messaging } from "https://deno.land/x/appwrite/mod.ts";
import { Client, Messaging, MessagePriority } from "https://deno.land/x/appwrite/mod.ts";
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
@@ -9,8 +9,8 @@ const messaging = new Messaging(client);
const response = await messaging.createPush(
'<MESSAGE_ID>', // messageId
'<TITLE>', // title
'<BODY>', // body
'<TITLE>', // title (optional)
'<BODY>', // body (optional)
[], // topics (optional)
[], // users (optional)
[], // targets (optional)
@@ -21,7 +21,10 @@ const response = await messaging.createPush(
'<SOUND>', // sound (optional)
'<COLOR>', // color (optional)
'<TAG>', // tag (optional)
'<BADGE>', // badge (optional)
null, // badge (optional)
false, // draft (optional)
'' // scheduledAt (optional)
'', // scheduledAt (optional)
false, // contentAvailable (optional)
false, // critical (optional)
MessagePriority.Normal // priority (optional)
);
@@ -1,4 +1,4 @@
import { Client, Messaging } from "https://deno.land/x/appwrite/mod.ts";
import { Client, Messaging, MessagePriority } from "https://deno.land/x/appwrite/mod.ts";
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
@@ -23,5 +23,8 @@ const response = await messaging.updatePush(
'<TAG>', // tag (optional)
null, // badge (optional)
false, // draft (optional)
'' // scheduledAt (optional)
'', // scheduledAt (optional)
false, // contentAvailable (optional)
false, // critical (optional)
MessagePriority.Normal // priority (optional)
);
@@ -15,6 +15,6 @@ AttributeString result = await databases.UpdateStringAttribute(
key: "",
required: false,
default: "<DEFAULT>",
size: 0, // optional
size: 1, // optional
newKey: "" // optional
);
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Enums;
using Appwrite.Models;
using Appwrite.Services;
@@ -11,8 +12,8 @@ Messaging messaging = new Messaging(client);
Message result = await messaging.CreatePush(
messageId: "<MESSAGE_ID>",
title: "<TITLE>",
body: "<BODY>",
title: "<TITLE>", // optional
body: "<BODY>", // optional
topics: new List<string>(), // optional
users: new List<string>(), // optional
targets: new List<string>(), // optional
@@ -23,7 +24,10 @@ Message result = await messaging.CreatePush(
sound: "<SOUND>", // optional
color: "<COLOR>", // optional
tag: "<TAG>", // optional
badge: "<BADGE>", // optional
badge: 0, // optional
draft: false, // optional
scheduledAt: "" // optional
scheduledAt: "", // optional
contentAvailable: false, // optional
critical: false, // optional
priority: MessagePriority.Normal // optional
);
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Enums;
using Appwrite.Models;
using Appwrite.Services;
@@ -25,5 +26,8 @@ Message result = await messaging.UpdatePush(
tag: "<TAG>", // optional
badge: 0, // optional
draft: false, // optional
scheduledAt: "" // optional
scheduledAt: "", // optional
contentAvailable: false, // optional
critical: false, // optional
priority: MessagePriority.Normal // optional
);
@@ -20,7 +20,7 @@ func main() {
"",
false,
"<DEFAULT>",
databases.WithUpdateStringAttributeSize(0),
databases.WithUpdateStringAttributeSize(1),
databases.WithUpdateStringAttributeNewKey(""),
)
@@ -16,8 +16,8 @@ func main() {
service := messaging.NewMessaging(client)
response, error := service.CreatePush(
"<MESSAGE_ID>",
"<TITLE>",
"<BODY>",
messaging.WithCreatePushTitle("<TITLE>"),
messaging.WithCreatePushBody("<BODY>"),
messaging.WithCreatePushTopics([]interface{}{}),
messaging.WithCreatePushUsers([]interface{}{}),
messaging.WithCreatePushTargets([]interface{}{}),
@@ -28,9 +28,12 @@ func main() {
messaging.WithCreatePushSound("<SOUND>"),
messaging.WithCreatePushColor("<COLOR>"),
messaging.WithCreatePushTag("<TAG>"),
messaging.WithCreatePushBadge("<BADGE>"),
messaging.WithCreatePushBadge(0),
messaging.WithCreatePushDraft(false),
messaging.WithCreatePushScheduledAt(""),
messaging.WithCreatePushContentAvailable(false),
messaging.WithCreatePushCritical(false),
messaging.WithCreatePushPriority("normal"),
)
if error != nil {
@@ -31,6 +31,9 @@ func main() {
messaging.WithUpdatePushBadge(0),
messaging.WithUpdatePushDraft(false),
messaging.WithUpdatePushScheduledAt(""),
messaging.WithUpdatePushContentAvailable(false),
messaging.WithUpdatePushCritical(false),
messaging.WithUpdatePushPriority("normal"),
)
if error != nil {
@@ -33,6 +33,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -28,6 +28,7 @@ query {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -31,6 +31,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -30,6 +30,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -31,6 +31,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -30,6 +30,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -31,6 +31,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -31,6 +31,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -30,6 +30,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -28,6 +28,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
default
}
}
@@ -23,6 +23,8 @@ mutation {
error
attributes
orders
_createdAt
_updatedAt
}
}
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -14,6 +14,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
elements
format
default
@@ -15,6 +15,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
min
max
default
@@ -13,5 +13,7 @@ mutation {
error
attributes
orders
_createdAt
_updatedAt
}
}
@@ -15,6 +15,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
min
max
default
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -15,6 +15,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
relatedCollection
relationType
twoWay
@@ -15,6 +15,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
size
default
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -19,6 +19,8 @@ query {
error
attributes
orders
_createdAt
_updatedAt
}
}
}
@@ -10,5 +10,7 @@ query {
error
attributes
orders
_createdAt
_updatedAt
}
}
@@ -22,6 +22,8 @@ query {
error
attributes
orders
_createdAt
_updatedAt
}
}
}
@@ -12,6 +12,8 @@ query {
error
attributes
orders
_createdAt
_updatedAt
}
}
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
default
}
}
@@ -23,6 +23,8 @@ mutation {
error
attributes
orders
_createdAt
_updatedAt
}
}
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -14,6 +14,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
elements
format
default
@@ -15,6 +15,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
min
max
default
@@ -15,6 +15,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
min
max
default
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -12,6 +12,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
relatedCollection
relationType
twoWay
@@ -5,7 +5,7 @@ mutation {
key: "",
required: false,
default: "<DEFAULT>",
size: 0,
size: 1,
newKey: ""
) {
key
@@ -14,6 +14,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
size
default
}
@@ -13,6 +13,8 @@ mutation {
error
required
array
_createdAt
_updatedAt
format
default
}
@@ -13,9 +13,12 @@ mutation {
sound: "<SOUND>",
color: "<COLOR>",
tag: "<TAG>",
badge: "<BADGE>",
badge: 0,
draft: false,
scheduledAt: ""
scheduledAt: "",
contentAvailable: false,
critical: false,
priority: "normal"
) {
_id
_createdAt
@@ -17,6 +17,7 @@ mutation {
providerId
providerType
identifier
expired
}
userId
userName
@@ -16,6 +16,7 @@ query {
providerId
providerType
identifier
expired
}
userId
userName
@@ -19,6 +19,7 @@ query {
providerId
providerType
identifier
expired
}
userId
userName
@@ -13,6 +13,7 @@ query {
providerId
providerType
identifier
expired
}
}
}
@@ -15,7 +15,10 @@ mutation {
tag: "<TAG>",
badge: 0,
draft: false,
scheduledAt: ""
scheduledAt: "",
contentAvailable: false,
critical: false,
priority: "normal"
) {
_id
_createdAt
@@ -33,6 +33,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -33,6 +33,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -33,6 +33,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -33,6 +33,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -34,6 +34,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -36,6 +36,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -38,6 +38,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -15,5 +15,6 @@ mutation {
providerId
providerType
identifier
expired
}
}
@@ -34,6 +34,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -31,6 +31,7 @@ mutation {
providerId
providerType
identifier
expired
}
accessedAt
}
@@ -11,5 +11,6 @@ query {
providerId
providerType
identifier
expired
}
}
@@ -30,6 +30,7 @@ query {
providerId
providerType
identifier
expired
}
accessedAt
}

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