mirror of
https://github.com/appwrite/appwrite
synced 2026-05-06 06:48:22 +00:00
Merge remote-tracking branch 'origin/1.8.x' into feat-multi-create
This commit is contained in:
commit
c09c2848af
11 changed files with 63 additions and 12 deletions
|
|
@ -24,9 +24,9 @@ ENV _APP_VERSION=$VERSION \
|
|||
_APP_HOME=https://appwrite.io
|
||||
|
||||
RUN \
|
||||
if [ "$DEBUG" == "true" ]; then \
|
||||
if [ "$DEBUG" == "true" ]; then \
|
||||
apk add boost boost-dev; \
|
||||
fi
|
||||
fi
|
||||
|
||||
WORKDIR /usr/src/code
|
||||
|
||||
|
|
|
|||
Binary file not shown.
BIN
app/assets/dbip/dbip-country-lite-2025-12.mmdb
Normal file
BIN
app/assets/dbip/dbip-country-lite-2025-12.mmdb
Normal file
Binary file not shown.
|
|
@ -681,7 +681,13 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
'metadata' => $metadata,
|
||||
]);
|
||||
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
try {
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::STORAGE_FILE_ALREADY_EXISTS);
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
} else {
|
||||
$file = $file
|
||||
->setAttribute('$permissions', $permissions)
|
||||
|
|
@ -731,6 +737,8 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
|
||||
try {
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getSequence(), $doc);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::STORAGE_FILE_ALREADY_EXISTS);
|
||||
} catch (NotFoundException) {
|
||||
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,14 +117,19 @@ function createUser(Hash $hash, string $userId, ?string $email, ?string $passwor
|
|||
$hashedPassword = null;
|
||||
|
||||
$isHashed = !$hash instanceof Plaintext;
|
||||
|
||||
$defaultHash = new ProofsPassword();
|
||||
if (!empty($password)) {
|
||||
if (!$isHashed) { // Password was never hashed, hash it with the default hash
|
||||
$defaultHash = new ProofsPassword();
|
||||
$hashedPassword = $defaultHash->hash($password);
|
||||
$hash = $defaultHash->getHash();
|
||||
} else {
|
||||
$hashedPassword = $password;
|
||||
}
|
||||
} else {
|
||||
// when password is not provided, plaintext was set as the default hash causing the issue
|
||||
$hash = $defaultHash->getHash();
|
||||
$isHashed = !$hash instanceof Plaintext;
|
||||
}
|
||||
|
||||
$user = new Document([
|
||||
|
|
@ -160,7 +165,7 @@ function createUser(Hash $hash, string $userId, ?string $email, ?string $passwor
|
|||
'emailIsFree' => $emailCanonical?->isFree(),
|
||||
]);
|
||||
|
||||
if (!$isHashed) {
|
||||
if (!$isHashed && !empty($password)) {
|
||||
$hooks->trigger('passwordValidator', [$dbForProject, $project, $plaintextPassword, &$user, true]);
|
||||
}
|
||||
|
||||
|
|
@ -2627,7 +2632,8 @@ App::post('/v1/users/:userId/jwts')
|
|||
$session = \count($sessions) > 0 ? $sessions[\count($sessions) - 1] : new Document();
|
||||
} else {
|
||||
// Find by ID
|
||||
foreach ($sessions as $loopSession) { /** @var Utopia\Database\Document $loopSession */
|
||||
foreach ($sessions as $loopSession) {
|
||||
/** @var Utopia\Database\Document $loopSession */
|
||||
if ($loopSession->getId() == $sessionId) {
|
||||
$session = $loopSession;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1796,7 +1796,8 @@ App::patch('/v1/vcs/github/installations/:installationId/repositories/:repositor
|
|||
throw new Exception(Exception::INSTALLATION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$repository = Authorization::skip(fn () => $dbForPlatform->getDocument('repositories', $repositoryId, [
|
||||
$repository = Authorization::skip(fn () => $dbForPlatform->findOne('repositories', [
|
||||
Query::equal('$id', [$repositoryId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
]));
|
||||
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ $register->set('smtp', function () {
|
|||
return $mail;
|
||||
});
|
||||
$register->set('geodb', function () {
|
||||
return new Reader(__DIR__ . '/../assets/dbip/dbip-country-lite-2024-09.mmdb');
|
||||
return new Reader(__DIR__ . '/../assets/dbip/dbip-country-lite-2025-12.mmdb');
|
||||
});
|
||||
$register->set('passwordsDictionary', function () {
|
||||
$content = \file_get_contents(__DIR__ . '/../assets/security/10k-common-passwords');
|
||||
|
|
|
|||
|
|
@ -849,7 +849,7 @@ $image = $this->getParam('image', '');
|
|||
- _APP_DB_PASS
|
||||
|
||||
appwrite-assistant:
|
||||
image: appwrite/assistant:0.8.3
|
||||
image: appwrite/assistant:0.8.4
|
||||
container_name: appwrite-assistant
|
||||
<<: *x-logging
|
||||
restart: unless-stopped
|
||||
|
|
@ -857,7 +857,7 @@ $image = $this->getParam('image', '');
|
|||
- appwrite
|
||||
environment:
|
||||
- _APP_ASSISTANT_OPENAI_API_KEY
|
||||
|
||||
|
||||
appwrite-browser:
|
||||
image: appwrite/browser:0.3.2
|
||||
container_name: appwrite-browser
|
||||
|
|
|
|||
|
|
@ -951,7 +951,7 @@ services:
|
|||
|
||||
appwrite-assistant:
|
||||
container_name: appwrite-assistant
|
||||
image: appwrite/assistant:0.8.3
|
||||
image: appwrite/assistant:0.8.4
|
||||
networks:
|
||||
- appwrite
|
||||
environment:
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ trait AccountBase
|
|||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => 'console',
|
||||
'x-forwarded-for' => '103.152.127.250' // Test IP for denied access region
|
||||
'x-forwarded-for' => '31.6.14.220' // Test IP for denied access region
|
||||
]), [
|
||||
'userId' => ID::unique(),
|
||||
'email' => $email,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Tests\E2E\Client;
|
|||
use Tests\E2E\Scopes\ProjectCustom;
|
||||
use Tests\E2E\Scopes\Scope;
|
||||
use Tests\E2E\Scopes\SideConsole;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
|
||||
class UsersConsoleClientTest extends Scope
|
||||
{
|
||||
|
|
@ -45,4 +46,39 @@ class UsersConsoleClientTest extends Scope
|
|||
$this->assertIsArray($response['body']['users']);
|
||||
$this->assertIsArray($response['body']['sessions']);
|
||||
}
|
||||
|
||||
public function testCreateUserWithoutPasswordThenSetPassword()
|
||||
{
|
||||
// Create a user with email but without password
|
||||
$userId = ID::unique();
|
||||
$email = $userId . '@example.com';
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/users', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'userId' => $userId,
|
||||
'email' => $email,
|
||||
// no password provided
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $response['headers']['status-code']);
|
||||
$this->assertEquals($userId, $response['body']['$id']);
|
||||
$this->assertEquals($email, $response['body']['email']);
|
||||
$this->assertEmpty($response['body']['password']);
|
||||
|
||||
// Now set the password for that user (console-side)
|
||||
$newPassword = 'NewPass123!';
|
||||
|
||||
$set = $this->client->call(Client::METHOD_PATCH, '/users/' . $userId . '/password', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id']
|
||||
], $this->getHeaders()), [
|
||||
'password' => $newPassword,
|
||||
]);
|
||||
|
||||
$this->assertEquals(200, $set['headers']['status-code']);
|
||||
$this->assertEquals($userId, $set['body']['$id']);
|
||||
$this->assertNotEmpty($set['body']['password']);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue