1
0
Fork 0
mirror of synced 2024-09-29 17:01:37 +13:00

Merge remote-tracking branch 'origin/master' into feat-graphql-support

# Conflicts:
#	app/controllers/api/databases.php
#	composer.lock
This commit is contained in:
Jake Barnby 2022-07-08 17:50:16 +12:00
commit da71aec774
17 changed files with 210 additions and 47 deletions

View file

@ -1,3 +1,11 @@
# Version 0.15.2
## Bugs
- Fixed Realtime Authentication for the Console by @TorstenDittmann in https://github.com/appwrite/appwrite/pull/3506
- Fixed Collection Usage by @stnguyen90 in https://github.com/appwrite/appwrite/pull/3505
- Fixed `$createdAt` after updating document by @Meldiron in https://github.com/appwrite/appwrite/pull/3498
- Fixed Redirect after deleting Collection in Console @TorstenDittmann in https://github.com/appwrite/appwrite/pull/3476
- Fixed broken Link for Documents under Collections by @TorstenDittmann in https://github.com/appwrite/appwrite/pull/3469
# Version 0.15.1
## Bugs
- Fixed SMS for `createVerification` by @christyjacob4 in https://github.com/appwrite/appwrite/pull/3454
@ -26,8 +34,8 @@
- `collections.[COLLECTION_ID]` is now `databases.[DATABASE_ID].collections.[COLLECTION_ID]`
- `collections.[COLLECTION_ID].documents.[DOCUMENT_ID]` is now `databases.[DATABASE_ID].collections.[COLLECTION_ID].documents.[DOCUMENT_ID]`
- Following Realtime Channels are changed:
- `collections.[COLLECTION_ID]` is now `databases.[DATABASE_ID].ollections.[COLLECTION_ID]`
- `collections.[COLLECTION_ID].documents` is now `databases.[DATABASE_ID].ollections.[COLLECTION_ID].documents`
- `collections.[COLLECTION_ID]` is now `databases.[DATABASE_ID].collections.[COLLECTION_ID]`
- `collections.[COLLECTION_ID].documents` is now `databases.[DATABASE_ID].collections.[COLLECTION_ID].documents`
- After Migration a Database called `default` is created for all your existing Database Collections
## Features

View file

@ -59,7 +59,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:0.15.1
appwrite/appwrite:0.15.2
```
### Windows
@ -71,7 +71,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:0.15.1
appwrite/appwrite:0.15.2
```
#### PowerShell
@ -81,7 +81,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:0.15.1
appwrite/appwrite:0.15.2
```
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。

View file

@ -65,7 +65,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:0.15.1
appwrite/appwrite:0.15.2
```
### Windows
@ -77,7 +77,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:0.15.1
appwrite/appwrite:0.15.2
```
#### PowerShell
@ -87,7 +87,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:0.15.1
appwrite/appwrite:0.15.2
```
Once the Docker installation completes, 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 installation completes.

View file

