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

This commit is contained in:
shimon 2024-09-22 09:49:50 +03:00
commit aa0a795ec6
33 changed files with 554 additions and 114 deletions

47
.github/workflows/nightly.yml vendored Normal file
View file

@ -0,0 +1,47 @@
name: Nightly Security Scan
on:
schedule:
- cron: '0 0 * * *' # 12am UTC daily runtime
workflow_dispatch:
jobs:
scan-image:
name: Scan Docker Image
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
with:
submodules: recursive
- name: Build the Docker image
run: docker build . -t appwrite_image:latest
- name: Run Trivy vulnerability scanner on image
uses: aquasecurity/trivy-action@0.20.0
with:
image-ref: 'appwrite_image:latest'
format: 'sarif'
output: 'trivy-image-results.sarif'
ignore-unfixed: 'false'
severity: 'CRITICAL,HIGH'
- name: Upload Docker Image Scan Results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-image-results.sarif'
scan-code:
name: Scan Code
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner on filesystem
uses: aquasecurity/trivy-action@0.20.0
with:
scan-type: 'fs'
format: 'sarif'
output: 'trivy-fs-results.sarif'
severity: 'CRITICAL,HIGH'
- name: Upload Code Scan Results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-fs-results.sarif'

View file

@ -1,17 +1,22 @@
name: PR Security Scan
on:
pull_request:
on:
pull_request_target:
types: [opened, synchronize, reopened]
workflow_dispatch:
jobs:
scan:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Check out code
- name: Check out code
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
fetch-depth: 0
submodules: 'recursive'
- name: Build the Docker image
uses: docker/build-push-action@v5
with:
@ -19,6 +24,7 @@ jobs:
push: false
load: true
tags: pr_image:${{ github.sha }}
- name: Run Trivy vulnerability scanner on image
uses: aquasecurity/trivy-action@0.20.0
with:
@ -26,6 +32,7 @@ jobs:
format: 'json'
output: 'trivy-image-results.json'
severity: 'CRITICAL,HIGH'
- name: Run Trivy vulnerability scanner on source code
uses: aquasecurity/trivy-action@0.20.0
with:
@ -34,10 +41,11 @@ jobs:
format: 'json'
output: 'trivy-fs-results.json'
severity: 'CRITICAL,HIGH'
- name: Process and post Trivy scan results
- name: Process Trivy scan results
id: process-results
uses: actions/github-script@v7
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
const fs = require('fs');
let commentBody = '## Security Scan Results for PR\n\n';
@ -79,9 +87,19 @@ jobs:
commentBody += 'Please contact the core team for assistance.';
}
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: commentBody
});
core.setOutput('comment-body', commentBody);
- name: Find Comment
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
comment-author: 'github-actions[bot]'
body-includes: Security Scan Results for PR
- name: Create or update comment
uses: peter-evans/create-or-update-comment@v3
with:
issue-number: ${{ github.event.pull_request.number }}
comment-id: ${{ steps.fc.outputs.comment-id }}
body: ${{ steps.process-results.outputs.comment-body }}
edit-mode: replace

View file

