mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch '1.6.x' into feat-update-sdk-gen
# Conflicts: # composer.lock
This commit is contained in:
@@ -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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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
@@ -349,11 +349,6 @@ return [
|
||||
'description' => 'Team with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::TEAM_INVITE_ALREADY_EXISTS => [
|
||||
'name' => Exception::TEAM_INVITE_ALREADY_EXISTS,
|
||||
'description' => 'User has already been invited or is already a member of this team',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::TEAM_INVITE_NOT_FOUND => [
|
||||
'name' => Exception::TEAM_INVITE_NOT_FOUND,
|
||||
'description' => 'The requested team invitation could not be found.',
|
||||
|
||||
@@ -1567,7 +1567,8 @@ return [
|
||||
'required' => false,
|
||||
'type' => 'number'
|
||||
]
|
||||
]
|
||||
],
|
||||
'scopes' => []
|
||||
],
|
||||
[
|
||||
'icon' => 'icon-chip',
|
||||
|
||||
+10
-10
@@ -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,
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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": {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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": []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,6 +268,24 @@ return [
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_COMPRESSION_ENABLED',
|
||||
'description' => 'This option allows you to enable or disable the response compression for the Appwrite API. It\'s enabled by default with value "enabled", and to disable it, pass value "disabled".',
|
||||
'introduction' => '1.6.0',
|
||||
'default' => 'enabled',
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
],
|
||||
[
|
||||
'name' => '_APP_COMPRESSION_MIN_SIZE_BYTES',
|
||||
'description' => 'This option allows you to set the minimum size in bytes for the response compression to be applied. The default value is 1024 bytes.',
|
||||
'introduction' => '1.6.0',
|
||||
'default' => 1024,
|
||||
'required' => false,
|
||||
'question' => '',
|
||||
'filter' => ''
|
||||
]
|
||||
],
|
||||
],
|
||||
[
|
||||
|
||||
@@ -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'))) {
|
||||
|
||||
@@ -400,6 +400,7 @@ App::post('/v1/functions')
|
||||
$allEvents = Event::generateEvents('rules.[ruleId].create', [
|
||||
'ruleId' => $rule->getId(),
|
||||
]);
|
||||
|
||||
$target = Realtime::fromPayload(
|
||||
// Pass first, most verbose event pattern
|
||||
event: $allEvents[0],
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
|
||||
@@ -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')
|
||||
@@ -367,6 +368,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')
|
||||
@@ -981,6 +984,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')
|
||||
@@ -1514,6 +1518,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')
|
||||
@@ -1678,6 +1683,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')
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -540,47 +546,58 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
throw new Exception(Exception::USER_UNAUTHORIZED, 'User is not allowed to send invitations for this team');
|
||||
}
|
||||
|
||||
$secret = Auth::tokenGenerator();
|
||||
|
||||
$membershipId = ID::unique();
|
||||
$membership = new Document([
|
||||
'$id' => $membershipId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::user($invitee->getId())),
|
||||
Permission::update(Role::team($team->getId(), 'owner')),
|
||||
Permission::delete(Role::user($invitee->getId())),
|
||||
Permission::delete(Role::team($team->getId(), 'owner')),
|
||||
],
|
||||
'userId' => $invitee->getId(),
|
||||
'userInternalId' => $invitee->getInternalId(),
|
||||
'teamId' => $team->getId(),
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'roles' => $roles,
|
||||
'invited' => DateTime::now(),
|
||||
'joined' => ($isPrivilegedUser || $isAppUser) ? DateTime::now() : null,
|
||||
'confirm' => ($isPrivilegedUser || $isAppUser),
|
||||
'secret' => Auth::hash($secret),
|
||||
'search' => implode(' ', [$membershipId, $invitee->getId()])
|
||||
$membership = $dbForProject->findOne('memberships', [
|
||||
Query::equal('userInternalId', [$invitee->getInternalId()]),
|
||||
Query::equal('teamInternalId', [$team->getInternalId()]),
|
||||
]);
|
||||
|
||||
if ($isPrivilegedUser || $isAppUser) { // Allow admin to create membership
|
||||
try {
|
||||
$membership = Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership));
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS);
|
||||
}
|
||||
if ($membership->isEmpty()) {
|
||||
$secret = Auth::tokenGenerator();
|
||||
|
||||
$membershipId = ID::unique();
|
||||
$membership = new Document([
|
||||
'$id' => $membershipId,
|
||||
'$permissions' => [
|
||||
Permission::read(Role::any()),
|
||||
Permission::update(Role::user($invitee->getId())),
|
||||
Permission::update(Role::team($team->getId(), 'owner')),
|
||||
Permission::delete(Role::user($invitee->getId())),
|
||||
Permission::delete(Role::team($team->getId(), 'owner')),
|
||||
],
|
||||
'userId' => $invitee->getId(),
|
||||
'userInternalId' => $invitee->getInternalId(),
|
||||
'teamId' => $team->getId(),
|
||||
'teamInternalId' => $team->getInternalId(),
|
||||
'roles' => $roles,
|
||||
'invited' => DateTime::now(),
|
||||
'joined' => ($isPrivilegedUser || $isAppUser) ? DateTime::now() : null,
|
||||
'confirm' => ($isPrivilegedUser || $isAppUser),
|
||||
'secret' => Auth::hash($secret),
|
||||
'search' => implode(' ', [$membershipId, $invitee->getId()])
|
||||
]);
|
||||
|
||||
$membership = ($isPrivilegedUser || $isAppUser) ?
|
||||
Authorization::skip(fn () => $dbForProject->createDocument('memberships', $membership)) :
|
||||
$dbForProject->createDocument('memberships', $membership);
|
||||
Authorization::skip(fn () => $dbForProject->increaseDocumentAttribute('teams', $team->getId(), 'total', 1));
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $invitee->getId());
|
||||
} else {
|
||||
try {
|
||||
$membership = $dbForProject->createDocument('memberships', $membership);
|
||||
} catch (Duplicate $th) {
|
||||
throw new Exception(Exception::TEAM_INVITE_ALREADY_EXISTS);
|
||||
$membership->setAttribute('invited', DateTime::now());
|
||||
|
||||
if ($isPrivilegedUser || $isAppUser) {
|
||||
$membership->setAttribute('joined', DateTime::now());
|
||||
$membership->setAttribute('confirm', true);
|
||||
}
|
||||
|
||||
$membership = ($isPrivilegedUser || $isAppUser) ?
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('memberships', $membership->getId(), $membership)) :
|
||||
$dbForProject->updateDocument('memberships', $membership->getId(), $membership);
|
||||
}
|
||||
|
||||
|
||||
if ($isPrivilegedUser || $isAppUser) {
|
||||
$dbForProject->purgeCachedDocument('users', $invitee->getId());
|
||||
} else {
|
||||
$url = Template::parseURL($url);
|
||||
$url['query'] = Template::mergeQuery(((isset($url['query'])) ? $url['query'] : ''), ['membershipId' => $membership->getId(), 'userId' => $invitee->getId(), 'secret' => $secret, 'teamId' => $teamId]);
|
||||
$url = Template::unParseURL($url);
|
||||
@@ -650,7 +667,7 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
'owner' => $user->getAttribute('name'),
|
||||
'direction' => $locale->getText('settings.direction'),
|
||||
/* {{user}}, {{team}}, {{redirect}} and {{project}} are required in default and custom templates */
|
||||
'user' => $user->getAttribute('name'),
|
||||
'user' => $name,
|
||||
'team' => $team->getAttribute('name'),
|
||||
'redirect' => $url,
|
||||
'project' => $projectName
|
||||
@@ -662,8 +679,8 @@ App::post('/v1/teams/:teamId/memberships')
|
||||
->setRecipient($invitee->getAttribute('email'))
|
||||
->setName($invitee->getAttribute('name'))
|
||||
->setVariables($emailVariables)
|
||||
->trigger()
|
||||
;
|
||||
->trigger();
|
||||
|
||||
} elseif (!empty($phone)) {
|
||||
if (empty(System::getEnv('_APP_SMS_PROVIDER'))) {
|
||||
throw new Exception(Exception::GENERAL_PHONE_DISABLED, 'Phone provider not configured');
|
||||
@@ -691,6 +708,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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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 {
|
||||
|
||||
@@ -894,7 +894,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());
|
||||
|
||||
@@ -58,7 +58,7 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
|
||||
return $label;
|
||||
};
|
||||
|
||||
$eventDatabaseListener = function (Document $document, Response $response, Event $queueForEvents, Func $queueForFunctions, Webhook $queueForWebhooks, Realtime $queueForRealtime) {
|
||||
$eventDatabaseListener = function (Document $project, Document $document, Response $response, Event $queueForEvents, Func $queueForFunctions, Webhook $queueForWebhooks, Realtime $queueForRealtime) {
|
||||
// Only trigger events for user creation with the database listener.
|
||||
if ($document->getCollection() !== 'users') {
|
||||
return;
|
||||
@@ -74,17 +74,20 @@ $eventDatabaseListener = function (Document $document, Response $response, Event
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
|
||||
$queueForWebhooks
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
|
||||
if ($queueForEvents->getProject()->getId() === 'console') {
|
||||
return;
|
||||
/** Trigger webhooks events only if a project has them enabled */
|
||||
if (!empty($project->getAttribute('webhooks'))) {
|
||||
$queueForWebhooks
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
}
|
||||
|
||||
$queueForRealtime
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
/** Trigger realtime events only for non console events */
|
||||
if ($queueForEvents->getProject()->getId() !== 'console') {
|
||||
$queueForRealtime
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
}
|
||||
};
|
||||
|
||||
$usageDatabaseListener = function (string $event, Document $document, Usage $queueForUsage) {
|
||||
@@ -506,6 +509,7 @@ App::init()
|
||||
->setMode($mode)
|
||||
->setUserAgent($request->getUserAgent(''))
|
||||
->setIP($request->getIP())
|
||||
->setHostname($request->getHostname())
|
||||
->setEvent($route->getLabel('audits.event', ''))
|
||||
->setProject($project)
|
||||
->setUser($user);
|
||||
@@ -526,6 +530,7 @@ App::init()
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForUsage))
|
||||
->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', fn ($event, $document) => $usageDatabaseListener($event, $document, $queueForUsage))
|
||||
->on(Database::EVENT_DOCUMENT_CREATE, 'create-trigger-events', fn ($event, $document) => $eventDatabaseListener(
|
||||
$project,
|
||||
$document,
|
||||
$response,
|
||||
$queueForEventsClone->from($queueForEvents),
|
||||
@@ -678,10 +683,6 @@ App::shutdown()
|
||||
$queueForEvents->setPayload($responsePayload);
|
||||
}
|
||||
|
||||
$queueForWebhooks
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
|
||||
$queueForFunctions
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
@@ -691,6 +692,17 @@ App::shutdown()
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
}
|
||||
|
||||
/** Trigger webhooks events only if a project has them enabled
|
||||
* A future optimisation is to only trigger webhooks if the webhook is "enabled"
|
||||
* But it might have performance implications on the API due to the number of webhooks etc.
|
||||
* Some profiling is needed to see if this is a problem.
|
||||
*/
|
||||
if (!empty($project->getAttribute('webhooks'))) {
|
||||
$queueForWebhooks
|
||||
->from($queueForEvents)
|
||||
->trigger();
|
||||
}
|
||||
}
|
||||
|
||||
$route = $utopia->getRoute();
|
||||
|
||||
@@ -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;
|
||||
|
||||
+1
-1
@@ -334,7 +334,7 @@ $http->on(Constant::EVENT_REQUEST, function (SwooleRequest $swooleRequest, Swool
|
||||
}
|
||||
|
||||
$app = new App('UTC');
|
||||
$app->setCompression(true);
|
||||
$app->setCompression(System::getEnv('_APP_COMPRESSION_ENABLED', 'enabled') === 'enabled');
|
||||
$app->setCompressionMinSize(intval(System::getEnv('_APP_COMPRESSION_MIN_SIZE_BYTES', '1024'))); // 1KB
|
||||
|
||||
$pools = $register->get('pools');
|
||||
|
||||
+24
-6
@@ -202,6 +202,7 @@ const DELETE_TYPE_TOPIC = 'topic';
|
||||
const DELETE_TYPE_TARGET = 'target';
|
||||
const DELETE_TYPE_EXPIRED_TARGETS = 'invalid_targets';
|
||||
const DELETE_TYPE_SESSION_TARGETS = 'session_targets';
|
||||
const DELETE_TYPE_MAINTENANCE = 'maintenance';
|
||||
|
||||
// Message types
|
||||
const MESSAGE_SEND_TYPE_INTERNAL = 'internal';
|
||||
@@ -733,12 +734,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));
|
||||
@@ -875,6 +883,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,
|
||||
@@ -1829,6 +1843,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') {
|
||||
|
||||
+6
-6
@@ -47,22 +47,22 @@
|
||||
"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.*",
|
||||
"utopia-php/fetch": "0.2.*",
|
||||
"utopia-php/fetch": "0.3.*",
|
||||
"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/platform": "0.7.1",
|
||||
"utopia-php/pools": "0.5.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
"utopia-php/queue": "0.7.*",
|
||||
@@ -84,7 +84,7 @@
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-fileinfo": "*",
|
||||
"appwrite/sdk-generator": "0.39.29",
|
||||
"appwrite/sdk-generator": "0.39.30",
|
||||
"phpunit/phpunit": "9.5.20",
|
||||
"swoole/ide-helper": "5.1.2",
|
||||
"textalk/websocket": "1.5.7",
|
||||
|
||||
Generated
+85
-85
@@ -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": "819d7979e0239b187e2a1875d97ed0cf",
|
||||
"content-hash": "c2d1dfd6ae18b888e605556e794608fa",
|
||||
"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,20 +1426,20 @@
|
||||
"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",
|
||||
"version": "1.2.1",
|
||||
"version": "1.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opentelemetry-php/gen-otlp-protobuf.git",
|
||||
"reference": "66c3b98e998a726691c92e6405a82e6e7b8b169d"
|
||||
"reference": "585bafddd4ae6565de154610b10a787a455c9ba0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/gen-otlp-protobuf/zipball/66c3b98e998a726691c92e6405a82e6e7b8b169d",
|
||||
"reference": "66c3b98e998a726691c92e6405a82e6e7b8b169d",
|
||||
"url": "https://api.github.com/repos/opentelemetry-php/gen-otlp-protobuf/zipball/585bafddd4ae6565de154610b10a787a455c9ba0",
|
||||
"reference": "585bafddd4ae6565de154610b10a787a455c9ba0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1489,20 +1489,20 @@
|
||||
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
|
||||
"source": "https://github.com/open-telemetry/opentelemetry-php"
|
||||
},
|
||||
"time": "2024-10-30T11:49:49+00:00"
|
||||
"time": "2025-01-15T23:07:07+00:00"
|
||||
},
|
||||
{
|
||||
"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",
|
||||
@@ -3379,16 +3379,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/compression",
|
||||
"version": "0.1.2",
|
||||
"version": "0.1.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/compression.git",
|
||||
"reference": "6062f70596415f8d5de40a589367b0eb2a435f98"
|
||||
"reference": "66f093557ba66d98245e562036182016c7dcfe8a"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/compression/zipball/6062f70596415f8d5de40a589367b0eb2a435f98",
|
||||
"reference": "6062f70596415f8d5de40a589367b0eb2a435f98",
|
||||
"url": "https://api.github.com/repos/utopia-php/compression/zipball/66f093557ba66d98245e562036182016c7dcfe8a",
|
||||
"reference": "66f093557ba66d98245e562036182016c7dcfe8a",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3419,9 +3419,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/compression/issues",
|
||||
"source": "https://github.com/utopia-php/compression/tree/0.1.2"
|
||||
"source": "https://github.com/utopia-php/compression/tree/0.1.3"
|
||||
},
|
||||
"time": "2024-11-08T14:59:54+00:00"
|
||||
"time": "2025-01-15T15:15:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/config",
|
||||
@@ -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",
|
||||
@@ -3639,16 +3639,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/fetch",
|
||||
"version": "0.2.1",
|
||||
"version": "0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/fetch.git",
|
||||
"reference": "1423c0ee3eef944d816ca6e31706895b585aea82"
|
||||
"reference": "02b12c05aec13399dcc2da8d51f908e328ab63f4"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/fetch/zipball/1423c0ee3eef944d816ca6e31706895b585aea82",
|
||||
"reference": "1423c0ee3eef944d816ca6e31706895b585aea82",
|
||||
"url": "https://api.github.com/repos/utopia-php/fetch/zipball/02b12c05aec13399dcc2da8d51f908e328ab63f4",
|
||||
"reference": "02b12c05aec13399dcc2da8d51f908e328ab63f4",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3672,22 +3672,22 @@
|
||||
"description": "A simple library that provides an interface for making HTTP Requests.",
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/fetch/issues",
|
||||
"source": "https://github.com/utopia-php/fetch/tree/0.2.1"
|
||||
"source": "https://github.com/utopia-php/fetch/tree/0.3.0"
|
||||
},
|
||||
"time": "2024-03-18T11:50:59+00:00"
|
||||
"time": "2025-01-17T06:11:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.33.15",
|
||||
"version": "0.33.16",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/http.git",
|
||||
"reference": "83b0628900c2c53e8c3efbf069f3e13050295edc"
|
||||
"reference": "e91d4c560d1b809e25faa63d564fef034363b50f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/83b0628900c2c53e8c3efbf069f3e13050295edc",
|
||||
"reference": "83b0628900c2c53e8c3efbf069f3e13050295edc",
|
||||
"url": "https://api.github.com/repos/utopia-php/http/zipball/e91d4c560d1b809e25faa63d564fef034363b50f",
|
||||
"reference": "e91d4c560d1b809e25faa63d564fef034363b50f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3719,9 +3719,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/http/issues",
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.15"
|
||||
"source": "https://github.com/utopia-php/http/tree/0.33.16"
|
||||
},
|
||||
"time": "2024-12-10T13:07:04+00:00"
|
||||
"time": "2025-01-16T15:58:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
@@ -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",
|
||||
@@ -4807,16 +4807,16 @@
|
||||
"packages-dev": [
|
||||
{
|
||||
"name": "appwrite/sdk-generator",
|
||||
"version": "0.39.29",
|
||||
"version": "0.39.30",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/appwrite/sdk-generator.git",
|
||||
"reference": "a9c3f6076ec162588dac7b0a741bc1a2c3d1a2b7"
|
||||
"reference": "830198d501f51163514305befefb775106a7198b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/a9c3f6076ec162588dac7b0a741bc1a2c3d1a2b7",
|
||||
"reference": "a9c3f6076ec162588dac7b0a741bc1a2c3d1a2b7",
|
||||
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/830198d501f51163514305befefb775106a7198b",
|
||||
"reference": "830198d501f51163514305befefb775106a7198b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4852,9 +4852,9 @@
|
||||
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
|
||||
"support": {
|
||||
"issues": "https://github.com/appwrite/sdk-generator/issues",
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.39.29"
|
||||
"source": "https://github.com/appwrite/sdk-generator/tree/0.39.30"
|
||||
},
|
||||
"time": "2025-01-07T05:28:35+00:00"
|
||||
"time": "2025-01-20T06:10:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/annotations",
|
||||
@@ -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",
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
appwrite messaging createPush \
|
||||
--messageId <MESSAGE_ID> \
|
||||
--title <TITLE> \
|
||||
--body <BODY> \
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,3 +15,6 @@ appwrite messaging updatePush \
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Client, Messaging } from "@appwrite.io/console";
|
||||
import { Client, Messaging, MessagePriority } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
|
||||
@@ -8,8 +8,8 @@ const messaging = new Messaging(client);
|
||||
|
||||
const result = await messaging.createPush(
|
||||
'<MESSAGE_ID>', // messageId
|
||||
'<TITLE>', // title
|
||||
'<BODY>', // body
|
||||
'<TITLE>', // title (optional)
|
||||
'<BODY>', // body (optional)
|
||||
[], // topics (optional)
|
||||
[], // users (optional)
|
||||
[], // targets (optional)
|
||||
@@ -20,9 +20,12 @@ const result = 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)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Client, Messaging } from "@appwrite.io/console";
|
||||
import { Client, Messaging, MessagePriority } from "@appwrite.io/console";
|
||||
|
||||
const client = new Client()
|
||||
.setEndpoint('https://cloud.appwrite.io/v1') // Your API Endpoint
|
||||
@@ -22,7 +22,10 @@ const result = 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)
|
||||
);
|
||||
|
||||
console.log(result);
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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)
|
||||
);
|
||||
|
||||
@@ -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
|
||||
);
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -15,7 +15,10 @@ mutation {
|
||||
tag: "<TAG>",
|
||||
badge: 0,
|
||||
draft: false,
|
||||
scheduledAt: ""
|
||||
scheduledAt: "",
|
||||
contentAvailable: false,
|
||||
critical: false,
|
||||
priority: "normal"
|
||||
) {
|
||||
_id
|
||||
_createdAt
|
||||
|
||||
@@ -11,8 +11,8 @@ Messaging messaging = new Messaging(client);
|
||||
|
||||
messaging.createPush(
|
||||
"<MESSAGE_ID>", // messageId
|
||||
"<TITLE>", // title
|
||||
"<BODY>", // body
|
||||
"<TITLE>", // title (optional)
|
||||
"<BODY>", // body (optional)
|
||||
listOf(), // topics (optional)
|
||||
listOf(), // users (optional)
|
||||
listOf(), // targets (optional)
|
||||
@@ -23,9 +23,12 @@ messaging.createPush(
|
||||
"<SOUND>", // sound (optional)
|
||||
"<COLOR>", // color (optional)
|
||||
"<TAG>", // tag (optional)
|
||||
"<BADGE>", // badge (optional)
|
||||
0, // badge (optional)
|
||||
false, // draft (optional)
|
||||
"", // scheduledAt (optional)
|
||||
false, // contentAvailable (optional)
|
||||
false, // critical (optional)
|
||||
MessagePriority.NORMAL, // priority (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -26,6 +26,9 @@ messaging.updatePush(
|
||||
0, // badge (optional)
|
||||
false, // draft (optional)
|
||||
"", // scheduledAt (optional)
|
||||
false, // contentAvailable (optional)
|
||||
false, // critical (optional)
|
||||
MessagePriority.NORMAL, // priority (optional)
|
||||
new CoroutineCallback<>((result, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
|
||||
@@ -11,8 +11,8 @@ val messaging = Messaging(client)
|
||||
|
||||
val response = messaging.createPush(
|
||||
messageId = "<MESSAGE_ID>",
|
||||
title = "<TITLE>",
|
||||
body = "<BODY>",
|
||||
title = "<TITLE>", // optional
|
||||
body = "<BODY>", // optional
|
||||
topics = listOf(), // optional
|
||||
users = listOf(), // optional
|
||||
targets = listOf(), // optional
|
||||
@@ -23,7 +23,10 @@ val response = 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 = "normal" // optional
|
||||
)
|
||||
|
||||
@@ -25,5 +25,8 @@ val response = messaging.updatePush(
|
||||
tag = "<TAG>", // optional
|
||||
badge = 0, // optional
|
||||
draft = false, // optional
|
||||
scheduledAt = "" // optional
|
||||
scheduledAt = "", // optional
|
||||
contentAvailable = false, // optional
|
||||
critical = false, // optional
|
||||
priority = "normal" // optional
|
||||
)
|
||||
|
||||
@@ -9,8 +9,8 @@ const messaging = new sdk.Messaging(client);
|
||||
|
||||
const result = 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 result = 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)
|
||||
sdk.MessagePriority.Normal // priority (optional)
|
||||
);
|
||||
|
||||
@@ -23,5 +23,8 @@ const result = await messaging.updatePush(
|
||||
'<TAG>', // tag (optional)
|
||||
null, // badge (optional)
|
||||
false, // draft (optional)
|
||||
'' // scheduledAt (optional)
|
||||
'', // scheduledAt (optional)
|
||||
false, // contentAvailable (optional)
|
||||
false, // critical (optional)
|
||||
sdk.MessagePriority.Normal // priority (optional)
|
||||
);
|
||||
|
||||
@@ -12,8 +12,8 @@ $messaging = new Messaging($client);
|
||||
|
||||
$result = $messaging->createPush(
|
||||
messageId: '<MESSAGE_ID>',
|
||||
title: '<TITLE>',
|
||||
body: '<BODY>',
|
||||
title: '<TITLE>', // optional
|
||||
body: '<BODY>', // optional
|
||||
topics: [], // optional
|
||||
users: [], // optional
|
||||
targets: [], // optional
|
||||
@@ -24,7 +24,10 @@ $result = $messaging->createPush(
|
||||
sound: '<SOUND>', // optional
|
||||
color: '<COLOR>', // optional
|
||||
tag: '<TAG>', // optional
|
||||
badge: '<BADGE>', // optional
|
||||
badge: null, // optional
|
||||
draft: false, // optional
|
||||
scheduledAt: '' // optional
|
||||
scheduledAt: '', // optional
|
||||
contentAvailable: false, // optional
|
||||
critical: false, // optional
|
||||
priority: MessagePriority::NORMAL() // optional
|
||||
);
|
||||
@@ -26,5 +26,8 @@ $result = $messaging->updatePush(
|
||||
tag: '<TAG>', // optional
|
||||
badge: null, // optional
|
||||
draft: false, // optional
|
||||
scheduledAt: '' // optional
|
||||
scheduledAt: '', // optional
|
||||
contentAvailable: false, // optional
|
||||
critical: false, // optional
|
||||
priority: MessagePriority::NORMAL() // optional
|
||||
);
|
||||
@@ -10,8 +10,8 @@ messaging = Messaging(client)
|
||||
|
||||
result = messaging.create_push(
|
||||
message_id = '<MESSAGE_ID>',
|
||||
title = '<TITLE>',
|
||||
body = '<BODY>',
|
||||
title = '<TITLE>', # optional
|
||||
body = '<BODY>', # optional
|
||||
topics = [], # optional
|
||||
users = [], # optional
|
||||
targets = [], # optional
|
||||
@@ -22,7 +22,10 @@ result = messaging.create_push(
|
||||
sound = '<SOUND>', # optional
|
||||
color = '<COLOR>', # optional
|
||||
tag = '<TAG>', # optional
|
||||
badge = '<BADGE>', # optional
|
||||
badge = None, # optional
|
||||
draft = False, # optional
|
||||
scheduled_at = '' # optional
|
||||
scheduled_at = '', # optional
|
||||
content_available = False, # optional
|
||||
critical = False, # optional
|
||||
priority = MessagePriority.NORMAL # optional
|
||||
)
|
||||
|
||||
@@ -24,5 +24,8 @@ result = messaging.update_push(
|
||||
tag = '<TAG>', # optional
|
||||
badge = None, # optional
|
||||
draft = False, # optional
|
||||
scheduled_at = '' # optional
|
||||
scheduled_at = '', # optional
|
||||
content_available = False, # optional
|
||||
critical = False, # optional
|
||||
priority = MessagePriority.NORMAL # optional
|
||||
)
|
||||
|
||||
@@ -19,7 +19,10 @@ X-Appwrite-Key: <YOUR_API_KEY>
|
||||
"sound": "<SOUND>",
|
||||
"color": "<COLOR>",
|
||||
"tag": "<TAG>",
|
||||
"badge": "<BADGE>",
|
||||
"badge": 0,
|
||||
"draft": false,
|
||||
"scheduledAt":
|
||||
"scheduledAt": ,
|
||||
"contentAvailable": false,
|
||||
"critical": false,
|
||||
"priority": "normal"
|
||||
}
|
||||
|
||||
@@ -20,5 +20,8 @@ X-Appwrite-Key: <YOUR_API_KEY>
|
||||
"tag": "<TAG>",
|
||||
"badge": 0,
|
||||
"draft": false,
|
||||
"scheduledAt":
|
||||
"scheduledAt": ,
|
||||
"contentAvailable": false,
|
||||
"critical": false,
|
||||
"priority": "normal"
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ messaging = Messaging.new(client)
|
||||
|
||||
result = messaging.create_push(
|
||||
message_id: '<MESSAGE_ID>',
|
||||
title: '<TITLE>',
|
||||
body: '<BODY>',
|
||||
title: '<TITLE>', # optional
|
||||
body: '<BODY>', # optional
|
||||
topics: [], # optional
|
||||
users: [], # optional
|
||||
targets: [], # optional
|
||||
@@ -23,7 +23,10 @@ result = messaging.create_push(
|
||||
sound: '<SOUND>', # optional
|
||||
color: '<COLOR>', # optional
|
||||
tag: '<TAG>', # optional
|
||||
badge: '<BADGE>', # optional
|
||||
badge: null, # optional
|
||||
draft: false, # optional
|
||||
scheduled_at: '' # optional
|
||||
scheduled_at: '', # optional
|
||||
content_available: false, # optional
|
||||
critical: false, # optional
|
||||
priority: MessagePriority::NORMAL # optional
|
||||
)
|
||||
|
||||
@@ -25,5 +25,8 @@ result = messaging.update_push(
|
||||
tag: '<TAG>', # optional
|
||||
badge: null, # optional
|
||||
draft: false, # optional
|
||||
scheduled_at: '' # optional
|
||||
scheduled_at: '', # optional
|
||||
content_available: false, # optional
|
||||
critical: false, # optional
|
||||
priority: MessagePriority::NORMAL # optional
|
||||
)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Appwrite
|
||||
import AppwriteEnums
|
||||
|
||||
let client = Client()
|
||||
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -9,8 +10,8 @@ let messaging = Messaging(client)
|
||||
|
||||
let message = try await messaging.createPush(
|
||||
messageId: "<MESSAGE_ID>",
|
||||
title: "<TITLE>",
|
||||
body: "<BODY>",
|
||||
title: "<TITLE>", // optional
|
||||
body: "<BODY>", // optional
|
||||
topics: [], // optional
|
||||
users: [], // optional
|
||||
targets: [], // optional
|
||||
@@ -21,8 +22,11 @@ let message = try 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: .normal // optional
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import Appwrite
|
||||
import AppwriteEnums
|
||||
|
||||
let client = Client()
|
||||
.setEndpoint("https://cloud.appwrite.io/v1") // Your API Endpoint
|
||||
@@ -23,6 +24,9 @@ let message = try await messaging.updatePush(
|
||||
tag: "<TAG>", // optional
|
||||
badge: 0, // optional
|
||||
draft: false, // optional
|
||||
scheduledAt: "" // optional
|
||||
scheduledAt: "", // optional
|
||||
contentAvailable: false, // optional
|
||||
critical: false, // optional
|
||||
priority: .normal // optional
|
||||
)
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Audit extends Event
|
||||
@@ -11,6 +10,7 @@ class Audit extends Event
|
||||
protected string $mode = '';
|
||||
protected string $userAgent = '';
|
||||
protected string $ip = '';
|
||||
protected string $hostname = '';
|
||||
|
||||
public function __construct(protected Connection $connection)
|
||||
{
|
||||
@@ -114,20 +114,37 @@ class Audit extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the event and sends it to the audit worker.
|
||||
* Set the hostname.
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
* @param string $hostname
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
public function setHostname(string $hostname): self
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
$this->hostname = $hostname;
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $client->enqueue([
|
||||
/**
|
||||
* Get the hostname.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getHostname(): string
|
||||
{
|
||||
return $this->hostname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare payload for queue.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'payload' => $this->payload,
|
||||
@@ -136,6 +153,7 @@ class Audit extends Event
|
||||
'ip' => $this->ip,
|
||||
'userAgent' => $this->userAgent,
|
||||
'event' => $this->event,
|
||||
]);
|
||||
'hostname' => $this->hostname
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Build extends Event
|
||||
@@ -105,26 +104,19 @@ class Build extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the function event and sends it to the functions worker.
|
||||
* Prepare payload for queue.
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
* @return array
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'resource' => $this->resource,
|
||||
'deployment' => $this->deployment,
|
||||
'type' => $this->type,
|
||||
'template' => $this->template
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Certificate extends Event
|
||||
@@ -67,23 +66,16 @@ class Certificate extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the event and sends it to the certificates worker.
|
||||
* Prepare the payload for the event
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
* @return array
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'domain' => $this->domain,
|
||||
'skipRenewCheck' => $this->skipRenewCheck
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\DSN\DSN;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Database extends Event
|
||||
@@ -100,18 +99,8 @@ class Database extends Event
|
||||
return $this->document;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the event and send it to the database worker.
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
public function getQueue(): string
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$dsn = new DSN($this->getProject()->getAttribute('database'));
|
||||
} catch (\InvalidArgumentException) {
|
||||
@@ -119,23 +108,25 @@ class Database extends Event
|
||||
$dsn = new DSN('mysql://' . $this->getProject()->getAttribute('database'));
|
||||
}
|
||||
|
||||
$this->setQueue($dsn->getHost());
|
||||
$this->queue = $dsn->getHost();
|
||||
return $this->queue;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
try {
|
||||
$result = $client->enqueue([
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'type' => $this->type,
|
||||
'collection' => $this->collection,
|
||||
'document' => $this->document,
|
||||
'database' => $this->database,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
]);
|
||||
return $result;
|
||||
} catch (\Throwable $th) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Prepare the payload for the event
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'type' => $this->type,
|
||||
'collection' => $this->collection,
|
||||
'document' => $this->document,
|
||||
'database' => $this->database,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Delete extends Event
|
||||
@@ -131,22 +130,14 @@ class Delete extends Event
|
||||
return $this->document;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Executes this event and sends it to the deletes worker.
|
||||
* Prepare the payload for the event
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
* @return array
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'type' => $this->type,
|
||||
'document' => $this->document,
|
||||
@@ -154,6 +145,6 @@ class Delete extends Event
|
||||
'resourceType' => $this->resourceType,
|
||||
'datetime' => $this->datetime,
|
||||
'hourlyUsageRetentionDatetime' => $this->hourlyUsageRetentionDatetime
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -137,7 +137,6 @@ class Event
|
||||
public function setProject(Document $project): self
|
||||
{
|
||||
$this->project = $project;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -312,6 +311,27 @@ class Event
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get trimmed values for sensitive/large payload fields.
|
||||
* Override this method in child classes to add more fields to trim.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function trimPayload(): array
|
||||
{
|
||||
$trimmed = [];
|
||||
|
||||
if ($this->project) {
|
||||
$trimmed['project'] = new Document([
|
||||
'$id' => $this->project->getId(),
|
||||
'$internalId' => $this->project->getInternalId(),
|
||||
'database' => $this->project->getAttribute('database')
|
||||
]);
|
||||
}
|
||||
|
||||
return $trimmed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute Event.
|
||||
*
|
||||
@@ -324,16 +344,30 @@ class Event
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
/** The getter is required since events like Databases need to override the queue name depending on the project */
|
||||
$client = new Client($this->getQueue(), $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
// Merge the base payload with any trimmed values
|
||||
$payload = array_merge($this->preparePayload(), $this->trimPayload());
|
||||
|
||||
return $client->enqueue($payload);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare payload for queue. Can be overridden by child classes to customize payload.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'userId' => $this->userId,
|
||||
'payload' => $this->payload,
|
||||
'context' => $this->context,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Func extends Event
|
||||
@@ -173,13 +172,13 @@ class Func extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set custom data for the function event.
|
||||
* Returns set JWT for the function event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getData(): string
|
||||
public function getJWT(): string
|
||||
{
|
||||
return $this->data;
|
||||
return $this->jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,37 +190,19 @@ class Func extends Event
|
||||
public function setJWT(string $jwt): self
|
||||
{
|
||||
$this->jwt = $jwt;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set JWT for the function event.
|
||||
* Prepare payload for the function event.
|
||||
*
|
||||
* @return string
|
||||
* @return array
|
||||
*/
|
||||
public function getJWT(): string
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
return $this->jwt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the function event and sends it to the functions worker.
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
$events = $this->getEvent() ? Event::generateEvents($this->getEvent(), $this->getParams()) : null;
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'userId' => $this->userId,
|
||||
@@ -236,6 +217,6 @@ class Func extends Event
|
||||
'path' => $this->path,
|
||||
'headers' => $this->headers,
|
||||
'method' => $this->method,
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Mail extends Event
|
||||
@@ -397,20 +396,13 @@ class Mail extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the event and sends it to the mails worker.
|
||||
* Prepare the payload for the event
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
* @return array
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'recipient' => $this->recipient,
|
||||
'name' => $this->name,
|
||||
@@ -421,6 +413,6 @@ class Mail extends Event
|
||||
'variables' => $this->variables,
|
||||
'attachment' => $this->attachment,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Messaging extends Event
|
||||
@@ -27,7 +26,7 @@ class Messaging extends Event
|
||||
/**
|
||||
* Sets type for the build event.
|
||||
*
|
||||
* @param string $type Can be `MESSAGE_TYPE_INTERNAL` or `MESSAGE_TYPE_EXTERNAL`.
|
||||
* @param string $type Can be `MESSAGE_SEND_TYPE_INTERNAL` or `MESSAGE_SEND_TYPE_EXTERNAL`.
|
||||
* @return self
|
||||
*/
|
||||
public function setType(string $type): self
|
||||
@@ -176,19 +175,13 @@ class Messaging extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the event and sends it to the messaging worker.
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
* Prepare the payload for the event
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function trigger(): string | bool
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'type' => $this->type,
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
@@ -196,6 +189,6 @@ class Messaging extends Event
|
||||
'message' => $this->message,
|
||||
'recipients' => $this->recipients,
|
||||
'providerType' => $this->providerType,
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Migration extends Event
|
||||
@@ -68,23 +67,16 @@ class Migration extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the migration event and sends it to the migrations worker.
|
||||
* Prepare the payload for the migration event.
|
||||
*
|
||||
* @return string|bool
|
||||
* @throws \InvalidArgumentException
|
||||
* @return array
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'migration' => $this->migration,
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Usage extends Event
|
||||
@@ -51,6 +50,20 @@ class Usage extends Event
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the payload for the usage event.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'reduce' => $this->reduce,
|
||||
'metrics' => $this->metrics,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends metrics to the usage worker.
|
||||
*
|
||||
@@ -58,20 +71,8 @@ class Usage extends Event
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
$result = $client->enqueue([
|
||||
'project' => $this->getProject(),
|
||||
'reduce' => $this->reduce,
|
||||
'metrics' => $this->metrics,
|
||||
]);
|
||||
|
||||
parent::trigger();
|
||||
$this->metrics = [];
|
||||
|
||||
return $result;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Queue\Client;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class UsageDump extends Event
|
||||
@@ -32,20 +31,14 @@ class UsageDump extends Event
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends metrics to the usage worker.
|
||||
* Prepare the payload for the usage dump event.
|
||||
*
|
||||
* @return string|bool
|
||||
* @return array
|
||||
*/
|
||||
public function trigger(): string|bool
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
if ($this->paused) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$client = new Client($this->queue, $this->connection);
|
||||
|
||||
return $client->enqueue([
|
||||
return [
|
||||
'stats' => $this->stats,
|
||||
]);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Connection;
|
||||
|
||||
class Webhook extends Event
|
||||
@@ -16,15 +15,17 @@ class Webhook extends Event
|
||||
->setClass(Event::WEBHOOK_CLASS_NAME);
|
||||
}
|
||||
|
||||
public function trigger(): string|bool
|
||||
/**
|
||||
* Trim the payload for the webhook event.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function trimPayload(): array
|
||||
{
|
||||
/** Filter out context and trim project to keep the payload small */
|
||||
$this->context = [];
|
||||
$this->project = new Document([
|
||||
'$id' => $this->project->getId(),
|
||||
'$internalId' => $this->project->getInternalId(),
|
||||
]);
|
||||
|
||||
return parent::trigger();
|
||||
$trimmed = parent::trimPayload();
|
||||
if (isset($this->context)) {
|
||||
$trimmed['context'] = [];
|
||||
}
|
||||
return $trimmed;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,7 +112,6 @@ class Exception extends \Exception
|
||||
|
||||
/** Teams */
|
||||
public const TEAM_NOT_FOUND = 'team_not_found';
|
||||
public const TEAM_INVITE_ALREADY_EXISTS = 'team_invite_already_exists';
|
||||
public const TEAM_INVITE_NOT_FOUND = 'team_invite_not_found';
|
||||
public const TEAM_INVALID_SECRET = 'team_invalid_secret';
|
||||
public const TEAM_MEMBERSHIP_MISMATCH = 'team_membership_mismatch';
|
||||
|
||||
@@ -47,9 +47,12 @@ class Maintenance extends Action
|
||||
Console::info("[{$time}] Notifying workers with maintenance tasks every {$interval} seconds");
|
||||
|
||||
$this->foreachProject($dbForPlatform, function (Document $project) use ($queueForDeletes, $usageStatsRetentionHourly) {
|
||||
$queueForDeletes->setProject($project);
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_MAINTENANCE)
|
||||
->setProject($project)
|
||||
->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly))
|
||||
->trigger();
|
||||
|
||||
$this->notifyProjects($queueForDeletes, $usageStatsRetentionHourly);
|
||||
});
|
||||
|
||||
$this->notifyDeleteConnections($queueForDeletes);
|
||||
@@ -59,18 +62,6 @@ class Maintenance extends Action
|
||||
}, $interval, $delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to allow sub-classes to extend project-level maintenance functionality.
|
||||
*/
|
||||
protected function notifyProjects(Delete $queueForDeletes, int $usageStatsRetentionHourly): void
|
||||
{
|
||||
$this->notifyDeleteTargets($queueForDeletes);
|
||||
$this->notifyDeleteExecutionLogs($queueForDeletes);
|
||||
$this->notifyDeleteAuditLogs($queueForDeletes);
|
||||
$this->notifyDeleteUsageStats($usageStatsRetentionHourly, $queueForDeletes);
|
||||
$this->notifyDeleteExpiredSessions($queueForDeletes);
|
||||
}
|
||||
|
||||
protected function foreachProject(Database $dbForPlatform, callable $callback): void
|
||||
{
|
||||
// TODO: @Meldiron name of this method no longer matches. It does not delete, and it gives whole document
|
||||
@@ -98,28 +89,6 @@ class Maintenance extends Action
|
||||
Console::info("Found {$count} projects " . ($executionEnd - $executionStart) . " seconds");
|
||||
}
|
||||
|
||||
private function notifyDeleteExecutionLogs(Delete $queueForDeletes): void
|
||||
{
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_EXECUTIONS)
|
||||
->trigger();
|
||||
}
|
||||
|
||||
private function notifyDeleteAuditLogs(Delete $queueForDeletes): void
|
||||
{
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_AUDIT)
|
||||
->trigger();
|
||||
}
|
||||
|
||||
private function notifyDeleteUsageStats(int $usageStatsRetentionHourly, Delete $queueForDeletes): void
|
||||
{
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_USAGE)
|
||||
->setUsageRetentionHourlyDateTime(DateTime::addSeconds(new \DateTime(), -1 * $usageStatsRetentionHourly))
|
||||
->trigger();
|
||||
}
|
||||
|
||||
private function notifyDeleteConnections(Delete $queueForDeletes): void
|
||||
{
|
||||
$queueForDeletes
|
||||
@@ -128,13 +97,6 @@ class Maintenance extends Action
|
||||
->trigger();
|
||||
}
|
||||
|
||||
private function notifyDeleteExpiredSessions(Delete $queueForDeletes): void
|
||||
{
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_SESSIONS)
|
||||
->trigger();
|
||||
}
|
||||
|
||||
private function renewCertificates(Database $dbForPlatform, Certificate $queueForCertificate): void
|
||||
{
|
||||
$time = DateTime::now();
|
||||
@@ -177,11 +139,4 @@ class Maintenance extends Action
|
||||
->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * $interval))
|
||||
->trigger();
|
||||
}
|
||||
|
||||
private function notifyDeleteTargets(Delete $queueForDeletes): void
|
||||
{
|
||||
$queueForDeletes
|
||||
->setType(DELETE_TYPE_EXPIRED_TARGETS)
|
||||
->trigger();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,15 +41,15 @@ class SDKs extends Action
|
||||
$this
|
||||
->desc('Generate Appwrite SDKs')
|
||||
->param('platform', null, new Nullable(new Text(256)), 'Selected Platform', optional: true)
|
||||
->param('sdk', null, new Nullable(new Text(256)), 'Selected SDK', optional:true)
|
||||
->param('version', null, new Nullable(new Text(256)), 'Selected SDK', optional:true)
|
||||
->param('sdk', null, new Nullable(new Text(256)), 'Selected SDK', optional: true)
|
||||
->param('version', null, new Nullable(new Text(256)), 'Selected SDK', optional: true)
|
||||
->param('git', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we use git push?', optional: true)
|
||||
->param('production', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we push to production?', optional:true)
|
||||
->param('message', null, new Nullable(new Text(256)), 'Commit Message', optional:true)
|
||||
->param('production', null, new Nullable(new WhiteList(['yes', 'no'])), 'Should we push to production?', optional: true)
|
||||
->param('message', null, new Nullable(new Text(256)), 'Commit Message', optional: true)
|
||||
->callback([$this, 'action']);
|
||||
}
|
||||
|
||||
public function action(?string $selectedPlatform, ?string $selectedSDK, ?string $version, ?string $git, ?string $production, ?string $message)
|
||||
public function action(?string $selectedPlatform, ?string $selectedSDK, ?string $version, ?string $git, ?string $production, ?string $message): void
|
||||
{
|
||||
$selectedPlatform ??= Console::confirm('Choose Platform ("' . APP_PLATFORM_CLIENT . '", "' . APP_PLATFORM_SERVER . '", "' . APP_PLATFORM_CONSOLE . '" or "*" for all):');
|
||||
$selectedSDK ??= \strtolower(Console::confirm('Choose SDK ("*" for all):'));
|
||||
@@ -275,9 +275,13 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
\exec('rm -rf ' . $target . ' && \
|
||||
mkdir -p ' . $target . ' && \
|
||||
cd ' . $target . ' && \
|
||||
git init --initial-branch=' . $gitBranch . ' && \
|
||||
git init && \
|
||||
git remote add origin ' . $gitUrl . ' && \
|
||||
git fetch origin ' . $gitBranch . ' && \
|
||||
git fetch origin && \
|
||||
git checkout main || git checkout -b main && \
|
||||
git pull origin main && \
|
||||
git checkout ' . $gitBranch . ' || git checkout -b ' . $gitBranch . ' && \
|
||||
git fetch origin ' . $gitBranch . ' || git push -u origin ' . $gitBranch . ' && \
|
||||
git pull origin ' . $gitBranch . ' && \
|
||||
rm -rf ' . $target . '/* && \
|
||||
cp -r ' . $result . '/. ' . $target . '/ && \
|
||||
|
||||
@@ -46,6 +46,7 @@ class Builds extends Action
|
||||
$this
|
||||
->desc('Builds worker')
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForFunctions')
|
||||
@@ -54,11 +55,12 @@ class Builds extends Action
|
||||
->inject('dbForProject')
|
||||
->inject('deviceForFunctions')
|
||||
->inject('log')
|
||||
->callback(fn ($message, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, Usage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log) => $this->action($message, $dbForPlatform, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $log));
|
||||
->callback(fn ($message, Document $project, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, Usage $usage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log) => $this->action($message, $project, $dbForPlatform, $queueForEvents, $queueForFunctions, $usage, $cache, $dbForProject, $deviceForFunctions, $log));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
* @param Document $project
|
||||
* @param Database $dbForPlatform
|
||||
* @param Event $queueForEvents
|
||||
* @param Func $queueForFunctions
|
||||
@@ -70,7 +72,7 @@ class Builds extends Action
|
||||
* @return void
|
||||
* @throws \Utopia\Database\Exception
|
||||
*/
|
||||
public function action(Message $message, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, Usage $queueForUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log): void
|
||||
public function action(Message $message, Document $project, Database $dbForPlatform, Event $queueForEvents, Func $queueForFunctions, Usage $queueForUsage, Cache $cache, Database $dbForProject, Device $deviceForFunctions, Log $log): void
|
||||
{
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
@@ -79,7 +81,6 @@ class Builds extends Action
|
||||
}
|
||||
|
||||
$type = $payload['type'] ?? '';
|
||||
$project = new Document($payload['project'] ?? []);
|
||||
$resource = new Document($payload['resource'] ?? []);
|
||||
$deployment = new Document($payload['deployment'] ?? []);
|
||||
$template = new Document($payload['template'] ?? []);
|
||||
|
||||
@@ -34,21 +34,23 @@ class Databases extends Action
|
||||
$this
|
||||
->desc('Databases worker')
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('dbForProject')
|
||||
->inject('log')
|
||||
->callback(fn (Message $message, Database $dbForPlatform, Database $dbForProject, Log $log) => $this->action($message, $dbForPlatform, $dbForProject, $log));
|
||||
->callback(fn (Message $message, Document $project, Database $dbForPlatform, Database $dbForProject, Log $log) => $this->action($message, $project, $dbForPlatform, $dbForProject, $log));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
* @param Document $project
|
||||
* @param Database $dbForPlatform
|
||||
* @param Database $dbForProject
|
||||
* @param Log $log
|
||||
* @return void
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function action(Message $message, Database $dbForPlatform, Database $dbForProject, Log $log): void
|
||||
public function action(Message $message, Document $project, Database $dbForPlatform, Database $dbForProject, Log $log): void
|
||||
{
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
@@ -57,7 +59,6 @@ class Databases extends Action
|
||||
}
|
||||
|
||||
$type = $payload['type'];
|
||||
$project = new Document($payload['project']);
|
||||
$collection = new Document($payload['collection'] ?? []);
|
||||
$document = new Document($payload['document'] ?? []);
|
||||
$database = new Document($payload['database'] ?? []);
|
||||
@@ -136,6 +137,9 @@ class Databases extends Action
|
||||
$options = $attribute->getAttribute('options', []);
|
||||
$project = $dbForPlatform->getDocument('projects', $projectId);
|
||||
|
||||
$relatedAttribute = new Document();
|
||||
$relatedCollection = new Document();
|
||||
|
||||
try {
|
||||
switch ($type) {
|
||||
case Database::VAR_RELATIONSHIP:
|
||||
@@ -175,7 +179,7 @@ class Databases extends Action
|
||||
|
||||
if ($e instanceof DatabaseException) {
|
||||
$attribute->setAttribute('error', $e->getMessage());
|
||||
if (isset($relatedAttribute)) {
|
||||
if (! $relatedAttribute->isEmpty()) {
|
||||
$relatedAttribute->setAttribute('error', $e->getMessage());
|
||||
}
|
||||
}
|
||||
@@ -186,7 +190,7 @@ class Databases extends Action
|
||||
$attribute->setAttribute('status', 'failed')
|
||||
);
|
||||
|
||||
if (isset($relatedAttribute)) {
|
||||
if (! $relatedAttribute->isEmpty()) {
|
||||
$dbForProject->updateDocument(
|
||||
'attributes',
|
||||
$relatedAttribute->getId(),
|
||||
@@ -198,7 +202,7 @@ class Databases extends Action
|
||||
} finally {
|
||||
$this->trigger($database, $collection, $attribute, $project, $projectId, $events);
|
||||
|
||||
if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) {
|
||||
if (! $relatedCollection->isEmpty()) {
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
}
|
||||
|
||||
@@ -364,7 +368,7 @@ class Databases extends Action
|
||||
} finally {
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $collectionId);
|
||||
|
||||
if (!$relatedCollection->isEmpty() && !$relatedAttribute->isEmpty()) {
|
||||
if (! $relatedCollection->isEmpty()) {
|
||||
$dbForProject->purgeCachedDocument('database_' . $database->getInternalId(), $relatedCollection->getId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,6 +43,7 @@ class Deletes extends Action
|
||||
$this
|
||||
->desc('Deletes worker')
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('getProjectDB')
|
||||
->inject('timelimit')
|
||||
@@ -55,8 +56,8 @@ class Deletes extends Action
|
||||
->inject('auditRetention')
|
||||
->inject('log')
|
||||
->callback(
|
||||
fn ($message, $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $executionRetention, string $auditRetention, Log $log) =>
|
||||
$this->action($message, $dbForPlatform, $getProjectDB, $timelimit, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $executionRetention, $auditRetention, $log)
|
||||
fn ($message, Document $project, Database $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $executionRetention, string $auditRetention, Log $log) =>
|
||||
$this->action($message, $project, $dbForPlatform, $getProjectDB, $timelimit, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $executionRetention, $auditRetention, $log)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -64,7 +65,7 @@ class Deletes extends Action
|
||||
* @throws Exception
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function action(Message $message, Database $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $executionRetention, string $auditRetention, Log $log): void
|
||||
public function action(Message $message, Document $project, Database $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $executionRetention, string $auditRetention, Log $log): void
|
||||
{
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
@@ -78,7 +79,6 @@ class Deletes extends Action
|
||||
$resource = $payload['resource'] ?? null;
|
||||
$resourceType = $payload['resourceType'] ?? null;
|
||||
$document = new Document($payload['document'] ?? []);
|
||||
$project = new Document($payload['project'] ?? []);
|
||||
|
||||
$log->addTag('projectId', $project->getId());
|
||||
$log->addTag('type', $type);
|
||||
@@ -153,6 +153,13 @@ class Deletes extends Action
|
||||
case DELETE_TYPE_SESSION_TARGETS:
|
||||
$this->deleteSessionTargets($project, $getProjectDB, $document);
|
||||
break;
|
||||
case DELETE_TYPE_MAINTENANCE:
|
||||
$this->deleteExpiredTargets($project, $getProjectDB);
|
||||
$this->deleteExecutionLogs($project, $getProjectDB, $executionRetention);
|
||||
$this->deleteAuditLogs($project, $getProjectDB, $auditRetention);
|
||||
$this->deleteUsageStats($project, $getProjectDB, $hourlyUsageRetentionDatetime);
|
||||
$this->deleteExpiredSessions($project, $getProjectDB);
|
||||
break;
|
||||
default:
|
||||
throw new \Exception('No delete operation for type: ' . \strval($type));
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ use Utopia\Messaging\Messages\Email;
|
||||
use Utopia\Messaging\Messages\Email\Attachment;
|
||||
use Utopia\Messaging\Messages\Push;
|
||||
use Utopia\Messaging\Messages\SMS;
|
||||
use Utopia\Messaging\Priority;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Queue\Message;
|
||||
use Utopia\Storage\Device;
|
||||
@@ -58,15 +59,17 @@ class Messaging extends Action
|
||||
$this
|
||||
->desc('Messaging worker')
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('log')
|
||||
->inject('dbForProject')
|
||||
->inject('deviceForFiles')
|
||||
->inject('queueForUsage')
|
||||
->callback(fn (Message $message, Log $log, Database $dbForProject, Device $deviceForFiles, Usage $queueForUsage) => $this->action($message, $log, $dbForProject, $deviceForFiles, $queueForUsage));
|
||||
->callback(fn (Message $message, Document $project, Log $log, Database $dbForProject, Device $deviceForFiles, Usage $queueForUsage) => $this->action($message, $project, $log, $dbForProject, $deviceForFiles, $queueForUsage));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
* @param Document $project
|
||||
* @param Log $log
|
||||
* @param Database $dbForProject
|
||||
* @param Device $deviceForFiles
|
||||
@@ -76,6 +79,7 @@ class Messaging extends Action
|
||||
*/
|
||||
public function action(
|
||||
Message $message,
|
||||
Document $project,
|
||||
Log $log,
|
||||
Database $dbForProject,
|
||||
Device $deviceForFiles,
|
||||
@@ -89,14 +93,13 @@ class Messaging extends Action
|
||||
}
|
||||
|
||||
$type = $payload['type'] ?? '';
|
||||
$project = new Document($payload['project'] ?? []);
|
||||
|
||||
switch ($type) {
|
||||
case MESSAGE_SEND_TYPE_INTERNAL:
|
||||
$message = new Document($payload['message'] ?? []);
|
||||
$recipients = $payload['recipients'] ?? [];
|
||||
|
||||
$this->sendInternalSMSMessage($message, $project, $recipients, $queueForUsage, $log);
|
||||
$this->sendInternalSMSMessage($message, $project, $recipients, $log);
|
||||
break;
|
||||
case MESSAGE_SEND_TYPE_EXTERNAL:
|
||||
$message = $dbForProject->getDocument('messages', $payload['messageId']);
|
||||
@@ -275,7 +278,7 @@ class Messaging extends Action
|
||||
Query::equal('identifier', [$result['recipient']])
|
||||
]);
|
||||
|
||||
if ($target instanceof Document && !$target->isEmpty()) {
|
||||
if (!$target->isEmpty()) {
|
||||
$dbForProject->updateDocument(
|
||||
'targets',
|
||||
$target->getId(),
|
||||
@@ -287,7 +290,7 @@ class Messaging extends Action
|
||||
} catch (\Throwable $e) {
|
||||
$deliveryErrors[] = 'Failed sending to targets with error: ' . $e->getMessage();
|
||||
} finally {
|
||||
$errorTotal = count($deliveryErrors);
|
||||
$errorTotal = \count($deliveryErrors);
|
||||
$queueForUsage
|
||||
->setProject($project)
|
||||
->addMetric(METRIC_MESSAGES, ($deliveredTotal + $errorTotal))
|
||||
@@ -333,7 +336,6 @@ class Messaging extends Action
|
||||
$message->setAttribute('status', MessageStatus::SENT);
|
||||
}
|
||||
|
||||
|
||||
$message->removeAttribute('to');
|
||||
|
||||
foreach ($providers as $provider) {
|
||||
@@ -377,7 +379,7 @@ class Messaging extends Action
|
||||
}
|
||||
}
|
||||
|
||||
private function sendInternalSMSMessage(Document $message, Document $project, array $recipients, Usage $queueForUsage, Log $log): void
|
||||
private function sendInternalSMSMessage(Document $message, Document $project, array $recipients, Log $log): void
|
||||
{
|
||||
if (empty(System::getEnv('_APP_SMS_PROVIDER')) || empty(System::getEnv('_APP_SMS_FROM'))) {
|
||||
throw new \Exception('Skipped SMS processing. Missing "_APP_SMS_PROVIDER" or "_APP_SMS_FROM" environment variables.');
|
||||
@@ -456,24 +458,14 @@ class Messaging extends Action
|
||||
$adapter->getMaxMessagesPerRequest()
|
||||
);
|
||||
|
||||
batch(\array_map(function ($batch) use ($message, $provider, $adapter, $project, $queueForUsage) {
|
||||
return function () use ($batch, $message, $provider, $adapter, $project, $queueForUsage) {
|
||||
batch(\array_map(function ($batch) use ($message, $provider, $adapter) {
|
||||
return function () use ($batch, $message, $provider, $adapter) {
|
||||
$message->setAttribute('to', $batch);
|
||||
|
||||
$data = $this->buildSmsMessage($message, $provider);
|
||||
|
||||
try {
|
||||
$adapter->send($data);
|
||||
|
||||
$countryCode = $adapter->getCountryCode($message['to'][0] ?? '');
|
||||
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();
|
||||
} catch (\Throwable $th) {
|
||||
throw new \Exception('Failed sending to targets with error: ' . $th->getMessage());
|
||||
}
|
||||
@@ -676,8 +668,8 @@ class Messaging extends Action
|
||||
private function buildPushMessage(Document $message): Push
|
||||
{
|
||||
$to = $message['to'];
|
||||
$title = $message['data']['title'];
|
||||
$body = $message['data']['body'];
|
||||
$title = $message['data']['title'] ?? null;
|
||||
$body = $message['data']['body'] ?? null;
|
||||
$data = $message['data']['data'] ?? null;
|
||||
$action = $message['data']['action'] ?? null;
|
||||
$image = $message['data']['image']['url'] ?? null;
|
||||
@@ -686,6 +678,21 @@ class Messaging extends Action
|
||||
$color = $message['data']['color'] ?? null;
|
||||
$tag = $message['data']['tag'] ?? null;
|
||||
$badge = $message['data']['badge'] ?? null;
|
||||
$contentAvailable = $message['data']['contentAvailable'] ?? null;
|
||||
$critical = $message['data']['critical'] ?? null;
|
||||
$priority = $message['data']['priority'] ?? null;
|
||||
|
||||
if ($title === '') {
|
||||
$title = null;
|
||||
}
|
||||
if ($body === '') {
|
||||
$body = null;
|
||||
}
|
||||
if ($priority !== null) {
|
||||
$priority = $priority === 'high'
|
||||
? Priority::HIGH
|
||||
: Priority::NORMAL;
|
||||
}
|
||||
|
||||
return new Push(
|
||||
$to,
|
||||
@@ -698,7 +705,10 @@ class Messaging extends Action
|
||||
$icon,
|
||||
$color,
|
||||
$tag,
|
||||
$badge
|
||||
$badge,
|
||||
$contentAvailable,
|
||||
$critical,
|
||||
$priority
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,16 +51,17 @@ class Migrations extends Action
|
||||
$this
|
||||
->desc('Migrations worker')
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('logError')
|
||||
->callback(fn (Message $message, Database $dbForProject, Database $dbForPlatform, callable $logError) => $this->action($message, $dbForProject, $dbForPlatform, $logError));
|
||||
->callback(fn (Message $message, Document $project, Database $dbForProject, Database $dbForPlatform, callable $logError) => $this->action($message, $project, $dbForProject, $dbForPlatform, $logError));
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws Exception
|
||||
*/
|
||||
public function action(Message $message, Database $dbForProject, Database $dbForPlatform, callable $logError): void
|
||||
public function action(Message $message, Document $project, Database $dbForProject, Database $dbForPlatform, callable $logError): void
|
||||
{
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
@@ -69,7 +70,6 @@ class Migrations extends Action
|
||||
}
|
||||
|
||||
$events = $payload['events'] ?? [];
|
||||
$project = new Document($payload['project'] ?? []);
|
||||
$migration = new Document($payload['migration'] ?? []);
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
|
||||
@@ -34,10 +34,11 @@ class Usage extends Action
|
||||
$this
|
||||
->desc('Usage worker')
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('getProjectDB')
|
||||
->inject('queueForUsageDump')
|
||||
->callback(function (Message $message, callable $getProjectDB, UsageDump $queueForUsageDump) {
|
||||
$this->action($message, $getProjectDB, $queueForUsageDump);
|
||||
->callback(function (Message $message, Document $project, callable $getProjectDB, UsageDump $queueForUsageDump) {
|
||||
$this->action($message, $project, $getProjectDB, $queueForUsageDump);
|
||||
});
|
||||
|
||||
$this->aggregationInterval = (int) System::getEnv('_APP_USAGE_AGGREGATION_INTERVAL', '20');
|
||||
@@ -46,21 +47,20 @@ class Usage extends Action
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
* @param Document $project
|
||||
* @param callable $getProjectDB
|
||||
* @param UsageDump $queueForUsageDump
|
||||
* @return void
|
||||
* @throws \Utopia\Database\Exception
|
||||
* @throws Exception
|
||||
*/
|
||||
public function action(Message $message, callable $getProjectDB, UsageDump $queueForUsageDump): void
|
||||
public function action(Message $message, Document $project, callable $getProjectDB, UsageDump $queueForUsageDump): void
|
||||
{
|
||||
$payload = $message->getPayload() ?? [];
|
||||
if (empty($payload)) {
|
||||
throw new Exception('Missing payload');
|
||||
}
|
||||
|
||||
$document = $payload['project'] ?? [];
|
||||
$project = new Document($document);
|
||||
|
||||
if (empty($project->getAttribute('database'))) {
|
||||
var_dump($payload);
|
||||
|
||||
@@ -59,26 +59,11 @@ class UsageDump extends Action
|
||||
|
||||
|
||||
foreach ($payload['stats'] ?? [] as $stats) {
|
||||
//$project = new Document($stats['project'] ?? []);
|
||||
|
||||
/**
|
||||
* Start temp bug fallback
|
||||
*/
|
||||
$document = $stats['project'] ?? [];
|
||||
if (!empty($document['$uid'])) {
|
||||
$document['$id'] = $document['$uid'];
|
||||
}
|
||||
|
||||
$project = new Document($document);
|
||||
|
||||
if (empty($project->getAttribute('database'))) {
|
||||
continue;
|
||||
}
|
||||
$project = new Document($stats['project'] ?? []);
|
||||
|
||||
/**
|
||||
* End temp bug fallback
|
||||
*/
|
||||
|
||||
$numberOfKeys = !empty($stats['keys']) ? count($stats['keys']) : 0;
|
||||
$receivedAt = $stats['receivedAt'] ?? 'NONE';
|
||||
if ($numberOfKeys === 0) {
|
||||
|
||||
@@ -32,22 +32,24 @@ class Webhooks extends Action
|
||||
$this
|
||||
->desc('Webhooks worker')
|
||||
->inject('message')
|
||||
->inject('project')
|
||||
->inject('dbForPlatform')
|
||||
->inject('queueForMails')
|
||||
->inject('queueForUsage')
|
||||
->inject('log')
|
||||
->callback(fn (Message $message, Database $dbForPlatform, Mail $queueForMails, Usage $queueForUsage, Log $log) => $this->action($message, $dbForPlatform, $queueForMails, $queueForUsage, $log));
|
||||
->callback(fn (Message $message, Document $project, Database $dbForPlatform, Mail $queueForMails, Usage $queueForUsage, Log $log) => $this->action($message, $project, $dbForPlatform, $queueForMails, $queueForUsage, $log));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Message $message
|
||||
* @param Document $project
|
||||
* @param Database $dbForPlatform
|
||||
* @param Mail $queueForMails
|
||||
* @param Log $log
|
||||
* @return void
|
||||
* @throws Exception
|
||||
*/
|
||||
public function action(Message $message, Database $dbForPlatform, Mail $queueForMails, Usage $queueForUsage, Log $log): void
|
||||
public function action(Message $message, Document $project, Database $dbForPlatform, Mail $queueForMails, Usage $queueForUsage, Log $log): void
|
||||
{
|
||||
$this->errors = [];
|
||||
$payload = $message->getPayload() ?? [];
|
||||
@@ -60,8 +62,6 @@ class Webhooks extends Action
|
||||
$webhookPayload = json_encode($payload['payload']);
|
||||
$user = new Document($payload['user'] ?? []);
|
||||
|
||||
$project = new Document($payload['project']);
|
||||
$project = $dbForPlatform->getDocument('projects', $project->getId());
|
||||
$log->addTag('projectId', $project->getId());
|
||||
|
||||
foreach ($project->getAttribute('webhooks', []) as $webhook) {
|
||||
|
||||
@@ -215,6 +215,8 @@ abstract class Format
|
||||
switch ($param) {
|
||||
case 'status':
|
||||
return 'MessageStatus';
|
||||
case 'priority':
|
||||
return 'MessagePriority';
|
||||
}
|
||||
break;
|
||||
case 'createSmtpProvider':
|
||||
|
||||
@@ -34,7 +34,6 @@ class Swagger2 extends Format
|
||||
foreach ($this->models as $m) {
|
||||
if ($m->getType() === $ruleType) {
|
||||
$this->getNestedModels($m, $usedModels);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +45,6 @@ class Swagger2 extends Format
|
||||
foreach ($this->models as $m) {
|
||||
if ($m->getType() === $rule['type']) {
|
||||
$this->getNestedModels($m, $usedModels);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ class MetricBreakdown extends Model
|
||||
'description' => 'Resource ID.',
|
||||
'default' => '',
|
||||
'example' => '5e5ea5c16897e',
|
||||
'required' => false,
|
||||
])
|
||||
->addRule('name', [
|
||||
'type' => self::TYPE_STRING,
|
||||
@@ -27,6 +28,13 @@ class MetricBreakdown extends Model
|
||||
'description' => 'The value of this metric at the timestamp.',
|
||||
'default' => 0,
|
||||
'example' => 1,
|
||||
])
|
||||
->addRule('estimate', [
|
||||
'type' => self::TYPE_FLOAT,
|
||||
'description' => 'The estimated value of this metric at the end of the period.',
|
||||
'default' => 0,
|
||||
'example' => 1,
|
||||
'required' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
@@ -152,6 +152,25 @@ class UsageProject extends Model
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
->addRule('authPhoneTotal', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Total aggregated number of phone auth.',
|
||||
'default' => 0,
|
||||
'example' => 0,
|
||||
])
|
||||
->addRule('authPhoneEstimate', [
|
||||
'type' => self::TYPE_FLOAT,
|
||||
'description' => 'Estimated total aggregated cost of phone auth.',
|
||||
'default' => 0,
|
||||
'example' => 0,
|
||||
])
|
||||
->addRule('authPhoneCountryBreakdown', [
|
||||
'type' => Response::MODEL_METRIC_BREAKDOWN,
|
||||
'description' => 'Aggregated breakdown in totals of phone auth by country.',
|
||||
'default' => [],
|
||||
'example' => [],
|
||||
'array' => true
|
||||
])
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ class UsageTest extends Scope
|
||||
);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertEquals(22, count($response['body']));
|
||||
$this->assertEquals(25, count($response['body']));
|
||||
$this->validateDates($response['body']['network']);
|
||||
$this->validateDates($response['body']['requests']);
|
||||
$this->validateDates($response['body']['users']);
|
||||
@@ -324,7 +324,7 @@ class UsageTest extends Scope
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals(22, count($response['body']));
|
||||
$this->assertEquals(25, count($response['body']));
|
||||
$this->assertEquals(1, count($response['body']['requests']));
|
||||
$this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']);
|
||||
$this->validateDates($response['body']['requests']);
|
||||
@@ -545,7 +545,7 @@ class UsageTest extends Scope
|
||||
]
|
||||
);
|
||||
|
||||
$this->assertEquals(22, count($response['body']));
|
||||
$this->assertEquals(25, count($response['body']));
|
||||
$this->assertEquals(1, count($response['body']['requests']));
|
||||
$this->assertEquals(1, count($response['body']['network']));
|
||||
$this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']);
|
||||
|
||||
@@ -375,7 +375,7 @@ class FunctionsCustomServerTest extends Scope
|
||||
|
||||
$this->assertEquals(200, $deployment['headers']['status-code']);
|
||||
$this->assertEquals('ready', $deployment['body']['status']);
|
||||
}, 500000, 1000);
|
||||
}, 50000, 1000);
|
||||
|
||||
$function = $this->getFunction($functionId);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Tests\E2E\Services\Messaging;
|
||||
|
||||
use Appwrite\Tests\Async;
|
||||
use Tests\E2E\Client;
|
||||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
@@ -11,6 +12,8 @@ use Utopia\Database\Query;
|
||||
|
||||
class MessagingConsoleClientTest extends Scope
|
||||
{
|
||||
use Async;
|
||||
|
||||
use MessagingBase;
|
||||
use ProjectCustom;
|
||||
use SideConsole;
|
||||
@@ -54,15 +57,18 @@ class MessagingConsoleClientTest extends Scope
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$logs = $this->client->call(Client::METHOD_GET, '/messaging/providers/' . $provider['body']['$id'] . '/logs', \array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
// required for Cloud x Audits
|
||||
$this->assertEventually(function () use ($provider) {
|
||||
$logs = $this->client->call(Client::METHOD_GET, '/messaging/providers/' . $provider['body']['$id'] . '/logs', \array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
$this->assertIsArray($logs['body']['logs']);
|
||||
$this->assertIsNumeric($logs['body']['total']);
|
||||
$this->assertCount(2, $logs['body']['logs']);
|
||||
$this->assertEquals($logs['headers']['status-code'], 200);
|
||||
$this->assertIsArray($logs['body']['logs']);
|
||||
$this->assertIsNumeric($logs['body']['total']);
|
||||
$this->assertCount(2, $logs['body']['logs']);
|
||||
});
|
||||
|
||||
$logs = $this->client->call(Client::METHOD_GET, '/messaging/providers/' . $provider['body']['$id'] . '/logs', \array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
||||
@@ -485,6 +485,8 @@ class ProjectsConsoleClientTest extends Scope
|
||||
$this->assertIsNumeric($response['body']['usersTotal']);
|
||||
$this->assertIsNumeric($response['body']['filesStorageTotal']);
|
||||
$this->assertIsNumeric($response['body']['deploymentStorageTotal']);
|
||||
$this->assertIsNumeric($response['body']['authPhoneTotal']);
|
||||
$this->assertIsNumeric($response['body']['authPhoneEstimate']);
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -291,10 +291,7 @@ trait TeamsBaseClient
|
||||
$this->assertEquals($secondName, $lastEmail['to'][0]['name']);
|
||||
$this->assertEquals('Invitation to ' . $teamName . ' Team at ' . $this->getProject()['name'], $lastEmail['subject']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
// test for resending invitation
|
||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
@@ -305,7 +302,11 @@ trait TeamsBaseClient
|
||||
'url' => 'http://localhost:5000/join-us#title'
|
||||
]);
|
||||
|
||||
$this->assertEquals(409, $response['headers']['status-code']);
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
||||
@@ -185,10 +185,7 @@ trait TeamsBaseServer
|
||||
// $this->assertContains('team:'.$teamUid.'/admin', $response['body']['roles']);
|
||||
// $this->assertContains('team:'.$teamUid.'/editor', $response['body']['roles']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
// test for resending invitation
|
||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
@@ -199,7 +196,11 @@ trait TeamsBaseServer
|
||||
'url' => 'http://localhost:5000/join-us#title'
|
||||
]);
|
||||
|
||||
$this->assertEquals(409, $response['headers']['status-code']);
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
||||
@@ -318,6 +318,14 @@ trait UsersBase
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/current', [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-session' => $session['secret']
|
||||
]);
|
||||
|
||||
$this->assertEquals(204, $response['headers']['status-code']);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user