@ -180,7 +180,7 @@ return [
[
'key' => 'cli',
'name' => 'Command Line',
'version' => '0.18.0',
'version' => '0.18.1',
'url' => 'https://github.com/appwrite/sdk-for-cli',
'package' => 'https://www.npmjs.com/package/appwrite-cli',
'enabled' => true,

View file

@ -2277,7 +2277,7 @@ App::patch('/v1/databases/:databaseId/collections/:collectionId/documents/:docum
$data = \array_merge($document->getArrayCopy(), $data);
$data['$collection'] = $collection->getId(); // Make sure user don't switch collectionID
$data['$createdAt'] = $collection->getCreatedAt(); // Make sure user don't switch createdAt
$data['$createdAt'] = $document->getCreatedAt(); // Make sure user don't switch createdAt
$data['$id'] = $document->getId(); // Make sure user don't switch document unique ID
$data['$read'] = (is_null($read)) ? ($document->getRead() ?? []) : $read; // By default inherit read permissions
$data['$write'] = (is_null($write)) ? ($document->getWrite() ?? []) : $write; // By default inherit write permissions
@ -2668,7 +2668,7 @@ App::get('/v1/databases/:databaseId/usage')
});
App::get('/v1/databases/:databaseId/collections/:collectionId/usage')
->alias('/v1/database/collections/:collectionId/usage', ['databaseId' => 'default'])
->alias('/v1/database/:collectionId/usage', ['databaseId' => 'default'])
->desc('Get usage stats for a collection')
->groups(['api', 'database'])
->label('scope', 'collections.read')

View file

@ -89,8 +89,8 @@ const APP_LIMIT_COMPRESSION = 20000000; //20MB
const APP_LIMIT_ARRAY_PARAMS_SIZE = 100; // Default maximum of how many elements can there be in API parameter that expects array value
const APP_LIMIT_ARRAY_ELEMENT_SIZE = 4096; // Default maximum length of element in array parameter represented by maximum URL length.
const APP_LIMIT_SUBQUERY = 1000;
const APP_CACHE_BUSTER = 401;
const APP_VERSION_STABLE = '0.15.1';
const APP_CACHE_BUSTER = 402;
const APP_VERSION_STABLE = '0.15.2';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';

View file

@ -491,8 +491,12 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
$database = new Database(new MariaDB($db), $cache);
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
$database->setNamespace("_console");
$project = Authorization::skip(fn() => $database->getDocument('projects', $realtime->connections[$connection]['projectId']));
$database->setNamespace("_{$project->getInternalId()}");
$projectId = $realtime->connections[$connection]['projectId'];
if ($projectId !== 'console') {
$project = Authorization::skip(fn() => $database->getDocument('projects', $projectId));
$database->setNamespace("_{$project->getInternalId()}");
}
/*
* Abuse Check

View file

@ -83,7 +83,7 @@ $logError = function (Throwable $error, string $action = 'syncUsageStats') use (
$version = App::getEnv('_APP_VERSION', 'UNKNOWN');
$log = new Log();
$log->setNamespace("realtime");
$log->setNamespace("usage");
$log->setServer(\gethostname());
$log->setVersion($version);
$log->setType(Log::TYPE_ERROR);

View file

@ -72,7 +72,7 @@
}
],
"require-dev": {
"appwrite/sdk-generator": "0.19.4",
"appwrite/sdk-generator": "0.19.5",
"phpunit/phpunit": "9.5.20",
"squizlabs/php_codesniffer": "^3.6",
"swoole/ide-helper": "4.8.9",

22
composer.lock generated
View file

@ -236,16 +236,16 @@
},
{
"name": "chillerlan/php-settings-container",
"version": "2.1.3",
"version": "2.1.4",
"source": {
"type": "git",
"url": "https://github.com/chillerlan/php-settings-container.git",
"reference": "125dd573b45ffc7cabecf385986a356ba2c6f602"
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/125dd573b45ffc7cabecf385986a356ba2c6f602",
"reference": "125dd573b45ffc7cabecf385986a356ba2c6f602",
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
"reference": "1beb7df3c14346d4344b0b2e12f6f9a74feabd4a",
"shasum": ""
},
"require": {
@ -296,7 +296,7 @@
"type": "ko_fi"
}
],
"time": "2022-03-09T13:18:58+00:00"
"time": "2022-07-05T22:32:14+00:00"
},
{
"name": "colinmollenhour/credis",
@ -2894,16 +2894,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.19.4",
"version": "0.19.5",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "51a8e4205cd4809deeff8121a24e717642d68564"
"reference": "04de540cf683e2b08b3192c137dde7f2c37003d9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/51a8e4205cd4809deeff8121a24e717642d68564",
"reference": "51a8e4205cd4809deeff8121a24e717642d68564",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/04de540cf683e2b08b3192c137dde7f2c37003d9",
"reference": "04de540cf683e2b08b3192c137dde7f2c37003d9",
"shasum": ""
},
"require": {
@ -2938,9 +2938,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.19.4"
"source": "https://github.com/appwrite/sdk-generator/tree/0.19.5"
},
"time": "2022-06-29T15:19:58+00:00"
"time": "2022-07-06T11:05:57+00:00"
},
{
"name": "doctrine/instantiator",

View file

@ -1 +1 @@
Sends the user an SMS with a secret key for creating a session. Use the returned user ID and secret and submit a request to the [PUT /account/sessions/phone](/docs/client/account#accountUpdatePhoneSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.
Sends the user an SMS with a secret key for creating a session. If the provided user ID has not be registered, a new user will be created. Use the returned user ID and secret and submit a request to the [PUT /account/sessions/phone](/docs/client/account#accountUpdatePhoneSession) endpoint to complete the login process. The secret sent to the user's phone is valid for 15 minutes.

View file

@ -31,12 +31,6 @@ You can also fetch all the collections in your current project using
appwrite init collection
```
The CLI also comes with a convenient `--all` flag to perform both these steps at once.
```sh
appwrite init --all
```
* ### Creating and deploying cloud functions
The CLI makes it extremely easy to create and deploy Appwrite's cloud functions. Initialise your new function using
@ -82,12 +76,6 @@ Similarly, you can deploy all your collections to your Appwrite server using
appwrite deploy collections
```
The `deploy` command also comes with a convenient `--all` flag to deploy all your functions and collections at once.
```sh
appwrite deploy --all
```
> ### Note
> By default, requests to domains with self signed SSL certificates (or no certificates) are disabled. If you trust the domain, you can bypass the certificate validation using
```sh

View file

@ -5,8 +5,8 @@
* **BREAKING** `dateCreated` attribute removed from `Team`, `Execution`, `File` models
* **BREAKING** `dateCreated` and `dateUpdated` attribute removed from `Func`, `Deployment`, `Bucket` models
* **BREAKING** Realtime channels
* collections.[COLLECTION_ID] is now databases.[DATABASE_ID].ollections.[COLLECTION_ID]
* collections.[COLLECTION_ID].documents is now databases.[DATABASE_ID].ollections.[COLLECTION_ID].documents
* collections.[COLLECTION_ID] is now databases.[DATABASE_ID].collections.[COLLECTION_ID]
* collections.[COLLECTION_ID].documents is now databases.[DATABASE_ID].collections.[COLLECTION_ID].documents
**Full Changelog for Appwrite 0.15 can be found here**: https://github.com/appwrite/appwrite/blob/master/CHANGES.md#version-0150

View file

@ -6,8 +6,8 @@
* **BREAKING** `dateCreated` attribute removed from `Team`, `Execution`, `File` models
* **BREAKING** `dateCreated` and `dateUpdated` attribute removed from `Func`, `Deployment`, `Bucket` models
* **BREAKING** Realtime channels
* collections.[COLLECTION_ID] is now databases.[DATABASE_ID].ollections.[COLLECTION_ID]
* collections.[COLLECTION_ID].documents is now databases.[DATABASE_ID].ollections.[COLLECTION_ID].documents
* collections.[COLLECTION_ID] is now databases.[DATABASE_ID].collections.[COLLECTION_ID]
* collections.[COLLECTION_ID].documents is now databases.[DATABASE_ID].collections.[COLLECTION_ID].documents
**Full Changelog for Appwrite 0.15 can be found here**: https://github.com/appwrite/appwrite/blob/master/CHANGES.md#version-0150

View file

@ -46,7 +46,8 @@ abstract class Migration
'0.14.1' => 'V13',
'0.14.2' => 'V13',
'0.15.0' => 'V14',
'0.15.1' => 'V14'
'0.15.1' => 'V14',
'0.15.2' => 'V14'
];
/**

View file

@ -922,6 +922,63 @@ trait DatabasesBase
return ['documents' => $documents['body']['documents'], 'databaseId' => $databaseId];
}
public function testCreateCollectionAlias(): array
{
// Create default database
$database = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => 'default',
'name' => 'Default'
]);
$this->assertNotEmpty($database['body']['$id']);
$this->assertEquals(201, $database['headers']['status-code']);
/**
* Test for SUCCESS
*/
$movies = $this->client->call(Client::METHOD_POST, '/database/collections', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => 'unique()',
'name' => 'Movies',
'read' => [],
'write' => [],
'permission' => 'document',
]);
$this->assertEquals($movies['headers']['status-code'], 201);
$this->assertEquals($movies['body']['name'], 'Movies');
return ['moviesId' => $movies['body']['$id']];
}
/**
* @depends testCreateCollectionAlias
*/
public function testListDocumentsAlias(array $data): array
{
/**
* Test for SUCCESS
*/
$documents = $this->client->call(Client::METHOD_GET, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals($documents['body']['total'], 0);
return [];
}
/**
* @depends testListDocuments
*/
@ -2376,7 +2433,7 @@ trait DatabasesBase
$document = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $moviesId . '/documents/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
], $this->getHeaders()), [
'read' => ['user:' . $this->getUser()['$id']],
]);

