diff --git a/CHANGES.md b/CHANGES.md
index 2db32ea4d2..2a38afd407 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -2,6 +2,8 @@
## Bugs
- Fixed nullable values in functions variables [#3885](https://github.com/appwrite/appwrite/pull/3885)
- Fixed migration for audit by migrating the `time` attribute [#4038](https://github.com/appwrite/appwrite/pull/4038)
+- Fixed default value for creating Boolean Attribute [#4040](https://github.com/appwrite/appwrite/pull/4040)
+- Fixed phone authentication code to be hashed in the internal database [#3906](https://github.com/appwrite/appwrite/pull/3906)
# Version 1.0.1
## Bugs
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a8968398bd..1e3c4ce911 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -378,7 +378,7 @@ To run end-2-end tests use:
docker compose exec appwrite test /usr/src/code/tests/e2e
```
-To run end-2-end tests for a spcific service use:
+To run end-2-end tests for a specific service use:
```bash
docker compose exec appwrite test /usr/src/code/tests/e2e/Services/[ServiceName]
diff --git a/README-CN.md b/README-CN.md
index 82908f1425..88c57ddf3d 100644
--- a/README-CN.md
+++ b/README-CN.md
@@ -8,13 +8,16 @@
-
+
+
+[](https://hacktoberfest.appwrite.io)
[](https://appwrite.io/discord?r=Github)
-[](https://hub.docker.com/r/appwrite/appwrite)
-[](https://travis-ci.com/appwrite/appwrite)
+[](https://github.com/appwrite/appwrite/actions)
[](https://twitter.com/appwrite)
-[](docs/tutorials/add-translations.md)
-[](https://store.appwrite.io)
+
+
+
+
[English](README.md) | 简体中文
@@ -128,7 +131,7 @@ docker run -it --rm ,
#### 服务器
* ✅ [NodeJS](https://github.com/appwrite/sdk-for-node) (由 Appwrite 团队维护)
-* ✅ [PHP](https://github.com/appwrite/sdk-for-php) (由 Appwr实验 团队维护)
+* ✅ [PHP](https://github.com/appwrite/sdk-for-php) (由 Appwrite 团队维护)
* ✅ [Dart](https://github.com/appwrite/sdk-for-dart) - (由 Appwrite 团队维护)
* ✅ [Deno](https://github.com/appwrite/sdk-for-deno) - **公测** (由 Appwrite 团队维护)
* ✅ [Ruby](https://github.com/appwrite/sdk-for-ruby) (由 Appwrite 团队维护)
diff --git a/README.md b/README.md
index d7a45ebcb6..bc84adbb64 100644
--- a/README.md
+++ b/README.md
@@ -11,15 +11,17 @@
-
+
+[](https://hacktoberfest.appwrite.io)
[](https://appwrite.io/discord?r=Github)
-[](https://hub.docker.com/r/appwrite/appwrite)
[](https://github.com/appwrite/appwrite/actions)
[](https://twitter.com/appwrite)
-[](docs/tutorials/add-translations.md)
-[](https://store.appwrite.io)
+
+
+
+
English | [简体中文](README-CN.md)
@@ -91,10 +93,10 @@ docker run -it --rm ^
#### PowerShell
```powershell
-docker run -it --rm ,
- --volume /var/run/docker.sock:/var/run/docker.sock ,
- --volume ${pwd}/appwrite:/usr/src/code/appwrite:rw ,
- --entrypoint="install" ,
+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.0.1
```
diff --git a/app/config/events.php b/app/config/events.php
index 0a7d819142..6fe030d4bf 100644
--- a/app/config/events.php
+++ b/app/config/events.php
@@ -1,7 +1,7 @@
'icon-apple',
'enabled' => true,
'sandbox' => false,
- 'form' => 'apple.phtml', // Perperation for adding ability to customized OAuth UI forms, currently handled hardcoded.
+ 'form' => 'apple.phtml', // Preparation for adding ability to customized OAuth UI forms, currently handled hardcoded.
'beta' => true,
'mock' => false,
],
diff --git a/app/controllers/api/account.php b/app/controllers/api/account.php
index 22d90fa3b1..fb91a4517d 100644
--- a/app/controllers/api/account.php
+++ b/app/controllers/api/account.php
@@ -937,7 +937,7 @@ App::post('/v1/account/sessions/phone')
'userId' => $user->getId(),
'userInternalId' => $user->getInternalId(),
'type' => Auth::TOKEN_TYPE_PHONE,
- 'secret' => $secret,
+ 'secret' => Auth::hash($secret),
'expire' => $expire,
'userAgent' => $request->getUserAgent('UNKNOWN'),
'ip' => $request->getIP(),
@@ -2265,7 +2265,7 @@ App::post('/v1/account/verification/phone')
'userId' => $user->getId(),
'userInternalId' => $user->getInternalId(),
'type' => Auth::TOKEN_TYPE_PHONE,
- 'secret' => $secret,
+ 'secret' => Auth::hash($secret),
'expire' => $expire,
'userAgent' => $request->getUserAgent('UNKNOWN'),
'ip' => $request->getIP(),
diff --git a/app/controllers/api/databases.php b/app/controllers/api/databases.php
index a66df37124..5278abae3e 100644
--- a/app/controllers/api/databases.php
+++ b/app/controllers/api/databases.php
@@ -89,11 +89,11 @@ function createAttribute(string $databaseId, string $collectionId, Document $att
}
// Must throw here since dbForProject->createAttribute is performed by db worker
- if ($required && $default) {
+ if ($required && isset($default)) {
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for required attribute');
}
- if ($array && $default) {
+ if ($array && isset($default)) {
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for array attributes');
}
diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php
index 4d6bdf4634..d3a26b414e 100644
--- a/app/controllers/api/functions.php
+++ b/app/controllers/api/functions.php
@@ -935,6 +935,67 @@ App::delete('/v1/functions/:functionId/deployments/:deploymentId')
$response->noContent();
});
+App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
+ ->groups(['api', 'functions'])
+ ->desc('Create Build')
+ ->label('scope', 'functions.write')
+ ->label('event', 'functions.[functionId].deployments.[deploymentId].update')
+ ->label('audits.event', 'deployment.update')
+ ->label('audits.resource', 'function/{request.functionId}')
+ ->label('sdk.auth', [APP_AUTH_TYPE_KEY])
+ ->label('sdk.namespace', 'functions')
+ ->label('sdk.method', 'createBuild')
+ ->label('sdk.description', '/docs/references/functions/create-build.md')
+ ->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
+ ->label('sdk.response.model', Response::MODEL_NONE)
+ ->param('functionId', '', new UID(), 'Function ID.')
+ ->param('deploymentId', '', new UID(), 'Deployment ID.')
+ ->param('buildId', '', new UID(), 'Build unique ID.')
+ ->inject('response')
+ ->inject('dbForProject')
+ ->inject('project')
+ ->inject('events')
+ ->action(function (string $functionId, string $deploymentId, string $buildId, Response $response, Database $dbForProject, Document $project, Event $events) {
+
+ $function = $dbForProject->getDocument('functions', $functionId);
+ $deployment = $dbForProject->getDocument('deployments', $deploymentId);
+
+ if ($function->isEmpty()) {
+ throw new Exception(Exception::FUNCTION_NOT_FOUND);
+ }
+
+ if ($deployment->isEmpty()) {
+ throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
+ }
+
+ $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $buildId));
+
+ if ($build->isEmpty()) {
+ throw new Exception(Exception::BUILD_NOT_FOUND);
+ }
+
+ if ($build->getAttribute('status') !== 'failed') {
+ throw new Exception(Exception::BUILD_IN_PROGRESS, 'Build not failed');
+ }
+
+ $events
+ ->setParam('functionId', $function->getId())
+ ->setParam('deploymentId', $deployment->getId());
+
+ // Retry the build
+ $buildEvent = new Build();
+ $buildEvent
+ ->setType(BUILD_TYPE_RETRY)
+ ->setResource($function)
+ ->setDeployment($deployment)
+ ->setProject($project)
+ ->trigger();
+
+ $response->noContent();
+ });
+
+
+
App::post('/v1/functions/:functionId/executions')
->groups(['api', 'functions'])
->desc('Create Execution')
@@ -1258,65 +1319,6 @@ App::get('/v1/functions/:functionId/executions/:executionId')
$response->dynamic($execution, Response::MODEL_EXECUTION);
});
-App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
- ->groups(['api', 'functions'])
- ->desc('Retry Build')
- ->label('scope', 'functions.write')
- ->label('event', 'functions.[functionId].deployments.[deploymentId].update')
- ->label('audits.event', 'deployment.update')
- ->label('audits.resource', 'function/{request.functionId}')
- ->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
- ->label('sdk.namespace', 'functions')
- ->label('sdk.method', 'retryBuild')
- ->label('sdk.description', '/docs/references/functions/retry-build.md')
- ->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
- ->label('sdk.response.model', Response::MODEL_NONE)
- ->param('functionId', '', new UID(), 'Function ID.')
- ->param('deploymentId', '', new UID(), 'Deployment ID.')
- ->param('buildId', '', new UID(), 'Build unique ID.')
- ->inject('response')
- ->inject('dbForProject')
- ->inject('project')
- ->inject('events')
- ->action(function (string $functionId, string $deploymentId, string $buildId, Response $response, Database $dbForProject, Document $project, Event $events) {
-
- $function = $dbForProject->getDocument('functions', $functionId);
- $deployment = $dbForProject->getDocument('deployments', $deploymentId);
-
- if ($function->isEmpty()) {
- throw new Exception(Exception::FUNCTION_NOT_FOUND);
- }
-
- if ($deployment->isEmpty()) {
- throw new Exception(Exception::DEPLOYMENT_NOT_FOUND);
- }
-
- $build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $buildId));
-
- if ($build->isEmpty()) {
- throw new Exception(Exception::BUILD_NOT_FOUND);
- }
-
- if ($build->getAttribute('status') !== 'failed') {
- throw new Exception(Exception::BUILD_IN_PROGRESS, 'Build not failed');
- }
-
- $events
- ->setParam('functionId', $function->getId())
- ->setParam('deploymentId', $deployment->getId());
-
- // Retry the build
- $buildEvent = new Build();
- $buildEvent
- ->setType(BUILD_TYPE_RETRY)
- ->setResource($function)
- ->setDeployment($deployment)
- ->setProject($project)
- ->trigger();
-
- $response->noContent();
- });
-
// Variables
App::post('/v1/functions/:functionId/variables')
diff --git a/composer.lock b/composer.lock
index 9ec0ea3197..7d676b49d5 100644
--- a/composer.lock
+++ b/composer.lock
@@ -5283,16 +5283,16 @@
},
{
"name": "twig/twig",
- "version": "v3.4.2",
+ "version": "v3.4.3",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077"
+ "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077",
- "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58",
+ "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58",
"shasum": ""
},
"require": {
@@ -5343,7 +5343,7 @@
],
"support": {
"issues": "https://github.com/twigphp/Twig/issues",
- "source": "https://github.com/twigphp/Twig/tree/v3.4.2"
+ "source": "https://github.com/twigphp/Twig/tree/v3.4.3"
},
"funding": [
{
@@ -5355,7 +5355,7 @@
"type": "tidelift"
}
],
- "time": "2022-08-12T06:47:24+00:00"
+ "time": "2022-09-28T08:42:51+00:00"
}
],
"aliases": [],
diff --git a/docker-compose.yml b/docker-compose.yml
index 9dd5b8721f..79a8d218fa 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -760,7 +760,7 @@ services:
# MailCatcher - An SMTP server. Catches all system emails and displays them in a nice UI.
# RequestCatcher - An HTTP server. Catches all system https calls and displays them using a simple HTTP API. Used to debug & tests webhooks and HTTP tasks
# RedisCommander - A nice UI for exploring Redis data
- # Resque - A nice UI for exploring Reddis pub/sub, view the different queues workloads, pending and failed tasks
+ # Resque - A nice UI for exploring Redis pub/sub, view the different queues workloads, pending and failed tasks
# Chronograf - A nice UI for exploring InfluxDB data
# Webgrind - A nice UI for exploring and debugging code-level stuff
diff --git a/phpunit.xml b/phpunit.xml
index 4074fe0f1c..4012c8c276 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -6,7 +6,7 @@
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
- stopOnFailure="true"
+ stopOnFailure="false"
>
diff --git a/src/Appwrite/Auth/Auth.php b/src/Appwrite/Auth/Auth.php
index f4cea0166e..dbe74af0d2 100644
--- a/src/Appwrite/Auth/Auth.php
+++ b/src/Appwrite/Auth/Auth.php
@@ -336,7 +336,7 @@ class Auth
$token->isSet('secret') &&
$token->isSet('expire') &&
$token->getAttribute('type') == Auth::TOKEN_TYPE_PHONE &&
- $token->getAttribute('secret') === $secret &&
+ $token->getAttribute('secret') === self::hash($secret) &&
DateTime::formatTz($token->getAttribute('expire')) >= DateTime::formatTz(DateTime::now())
) {
return (string) $token->getId();
diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php
index a32bbb5e97..d25cfb0d40 100644
--- a/src/Appwrite/Extend/Exception.php
+++ b/src/Appwrite/Extend/Exception.php
@@ -12,7 +12,7 @@ class Exception extends \Exception
* Naming the error types based on the following convention
* _
*
- * Appwrite has the follwing entities:
+ * Appwrite has the following entities:
* - General
* - Users
* - Teams
diff --git a/tests/e2e/Services/Databases/DatabasesBase.php b/tests/e2e/Services/Databases/DatabasesBase.php
index fc3cf161e8..a183325039 100644
--- a/tests/e2e/Services/Databases/DatabasesBase.php
+++ b/tests/e2e/Services/Databases/DatabasesBase.php
@@ -2968,4 +2968,52 @@ trait DatabasesBase
return [];
}
+
+ /**
+ * @depends testCreateDatabase
+ */
+ public function testAttributeBooleanDefault(array $data): void
+ {
+ $databaseId = $data['databaseId'];
+
+ /**
+ * Test for SUCCESS
+ */
+ $collection = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'collectionId' => ID::unique(),
+ 'name' => 'Boolean'
+ ]);
+
+ $this->assertEquals(201, $collection['headers']['status-code']);
+
+ $collectionId = $collection['body']['$id'];
+
+ $true = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'key' => 'true',
+ 'required' => false,
+ 'default' => true
+ ]);
+
+ $this->assertEquals(202, $true['headers']['status-code']);
+
+ $false = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/boolean', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'key' => 'false',
+ 'required' => false,
+ 'default' => false
+ ]);
+
+ $this->assertEquals(202, $false['headers']['status-code']);
+ }
}