Merge branch '1.4.x' of github.com:appwrite/appwrite into disallow-personal-data

This commit is contained in:
Christy Jacob
2023-07-20 01:44:25 +04:00
194 changed files with 701 additions and 107 deletions
+1
View File
@@ -117,6 +117,7 @@
## Changes
- Released `appwrite/console` [2.0.2](https://github.com/appwrite/console/releases/tag/2.0.2)
- Make `region` parameter optional with default for project create [#4763](https://github.com/appwrite/appwrite/pull/4763)
- Add security headers to the console endpoint [#4758](https://github.com/appwrite/appwrite/pull/4758)
## Bugs
- Fix default oauth paths [#4725](https://github.com/appwrite/appwrite/pull/4725)
+12 -1
View File
@@ -1277,6 +1277,17 @@ $collections = [
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('labels'),
'type' => Database::VAR_STRING,
'format' => '',
'size' => 128,
'signed' => true,
'required' => false,
'default' => null,
'array' => true,
'filters' => [],
],
[
'$id' => ID::custom('passwordHistory'),
'type' => Database::VAR_STRING,
@@ -1429,7 +1440,7 @@ $collections = [
'required' => false,
'default' => null,
'array' => false,
'filters' => [],
'filters' => ['userSearch'],
]
],
'indexes' => [
+11 -1
View File
@@ -237,6 +237,11 @@ return [
'description' => 'The invite does not belong to the current user.',
'code' => 401,
],
Exception::TEAM_ALREADY_EXISTS => [
'name' => Exception::TEAM_ALREADY_EXISTS,
'description' => 'Team with requested ID already exists.',
'code' => 409,
],
/** Membership */
Exception::MEMBERSHIP_NOT_FOUND => [
@@ -413,9 +418,14 @@ return [
'description' => 'The document structure is invalid. Please ensure the attributes match the collection definition.',
'code' => 400,
],
Exception::DOCUMENT_MISSING_DATA => [
'name' => Exception::DOCUMENT_MISSING_DATA,
'description' => 'The document data is missing. You must provide the document data.',
'code' => 400,
],
Exception::DOCUMENT_MISSING_PAYLOAD => [
'name' => Exception::DOCUMENT_MISSING_PAYLOAD,
'description' => 'The document payload is missing.',
'description' => 'The document data and permissions are missing. You must provide either the document data or permissions to be updated.',
'code' => 400,
],
Exception::DOCUMENT_ALREADY_EXISTS => [
+2 -2
View File
@@ -285,7 +285,7 @@ return [
[
'key' => 'python',
'name' => 'Python',
'version' => '2.0.0',
'version' => '2.0.2',
'url' => 'https://github.com/appwrite/sdk-for-python',
'package' => 'https://pypi.org/project/appwrite/',
'enabled' => true,
@@ -357,7 +357,7 @@ return [
[
'key' => 'dotnet',
'name' => '.NET',
'version' => '0.4.0',
'version' => '0.4.2',
'url' => 'https://github.com/appwrite/sdk-for-dotnet',
'package' => 'https://www.nuget.org/packages/Appwrite',
'enabled' => true,
+21 -24
View File
@@ -557,7 +557,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), $duration);
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration));
$session = new Document(array_merge([
'$id' => ID::unique(),
@@ -574,13 +574,12 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
'countryCode' => ($record) ? \strtolower($record['country']['iso_code']) : '--',
], $detector->getOS(), $detector->getClient(), $detector->getDevice()));
$isAnonymousUser = Auth::isAnonymousUser($user);
if (empty($user->getAttribute('email'))) {
$user->setAttribute('email', $oauth2->getUserEmail($accessToken));
}
if ($isAnonymousUser) {
$user
->setAttribute('name', $oauth2->getUserName($accessToken))
->setAttribute('email', $oauth2->getUserEmail($accessToken))
;
if (empty($user->getAttribute('name'))) {
$user->setAttribute('name', $oauth2->getUserName($accessToken));
}
$user
@@ -709,7 +708,7 @@ App::post('/v1/account/sessions/magic-url')
}
$loginSecret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM);
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM));
$token = new Document([
'$id' => ID::unique(),
@@ -835,7 +834,7 @@ App::put('/v1/account/sessions/magic-url')
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), $duration);
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration));
$session = new Document(array_merge(
[
@@ -984,7 +983,7 @@ App::post('/v1/account/sessions/phone')
}
$secret = Auth::codeGenerator();
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_PHONE);
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_PHONE));
$token = new Document([
'$id' => ID::unique(),
@@ -1072,7 +1071,7 @@ App::put('/v1/account/sessions/phone')
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), $duration);
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration));
$session = new Document(array_merge(
[
@@ -1224,7 +1223,7 @@ App::post('/v1/account/sessions/anonymous')
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), $duration);
$expire = DateTime::formatTz(DateTime::addSeconds(new \DateTime(), $duration));
$session = new Document(array_merge(
[
@@ -1397,6 +1396,7 @@ App::get('/v1/account/sessions')
$session->setAttribute('countryName', $countryName);
$session->setAttribute('current', ($current == $session->getId()) ? true : false);
$session->setAttribute('expire', DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration)));
$sessions[$key] = $session;
}
@@ -1503,7 +1503,7 @@ App::get('/v1/account/sessions/:sessionId')
$session
->setAttribute('current', ($session->getAttribute('secret') == Auth::hash(Auth::$secret)))
->setAttribute('countryName', $countryName)
->setAttribute('expire', DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration))
->setAttribute('expire', DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration)))
;
return $response->dynamic($session, Response::MODEL_SESSION);
@@ -1539,9 +1539,7 @@ App::patch('/v1/account/name')
->inject('events')
->action(function (string $name, ?\DateTime $requestTimestamp, Response $response, Document $user, Database $dbForProject, Event $events) {
$user
->setAttribute('name', $name)
->setAttribute('search', implode(' ', [$user->getId(), $name, $user->getAttribute('email', ''), $user->getAttribute('phone', '')]));
$user->setAttribute('name', $name);
$user = $dbForProject->withRequestTimestamp($requestTimestamp, fn () => $dbForProject->updateDocument('users', $user->getId(), $user));
@@ -1658,7 +1656,7 @@ App::patch('/v1/account/email')
$user
->setAttribute('email', $email)
->setAttribute('emailVerification', false) // After this user needs to confirm mail again
->setAttribute('search', implode(' ', [$user->getId(), $user->getAttribute('name', ''), $email, $user->getAttribute('phone', '')]));
;
if (empty($passwordUpdate)) {
$user
@@ -1718,7 +1716,7 @@ App::patch('/v1/account/phone')
$user
->setAttribute('phone', $phone)
->setAttribute('phoneVerification', false) // After this user needs to confirm phone number again
->setAttribute('search', implode(' ', [$user->getId(), $user->getAttribute('name', ''), $user->getAttribute('email', ''), $phone]));
;
if (empty($passwordUpdate)) {
$user
@@ -1967,7 +1965,7 @@ App::patch('/v1/account/sessions/:sessionId')
$authDuration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$session->setAttribute('expire', DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration));
$session->setAttribute('expire', DateTime::formatTz(DateTime::addSeconds(new \DateTime($session->getCreatedAt()), $authDuration)));
$events
->setParam('userId', $user->getId())
@@ -2350,7 +2348,7 @@ App::post('/v1/account/verification')
->setBody($body)
->setFrom($from)
->setRecipient($user->getAttribute('email'))
->setName($user->getAttribute('name'))
->setName($user->getAttribute('name') ?? '')
->trigger()
;
@@ -2424,7 +2422,7 @@ App::put('/v1/account/verification')
$dbForProject->deleteCachedDocument('users', $profile->getId());
$events
->setParam('userId', $user->getId())
->setParam('userId', $userId)
->setParam('tokenId', $verificationDocument->getId())
;
@@ -2468,7 +2466,6 @@ App::post('/v1/account/verification/phone')
$roles = Authorization::getRoles();
$isPrivilegedUser = Auth::isPrivilegedUser($roles);
$isAppUser = Auth::isAppUser($roles);
$verificationSecret = Auth::tokenGenerator();
$secret = Auth::codeGenerator();
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_CONFIRM);
@@ -2504,13 +2501,13 @@ App::post('/v1/account/verification/phone')
->setParam('userId', $user->getId())
->setParam('tokenId', $verification->getId())
->setPayload($response->output(
$verification->setAttribute('secret', $verificationSecret),
$verification->setAttribute('secret', $secret),
Response::MODEL_TOKEN
))
;
// Hide secret for clients
$verification->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $verificationSecret : '');
$verification->setAttribute('secret', ($isPrivilegedUser || $isAppUser) ? $secret : '');
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
+10 -10
View File
@@ -328,22 +328,22 @@ function updateAttribute(
}
if ($type === Database::VAR_RELATIONSHIP) {
$options = \array_merge($attribute->getAttribute('options', []), $options);
$attribute->setAttribute('options', $options);
$primaryDocumentOptions = \array_merge($attribute->getAttribute('options', []), $options);
$attribute->setAttribute('options', $primaryDocumentOptions);
$dbForProject->updateRelationship(
collection: $collectionId,
id: $key,
onDelete: $options['onDelete'],
onDelete: $primaryDocumentOptions['onDelete'],
);
if ($options['twoWay']) {
$relatedCollection = $dbForProject->getDocument('database_' . $db->getInternalId(), $options['relatedCollection']);
$relatedAttribute = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey']);
if ($primaryDocumentOptions['twoWay']) {
$relatedCollection = $dbForProject->getDocument('database_' . $db->getInternalId(), $primaryDocumentOptions['relatedCollection']);
$relatedAttribute = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $primaryDocumentOptions['twoWayKey']);
$relatedOptions = \array_merge($relatedAttribute->getAttribute('options'), $options);
$relatedAttribute->setAttribute('options', $relatedOptions);
$dbForProject->updateDocument('attributes', $db->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey'], $relatedAttribute);
$dbForProject->updateDocument('attributes', $db->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $primaryDocumentOptions['twoWayKey'], $relatedAttribute);
$dbForProject->deleteCachedDocument('database_' . $db->getInternalId(), $relatedCollection->getId());
}
} else {
@@ -2631,7 +2631,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
->label('event', 'databases.[databaseId].collections.[collectionId].documents.[documentId].create')
->label('scope', 'documents.write')
->label('audits.event', 'document.create')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}/document/{response.$id}')
->label('usage.metric', 'documents.{scope}.requests.create')
->label('usage.params', ['databaseId:{request.databaseId}', 'collectionId:{request.collectionId}'])
->label('abuse-key', 'ip:{ip},method:{method},url:{url},userId:{userId}')
@@ -2661,7 +2661,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
if (empty($data)) {
throw new Exception(Exception::DOCUMENT_MISSING_PAYLOAD);
throw new Exception(Exception::DOCUMENT_MISSING_DATA);
}
if (isset($data['$id'])) {
+4 -2
View File
@@ -650,11 +650,13 @@ App::post('/v1/functions/:functionId/deployments')
$end = $request->getContentRangeEnd();
$fileSize = $request->getContentRangeSize();
$deploymentId = $request->getHeader('x-appwrite-id', $deploymentId);
if (is_null($start) || is_null($end) || is_null($fileSize)) {
// TODO make `end >= $fileSize` in next breaking version
if (is_null($start) || is_null($end) || is_null($fileSize) || $end > $fileSize) {
throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);
}
if ($end === $fileSize) {
// TODO remove the condition that checks `$end === $fileSize` in next breaking version
if ($end === $fileSize - 1 || $end === $fileSize) {
//if it's a last chunks the chunk size might differ, so we set the $chunks and $chunk to notify it's last chunk
$chunks = $chunk = -1;
} else {
+3 -9
View File
@@ -9,7 +9,7 @@ use Appwrite\Network\Validator\CNAME;
use Utopia\Validator\Domain as DomainValidator;
use Appwrite\Network\Validator\Origin;
use Utopia\Validator\URL;
use Appwrite\Utopia\Database\Validator\CustomId;
use Appwrite\Utopia\Database\Validator\ProjectId;
use Appwrite\Utopia\Response;
use Utopia\Abuse\Adapters\TimeLimit;
use Utopia\App;
@@ -56,7 +56,7 @@ App::post('/v1/projects')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new CustomId(), 'Unique 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('projectId', '', new ProjectId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, and hyphen. Can\'t start with a special char. Max length is 36 chars.')
->param('name', null, new Text(128), 'Project name. Max length: 128 chars.')
->param('teamId', '', new UID(), 'Team unique ID.')
->param('region', App::getEnv('_APP_REGION', 'default'), new Whitelist(array_keys(array_filter(Config::getParam('regions'), fn($config) => !$config['disabled']))), 'Project Region.', true)
@@ -789,17 +789,11 @@ App::delete('/v1/projects/:projectId')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('password', '', new Password(), 'Your user password for confirmation. Must be at least 8 chars.')
->inject('response')
->inject('user')
->inject('dbForConsole')
->inject('deletes')
->action(function (string $projectId, string $password, Response $response, Document $user, Database $dbForConsole, Delete $deletes) {
if (!Auth::passwordVerify($password, $user->getAttribute('password'), $user->getAttribute('hash'), $user->getAttribute('hashOptions'))) { // Double check user password
throw new Exception(Exception::USER_INVALID_CREDENTIALS);
}
->action(function (string $projectId, Response $response, Document $user, Database $dbForConsole, Delete $deletes) {
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
+4 -2
View File
@@ -445,11 +445,13 @@ App::post('/v1/storage/buckets/:bucketId/files')
$end = $request->getContentRangeEnd();
$fileSize = $request->getContentRangeSize();
$fileId = $request->getHeader('x-appwrite-id', $fileId);
if (is_null($start) || is_null($end) || is_null($fileSize)) {
// TODO make `end >= $fileSize` in next breaking version
if (is_null($start) || is_null($end) || is_null($fileSize) || $end > $fileSize) {
throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);
}
if ($end === $fileSize) {
// TODO remove the condition that checks `$end === $fileSize` in next breaking version
if ($end === $fileSize - 1 || $end === $fileSize) {
//if it's a last chunks the chunk size might differ, so we set the $chunks and $chunk to -1 notify it's last chunk
$chunks = $chunk = -1;
} else {
+17 -12
View File
@@ -67,18 +67,23 @@ App::post('/v1/teams')
$isAppUser = Auth::isAppUser(Authorization::getRoles());
$teamId = $teamId == 'unique()' ? ID::unique() : $teamId;
$team = Authorization::skip(fn() => $dbForProject->createDocument('teams', new Document([
'$id' => $teamId,
'$permissions' => [
Permission::read(Role::team($teamId)),
Permission::update(Role::team($teamId, 'owner')),
Permission::delete(Role::team($teamId, 'owner')),
],
'name' => $name,
'total' => ($isPrivilegedUser || $isAppUser) ? 0 : 1,
'prefs' => new \stdClass(),
'search' => implode(' ', [$teamId, $name]),
])));
try {
$team = Authorization::skip(fn() => $dbForProject->createDocument('teams', new Document([
'$id' => $teamId,
'$permissions' => [
Permission::read(Role::team($teamId)),
Permission::update(Role::team($teamId, 'owner')),
Permission::delete(Role::team($teamId, 'owner')),
],
'name' => $name,
'total' => ($isPrivilegedUser || $isAppUser) ? 0 : 1,
'prefs' => new \stdClass(),
'search' => implode(' ', [$teamId, $name]),
])));
} catch (Duplicate $th) {
throw new Exception(Exception::TEAM_ALREADY_EXISTS);
}
if (!$isPrivilegedUser && !$isAppUser) { // Don't add user on server mode
if (!\in_array('owner', $roles)) {
+44 -6
View File
@@ -28,6 +28,7 @@ use Utopia\Database\Validator\UID;
use Utopia\Database\Database;
use Utopia\Database\Query;
use Utopia\Database\Validator\Authorization;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Assoc;
use Utopia\Validator\WhiteList;
use Utopia\Validator\Text;
@@ -73,6 +74,7 @@ function createUser(string $hash, mixed $hashOptions, string $userId, ?string $e
'phone' => $phone,
'phoneVerification' => false,
'status' => true,
'labels' => [],
'password' => $password,
'passwordHistory' => is_null($password) && $passwordHistory === 0 ? [] : [$password],
'passwordUpdate' => (!empty($password)) ? DateTime::now() : null,
@@ -671,6 +673,45 @@ App::patch('/v1/users/:userId/status')
$response->dynamic($user, Response::MODEL_USER);
});
App::put('/v1/users/:userId/labels')
->desc('Update User Labels')
->groups(['api', 'users'])
->label('event', 'users.[userId].update.labels')
->label('scope', 'users.write')
->label('audits.event', 'user.update')
->label('audits.resource', 'user/{response.$id}')
->label('audits.userId', '{response.$id}')
->label('usage.metric', 'users.{scope}.requests.update')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.namespace', 'users')
->label('sdk.method', 'updateLabels')
->label('sdk.description', '/docs/references/users/update-user-labels.md')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_USER)
->param('userId', '', new UID(), 'User ID.')
->param('labels', [], new ArrayList(new Text(36, allowList: [...Text::NUMBERS, ...Text::ALPHABET_UPPER, ...Text::ALPHABET_LOWER]), 5), 'Array of user labels. Replaces the previous labels. Maximum of 5 labels are allowed, each up to 36 alphanumeric characters long.')
->inject('response')
->inject('dbForProject')
->inject('events')
->action(function (string $userId, array $labels, Response $response, Database $dbForProject, Event $events) {
$user = $dbForProject->getDocument('users', $userId);
if ($user->isEmpty()) {
throw new Exception(Exception::USER_NOT_FOUND);
}
$user->setAttribute('labels', (array) \array_values(\array_unique($labels)));
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
$events
->setParam('userId', $user->getId());
$response->dynamic($user, Response::MODEL_USER);
});
App::patch('/v1/users/:userId/verification')
->desc('Update Email Verification')
->groups(['api', 'users'])
@@ -772,10 +813,7 @@ App::patch('/v1/users/:userId/name')
throw new Exception(Exception::USER_NOT_FOUND);
}
$user
->setAttribute('name', $name)
->setAttribute('search', \implode(' ', [$user->getId(), $user->getAttribute('email', ''), $name, $user->getAttribute('phone', '')]));
;
$user->setAttribute('name', $name);
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
@@ -883,7 +921,8 @@ App::patch('/v1/users/:userId/email')
$user
->setAttribute('email', $email)
->setAttribute('emailVerification', false)
->setAttribute('search', \implode(' ', [$user->getId(), $email, $user->getAttribute('name', ''), $user->getAttribute('phone', '')]));
;
try {
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
@@ -927,7 +966,6 @@ App::patch('/v1/users/:userId/phone')
$user
->setAttribute('phone', $number)
->setAttribute('phoneVerification', false)
->setAttribute('search', implode(' ', [$user->getId(), $user->getAttribute('name', ''), $user->getAttribute('email', ''), $number]));
;
try {
+1
View File
@@ -41,6 +41,7 @@ Config::setParam('cookieDomain', 'localhost');
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
App::init()
->groups(['api'])
->inject('utopia')
->inject('request')
->inject('response')
+6 -6
View File
@@ -286,7 +286,7 @@ App::post('/v1/mock/tests/general/upload')
$id = $request->getHeader('x-appwrite-id', '');
$file['size'] = (\is_array($file['size'])) ? $file['size'][0] : $file['size'];
if (is_null($start) || is_null($end) || is_null($size)) {
if (is_null($start) || is_null($end) || is_null($size) || $end >= $size) {
throw new Exception(Exception::GENERAL_MOCK, 'Invalid content-range header');
}
@@ -302,11 +302,11 @@ App::post('/v1/mock/tests/general/upload')
throw new Exception(Exception::GENERAL_MOCK, 'All chunked request must have id header (except first)');
}
if ($end !== $size && $end - $start + 1 !== $chunkSize) {
if ($end !== $size - 1 && $end - $start + 1 !== $chunkSize) {
throw new Exception(Exception::GENERAL_MOCK, 'Chunk size must be 5MB (except last chunk)');
}
if ($end !== $size && $file['size'] !== $chunkSize) {
if ($end !== $size - 1 && $file['size'] !== $chunkSize) {
throw new Exception(Exception::GENERAL_MOCK, 'Wrong chunk size');
}
@@ -314,11 +314,11 @@ App::post('/v1/mock/tests/general/upload')
throw new Exception(Exception::GENERAL_MOCK, 'Chunk size must be 5MB or less');
}
if ($end !== $size) {
if ($end !== $size - 1) {
$response->json([
'$id' => ID::custom('newfileid'),
'chunksTotal' => $file['size'] / $chunkSize,
'chunksUploaded' => $start / $chunkSize
'chunksTotal' => (int) ceil($size / ($end + 1 - $start)),
'chunksUploaded' => ceil($start / $chunkSize) + 1
]);
}
} else {
+13
View File
@@ -1,8 +1,21 @@
<?php
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use Utopia\App;
App::init()
->groups(['web'])
->inject('request')
->inject('response')
->action(function (Request $request, Response $response) {
$response
->addHeader('X-Frame-Options', 'SAMEORIGIN') // Avoid console and homepage from showing in iframes
->addHeader('X-XSS-Protection', '1; mode=block; report=/v1/xss?url=' . \urlencode($request->getURI()))
->addHeader('X-UA-Compatible', 'IE=Edge') // Deny IE browsers from going into quirks mode
;
});
App::get('/console/*')
->alias('/')
->alias('auth/*')
+1 -1
View File
@@ -6,7 +6,7 @@ use Utopia\Config\Config;
App::get('/versions')
->desc('Get Version')
->groups(['web', 'home'])
->groups(['home'])
->label('scope', 'public')
->inject('response')
->action(function (Response $response) {
+24 -1
View File
@@ -457,6 +457,29 @@ Database::addFilter(
}
);
Database::addFilter(
'userSearch',
function (mixed $value, Document $user) {
$searchValues = [
$user->getId(),
$user->getAttribute('email', ''),
$user->getAttribute('name', ''),
$user->getAttribute('phone', '')
];
foreach ($user->getAttribute('labels', []) as $label) {
$searchValues[] = 'label:' . $label;
}
$search = implode(' ', \array_filter($searchValues));
return $search;
},
function (mixed $value) {
return $value;
}
);
/**
* DB Formats
*/
@@ -903,7 +926,7 @@ App::setResource('project', function ($dbForConsole, $request, $console) {
/** @var Utopia\Database\Database $dbForConsole */
/** @var Utopia\Database\Document $console */
$projectId = $request->getParam('project', $request->getHeader('x-appwrite-project', 'console'));
$projectId = $request->getParam('project', $request->getHeader('x-appwrite-project', ''));
if ($projectId === 'console') {
return $console;
Generated
+6 -6
View File
@@ -3029,16 +3029,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.33.7",
"version": "0.33.6",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "9f5db4a637b23879ceacea9ed2d33b0486771ffc"
"reference": "237fe97b68090a244382c36f96482c352880a38c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/9f5db4a637b23879ceacea9ed2d33b0486771ffc",
"reference": "9f5db4a637b23879ceacea9ed2d33b0486771ffc",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/237fe97b68090a244382c36f96482c352880a38c",
"reference": "237fe97b68090a244382c36f96482c352880a38c",
"shasum": ""
},
"require": {
@@ -3074,9 +3074,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.33.7"
"source": "https://github.com/appwrite/sdk-generator/tree/0.33.6"
},
"time": "2023-07-12T12:15:43+00:00"
"time": "2023-07-10T16:27:53+00:00"
},
{
"name": "doctrine/deprecations",
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -11,5 +12,5 @@ var functions = new Functions(client);
Deployment result = await functions.CreateDeployment(
functionId: "[FUNCTION_ID]",
entrypoint: "[ENTRYPOINT]",
code: new File("./path-to-files/image.jpg"),
code: InputFile.FromPath("./path-to-files/image.jpg"),
activate: false);
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()
@@ -1,4 +1,5 @@
using Appwrite;
using Appwrite.Services;
using Appwrite.Models;
var client = new Client()

Some files were not shown because too many files have changed in this diff Show More