View file

@ -13,6 +13,111 @@ class RealtimeConsoleClientTest extends Scope
use ProjectCustom;
use SideConsole;
public function testManualAuthentication()
{
$user = $this->getUser();
$userId = $user['$id'] ?? '';
$session = $user['session'] ?? '';
/**
* Test for SUCCESS
*/
$client = $this->getWebsocket(['account'], [
'origin' => 'http://localhost'
]);
$response = json_decode($client->receive(), true);
$this->assertArrayHasKey('type', $response);
$this->assertArrayHasKey('data', $response);
$this->assertEquals('connected', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertCount(1, $response['data']['channels']);
$this->assertContains('account', $response['data']['channels']);
$client->send(\json_encode([
'type' => 'authentication',
'data' => [
'session' => $session
]
]));
$response = json_decode($client->receive(), true);
$this->assertArrayHasKey('type', $response);
$this->assertArrayHasKey('data', $response);
$this->assertEquals('response', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertEquals('authentication', $response['data']['to']);
$this->assertTrue($response['data']['success']);
$this->assertNotEmpty($response['data']['user']);
$this->assertEquals($userId, $response['data']['user']['$id']);
/**
* Test for FAILURE
*/
$client->send(\json_encode([
'type' => 'authentication',
'data' => [
'session' => 'invalid_session'
]
]));
$response = json_decode($client->receive(), true);
$this->assertArrayHasKey('type', $response);
$this->assertArrayHasKey('data', $response);
$this->assertEquals('error', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertEquals(1003, $response['data']['code']);
$this->assertEquals('Session is not valid.', $response['data']['message']);
$client->send(\json_encode([
'type' => 'authentication',
'data' => []
]));
$response = json_decode($client->receive(), true);
$this->assertArrayHasKey('type', $response);
$this->assertArrayHasKey('data', $response);
$this->assertEquals('error', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertEquals(1003, $response['data']['code']);
$this->assertEquals('Payload is not valid.', $response['data']['message']);
$client->send(\json_encode([
'type' => 'unknown',
'data' => [
'session' => 'invalid_session'
]
]));
$response = json_decode($client->receive(), true);
$this->assertArrayHasKey('type', $response);
$this->assertArrayHasKey('data', $response);
$this->assertEquals('error', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertEquals(1003, $response['data']['code']);
$this->assertEquals('Message type is not valid.', $response['data']['message']);
$client->send(\json_encode([
'test' => '123',
]));
$response = json_decode($client->receive(), true);
$this->assertArrayHasKey('type', $response);
$this->assertArrayHasKey('data', $response);
$this->assertEquals('error', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertEquals(1003, $response['data']['code']);
$this->assertEquals('Message format is not valid.', $response['data']['message']);
$client->close();
}
public function testAttributes()
{
$user = $this->getUser();