@ -1,3 +1,145 @@
# Version 1.6.0
## What's Changed
### Notable changes
* Allow execution filter attributes in [#7607](https://github.com/appwrite/appwrite/pull/7607)
* Add dynamic API keys for function executions in [#7512](https://github.com/appwrite/appwrite/pull/7512)
* Add metrics for successful and failed builds in [#8210](https://github.com/appwrite/appwrite/pull/8210)
* Update logging config to use a DSN approach in [#8187](https://github.com/appwrite/appwrite/pull/8187)
* Add projects.createJWT endpoint for dynamic keys in [#8213](https://github.com/appwrite/appwrite/pull/8213)
* Add users.createJWT() endpoint for local function development in [#8207](https://github.com/appwrite/appwrite/pull/8207)
* Added cancel build endpoint in [#7605](https://github.com/appwrite/appwrite/pull/7605)
* Add CLI as a function deployment type in [#8215](https://github.com/appwrite/appwrite/pull/8215)
* Add vcs.getRepositoryContents() endpoint in [#8330](https://github.com/appwrite/appwrite/pull/8330)
* Add appwrite version in function variables in [#8336](https://github.com/appwrite/appwrite/pull/8336)
* Add support for scheduled executions in [#8243](https://github.com/appwrite/appwrite/pull/8243)
* Add endpoint to delete execution in [#8337](https://github.com/appwrite/appwrite/pull/8337)
* OPR v4 support in [#8323](https://github.com/appwrite/appwrite/pull/8323)
* Mock OTP and phone numbers in [#7565](https://github.com/appwrite/appwrite/pull/7565)
* Support scheduled executions in [#8355](https://github.com/appwrite/appwrite/pull/8355)
* Add alert for new sessions in [#8315](https://github.com/appwrite/appwrite/pull/8315)
* Update delete authenticator to remove OTP Validation in [#8367](https://github.com/appwrite/appwrite/pull/8367)
* Track project last activity in [#8366](https://github.com/appwrite/appwrite/pull/8366)
* Containerize the console in [#8406](https://github.com/appwrite/appwrite/pull/8406)
* Implement MBSeconds Metric on 1.5.X in [#8385](https://github.com/appwrite/appwrite/pull/8385)
* Support JWTs without session ID in [#8420](https://github.com/appwrite/appwrite/pull/8420)
* 1.6.x sdks in [#8359](https://github.com/appwrite/appwrite/pull/8359)
* Base migration for 1.6.x in [#8417](https://github.com/appwrite/appwrite/pull/8417)
* 1.6.x migrations and filters in [#8403](https://github.com/appwrite/appwrite/pull/8403)
* Add APPWRITE_REGION in function variables in [#8394](https://github.com/appwrite/appwrite/pull/8394)
* Support dynamic keys for domain executions in [#8428](https://github.com/appwrite/appwrite/pull/8428)
* Bump DBIP to latest version in [#8467](https://github.com/appwrite/appwrite/pull/8467)
* Automatically restart function on crash in [#8473](https://github.com/appwrite/appwrite/pull/8473)
* Don't send session alerts for otp and magic-url logins in [#8459](https://github.com/appwrite/appwrite/pull/8459)
* Mark 4XX executions as successful in [#8493](https://github.com/appwrite/appwrite/pull/8493)
* Add dynamic keys in builds in [#8492](https://github.com/appwrite/appwrite/pull/8492)
* Allow deployment queries on type and size in [#8515](https://github.com/appwrite/appwrite/pull/8515)
* Add OTP email template in [#8501](https://github.com/appwrite/appwrite/pull/8501)
* Update console links in [#8523](https://github.com/appwrite/appwrite/pull/8523)
* Add multipart support in [#8477](https://github.com/appwrite/appwrite/pull/8477)
* Separate deployment sizes in [#8556](https://github.com/appwrite/appwrite/pull/8556)
* Add go runtime in [#8572](https://github.com/appwrite/appwrite/pull/8572)
* Add react native platform in [#8562](https://github.com/appwrite/appwrite/pull/8562)
* Merge deployments and build storage metrics together in API in [#8443](https://github.com/appwrite/appwrite/pull/8443)
* Support string attribute resizing in [#8597](https://github.com/appwrite/appwrite/pull/8597)
* Support renaming attributes in [#8544](https://github.com/appwrite/appwrite/pull/8544)
* Add VCS vars to deployments & executions in [#8631](https://github.com/appwrite/appwrite/pull/8631)
* Function storage metrics in [#8668](https://github.com/appwrite/appwrite/pull/8668)
* External messaging usage count in [#8672](https://github.com/appwrite/appwrite/pull/8672)
### Fixes
* Fix execution duration in [#8357](https://github.com/appwrite/appwrite/pull/8357)
* Fix file size calculations in [#8432](https://github.com/appwrite/appwrite/pull/8432)
* Fix disabled function logging in [#8398](https://github.com/appwrite/appwrite/pull/8398)
* Fix function redeployments in [#8434](https://github.com/appwrite/appwrite/pull/8434)
* Add value to variables template in [#8483](https://github.com/appwrite/appwrite/pull/8483)
* Fix build size limits in [#8396](https://github.com/appwrite/appwrite/pull/8396)
* Fix deployment method name in [#8490](https://github.com/appwrite/appwrite/pull/8490)
* Fix function disconnecting from git in [#8500](https://github.com/appwrite/appwrite/pull/8500)
* Increase buckets metadata in [#8452](https://github.com/appwrite/appwrite/pull/8452)
* Fix deploy from git with space in [#8517](https://github.com/appwrite/appwrite/pull/8517)
* Fix missing build logs in [#8484](https://github.com/appwrite/appwrite/pull/8484)
* Delete team memberships synchronously in [#8217](https://github.com/appwrite/appwrite/pull/8217)
* Fix Anyof validator in specs in [#8543](https://github.com/appwrite/appwrite/pull/8543)
* Fix missing function variables in [#8554](https://github.com/appwrite/appwrite/pull/8554)
* Fix deadlock in [#8609](https://github.com/appwrite/appwrite/pull/8609)
* Fix domain execution stats in [#8608](https://github.com/appwrite/appwrite/pull/8608)
* Update console redirect to include query params in [#8619](https://github.com/appwrite/appwrite/pull/8619)
* Update abuse-key for mfa challenge endpoints in [#8649](https://github.com/appwrite/appwrite/pull/8649)
* Fix cross-project scheduler stability in [#8641](https://github.com/appwrite/appwrite/pull/8641)
* Fix vcs deployment size in [#8640](https://github.com/appwrite/appwrite/pull/8640)
* Fix logging behaviour for Functions in [#8627](https://github.com/appwrite/appwrite/pull/8627)
* Add retention env vars to deletes worker in [#8662](https://github.com/appwrite/appwrite/pull/8662)
* Fix scheduled executions data in [#8639](https://github.com/appwrite/appwrite/pull/8639)
### Miscellaneous
* Sync 1.6.x with main in [#8163](https://github.com/appwrite/appwrite/pull/8163)
* Remove build ID from rebuild deployment endpoint in [#8214](https://github.com/appwrite/appwrite/pull/8214)
* 1.6.x specs in [#8304](https://github.com/appwrite/appwrite/pull/8304)
* Sync with main in [#8295](https://github.com/appwrite/appwrite/pull/8295)
* Fix 1.6.x failing tests in [#8333](https://github.com/appwrite/appwrite/pull/8333)
* Ensure CI/CD works in [#8350](https://github.com/appwrite/appwrite/pull/8350)
* Update specs in [#8356](https://github.com/appwrite/appwrite/pull/8356)
* Sync main to 1.6.x in [#8430](https://github.com/appwrite/appwrite/pull/8430)
* Add scheduledAt in execution response model in [#8425](https://github.com/appwrite/appwrite/pull/8425)
* Move functions marketplace to appwrite in [#8427](https://github.com/appwrite/appwrite/pull/8427)
* Refactor deployment check in function tests in [#8444](https://github.com/appwrite/appwrite/pull/8444)
* Add ci/cd benchmark in [#8414](https://github.com/appwrite/appwrite/pull/8414)
* Upgrade SDK version in [#8465](https://github.com/appwrite/appwrite/pull/8465)
* Improve session alert in [#8399](https://github.com/appwrite/appwrite/pull/8399)
* Address review comments in [#8422](https://github.com/appwrite/appwrite/pull/8422)
* Add scopes to function template in [#8496](https://github.com/appwrite/appwrite/pull/8496)
* Update benchmark comment in [#8507](https://github.com/appwrite/appwrite/pull/8507)
* Add key to runtime model in [#8503](https://github.com/appwrite/appwrite/pull/8503)
* Upgrade logger in [#8497](https://github.com/appwrite/appwrite/pull/8497)
* Change default email addresses in [#8466](https://github.com/appwrite/appwrite/pull/8466)
* Improve scheduled executions in [#8412](https://github.com/appwrite/appwrite/pull/8412)
* Sync 1.5.x into main in [#8509](https://github.com/appwrite/appwrite/pull/8509)
* Sync 1.6 with main in [#8529](https://github.com/appwrite/appwrite/pull/8529)
* Fix templates CORS in [#8528](https://github.com/appwrite/appwrite/pull/8528)
* Update size to specification for variable runtimes in [#8537](https://github.com/appwrite/appwrite/pull/8537)
* Add boundary to multipart header in [#8539](https://github.com/appwrite/appwrite/pull/8539)
* Support manual templates in [#8527](https://github.com/appwrite/appwrite/pull/8527)
* Reorder runtimes in [#8540](https://github.com/appwrite/appwrite/pull/8540)
* Fix 1.6 bugs in [#8358](https://github.com/appwrite/appwrite/pull/8358)
* Add seconds precision to scheduledAt in [#8546](https://github.com/appwrite/appwrite/pull/8546)
* Update docker base image in [#8485](https://github.com/appwrite/appwrite/pull/8485)
* Update create execution return type in [#8542](https://github.com/appwrite/appwrite/pull/8542)
* Default fallback to for templateBranch in [#8547](https://github.com/appwrite/appwrite/pull/8547)
* Fix env vars functions test in [#8555](https://github.com/appwrite/appwrite/pull/8555)
* Fix session alerts in [#8550](https://github.com/appwrite/appwrite/pull/8550)
* Add runtime controls in [#8384](https://github.com/appwrite/appwrite/pull/8384)
* Revert request type to json in create execution in [#8563](https://github.com/appwrite/appwrite/pull/8563)
* Sync 1.6.x Filters and Migrations with latest in [#8553](https://github.com/appwrite/appwrite/pull/8553)
* Update sdks in [#8551](https://github.com/appwrite/appwrite/pull/8551)
* Update Docs in [#8567](https://github.com/appwrite/appwrite/pull/8567)
* Headers validator benchmark in [#8561](https://github.com/appwrite/appwrite/pull/8561)
* Fix go version in [#8571](https://github.com/appwrite/appwrite/pull/8571)
* Update dependencies in [#8574](https://github.com/appwrite/appwrite/pull/8574)
* Upgrade console in [#8575](https://github.com/appwrite/appwrite/pull/8575)
* 1.6.x logging test in [#8580](https://github.com/appwrite/appwrite/pull/8580)
* Bump console sdk in [#8581](https://github.com/appwrite/appwrite/pull/8581)
* Update sdks in [#8582](https://github.com/appwrite/appwrite/pull/8582)
* Add changelogs for dart and flutter in [#8587](https://github.com/appwrite/appwrite/pull/8587)
* Add payload validator in [#8594](https://github.com/appwrite/appwrite/pull/8594)
* Update geodb in [#8615](https://github.com/appwrite/appwrite/pull/8615)
* Update createdeployment methodtype to upload in [#8616](https://github.com/appwrite/appwrite/pull/8616)
* Remove tenant in document filter in [#8624](https://github.com/appwrite/appwrite/pull/8624)
* Improve mail datetime format in [#8628](https://github.com/appwrite/appwrite/pull/8628)
* Fix router function execution logging in [#8625](https://github.com/appwrite/appwrite/pull/8625)
* Add Functions templates async test in [#8622](https://github.com/appwrite/appwrite/pull/8622)
* Update console in [#8629](https://github.com/appwrite/appwrite/pull/8629)
* 1.6.1 in [#8630](https://github.com/appwrite/appwrite/pull/8630)
* Update version in [#8646](https://github.com/appwrite/appwrite/pull/8646)
* Phone auth metric rename in [#8648](https://github.com/appwrite/appwrite/pull/8648)
* Pretty print specs in [#8643](https://github.com/appwrite/appwrite/pull/8643)
* Fix messaging metrics in [#8674](https://github.com/appwrite/appwrite/pull/8674)
* Bump console to 5.0.6 in [#8585](https://github.com/appwrite/appwrite/pull/8585)
# Version 1.5.10
## What's Changed

View file

@ -1,4 +1,4 @@
FROM composer:2.0 as composer
FROM composer:2.0 AS composer
ARG TESTING=false
ENV TESTING=$TESTING
@ -12,7 +12,7 @@ RUN composer install --ignore-platform-reqs --optimize-autoloader \
--no-plugins --no-scripts --prefer-dist \
`if [ "$TESTING" != "true" ]; then echo "--no-dev"; fi`
FROM appwrite/base:0.9.2 as final
FROM appwrite/base:0.9.3 AS final
LABEL maintainer="team@appwrite.io"

View file

@ -67,7 +67,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:1.5.10
appwrite/appwrite:1.6.0
```
### Windows
@ -79,7 +79,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:1.5.10
appwrite/appwrite:1.6.0
```
#### PowerShell
@ -89,7 +89,7 @@ docker run -it --rm `
--volume /var/run/docker.sock:/var/run/docker.sock `
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
--entrypoint="install" `
appwrite/appwrite:1.5.10
appwrite/appwrite:1.6.0
```
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。

View file

@ -1,4 +1,4 @@
> Our Appwrite Init event has concluded. You can check out all the new and upcoming features [on our Init website](https://appwrite.io/init) 🚀
> Appwrite Init has concluded! You can check out all the latest announcements [on our Init website](https://appwrite.io/init) 🚀
<br />
<p align="center">
@ -75,7 +75,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:1.5.10
appwrite/appwrite:1.6.0
```
### Windows
@ -87,7 +87,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:1.5.10
appwrite/appwrite:1.6.0
```
#### PowerShell
@ -97,7 +97,7 @@ docker run -it --rm `
--volume /var/run/docker.sock:/var/run/docker.sock `
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
--entrypoint="install" `
appwrite/appwrite:1.5.10
appwrite/appwrite:1.6.0
```
Once the Docker installation is complete, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after completing the installation.
@ -134,6 +134,12 @@ Choose from one of the providers below:
<br /><sub><b>Akamai Compute</b></sub></a>
</a>
</td>
<td align="center" width="100" height="100">
<a href="https://aws.amazon.com/marketplace/pp/prodview-2hiaeo2px4md6">
<img width="50" height="39" src="public/images/integrations/aws-logo.svg" alt="AWS Logo" />
<br /><sub><b>AWS Marketplace</b></sub></a>
</a>
</td>
</tr>
</table>

View file

@ -1,12 +1,12 @@
<?php
require_once __DIR__ . '/init.php';
require_once __DIR__ . '/controllers/general.php';
use Appwrite\Event\Certificate;
use Appwrite\Event\Delete;
use Appwrite\Event\Func;
use Appwrite\Platform\Appwrite;
use Appwrite\Runtimes\Runtimes;
use Utopia\Cache\Adapter\Sharding;
use Utopia\Cache\Cache;
use Utopia\CLI\CLI;
@ -23,6 +23,12 @@ use Utopia\Queue\Connection;
use Utopia\Registry\Registry;
use Utopia\System\System;
// overwriting runtimes to be architectur agnostic for CLI
Config::setParam('runtimes', (new Runtimes('v4'))->getAll(supported: false));
// require controllers after overwriting runtimes
require_once __DIR__ . '/controllers/general.php';
Authorization::disable();
CLI::setResource('register', fn () => $register);

View file

@ -82,7 +82,7 @@ return [
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => [],
'scopes' => ["users.read"]
'scopes' => ['users.read']
],
[
'icon' => 'icon-upstash',
@ -125,7 +125,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-redis',
@ -167,7 +168,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-neo4j',
@ -217,7 +219,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-mongodb',
@ -253,7 +256,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-neon',
@ -320,7 +324,8 @@ return [
'required' => true,
'type' => 'text'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-open-ai',
@ -380,7 +385,8 @@ return [
'required' => false,
'type' => 'number'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-discord',
@ -442,7 +448,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-perspective-api',
@ -476,7 +483,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-pangea',
@ -523,7 +531,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-document',
@ -543,7 +552,8 @@ return [
'providerRepositoryId' => 'templates',
'providerOwner' => 'appwrite',
'providerVersion' => '0.2.*',
'variables' => []
'variables' => [],
'scopes' => []
],
[
'icon' => 'icon-github',
@ -586,7 +596,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-bookmark',
@ -637,7 +648,7 @@ return [
'type' => 'url'
]
],
'scopes' => ["databases.read", "databases.write", "collections.write", "attributes.write", "documents.read", "documents.write"]
'scopes' => ['databases.read', 'databases.write', 'collections.write', 'attributes.write', 'documents.read', 'documents.write']
],
[
'icon' => 'icon-algolia',
@ -718,7 +729,7 @@ return [
'type' => 'password'
],
],
'scopes' => ["databases.read", "collections.read", "documents.read"]
'scopes' => ['databases.read', 'collections.read', 'documents.read']
],
[
'icon' => 'icon-meilisearch',
@ -811,7 +822,7 @@ return [
'type' => 'text'
],
],
'scopes' => ["databases.read", "collections.read", "documents.read"]
'scopes' => ['databases.read', 'collections.read', 'documents.read']
],
[
'icon' => 'icon-vonage',
@ -896,7 +907,8 @@ return [
'required' => true,
'type' => 'phone'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-bell',
@ -951,7 +963,8 @@ return [
'required' => true,
'type' => 'url'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-mail',
@ -1033,7 +1046,8 @@ return [
'required' => false,
'type' => 'text'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-stripe',
@ -1074,7 +1088,7 @@ return [
'type' => 'password'
]
],
'scopes' => ["users.read", "sessions.write", "users.write"]
'scopes' => ['users.read', 'sessions.write', 'users.write']
],
[
'icon' => 'icon-stripe',
@ -1131,7 +1145,7 @@ return [
'type' => 'text'
]
],
'scopes' => ["databases.read", "databases.write", "collections.write", "attributes.write", "documents.read", "documents.write"]
'scopes' => ['databases.read', 'databases.write', 'collections.write', 'attributes.write', 'documents.read', 'documents.write']
],
[
'icon' => 'icon-chat',
@ -1164,7 +1178,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-translate',
@ -1197,7 +1212,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-eye',
@ -1255,7 +1271,7 @@ return [
'type' => 'password'
]
],
'scopes' => ["databases.read", "databases.write", "collections.read", "collections.write", "attributes.write", "documents.read", "documents.write", "buckets.read", "buckets.write", "files.read"]
'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.write', 'documents.read', 'documents.write', 'buckets.read', 'buckets.write', 'files.read']
],
[
'icon' => 'icon-eye',
@ -1313,7 +1329,7 @@ return [
'type' => 'password'
]
],
"scopes" => ["databases.read", "databases.write", "collections.read", "collections.write", "attributes.write", "documents.read", "documents.write", "buckets.read", "buckets.write", "files.read"]
'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.write', 'documents.read', 'documents.write', 'buckets.read', 'buckets.write', 'files.read']
],
[
'icon' => 'icon-text',
@ -1371,7 +1387,7 @@ return [
'type' => 'password'
]
],
"scopes" => ["databases.read", "databases.write", "collections.read", "collections.write", "attributes.write", "documents.read", "documents.write", "buckets.read", "buckets.write", "files.read"]
'scopes' => ['databases.read', 'databases.write', 'collections.read', 'collections.write', 'attributes.write', 'documents.read', 'documents.write', 'buckets.read', 'buckets.write', 'files.read']
],
[
'icon' => 'icon-chat',
@ -1429,7 +1445,7 @@ return [
'type' => 'password'
]
],
"scopes" => ["buckets.read", "buckets.write", "files.read", "files.write"]
'scopes' => ['buckets.read', 'buckets.write', 'files.read', 'files.write']
],
[
'icon' => 'icon-chip',
@ -1463,7 +1479,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-chip',
@ -1505,7 +1522,7 @@ return [
'type' => 'text'
]
],
"scopes" => ["buckets.write", "files.read", "files.write"]
'scopes' => ['buckets.write', 'files.read', 'files.write']
],
[
'icon' => 'icon-chip',
@ -1579,7 +1596,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-document-search',
@ -1642,7 +1660,7 @@ return [
'type' => 'text'
]
],
"scopes" => ["databases.read", "collections.read", "documents.read"]
'scopes' => ['databases.read', 'collections.read', 'documents.read']
],
[
'icon' => 'icon-chip',
@ -1705,7 +1723,7 @@ return [
'type' => 'text'
]
],
"scopes" => ["databases.read", "collections.read", "documents.read"]
'scopes' => ['databases.read', 'collections.read', 'documents.read']
],
[
'icon' => 'icon-chat',
@ -1760,7 +1778,7 @@ return [
'type' => 'text'
]
],
"scopes" => ["buckets.read", "buckets.write", "files.read", "files.write"]
'scopes' => ['buckets.read', 'buckets.write', 'files.read', 'files.write']
],
[
'icon' => 'icon-chip',
@ -1801,7 +1819,7 @@ return [
'type' => 'text'
]
],
"scopes" => ["buckets.read", "buckets.write", "files.read", "files.write"]
'scopes' => ['buckets.read', 'buckets.write', 'files.read', 'files.write']
],
[
'icon' => 'icon-chip',
@ -1841,7 +1859,8 @@ return [
'required' => false,
'type' => 'number'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-music-note',
@ -1883,7 +1902,7 @@ return [
'type' => 'password'
]
],
"scopes" => ["buckets.read", "buckets.write", "files.read", "files.write"]
'scopes' => ['buckets.read', 'buckets.write', 'files.read', 'files.write']
],
[
'icon' => 'icon-chip',
@ -1917,7 +1936,8 @@ return [
'required' => true,
'type' => 'password'
]
]
],
'scopes' => []
],
[
'icon' => 'icon-currency-dollar',
@ -1972,7 +1992,7 @@ return [
'type' => 'text'
]
],
"scopes" => ["users.read", "users.write"]
'scopes' => ['users.read', 'users.write']
],
[
'icon' => 'icon-currency-dollar',
@ -2043,6 +2063,6 @@ return [
'type' => 'text'
]
],
"scopes" => ["users.read", "users.write"]
'scopes' => ['users.read', 'users.write']
]
];

View file

@ -37384,6 +37384,18 @@
"x-example": 0,
"format": "int32"
},
"buildsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of builds storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"deploymentsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of deployments storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"bucketsTotal": {
"type": "integer",
"description": "Total aggregated number of buckets.",
@ -37482,6 +37494,8 @@
"usersTotal",
"filesStorageTotal",
"functionsStorageTotal",
"buildsStorageTotal",
"deploymentsStorageTotal",
"bucketsTotal",
"executionsMbSecondsTotal",
"buildsMbSecondsTotal",

View file

@ -37384,6 +37384,18 @@
"x-example": 0,
"format": "int32"
},
"buildsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of builds storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"deploymentsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of deployments storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"bucketsTotal": {
"type": "integer",
"description": "Total aggregated number of buckets.",
@ -37482,6 +37494,8 @@
"usersTotal",
"filesStorageTotal",
"functionsStorageTotal",
"buildsStorageTotal",
"deploymentsStorageTotal",
"bucketsTotal",
"executionsMbSecondsTotal",
"buildsMbSecondsTotal",

View file

@ -37939,6 +37939,18 @@
"x-example": 0,
"format": "int32"
},
"buildsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of builds storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"deploymentsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of deployments storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"bucketsTotal": {
"type": "integer",
"description": "Total aggregated number of buckets.",
@ -38046,6 +38058,8 @@
"usersTotal",
"filesStorageTotal",
"functionsStorageTotal",
"buildsStorageTotal",
"deploymentsStorageTotal",
"bucketsTotal",
"executionsMbSecondsTotal",
"buildsMbSecondsTotal",

View file

@ -37939,6 +37939,18 @@
"x-example": 0,
"format": "int32"
},
"buildsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of builds storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"deploymentsStorageTotal": {
"type": "integer",
"description": "Total aggregated sum of deployments storage size (in bytes).",
"x-example": 0,
"format": "int32"
},
"bucketsTotal": {
"type": "integer",
"description": "Total aggregated number of buckets.",
@ -38046,6 +38058,8 @@
"usersTotal",
"filesStorageTotal",
"functionsStorageTotal",
"buildsStorageTotal",
"deploymentsStorageTotal",
"bucketsTotal",
"executionsMbSecondsTotal",
"buildsMbSecondsTotal",

View file

@ -193,7 +193,7 @@ return [
'introduction' => '1.5.1',
'default' => '',
'required' => true,
'question' => '',
'question' => 'Enter an email that will be used when registering for SSL certificates',
'filter' => ''
],
[

View file

@ -1923,7 +1923,7 @@ App::post('/v1/functions/:functionId/executions')
'path' => $path,
'method' => $method,
'body' => $body,
'jwt' => $jwt,
'userId' => $user->getId()
];
$schedule = $dbForConsole->createDocument('schedules', new Document([

View file

@ -273,6 +273,8 @@ App::get('/v1/project/usage')
'bucketsTotal' => $total[METRIC_BUCKETS],
'filesStorageTotal' => $total[METRIC_FILES_STORAGE],
'functionsStorageTotal' => $total[METRIC_DEPLOYMENTS_STORAGE] + $total[METRIC_BUILDS_STORAGE],
'buildsStorageTotal' => $total[METRIC_BUILDS_STORAGE],
'deploymentsStorageTotal' => $total[METRIC_DEPLOYMENTS_STORAGE],
'executionsBreakdown' => $executionsBreakdown,
'executionsMbSecondsBreakdown' => $executionsMbSecondsBreakdown,
'buildsMbSecondsBreakdown' => $buildsMbSecondsBreakdown,

View file

@ -603,10 +603,11 @@ App::shutdown()
/**
* Trigger functions.
*/
$queueForFunctions
->from($queueForEvents)
->trigger();
if (!$queueForEvents->isPaused()) {
$queueForFunctions
->from($queueForEvents)
->trigger();
}
/**
* Trigger webhooks.
*/

View file

@ -227,8 +227,18 @@ const API_KEY_DYNAMIC = 'dynamic';
// Usage metrics
const METRIC_TEAMS = 'teams';
const METRIC_USERS = 'users';
const METRIC_AUTH_METHOD_PHONE = 'auth.method.phone';
const METRIC_AUTH_METHOD_PHONE_COUNTRY_CODE = METRIC_AUTH_METHOD_PHONE . '.{countryCode}';
const METRIC_MESSAGES = 'messages';
const METRIC_MESSAGES_SENT = METRIC_MESSAGES . '.sent';
const METRIC_MESSAGES_FAILED = METRIC_MESSAGES . '.failed';
const METRIC_MESSAGES_TYPE = METRIC_MESSAGES . '.{type}';
const METRIC_MESSAGES_TYPE_SENT = METRIC_MESSAGES . '.{type}.sent';
const METRIC_MESSAGES_TYPE_FAILED = METRIC_MESSAGES . '.{type}.failed';
const METRIC_MESSAGES_TYPE_PROVIDER = METRIC_MESSAGES . '.{type}.{provider}';
const METRIC_MESSAGES_TYPE_PROVIDER_SENT = METRIC_MESSAGES . '.{type}.{provider}.sent';
const METRIC_MESSAGES_TYPE_PROVIDER_FAILED = METRIC_MESSAGES . '.{type}.{provider}.failed';
const METRIC_SESSIONS = 'sessions';
const METRIC_DATABASES = 'databases';
const METRIC_COLLECTIONS = 'collections';

View file

@ -166,7 +166,7 @@ $image = $this->getParam('image', '');
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: <?php echo $organization; ?>/console:5.0.11
image: <?php echo $organization; ?>/console:5.0.12
restart: unless-stopped
networks:
- appwrite
@ -336,6 +336,9 @@ $image = $this->getParam('image', '');
- _APP_LOGGING_CONFIG
- _APP_EXECUTOR_SECRET
- _APP_EXECUTOR_HOST
- _APP_MAINTENANCE_RETENTION_ABUSE
- _APP_MAINTENANCE_RETENTION_AUDIT
- _APP_MAINTENANCE_RETENTION_EXECUTION
appwrite-worker-databases:
image: <?php echo $organization; ?>/<?php echo $image; ?>:<?php echo $version."\n"; ?>
@ -676,6 +679,7 @@ $image = $this->getParam('image', '');
entrypoint: worker-usage-dump
<<: *x-logging
container_name: appwrite-worker-usage-dump
restart: unless-stopped
networks:
- appwrite
depends_on:
@ -789,7 +793,7 @@ $image = $this->getParam('image', '');
<<: *x-logging
restart: unless-stopped
stop_signal: SIGINT
image: openruntimes/executor:0.6.7
image: openruntimes/executor:0.6.11
networks:
- appwrite
- runtimes

12
composer.lock generated
View file

@ -3564,16 +3564,16 @@
},
{
"name": "nikic/php-parser",
"version": "v5.1.0",
"version": "v5.2.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1"
"reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1",
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb",
"reference": "23c79fbbfb725fb92af9bcf41065c8e9a0d49ddb",
"shasum": ""
},
"require": {
@ -3616,9 +3616,9 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0"
"source": "https://github.com/nikic/PHP-Parser/tree/v5.2.0"
},
"time": "2024-07-01T20:03:41+00:00"
"time": "2024-09-15T16:40:33+00:00"
},
{
"name": "phar-io/manifest",

View file

@ -196,7 +196,7 @@ services:
appwrite-console:
<<: *x-logging
container_name: appwrite-console
image: appwrite/console:5.0.11
image: appwrite/console:5.0.12
restart: unless-stopped
networks:
- appwrite
@ -874,7 +874,7 @@ services:
hostname: exc1
<<: *x-logging
stop_signal: SIGINT
image: openruntimes/executor:0.6.7
image: openruntimes/executor:0.6.11
restart: unless-stopped
networks:
- appwrite

View file

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 304 182" style="enable-background:new 0 0 304 182;" xml:space="preserve">
<style type="text/css">
.st0{fill:#252F3E;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FF9900;}
</style>
<g>
<path class="st0" d="M86.4,66.4c0,3.7,0.4,6.7,1.1,8.9c0.8,2.2,1.8,4.6,3.2,7.2c0.5,0.8,0.7,1.6,0.7,2.3c0,1-0.6,2-1.9,3l-6.3,4.2
c-0.9,0.6-1.8,0.9-2.6,0.9c-1,0-2-0.5-3-1.4C76.2,90,75,88.4,74,86.8c-1-1.7-2-3.6-3.1-5.9c-7.8,9.2-17.6,13.8-29.4,13.8
c-8.4,0-15.1-2.4-20-7.2c-4.9-4.8-7.4-11.2-7.4-19.2c0-8.5,3-15.4,9.1-20.6c6.1-5.2,14.2-7.8,24.5-7.8c3.4,0,6.9,0.3,10.6,0.8
c3.7,0.5,7.5,1.3,11.5,2.2v-7.3c0-7.6-1.6-12.9-4.7-16c-3.2-3.1-8.6-4.6-16.3-4.6c-3.5,0-7.1,0.4-10.8,1.3c-3.7,0.9-7.3,2-10.8,3.4
c-1.6,0.7-2.8,1.1-3.5,1.3c-0.7,0.2-1.2,0.3-1.6,0.3c-1.4,0-2.1-1-2.1-3.1v-4.9c0-1.6,0.2-2.8,0.7-3.5c0.5-0.7,1.4-1.4,2.8-2.1
c3.5-1.8,7.7-3.3,12.6-4.5c4.9-1.3,10.1-1.9,15.6-1.9c11.9,0,20.6,2.7,26.2,8.1c5.5,5.4,8.3,13.6,8.3,24.6V66.4z M45.8,81.6
c3.3,0,6.7-0.6,10.3-1.8c3.6-1.2,6.8-3.4,9.5-6.4c1.6-1.9,2.8-4,3.4-6.4c0.6-2.4,1-5.3,1-8.7v-4.2c-2.9-0.7-6-1.3-9.2-1.7
c-3.2-0.4-6.3-0.6-9.4-0.6c-6.7,0-11.6,1.3-14.9,4c-3.3,2.7-4.9,6.5-4.9,11.5c0,4.7,1.2,8.2,3.7,10.6
C37.7,80.4,41.2,81.6,45.8,81.6z M126.1,92.4c-1.8,0-3-0.3-3.8-1c-0.8-0.6-1.5-2-2.1-3.9L96.7,10.2c-0.6-2-0.9-3.3-0.9-4
c0-1.6,0.8-2.5,2.4-2.5h9.8c1.9,0,3.2,0.3,3.9,1c0.8,0.6,1.4,2,2,3.9l16.8,66.2l15.6-66.2c0.5-2,1.1-3.3,1.9-3.9c0.8-0.6,2.2-1,4-1
h8c1.9,0,3.2,0.3,4,1c0.8,0.6,1.5,2,1.9,3.9l15.8,67l17.3-67c0.6-2,1.3-3.3,2-3.9c0.8-0.6,2.1-1,3.9-1h9.3c1.6,0,2.5,0.8,2.5,2.5
c0,0.5-0.1,1-0.2,1.6c-0.1,0.6-0.3,1.4-0.7,2.5l-24.1,77.3c-0.6,2-1.3,3.3-2.1,3.9c-0.8,0.6-2.1,1-3.8,1h-8.6c-1.9,0-3.2-0.3-4-1
c-0.8-0.7-1.5-2-1.9-4L156,23l-15.4,64.4c-0.5,2-1.1,3.3-1.9,4c-0.8,0.7-2.2,1-4,1H126.1z M254.6,95.1c-5.2,0-10.4-0.6-15.4-1.8
c-5-1.2-8.9-2.5-11.5-4c-1.6-0.9-2.7-1.9-3.1-2.8c-0.4-0.9-0.6-1.9-0.6-2.8v-5.1c0-2.1,0.8-3.1,2.3-3.1c0.6,0,1.2,0.1,1.8,0.3
c0.6,0.2,1.5,0.6,2.5,1c3.4,1.5,7.1,2.7,11,3.5c4,0.8,7.9,1.2,11.9,1.2c6.3,0,11.2-1.1,14.6-3.3c3.4-2.2,5.2-5.4,5.2-9.5
c0-2.8-0.9-5.1-2.7-7c-1.8-1.9-5.2-3.6-10.1-5.2L246,52c-7.3-2.3-12.7-5.7-16-10.2c-3.3-4.4-5-9.3-5-14.5c0-4.2,0.9-7.9,2.7-11.1
c1.8-3.2,4.2-6,7.2-8.2c3-2.3,6.4-4,10.4-5.2c4-1.2,8.2-1.7,12.6-1.7c2.2,0,4.5,0.1,6.7,0.4c2.3,0.3,4.4,0.7,6.5,1.1
c2,0.5,3.9,1,5.7,1.6c1.8,0.6,3.2,1.2,4.2,1.8c1.4,0.8,2.4,1.6,3,2.5c0.6,0.8,0.9,1.9,0.9,3.3v4.7c0,2.1-0.8,3.2-2.3,3.2
c-0.8,0-2.1-0.4-3.8-1.2c-5.7-2.6-12.1-3.9-19.2-3.9c-5.7,0-10.2,0.9-13.3,2.8c-3.1,1.9-4.7,4.8-4.7,8.9c0,2.8,1,5.2,3,7.1
c2,1.9,5.7,3.8,11,5.5l14.2,4.5c7.2,2.3,12.4,5.5,15.5,9.6c3.1,4.1,4.6,8.8,4.6,14c0,4.3-0.9,8.2-2.6,11.6
c-1.8,3.4-4.2,6.4-7.3,8.8c-3.1,2.5-6.8,4.3-11.1,5.6C264.4,94.4,259.7,95.1,254.6,95.1z"/>
<g>
<path class="st1" d="M273.5,143.7c-32.9,24.3-80.7,37.2-121.8,37.2c-57.6,0-109.5-21.3-148.7-56.7c-3.1-2.8-0.3-6.6,3.4-4.4
c42.4,24.6,94.7,39.5,148.8,39.5c36.5,0,76.6-7.6,113.5-23.2C274.2,133.6,278.9,139.7,273.5,143.7z"/>
<path class="st1" d="M287.2,128.1c-4.2-5.4-27.8-2.6-38.5-1.3c-3.2,0.4-3.7-2.4-0.8-4.5c18.8-13.2,49.7-9.4,53.3-5
c3.6,4.5-1,35.4-18.6,50.2c-2.7,2.3-5.3,1.1-4.1-1.9C282.5,155.7,291.4,133.4,287.2,128.1z"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View file

@ -55,6 +55,7 @@ class Event
protected array $context = [];
protected ?Document $project = null;
protected ?Document $user = null;
protected ?string $userId = null;
protected bool $paused = false;
/**
@ -153,6 +154,18 @@ class Event
return $this;
}
/**
* Set user ID for this event.
*
* @return self
*/
public function setUserId(string $userId): self
{
$this->userId = $userId;
return $this;
}
/**
* Get user responsible for triggering this event.
*
@ -163,6 +176,14 @@ class Event
return $this->user;
}
/**
* Get user responsible for triggering this event.
*/
public function getUserId(): ?string
{
return $this->userId;
}
/**
* Set payload for this event.
*
@ -312,6 +333,7 @@ class Event
'sourceRegion' => $this->getSourceRegion(),
'project' => $this->project,
'user' => $this->user,
'userId' => $this->userId,
'payload' => $this->payload,
'context' => $this->context,
'events' => Event::generateEvents($this->getEvent(), $this->getParams())

View file

@ -223,6 +223,7 @@ class Func extends Event
'sourceRegion' => $this->getSourceRegion(),
'project' => $this->project,
'user' => $this->user,
'userId' => $this->userId,
'function' => $this->function,
'functionId' => $this->functionId,
'execution' => $this->execution,

View file

@ -88,7 +88,8 @@ abstract class Migration
'1.5.7' => 'V20',
'1.5.8' => 'V20',
'1.5.9' => 'V20',
'1.5.10' => 'V20',
'1.5.10' => 'V20',
'1.5.11' => 'V20',
'1.6.0' => 'V21',
];

View file

@ -164,7 +164,7 @@ abstract class ScheduleBase extends Action
$total = $total + $sum;
foreach ($results as $document) {
$localDocument = $schedules[$document['resourceId']] ?? null;
$localDocument = $this->schedules[$document->getInternalId()] ?? null;
// Check if resource has been updated since last sync
$org = $localDocument !== null ? \strtotime($localDocument['resourceUpdatedAt']) : null;

View file

@ -45,23 +45,27 @@ class ScheduleExecutions extends ScheduleBase
continue;
}
$data = $dbForConsole->getDocument(
'schedules',
$schedule['$id'],
)->getAttribute('data', []);
$delay = $scheduledAt->getTimestamp() - (new \DateTime())->getTimestamp();
\go(function () use ($queueForFunctions, $schedule, $delay) {
\go(function () use ($queueForFunctions, $schedule, $delay, $data) {
Co::sleep($delay);
$queueForFunctions
->setType('schedule')
$queueForFunctions->setType('schedule')
// Set functionId instead of function as we don't have $dbForProject
// TODO: Refactor to use function instead of functionId
->setFunctionId($schedule['resource']['functionId'])
->setExecution($schedule['resource'])
->setMethod($schedule['data']['method'] ?? 'POST')
->setPath($schedule['data']['path'] ?? '/')
->setHeaders($schedule['data']['headers'] ?? [])
->setBody($schedule['data']['body'] ?? '')
->setMethod($data['method'] ?? 'POST')
->setPath($data['path'] ?? '/')
->setHeaders($data['headers'] ?? [])
->setBody($data['body'] ?? '')
->setProject($schedule['project'])
->setUserId($data['userId'] ?? '')
->trigger();
});

View file

@ -77,12 +77,6 @@ class Functions extends Action
throw new Exception('Missing payload');
}
$payload = $message->getPayload() ?? [];
if (empty($payload)) {
throw new Exception('Missing payload');
}
$type = $payload['type'] ?? '';
$events = $payload['events'] ?? [];
$data = $payload['body'] ?? '';
@ -91,9 +85,23 @@ class Functions extends Action
$function = new Document($payload['function'] ?? []);
$functionId = $payload['functionId'] ?? '';
$user = new Document($payload['user'] ?? []);
$userId = $payload['userId'] ?? '';
$method = $payload['method'] ?? 'POST';
$headers = $payload['headers'] ?? [];
$path = $payload['path'] ?? '/';
$jwt = $payload['jwt'] ?? '';
if ($user->isEmpty() && !empty($userId)) {
$user = $dbForProject->getDocument('users', $userId);
}
if (empty($jwt) && !$user->isEmpty()) {
$jwtExpiry = $function->getAttribute('timeout', 900);
$jwtObj = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', $jwtExpiry, 0);
$jwt = $jwtObj->encode([
'userId' => $user->getId(),
]);
}
if ($project->getId() === 'console') {
return;
@ -166,7 +174,6 @@ class Functions extends Action
*/
switch ($type) {
case 'http':
$jwt = $payload['jwt'] ?? '';
$execution = new Document($payload['execution'] ?? []);
$user = new Document($payload['user'] ?? []);
$this->execute(
@ -205,9 +212,9 @@ class Functions extends Action
path: $path,
method: $method,
headers: $headers,
data: null,
user: null,
jwt: null,
data: $data,
user: $user,
jwt: $jwt,
event: null,
eventData: null,
executionId: $execution->getId() ?? null

View file

@ -101,7 +101,7 @@ class Messaging extends Action
case MESSAGE_SEND_TYPE_EXTERNAL:
$message = $dbForProject->getDocument('messages', $payload['messageId']);
$this->sendExternalMessage($dbForProject, $message, $deviceForFiles, $project);
$this->sendExternalMessage($dbForProject, $message, $deviceForFiles, $project, $queueForUsage);
break;
default:
throw new \Exception('Unknown message type: ' . $type);
@ -113,6 +113,7 @@ class Messaging extends Action
Document $message,
Device $deviceForFiles,
Document $project,
Usage $queueForUsage
): void {
$topicIds = $message->getAttribute('topics', []);
$targetIds = $message->getAttribute('targets', []);
@ -218,8 +219,8 @@ class Messaging extends Action
/**
* @var array<array> $results
*/
$results = batch(\array_map(function ($providerId) use ($identifiers, &$providers, $default, $message, $dbForProject, $deviceForFiles, $project) {
return function () use ($providerId, $identifiers, &$providers, $default, $message, $dbForProject, $deviceForFiles, $project) {
$results = batch(\array_map(function ($providerId) use ($identifiers, &$providers, $default, $message, $dbForProject, $deviceForFiles, $project, $queueForUsage) {
return function () use ($providerId, $identifiers, &$providers, $default, $message, $dbForProject, $deviceForFiles, $project, $queueForUsage) {
if (\array_key_exists($providerId, $providers)) {
$provider = $providers[$providerId];
} else {
@ -246,8 +247,8 @@ class Messaging extends Action
$adapter->getMaxMessagesPerRequest()
);
return batch(\array_map(function ($batch) use ($message, $provider, $adapter, $dbForProject, $deviceForFiles, $project) {
return function () use ($batch, $message, $provider, $adapter, $dbForProject, $deviceForFiles, $project) {
return batch(\array_map(function ($batch) use ($message, $provider, $adapter, $dbForProject, $deviceForFiles, $project, $queueForUsage) {
return function () use ($batch, $message, $provider, $adapter, $dbForProject, $deviceForFiles, $project, $queueForUsage) {
$deliveredTotal = 0;
$deliveryErrors = [];
$messageData = clone $message;
@ -286,6 +287,20 @@ class Messaging extends Action
} catch (\Throwable $e) {
$deliveryErrors[] = 'Failed sending to targets with error: ' . $e->getMessage();
} finally {
$errorTotal = count($deliveryErrors);
$queueForUsage
->setProject($project)
->addMetric(METRIC_MESSAGES, ($deliveredTotal + $errorTotal))
->addMetric(METRIC_MESSAGES_SENT, $deliveredTotal)
->addMetric(METRIC_MESSAGES_FAILED, $errorTotal)
->addMetric(str_replace('{type}', $provider->getAttribute('type'), METRIC_MESSAGES_TYPE), ($deliveredTotal + $errorTotal))
->addMetric(str_replace('{type}', $provider->getAttribute('type'), METRIC_MESSAGES_TYPE_SENT), $deliveredTotal)
->addMetric(str_replace('{type}', $provider->getAttribute('type'), METRIC_MESSAGES_TYPE_FAILED), $errorTotal)
->addMetric(str_replace(['{type}', '{provider}'], [$provider->getAttribute('type'), $provider->getAttribute('provider')], METRIC_MESSAGES_TYPE_PROVIDER), ($deliveredTotal + $errorTotal))
->addMetric(str_replace(['{type}', '{provider}'], [$provider->getAttribute('type'), $provider->getAttribute('provider')], METRIC_MESSAGES_TYPE_PROVIDER_SENT), $deliveredTotal)
->addMetric(str_replace(['{type}', '{provider}'], [$provider->getAttribute('type'), $provider->getAttribute('provider')], METRIC_MESSAGES_TYPE_PROVIDER_FAILED), $errorTotal)
->trigger();
return [
'deliveredTotal' => $deliveredTotal,
'deliveryErrors' => $deliveryErrors,
@ -318,6 +333,7 @@ class Messaging extends Action
$message->setAttribute('status', MessageStatus::SENT);
}
$message->removeAttribute('to');
foreach ($providers as $provider) {

View file

@ -46,6 +46,18 @@ class UsageProject extends Model
'default' => 0,
'example' => 0,
])
->addRule('buildsStorageTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated sum of builds storage size (in bytes).',
'default' => 0,
'example' => 0,
])
->addRule('deploymentsStorageTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated sum of deployments storage size (in bytes).',
'default' => 0,
'example' => 0,
])
->addRule('bucketsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated number of buckets.',

View file

@ -143,7 +143,7 @@ class UsageTest extends Scope
);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(18, count($response['body']));
$this->assertEquals(20, 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(18, count($response['body']));
$this->assertEquals(20, 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(18, count($response['body']));
$this->assertEquals(20, 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']);

View file

@ -164,7 +164,8 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals($executions['body']['executions'][1]['status'], 'completed');
$this->assertEquals($executions['body']['executions'][1]['responseStatusCode'], 200);
$this->assertEquals($executions['body']['executions'][1]['responseBody'], '');
$this->assertEquals($executions['body']['executions'][1]['logs'], '');
$this->assertNotEmpty($executions['body']['executions'][1]['logs'], '');
$this->assertNotEmpty($executions['body']['executions'][1]['errors'], '');
$this->assertGreaterThan(0, $executions['body']['executions'][1]['duration']);
// Cleanup : Delete function
@ -228,17 +229,22 @@ class FunctionsCustomClientTest extends Scope
], $this->getHeaders()), [
'async' => true,
'scheduledAt' => $futureTime->format(\DateTime::ATOM),
'path' => '/custom',
'method' => 'GET'
'path' => '/custom-path',
'method' => 'PATCH',
'body' => 'custom-body',
'headers' => [
'x-custom-header' => 'custom-value'
]
]);
$this->assertEquals(202, $execution['headers']['status-code']);
$this->assertEquals('scheduled', $execution['body']['status']);
$this->assertEquals('PATCH', $execution['body']['requestMethod']);
$this->assertEquals('/custom-path', $execution['body']['requestPath']);
$this->assertCount(0, $execution['body']['requestHeaders']);
$executionId = $execution['body']['$id'];
sleep(60 + 60 + 15); // up to 1 minute round up, 1 minute schedule postpone, 15s cold start safety
$start = \microtime(true);
while (true) {
$execution = $this->client->call(Client::METHOD_GET, '/functions/' . $function['body']['$id'] . '/executions/' . $executionId, [
@ -251,7 +257,8 @@ class FunctionsCustomClientTest extends Scope
break;
}
if (\microtime(true) - $start > 10) {
$timeout = 60 + 60 + 15; // up to 1 minute round up, 1 minute schedule postpone, 15s cold start safety
if (\microtime(true) - $start > $timeout) {
$this->fail('Scheduled execution did not complete with status ' . $execution['body']['status'] . ': ' . \json_encode($execution));
}
@ -261,8 +268,14 @@ class FunctionsCustomClientTest extends Scope
$this->assertEquals(200, $execution['headers']['status-code']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals('/custom', $execution['body']['requestPath']);
$this->assertEquals('GET', $execution['body']['requestMethod']);
$this->assertEquals('/custom-path', $execution['body']['requestPath']);
$this->assertEquals('PATCH', $execution['body']['requestMethod']);
$this->assertStringContainsString('body-is-custom-body', $execution['body']['logs']);
$this->assertStringContainsString('custom-header-is-custom-value', $execution['body']['logs']);
$this->assertStringContainsString('method-is-patch', $execution['body']['logs']);
$this->assertStringContainsString('path-is-/custom-path', $execution['body']['logs']);
$this->assertStringContainsString('user-is-' . $this->getUser()['$id'], $execution['body']['logs']);
$this->assertStringContainsString('jwt-is-valid', $execution['body']['logs']);
$this->assertGreaterThan(0, $execution['body']['duration']);
/* Test for FAILURE */

View file

@ -1179,8 +1179,8 @@ class FunctionsCustomServerTest extends Scope
$this->assertStringContainsString('8.0', $execution['body']['responseBody']);
$this->assertStringContainsString('Global Variable Value', $execution['body']['responseBody']);
// $this->assertStringContainsString('êä', $execution['body']['responseBody']); // tests unknown utf-8 chars
$this->assertEquals('', $execution['body']['errors']);
$this->assertEquals('', $execution['body']['logs']);
$this->assertNotEmpty($execution['body']['errors']);
$this->assertNotEmpty($execution['body']['logs']);
$this->assertLessThan(10, $execution['body']['duration']);
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/executions', array_merge([

View file

@ -1,6 +1,20 @@
<?php
return function ($context) {
$context->log('body-is-' . ($context->req->body ?? ''));
$context->log('custom-header-is-' . ($context->req->headers['x-custom-header'] ?? ''));
$context->log('method-is-' . \strtolower($context->req->method ?? ''));
$context->log('path-is-' . ($context->req->path ?? ''));
$context->log('user-is-' . $context->req->headers['x-appwrite-user-id'] ?? '');
if (empty($context->req->headers['x-appwrite-user-jwt'] ?? '')) {
$context->log('jwt-is-invalid');
} else {
$context->log('jwt-is-valid');
}
$context->error('error-log-works');
$statusCode = $context->req->query['code'] ?? '200';
return $context->res->json([