Merge branch '0.14.x' of https://github.com/appwrite/appwrite into feat-user-verification-ui
This commit is contained in:
commit
d74c234334
40 changed files with 516 additions and 611 deletions
|
@ -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 node:16.13.2-alpine3.15 as node
|
||||
FROM node:16.14.2-alpine3.15 as node
|
||||
|
||||
WORKDIR /usr/local/src/
|
||||
|
||||
|
@ -30,8 +30,8 @@ ARG DEBUG=false
|
|||
ENV DEBUG=$DEBUG
|
||||
|
||||
ENV PHP_REDIS_VERSION=5.3.7 \
|
||||
PHP_MONGODB_VERSION=1.9.1 \
|
||||
PHP_SWOOLE_VERSION=v4.8.7 \
|
||||
PHP_MONGODB_VERSION=1.13.0 \
|
||||
PHP_SWOOLE_VERSION=v4.8.9 \
|
||||
PHP_IMAGICK_VERSION=3.7.0 \
|
||||
PHP_YAML_VERSION=2.2.2 \
|
||||
PHP_MAXMINDDB_VERSION=v1.11.0
|
||||
|
|
|
@ -2425,7 +2425,7 @@ $collections = [
|
|||
'$id' => 'value',
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'size' => 8,
|
||||
'signed' => false,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
|
|
|
@ -838,6 +838,7 @@ App::put('/v1/account/sessions/magic-url')
|
|||
}
|
||||
|
||||
$user
|
||||
->setAttribute('emailVerification', true)
|
||||
->setAttribute('sessions', $session, Document::SET_TYPE_APPEND)
|
||||
->setAttribute('tokens', $tokens);
|
||||
|
||||
|
@ -868,9 +869,7 @@ App::put('/v1/account/sessions/magic-url')
|
|||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
;
|
||||
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
$countryName = $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown'));
|
||||
|
||||
$session
|
||||
->setAttribute('current', true)
|
||||
|
@ -1013,9 +1012,7 @@ App::post('/v1/account/sessions/anonymous')
|
|||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
;
|
||||
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
$countryName = $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown'));
|
||||
|
||||
$session
|
||||
->setAttribute('current', true)
|
||||
|
@ -1280,15 +1277,13 @@ App::get('/v1/account/sessions/:sessionId')
|
|||
|
||||
$sessions = $user->getAttribute('sessions', []);
|
||||
$sessionId = ($sessionId === 'current')
|
||||
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret)
|
||||
: $sessionId;
|
||||
? Auth::sessionVerify($user->getAttribute('sessions'), Auth::$secret)
|
||||
: $sessionId;
|
||||
|
||||
foreach ($sessions as $session) {/** @var Document $session */
|
||||
if ($sessionId == $session->getId()) {
|
||||
|
||||
$countryName = (isset($countries[strtoupper($session->getAttribute('countryCode'))]))
|
||||
? $countries[strtoupper($session->getAttribute('countryCode'))]
|
||||
: $locale->getText('locale.country.unknown');
|
||||
$countryName = $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown'));
|
||||
|
||||
$session
|
||||
->setAttribute('current', ($session->getAttribute('secret') == Auth::hash(Auth::$secret)))
|
||||
|
@ -1622,7 +1617,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
|
||||
$session
|
||||
->setAttribute('current', true)
|
||||
->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown'))
|
||||
->setAttribute('countryName', $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown')))
|
||||
;
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
|
@ -1806,7 +1801,7 @@ App::delete('/v1/account/sessions')
|
|||
|
||||
$session
|
||||
->setAttribute('current', false)
|
||||
->setAttribute('countryName', (isset($countries[strtoupper($session->getAttribute('countryCode'))])) ? $countries[strtoupper($session->getAttribute('countryCode'))] : $locale->getText('locale.country.unknown'))
|
||||
->setAttribute('countryName', $locale->getText('countries.'.strtolower($session->getAttribute('countryCode')), $locale->getText('locale.country.unknown')))
|
||||
;
|
||||
|
||||
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
|
||||
|
|
|
@ -214,24 +214,6 @@ App::get('/v1/health/queue/logs')
|
|||
$response->dynamic(new Document([ 'size' => Resque::size(Event::AUDITS_QUEUE_NAME) ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/usage')
|
||||
->desc('Get Usage Queue')
|
||||
->groups(['api', 'health'])
|
||||
->label('scope', 'health.read')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'health')
|
||||
->label('sdk.method', 'getQueueUsage')
|
||||
->label('sdk.description', '/docs/references/health/get-queue-usage.md')
|
||||
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||
->label('sdk.response.model', Response::MODEL_HEALTH_QUEUE)
|
||||
->inject('response')
|
||||
->action(function ($response) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
||||
$response->dynamic(new Document([ 'size' => Resque::size(Event::USAGE_QUEUE_NAME) ]), Response::MODEL_HEALTH_QUEUE);
|
||||
}, ['response']);
|
||||
|
||||
App::get('/v1/health/queue/certificates')
|
||||
->desc('Get Certificates Queue')
|
||||
->groups(['api', 'health'])
|
||||
|
|
|
@ -77,6 +77,9 @@ App::post('/v1/projects')
|
|||
}
|
||||
|
||||
$projectId = ($projectId == 'unique()') ? $dbForConsole->getId() : $projectId;
|
||||
if($projectId === 'console') {
|
||||
throw new Exception("'console' is a reserved project.", 400, Exception::PROJECT_RESERVED_PROJECT);
|
||||
}
|
||||
$project = $dbForConsole->createDocument('projects', new Document([
|
||||
'$id' => $projectId == 'unique()' ? $dbForConsole->getId() : $projectId,
|
||||
'$read' => ['team:' . $teamId],
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
CREATE DATABASE IF NOT EXISTS `appwrite` /*!40100 DEFAULT CHARACTER SET utf8mb4 */;
|
||||
|
||||
USE `appwrite`;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `template.abuse.abuse` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`_key` varchar(255) NOT NULL,
|
||||
`_time` int(11) NOT NULL,
|
||||
`_count` int(11) NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `unique1` (`_key`,`_time`),
|
||||
KEY `index1` (`_key`,`_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `template.audit.audit` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`userId` varchar(45) NOT NULL,
|
||||
`event` varchar(45) NOT NULL,
|
||||
`resource` varchar(45) DEFAULT NULL,
|
||||
`userAgent` text NOT NULL,
|
||||
`ip` varchar(45) NOT NULL,
|
||||
`location` varchar(45) DEFAULT NULL,
|
||||
`time` datetime NOT NULL,
|
||||
`data` longtext DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `id_UNIQUE` (`id`),
|
||||
KEY `index_1` (`userId`),
|
||||
KEY `index_2` (`event`),
|
||||
KEY `index_3` (`resource`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `template.database.documents` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Unique ID for each node',
|
||||
`uid` varchar(45) DEFAULT NULL,
|
||||
`status` int(11) NOT NULL DEFAULT 0,
|
||||
`createdAt` datetime DEFAULT NULL,
|
||||
`updatedAt` datetime DEFAULT NULL,
|
||||
`signature` varchar(32) NOT NULL,
|
||||
`revision` varchar(45) NOT NULL,
|
||||
`permissions` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `id_UNIQUE` (`id`),
|
||||
UNIQUE KEY `index2` (`uid`),
|
||||
KEY `index3` (`signature`,`uid`,`revision`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `template.database.properties` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'Primary Key',
|
||||
`documentUid` varchar(45) NOT NULL COMMENT 'Unique UID foreign key',
|
||||
`documentRevision` varchar(45) NOT NULL,
|
||||
`key` varchar(32) NOT NULL COMMENT 'Property key name',
|
||||
`value` text NOT NULL COMMENT 'Value of property',
|
||||
`primitive` varchar(32) NOT NULL COMMENT 'Primitive type of property value',
|
||||
`array` tinyint(4) NOT NULL DEFAULT 0,
|
||||
`order` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `index1` (`documentUid`),
|
||||
KEY `index2` (`key`,`value`(5)),
|
||||
FULLTEXT KEY `index3` (`value`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `template.database.relationships` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`revision` varchar(45) NOT NULL,
|
||||
`start` varchar(45) NOT NULL COMMENT 'Unique UID foreign key',
|
||||
`end` varchar(45) NOT NULL COMMENT 'Unique UID foreign key',
|
||||
`key` varchar(256) NOT NULL,
|
||||
`path` int(11) NOT NULL DEFAULT 0,
|
||||
`array` tinyint(4) NOT NULL DEFAULT 0,
|
||||
`order` int(11) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `relationships_start_nodes_id_idx` (`start`),
|
||||
KEY `relationships_end_nodes_id_idx` (`end`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `template.database.unique` (
|
||||
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`key` varchar(128) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `index1` (`key`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
/* Default App */
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `app_console.database.documents` LIKE `template.database.documents`;
|
||||
CREATE TABLE IF NOT EXISTS `app_console.database.properties` LIKE `template.database.properties`;
|
||||
CREATE TABLE IF NOT EXISTS `app_console.database.relationships` LIKE `template.database.relationships`;
|
||||
CREATE TABLE IF NOT EXISTS `app_console.database.unique` LIKE `template.database.unique`;
|
||||
CREATE TABLE IF NOT EXISTS `app_console.audit.audit` LIKE `template.audit.audit`;
|
||||
CREATE TABLE IF NOT EXISTS `app_console.abuse.abuse` LIKE `template.abuse.abuse`;
|
|
@ -408,7 +408,7 @@ App::post('/v1/execution')
|
|||
->desc('Create an execution')
|
||||
->param('runtimeId', '', new Text(64), 'The runtimeID to execute')
|
||||
->param('vars', [], new Assoc(), 'Environment variables required for the build')
|
||||
->param('data', '{}', new Text(8192), 'Data to be forwarded to the function, this is user specified.', true)
|
||||
->param('data', '', new Text(8192), 'Data to be forwarded to the function, this is user specified.', true)
|
||||
->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Function maximum execution time in seconds.')
|
||||
->inject('activeRuntimes')
|
||||
->inject('response')
|
||||
|
|
|
@ -181,7 +181,7 @@ if(!empty($user) || !empty($pass)) {
|
|||
*/
|
||||
Database::addFilter('casting',
|
||||
function($value) {
|
||||
return json_encode(['value' => $value]);
|
||||
return json_encode(['value' => $value], JSON_PRESERVE_ZERO_FRACTION);
|
||||
},
|
||||
function($value) {
|
||||
if (is_null($value)) {
|
||||
|
|
|
@ -163,28 +163,6 @@ $server->onStart(function () use ($stats, $register, $containerId, &$statsDocume
|
|||
* Save current connections to the Database every 5 seconds.
|
||||
*/
|
||||
Timer::tick(5000, function () use ($register, $stats, &$statsDocument, $logError) {
|
||||
/** @var Document $statsDocument */
|
||||
foreach ($stats as $projectId => $value) {
|
||||
$connections = $stats->get($projectId, 'connections') ?? 0;
|
||||
$messages = $stats->get($projectId, 'messages' ?? 0);
|
||||
|
||||
$usage = new Event('v1-usage', 'UsageV1');
|
||||
$usage
|
||||
->setParam('projectId', $projectId)
|
||||
->setParam('realtimeConnections', $connections)
|
||||
->setParam('realtimeMessages', $messages)
|
||||
->setParam('networkRequestSize', 0)
|
||||
->setParam('networkResponseSize', 0);
|
||||
|
||||
$stats->set($projectId, [
|
||||
'messages' => 0,
|
||||
'connections' => 0
|
||||
]);
|
||||
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$usage->trigger();
|
||||
}
|
||||
}
|
||||
$payload = [];
|
||||
foreach ($stats as $projectId => $value) {
|
||||
$payload[$projectId] = $stats->get($projectId, 'connectionsTotal');
|
||||
|
|
|
@ -418,7 +418,7 @@ $cli
|
|||
|
||||
// Get total storage
|
||||
$dbForProject->setNamespace('_' . $projectId);
|
||||
$storageTotal = $dbForProject->sum('deployments', 'size');
|
||||
$deploymentsTotal = $dbForProject->sum('deployments', 'size');
|
||||
|
||||
$time = (int) (floor(time() / 1800) * 1800); // Time rounded to nearest 30 minutes
|
||||
$id = \md5($time . '_30m_storage.deployments.total'); //Construct unique id for each metric using time, period and metric
|
||||
|
@ -431,14 +431,14 @@ $cli
|
|||
'period' => '30m',
|
||||
'time' => $time,
|
||||
'metric' => 'storage.deployments.total',
|
||||
'value' => $storageTotal,
|
||||
'value' => $deploymentsTotal,
|
||||
'type' => 1,
|
||||
]));
|
||||
} else {
|
||||
$dbForProject->updateDocument(
|
||||
'stats',
|
||||
$document->getId(),
|
||||
$document->setAttribute('value', $storageTotal)
|
||||
$document->setAttribute('value', $deploymentsTotal)
|
||||
);
|
||||
}
|
||||
$time = (int) (floor(time() / 86400) * 86400); // Time rounded to nearest day
|
||||
|
@ -450,14 +450,14 @@ $cli
|
|||
'period' => '1d',
|
||||
'time' => $time,
|
||||
'metric' => 'storage.deployments.total',
|
||||
'value' => $storageTotal,
|
||||
'value' => $deploymentsTotal,
|
||||
'type' => 1,
|
||||
]));
|
||||
} else {
|
||||
$dbForProject->updateDocument(
|
||||
'stats',
|
||||
$document->getId(),
|
||||
$document->setAttribute('value', $storageTotal)
|
||||
$document->setAttribute('value', $deploymentsTotal)
|
||||
);
|
||||
}
|
||||
} catch(\Exception $e) {
|
||||
|
@ -714,7 +714,7 @@ $cli
|
|||
}
|
||||
|
||||
/**
|
||||
* Inserting project level sums for sub collections like storage.total
|
||||
* Inserting project level sums for sub collections like storage.files.total
|
||||
*/
|
||||
foreach ($subCollectionTotals as $subCollection => $count) {
|
||||
$dbForProject->setNamespace("_{$projectId}");
|
||||
|
@ -754,6 +754,44 @@ $cli
|
|||
$dbForProject->updateDocument('stats', $document->getId(),
|
||||
$document->setAttribute('value', $count));
|
||||
}
|
||||
|
||||
// aggregate storage.total = storage.files.total + storage.deployments.total
|
||||
if($metricPrefix === 'storage' && $subCollection === 'files') {
|
||||
$metric = 'storage.total';
|
||||
$time = (int) (floor(time() / 1800) * 1800); // Time rounded to nearest 30 minutes
|
||||
$id = \md5($time . '_30m_' . $metric); //Construct unique id for each metric using time, period and metric
|
||||
$document = $dbForProject->getDocument('stats', $id);
|
||||
if ($document->isEmpty()) {
|
||||
$dbForProject->createDocument('stats', new Document([
|
||||
'$id' => $id,
|
||||
'time' => $time,
|
||||
'period' => '30m',
|
||||
'metric' => $metric,
|
||||
'value' => $count + $deploymentsTotal,
|
||||
'type' => 1,
|
||||
]));
|
||||
} else {
|
||||
$dbForProject->updateDocument('stats', $document->getId(),
|
||||
$document->setAttribute('value', $count + $deploymentsTotal));
|
||||
}
|
||||
|
||||
$time = (int) (floor(time() / 86400) * 86400); // Time rounded to nearest day
|
||||
$id = \md5($time . '_1d_' . $metric); //Construct unique id for each metric using time, period and metric
|
||||
$document = $dbForProject->getDocument('stats', $id);
|
||||
if ($document->isEmpty()) {
|
||||
$dbForProject->createDocument('stats', new Document([
|
||||
'$id' => $id,
|
||||
'time' => $time,
|
||||
'period' => '1d',
|
||||
'metric' => $metric,
|
||||
'value' => $count + $deploymentsTotal,
|
||||
'type' => 1,
|
||||
]));
|
||||
} else {
|
||||
$dbForProject->updateDocument('stats', $document->getId(),
|
||||
$document->setAttribute('value', $count + $deploymentsTotal));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Exception$e) {
|
||||
Console::warning("Failed to save database counters data for project {$collection}: {$e->getMessage()}");
|
||||
|
|
|
@ -621,7 +621,7 @@ $logs = $this->getParam('logs', null);
|
|||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
x-data="{ array: false, required: false, size: null }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
<input type="hidden" name="collectionId" data-ls-bind="{{router.params.id}}" />
|
||||
|
@ -631,7 +631,7 @@ $logs = $this->getParam('logs', null);
|
|||
<div class="text-fade text-size-xs margin-top-negative-small margin-bottom">Allowed Characters A-Z, a-z, 0-9, and non-leading underscore, hyphen and dot</div>
|
||||
|
||||
<label for="string-length">Size</label>
|
||||
<input id="string-length" name="size" type="number" class="margin-bottom" autocomplete="off" required value="255" data-cast-to="integer" />
|
||||
<input id="string-length" name="size" type="number" class="margin-bottom" autocomplete="off" required value="255" data-cast-to="integer" x-model="size" />
|
||||
|
||||
<div class="margin-bottom">
|
||||
<input x-model="required" name="required" class="button switch" type="checkbox" /> Required <span class="tooltip" data-tooltip="Mark whether this is a required attribute"><i class="icon-info-circled"></i></span>
|
||||
|
@ -643,7 +643,7 @@ $logs = $this->getParam('logs', null);
|
|||
|
||||
<label for="xdefault">Default Value</label>
|
||||
<template x-if="!(array || required)">
|
||||
<input name="xdefault" type="text" class="margin-bottom-large" autocomplete="off">
|
||||
<input name="xdefault" type="text" class="margin-bottom-large" autocomplete="off" :maxlength="size">
|
||||
</template>
|
||||
<template x-if="(array || required)">
|
||||
<input name="xdefault" type="text" class="margin-bottom-large" autocomplete="off" disabled value="">
|
||||
|
@ -677,7 +677,7 @@ $logs = $this->getParam('logs', null);
|
|||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
x-data="{ array: false, required: false, min: null, max: null }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
<input type="hidden" name="collectionId" data-ls-bind="{{router.params.id}}" />
|
||||
|
@ -697,18 +697,18 @@ $logs = $this->getParam('logs', null);
|
|||
<div class="row responsive thin">
|
||||
<div class="col span-6 margin-bottom-small">
|
||||
<label for="integer-min">Min</label>
|
||||
<input id="integer-min" type="number" step="1" class="full-width" name="min" autocomplete="off" data-cast-to="integer" />
|
||||
<input id="integer-min" type="number" step="1" class="full-width" name="min" autocomplete="off" data-cast-to="integer" x-model="min" />
|
||||
</div>
|
||||
<div class="col span-6 margin-bottom-small">
|
||||
<label for="integer-max">Max</label>
|
||||
<input id="integer-max" type="number" step="1" class="full-width" name="max" autocomplete="off" data-cast-to="integer" />
|
||||
<input id="integer-max" type="number" step="1" class="full-width" name="max" autocomplete="off" data-cast-to="integer" x-model="max" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="integer-default">Default Value</label>
|
||||
|
||||
<template x-if="!(array || required)">
|
||||
<input name="xdefault" type="number" class="margin-bottom-large" autocomplete="off" data-cast-to="integer">
|
||||
<input name="xdefault" type="number" class="margin-bottom-large" autocomplete="off" data-cast-to="integer" :min="min" :max="max">
|
||||
</template>
|
||||
<template x-if="(array || required)">
|
||||
<input name="xdefault" type="number" class="margin-bottom-large" autocomplete="off" data-cast-to="integer" disabled>
|
||||
|
@ -742,7 +742,7 @@ $logs = $this->getParam('logs', null);
|
|||
data-failure-param-alert-text="Failed to create attribute"
|
||||
data-failure-param-alert-classname="error"
|
||||
@reset="array = required = false"
|
||||
x-data="{ array: false, required: false }">
|
||||
x-data="{ array: false, required: false, min: null, max: null }">
|
||||
|
||||
<input type="hidden" name="projectId" data-ls-bind="{{router.params.project}}" />
|
||||
<input type="hidden" name="collectionId" data-ls-bind="{{router.params.id}}" />
|
||||
|
@ -762,18 +762,18 @@ $logs = $this->getParam('logs', null);
|
|||
<div class="row responsive thin">
|
||||
<div class="col span-6 margin-bottom-small">
|
||||
<label for="float-min">Min</label>
|
||||
<input id="float-min" type="number" class="full-width" name="min" step="any" autocomplete="off" data-cast-to="float" />
|
||||
<input id="float-min" type="number" class="full-width" name="min" step="any" autocomplete="off" data-cast-to="float" x-model="min" />
|
||||
</div>
|
||||
<div class="col span-6 margin-bottom-small">
|
||||
<label for="float-max">Max</label>
|
||||
<input id="float-max" type="number" class="full-width" name="max" step="any" autocomplete="off" data-cast-to="float" />
|
||||
<input id="float-max" type="number" class="full-width" name="max" step="any" autocomplete="off" data-cast-to="float" x-model="max" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<label for="float-default">Default Value</label>
|
||||
|
||||
<template x-if="!(array || required)">
|
||||
<input name="xdefault" type="number" step="any" class="margin-bottom-large" autocomplete="off" data-cast-to="float">
|
||||
<input name="xdefault" type="number" step="any" class="margin-bottom-large" autocomplete="off" data-cast-to="float" :min="min" :max="max">
|
||||
</template>
|
||||
<template x-if="(array || required)">
|
||||
<input name="xdefault" type="number" step="any" class="margin-bottom-large" autocomplete="off" data-cast-to="float" disabled>
|
||||
|
|
|
@ -104,6 +104,8 @@ $logs = $this->getParam('logs', null);
|
|||
:placeholder="attr.default"
|
||||
:name="attr.key"
|
||||
:required="attr.required"
|
||||
:min="attr.min"
|
||||
:max="attr.max"
|
||||
x-model="doc[attr.key]"
|
||||
data-cast-to="integer" />
|
||||
</template>
|
||||
|
@ -114,6 +116,8 @@ $logs = $this->getParam('logs', null);
|
|||
:placeholder="attr.default"
|
||||
:name="attr.key"
|
||||
:required="attr.required"
|
||||
:min="attr.min"
|
||||
:max="attr.max"
|
||||
x-model="doc[attr.key]"
|
||||
data-cast-to="float" />
|
||||
</template>
|
||||
|
@ -131,6 +135,7 @@ $logs = $this->getParam('logs', null);
|
|||
:placeholder="attr.default"
|
||||
:name="attr.key"
|
||||
:required="attr.required"
|
||||
:maxlength="attr.size"
|
||||
x-model="doc[attr.key]"
|
||||
data-cast-to="string"></textarea>
|
||||
</template>
|
||||
|
@ -197,6 +202,8 @@ $logs = $this->getParam('logs', null);
|
|||
:placeholder="attr.default"
|
||||
:name="attr.key"
|
||||
:required="attr.required"
|
||||
:min="attr.min"
|
||||
:max="attr.max"
|
||||
x-model="doc[attr.key][index]"
|
||||
data-cast-to="integer" />
|
||||
</template>
|
||||
|
@ -207,6 +214,8 @@ $logs = $this->getParam('logs', null);
|
|||
:placeholder="attr.default"
|
||||
:name="attr.key"
|
||||
:required="attr.required"
|
||||
:min="attr.min"
|
||||
:max="attr.max"
|
||||
x-model="doc[attr.key][index]"
|
||||
data-cast-to="float" />
|
||||
</template>
|
||||
|
@ -226,6 +235,7 @@ $logs = $this->getParam('logs', null);
|
|||
:placeholder="attr.default"
|
||||
:name="attr.key"
|
||||
:required="attr.required"
|
||||
:maxlength="attr.size"
|
||||
x-model="doc[attr.key][index]"
|
||||
data-cast-to="string"></textarea>
|
||||
</template>
|
||||
|
@ -267,9 +277,9 @@ $logs = $this->getParam('logs', null);
|
|||
:required="attr.required"
|
||||
:name="attr.key"
|
||||
data-cast-to="string">
|
||||
<template x-for="element in attr.elements">
|
||||
<option :disabled="attr.required" selected label=" "></option>
|
||||
<option :disabled="attr.required" selected label=" "></option>
|
||||
|
||||
<template x-for="element in attr.elements">
|
||||
<option
|
||||
:value="element"
|
||||
x-text="element"
|
||||
|
|
|
@ -16,7 +16,7 @@ $image = $this->getParam('image', '');
|
|||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:2.5
|
||||
image: traefik:2.7
|
||||
container_name: appwrite-traefik
|
||||
command:
|
||||
- --providers.file.directory=/storage/config
|
||||
|
|
|
@ -71,6 +71,11 @@ class DatabaseV1 extends Worker
|
|||
$dbForConsole = $this->getConsoleDB();
|
||||
$dbForProject = $this->getProjectDB($projectId);
|
||||
|
||||
/**
|
||||
* Fetch attribute from the database, since with Resque float values are loosing informations.
|
||||
*/
|
||||
$attribute = $dbForProject->getDocument('attributes', $attribute->getId());
|
||||
|
||||
$event = 'database.attributes.update';
|
||||
$collectionId = $collection->getId();
|
||||
$key = $attribute->getAttribute('key', '');
|
||||
|
|
|
@ -56,7 +56,7 @@
|
|||
"utopia-php/image": "0.5.*",
|
||||
"utopia-php/orchestration": "0.4.*",
|
||||
"resque/php-resque": "1.3.6",
|
||||
"matomo/device-detector": "5.0.4",
|
||||
"matomo/device-detector": "6.0.0",
|
||||
"dragonmantank/cron-expression": "3.3.1",
|
||||
"influxdb/influxdb-php": "1.15.2",
|
||||
"phpmailer/phpmailer": "6.6.0",
|
||||
|
@ -72,9 +72,9 @@
|
|||
],
|
||||
"require-dev": {
|
||||
"appwrite/sdk-generator": "0.18.3",
|
||||
"phpunit/phpunit": "9.5.10",
|
||||
"swoole/ide-helper": "4.8.5",
|
||||
"textalk/websocket": "1.5.5",
|
||||
"phpunit/phpunit": "9.5.20",
|
||||
"swoole/ide-helper": "4.8.9",
|
||||
"textalk/websocket": "1.5.7",
|
||||
"vimeo/psalm": "4.13.1"
|
||||
},
|
||||
"provide": {
|
||||
|
|
84
composer.lock
generated
84
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "e0de8d0bba618a46646cf3da1e06a652",
|
||||
"content-hash": "78c5402d7bf745469d0063a9bc955df0",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
|
@ -925,16 +925,16 @@
|
|||
},
|
||||
{
|
||||
"name": "matomo/device-detector",
|
||||
"version": "5.0.4",
|
||||
"version": "6.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/matomo-org/device-detector.git",
|
||||
"reference": "99ea1953fc7f23f785e593ce1499a00586645530"
|
||||
"reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/99ea1953fc7f23f785e593ce1499a00586645530",
|
||||
"reference": "99ea1953fc7f23f785e593ce1499a00586645530",
|
||||
"url": "https://api.github.com/repos/matomo-org/device-detector/zipball/7fc2af3af62bd69e6e3404d561e371a83c112be9",
|
||||
"reference": "7fc2af3af62bd69e6e3404d561e371a83c112be9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -990,7 +990,7 @@
|
|||
"source": "https://github.com/matomo-org/matomo",
|
||||
"wiki": "https://dev.matomo.org/"
|
||||
},
|
||||
"time": "2022-02-18T19:51:56+00:00"
|
||||
"time": "2022-04-11T09:58:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "mongodb/mongodb",
|
||||
|
@ -2250,16 +2250,16 @@
|
|||
},
|
||||
{
|
||||
"name": "utopia-php/framework",
|
||||
"version": "0.19.9",
|
||||
"version": "0.19.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/framework.git",
|
||||
"reference": "4af9fc866edce1b8cff94731fb26c27599118e87"
|
||||
"reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/4af9fc866edce1b8cff94731fb26c27599118e87",
|
||||
"reference": "4af9fc866edce1b8cff94731fb26c27599118e87",
|
||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/65ced168db8f6e188ceeb0d101f57552c3d8b2af",
|
||||
"reference": "65ced168db8f6e188ceeb0d101f57552c3d8b2af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2293,9 +2293,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/framework/issues",
|
||||
"source": "https://github.com/utopia-php/framework/tree/0.19.9"
|
||||
"source": "https://github.com/utopia-php/framework/tree/0.19.20"
|
||||
},
|
||||
"time": "2022-04-14T15:39:47+00:00"
|
||||
"time": "2022-04-14T15:42:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/image",
|
||||
|
@ -4549,16 +4549,16 @@
|
|||
},
|
||||
{
|
||||
"name": "phpunit/phpunit",
|
||||
"version": "9.5.10",
|
||||
"version": "9.5.20",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/phpunit.git",
|
||||
"reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a"
|
||||
"reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a",
|
||||
"reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba",
|
||||
"reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -4574,7 +4574,7 @@
|
|||
"phar-io/version": "^3.0.2",
|
||||
"php": ">=7.3",
|
||||
"phpspec/prophecy": "^1.12.1",
|
||||
"phpunit/php-code-coverage": "^9.2.7",
|
||||
"phpunit/php-code-coverage": "^9.2.13",
|
||||
"phpunit/php-file-iterator": "^3.0.5",
|
||||
"phpunit/php-invoker": "^3.1.1",
|
||||
"phpunit/php-text-template": "^2.0.3",
|
||||
|
@ -4588,7 +4588,7 @@
|
|||
"sebastian/global-state": "^5.0.1",
|
||||
"sebastian/object-enumerator": "^4.0.3",
|
||||
"sebastian/resource-operations": "^3.0.3",
|
||||
"sebastian/type": "^2.3.4",
|
||||
"sebastian/type": "^3.0",
|
||||
"sebastian/version": "^3.0.2"
|
||||
},
|
||||
"require-dev": {
|
||||
|
@ -4636,11 +4636,11 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/phpunit/issues",
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10"
|
||||
"source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://phpunit.de/donate.html",
|
||||
"url": "https://phpunit.de/sponsors.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
|
@ -4648,7 +4648,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-09-25T07:38:51+00:00"
|
||||
"time": "2022-04-01T12:37:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/container",
|
||||
|
@ -5560,28 +5560,28 @@
|
|||
},
|
||||
{
|
||||
"name": "sebastian/type",
|
||||
"version": "2.3.4",
|
||||
"version": "3.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/sebastianbergmann/type.git",
|
||||
"reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914"
|
||||
"reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914",
|
||||
"reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914",
|
||||
"url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
|
||||
"reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.3"
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
"dev-master": "3.0-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -5604,7 +5604,7 @@
|
|||
"homepage": "https://github.com/sebastianbergmann/type",
|
||||
"support": {
|
||||
"issues": "https://github.com/sebastianbergmann/type/issues",
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/2.3.4"
|
||||
"source": "https://github.com/sebastianbergmann/type/tree/3.0.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -5612,7 +5612,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-15T12:49:02+00:00"
|
||||
"time": "2022-03-15T09:54:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "sebastian/version",
|
||||
|
@ -5669,16 +5669,16 @@
|
|||
},
|
||||
{
|
||||
"name": "swoole/ide-helper",
|
||||
"version": "4.8.5",
|
||||
"version": "4.8.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/swoole/ide-helper.git",
|
||||
"reference": "d03c707d4dc803228e93b4884c72949c4d28e8b8"
|
||||
"reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/d03c707d4dc803228e93b4884c72949c4d28e8b8",
|
||||
"reference": "d03c707d4dc803228e93b4884c72949c4d28e8b8",
|
||||
"url": "https://api.github.com/repos/swoole/ide-helper/zipball/8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe",
|
||||
"reference": "8f82ba3b6af04a5bccb97c1654af992d1ee8b0fe",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "library",
|
||||
|
@ -5695,7 +5695,7 @@
|
|||
"description": "IDE help files for Swoole.",
|
||||
"support": {
|
||||
"issues": "https://github.com/swoole/ide-helper/issues",
|
||||
"source": "https://github.com/swoole/ide-helper/tree/4.8.5"
|
||||
"source": "https://github.com/swoole/ide-helper/tree/4.8.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -5707,7 +5707,7 @@
|
|||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-24T22:44:20+00:00"
|
||||
"time": "2022-04-18T20:38:04+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
|
@ -6221,16 +6221,16 @@
|
|||
},
|
||||
{
|
||||
"name": "textalk/websocket",
|
||||
"version": "1.5.5",
|
||||
"version": "1.5.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Textalk/websocket-php.git",
|
||||
"reference": "846542f82658132cd36acb7a7e8ce0f03960c295"
|
||||
"reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Textalk/websocket-php/zipball/846542f82658132cd36acb7a7e8ce0f03960c295",
|
||||
"reference": "846542f82658132cd36acb7a7e8ce0f03960c295",
|
||||
"url": "https://api.github.com/repos/Textalk/websocket-php/zipball/1712325e99b6bf869ccbf9bf41ab749e7328ea46",
|
||||
"reference": "1712325e99b6bf869ccbf9bf41ab749e7328ea46",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -6264,9 +6264,9 @@
|
|||
"description": "WebSocket client and server",
|
||||
"support": {
|
||||
"issues": "https://github.com/Textalk/websocket-php/issues",
|
||||
"source": "https://github.com/Textalk/websocket-php/tree/1.5.5"
|
||||
"source": "https://github.com/Textalk/websocket-php/tree/1.5.7"
|
||||
},
|
||||
"time": "2021-08-07T10:21:40+00:00"
|
||||
"time": "2022-03-29T09:46:59+00:00"
|
||||
},
|
||||
{
|
||||
"name": "theseer/tokenizer",
|
||||
|
@ -6576,5 +6576,5 @@
|
|||
"platform-overrides": {
|
||||
"php": "8.0"
|
||||
},
|
||||
"plugin-api-version": "2.3.0"
|
||||
"plugin-api-version": "2.1.0"
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ version: '3'
|
|||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:2.5
|
||||
image: traefik:2.7
|
||||
<<: *x-logging
|
||||
container_name: appwrite-traefik
|
||||
command:
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Get the number of usage stats that are waiting to be processed in the Appwrite internal queue server.
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -12,7 +12,7 @@
|
|||
"chart.js": "^3.7.1",
|
||||
"markdown-it": "^12.3.2",
|
||||
"pell": "^1.0.6",
|
||||
"prismjs": "^1.27.0",
|
||||
"prismjs": "^1.28.0",
|
||||
"turndown": "^7.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -3566,9 +3566,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/prismjs": {
|
||||
"version": "1.27.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
|
||||
"integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA==",
|
||||
"version": "1.28.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.28.0.tgz",
|
||||
"integrity": "sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
|
@ -7981,9 +7981,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"prismjs": {
|
||||
"version": "1.27.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.27.0.tgz",
|
||||
"integrity": "sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA=="
|
||||
"version": "1.28.0",
|
||||
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.28.0.tgz",
|
||||
"integrity": "sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw=="
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
"chart.js": "^3.7.1",
|
||||
"markdown-it": "^12.3.2",
|
||||
"pell": "^1.0.6",
|
||||
"prismjs": "^1.27.0",
|
||||
"prismjs": "^1.28.0",
|
||||
"turndown": "^7.1.1"
|
||||
}
|
||||
}
|
||||
|
|
4
public/dist/scripts/app-all.js
vendored
4
public/dist/scripts/app-all.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/scripts/app-dep.js
vendored
2
public/dist/scripts/app-dep.js
vendored
File diff suppressed because one or more lines are too long
2
public/dist/scripts/app.js
vendored
2
public/dist/scripts/app.js
vendored
|
@ -696,7 +696,7 @@ if(this.getFile(id)){this.updateFile(id,{name:file.name,completed:false,failed:f
|
|||
target.reset();try{const response=await sdk.storage.createFile(bucketId,fileId,file,read,write,(progress)=>{this.updateFile(id,{id:progress.$id,progress:Math.round(progress.progress),error:"",});id=progress.$id;const file=this.getFile(id)??{};if(file.cancelled===true){throw'USER_CANCELLED';}});const existingFile=this.getFile(id)??{};if(existingFile.cancelled){this.updateFile(id,{id:response.$id,name:response.name,failed:false,});id=response.$id;throw'USER_CANCELLED'}else{this.updateFile(id,{id:response.$id,name:response.name,progress:100,completed:true,failed:false,});id=response.$id;}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));}catch(error){if(error==='USER_CANCELLED'){await sdk.storage.deleteFile(bucketId,id);this.updateFile(id,{cancelled:false,failed:true,});this.removeFile(id);}else{this.updateFile(id,{id:id,failed:true,error:error.message??error});}
|
||||
document.dispatchEvent(new CustomEvent('storage.createFile'));}}});});})(window);(function(window){"use strict";window.ls.view.add({selector:"data-service",controller:function(element,view,container,form,alerts,expression,window){let action=element.dataset["service"];let service=element.dataset["name"]||null;let event=expression.parse(element.dataset["event"]);let confirm=element.dataset["confirm"]||"";let loading=element.dataset["loading"]||"";let loaderId=null;let scope=element.dataset["scope"]||"sdk";let success=element.dataset["success"]||"";let failure=element.dataset["failure"]||"";let running=false;let callbacks={hide:function(){return function(){return element.style.opacity='0';};},reset:function(){return function(){if("FORM"===element.tagName){return element.reset();}
|
||||
throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},3000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;}
|
||||
throw new Error("This callback is only valid for forms");};},alert:function(text,classname){return function(alerts){alerts.add({text:text,class:classname||"success"},6000);};},redirect:function(url){return function(router){if(url==="/console"){window.location=url;return;}
|
||||
router.change(url||"/");};},reload:function(){return function(router){router.reload();};},state:function(keys){let updateQueryString=function(key,value,url){var re=new RegExp("([?&])"+key+"=.*?(&|#|$)(.*)","gi"),hash;if(re.test(url)){if(typeof value!=="undefined"&&value!==null){return url.replace(re,"$1"+key+"="+value+"$2$3");}else{hash=url.split("#");url=hash[0].replace(re,"$1$3").replace(/(&|\?)$/,"");if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];}
|
||||
return url;}}else{if(typeof value!=="undefined"&&value!==null){var separator=url.indexOf("?")!==-1?"&":"?";hash=url.split("#");url=hash[0]+separator+key+"="+value;if(typeof hash[1]!=="undefined"&&hash[1]!==null){url+="#"+hash[1];}
|
||||
return url;}else{return url;}}};keys=keys.split(",").map(element=>element.trim());return function(serviceForm,router,window){let url=window.location.href;keys.map(node=>{node=node.split("=");let key=node[0]||"";let name=node[1]||key;let value=getValue(key,"param",serviceForm);url=updateQueryString(name,value?value:null,url);});if(url!==window.location.href){window.history.pushState({},"",url);router.reset();}};},trigger:function(events){return function(document){events=events.trim().split(",");for(let i=0;i<events.length;i++){if(""===events[i]){continue;}
|
||||
|
|
2
public/dist/styles/default-ltr.css
vendored
2
public/dist/styles/default-ltr.css
vendored
File diff suppressed because one or more lines are too long
2
public/dist/styles/default-rtl.css
vendored
2
public/dist/styles/default-rtl.css
vendored
File diff suppressed because one or more lines are too long
Binary file not shown.
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 208 KiB After Width: | Height: | Size: 507 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 250 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -34,7 +34,7 @@
|
|||
|
||||
alert: function(text, classname) {
|
||||
return function(alerts) {
|
||||
alerts.add({ text: text, class: classname || "success" }, 3000);
|
||||
alerts.add({ text: text, class: classname || "success" }, 6000);
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
[data-views-current="1"] {
|
||||
.scroll-to {
|
||||
opacity: 0!important;
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -96,6 +96,10 @@
|
|||
}
|
||||
}
|
||||
|
||||
[data-views-current]:not([data-views-current="0"]):not([data-views-current="1"]) .upload-box {
|
||||
margin-right: 4rem;
|
||||
}
|
||||
|
||||
.icon-button {
|
||||
--p-icon-button-size:var(--icon-button-size, 20px);
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
@font-face {font-family: "icon";
|
||||
src: url('/fonts/icon.eot?t=1645269945236'); /* IE9*/
|
||||
src: url('/fonts/icon.eot?t=1645269945236#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url("/fonts/icon.woff2?t=1645269945236") format("woff2"),
|
||||
url("/fonts/icon.woff?t=1645269945236") format("woff"),
|
||||
url('/fonts/icon.ttf?t=1645269945236') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||
url('/fonts/icon.svg?t=1645269945236#icon') format('svg'); /* iOS 4.1- */
|
||||
src: url('/fonts/icon.eot?t=1650537780691'); /* IE9*/
|
||||
src: url('/fonts/icon.eot?t=1650537780691#iefix') format('embedded-opentype'), /* IE6-IE8 */
|
||||
url("/fonts/icon.woff2?t=1650537780691") format("woff2"),
|
||||
url("/fonts/icon.woff?t=1650537780691") format("woff"),
|
||||
url('/fonts/icon.ttf?t=1650537780691') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+*/
|
||||
url('/fonts/icon.svg?t=1650537780691#icon') format('svg'); /* iOS 4.1- */
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
@ -17,7 +17,6 @@
|
|||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
text-decoration: inherit;
|
||||
width: 1em;
|
||||
margin-right: .2em;
|
||||
text-align: center;
|
||||
/* opacity: .8; */
|
||||
|
@ -79,101 +78,101 @@
|
|||
.icon-down-open:before { content: "\ea22"; }
|
||||
.icon-download:before { content: "\ea23"; }
|
||||
.icon-edit:before { content: "\ea24"; }
|
||||
.icon-enum:before { content: "\ea25"; }
|
||||
.icon-export:before { content: "\ea26"; }
|
||||
.icon-eye:before { content: "\ea27"; }
|
||||
.icon-facebook:before { content: "\ea28"; }
|
||||
.icon-file:before { content: "\ea29"; }
|
||||
.icon-film:before { content: "\ea2a"; }
|
||||
.icon-filter:before { content: "\ea2b"; }
|
||||
.icon-fire:before { content: "\ea2c"; }
|
||||
.icon-float:before { content: "\ea2d"; }
|
||||
.icon-folder:before { content: "\ea2e"; }
|
||||
.icon-github:before { content: "\ea2f"; }
|
||||
.icon-gitlab:before { content: "\ea30"; }
|
||||
.icon-glasses:before { content: "\ea31"; }
|
||||
.icon-google:before { content: "\ea32"; }
|
||||
.icon-hackernews:before { content: "\ea33"; }
|
||||
.icon-header:before { content: "\ea34"; }
|
||||
.icon-heart:before { content: "\ea35"; }
|
||||
.icon-home:before { content: "\ea36"; }
|
||||
.icon-image:before { content: "\ea37"; }
|
||||
.icon-inbox:before { content: "\ea38"; }
|
||||
.icon-info-circled:before { content: "\ea39"; }
|
||||
.icon-instagram:before { content: "\ea3a"; }
|
||||
.icon-integer:before { content: "\ea3b"; }
|
||||
.icon-ip:before { content: "\ea3c"; }
|
||||
.icon-italic:before { content: "\ea3d"; }
|
||||
.icon-key-inv:before { content: "\ea3e"; }
|
||||
.icon-key:before { content: "\ea3f"; }
|
||||
.icon-keyboard:before { content: "\ea40"; }
|
||||
.icon-lamp:before { content: "\ea41"; }
|
||||
.icon-left-dir:before { content: "\ea42"; }
|
||||
.icon-left-open:before { content: "\ea43"; }
|
||||
.icon-lifebuoy:before { content: "\ea44"; }
|
||||
.icon-lightning:before { content: "\ea45"; }
|
||||
.icon-link-ext:before { content: "\ea46"; }
|
||||
.icon-link:before { content: "\ea47"; }
|
||||
.icon-url:before { content: "\ea47"; }
|
||||
.icon-linkedin:before { content: "\ea48"; }
|
||||
.icon-list-bullet:before { content: "\ea49"; }
|
||||
.icon-list-numbered:before { content: "\ea4a"; }
|
||||
.icon-list:before { content: "\ea4b"; }
|
||||
.icon-location:before { content: "\ea4c"; }
|
||||
.icon-lock:before { content: "\ea4d"; }
|
||||
.icon-login:before { content: "\ea4e"; }
|
||||
.icon-mail:before { content: "\ea4f"; }
|
||||
.icon-email:before { content: "\ea4f"; }
|
||||
.icon-medium:before { content: "\ea50"; }
|
||||
.icon-menu:before { content: "\ea51"; }
|
||||
.icon-minus:before { content: "\ea52"; }
|
||||
.icon-moon-inv:before { content: "\ea53"; }
|
||||
.icon-moon:before { content: "\ea54"; }
|
||||
.icon-more:before { content: "\ea55"; }
|
||||
.icon-network:before { content: "\ea56"; }
|
||||
.icon-ok-circled:before { content: "\ea57"; }
|
||||
.icon-ok:before { content: "\ea58"; }
|
||||
.icon-palette:before { content: "\ea59"; }
|
||||
.icon-pause:before { content: "\ea5a"; }
|
||||
.icon-phone:before { content: "\ea5b"; }
|
||||
.icon-photograph:before { content: "\ea5c"; }
|
||||
.icon-picture:before { content: "\ea5d"; }
|
||||
.icon-pinterest:before { content: "\ea5e"; }
|
||||
.icon-play:before { content: "\ea5f"; }
|
||||
.icon-plus:before { content: "\ea60"; }
|
||||
.icon-qrcode:before { content: "\ea61"; }
|
||||
.icon-question:before { content: "\ea62"; }
|
||||
.icon-quote-right:before { content: "\ea63"; }
|
||||
.icon-random:before { content: "\ea64"; }
|
||||
.icon-reddit:before { content: "\ea65"; }
|
||||
.icon-refresh:before { content: "\ea66"; }
|
||||
.icon-right-dir:before { content: "\ea67"; }
|
||||
.icon-right-open:before { content: "\ea68"; }
|
||||
.icon-rocket:before { content: "\ea69"; }
|
||||
.icon-search:before { content: "\ea6a"; }
|
||||
.icon-shield:before { content: "\ea6b"; }
|
||||
.icon-shuffle:before { content: "\ea6c"; }
|
||||
.icon-smile-o:before { content: "\ea6d"; }
|
||||
.icon-sort:before { content: "\ea6e"; }
|
||||
.icon-stackoverflow:before { content: "\ea6f"; }
|
||||
.icon-stopwatch:before { content: "\ea70"; }
|
||||
.icon-string:before { content: "\ea71"; }
|
||||
.icon-sun-inv:before { content: "\ea72"; }
|
||||
.icon-telegram:before { content: "\ea73"; }
|
||||
.icon-trash-2:before { content: "\ea74"; }
|
||||
.icon-trash:before { content: "\ea75"; }
|
||||
.icon-twitter:before { content: "\ea76"; }
|
||||
.icon-underline:before { content: "\ea77"; }
|
||||
.icon-up-dir:before { content: "\ea78"; }
|
||||
.icon-up-open:before { content: "\ea79"; }
|
||||
.icon-upload:before { content: "\ea7a"; }
|
||||
.icon-user:before { content: "\ea7b"; }
|
||||
.icon-users:before { content: "\ea7c"; }
|
||||
.icon-videocam:before { content: "\ea7d"; }
|
||||
.icon-warning:before { content: "\ea7e"; }
|
||||
.icon-whatsapp:before { content: "\ea7f"; }
|
||||
.icon-wheelchair:before { content: "\ea80"; }
|
||||
.icon-windows:before { content: "\ea81"; }
|
||||
.icon-wrench:before { content: "\ea82"; }
|
||||
.icon-x:before { content: "\ea83"; }
|
||||
.icon-youtube-play:before { content: "\ea84"; }
|
||||
.icon-email:before { content: "\ea25"; }
|
||||
.icon-enum:before { content: "\ea26"; }
|
||||
.icon-export:before { content: "\ea27"; }
|
||||
.icon-eye:before { content: "\ea28"; }
|
||||
.icon-facebook:before { content: "\ea29"; }
|
||||
.icon-file:before { content: "\ea2a"; }
|
||||
.icon-film:before { content: "\ea2b"; }
|
||||
.icon-filter:before { content: "\ea2c"; }
|
||||
.icon-fire:before { content: "\ea2d"; }
|
||||
.icon-float:before { content: "\ea2e"; }
|
||||
.icon-folder:before { content: "\ea2f"; }
|
||||
.icon-github:before { content: "\ea30"; }
|
||||
.icon-gitlab:before { content: "\ea31"; }
|
||||
.icon-glasses:before { content: "\ea32"; }
|
||||
.icon-google:before { content: "\ea33"; }
|
||||
.icon-hackernews:before { content: "\ea34"; }
|
||||
.icon-header:before { content: "\ea35"; }
|
||||
.icon-heart:before { content: "\ea36"; }
|
||||
.icon-home:before { content: "\ea37"; }
|
||||
.icon-image:before { content: "\ea38"; }
|
||||
.icon-inbox:before { content: "\ea39"; }
|
||||
.icon-info-circled:before { content: "\ea3a"; }
|
||||
.icon-instagram:before { content: "\ea3b"; }
|
||||
.icon-integer:before { content: "\ea3c"; }
|
||||
.icon-ip:before { content: "\ea3d"; }
|
||||
.icon-italic:before { content: "\ea3e"; }
|
||||
.icon-key-inv:before { content: "\ea3f"; }
|
||||
.icon-key:before { content: "\ea40"; }
|
||||
.icon-keyboard:before { content: "\ea41"; }
|
||||
.icon-lamp:before { content: "\ea42"; }
|
||||
.icon-left-dir:before { content: "\ea43"; }
|
||||
.icon-left-open:before { content: "\ea44"; }
|
||||
.icon-lifebuoy:before { content: "\ea45"; }
|
||||
.icon-lightning:before { content: "\ea46"; }
|
||||
.icon-link-ext:before { content: "\ea47"; }
|
||||
.icon-link:before { content: "\ea48"; }
|
||||
.icon-linkedin:before { content: "\ea49"; }
|
||||
.icon-list-bullet:before { content: "\ea4a"; }
|
||||
.icon-list-numbered:before { content: "\ea4b"; }
|
||||
.icon-list:before { content: "\ea4c"; }
|
||||
.icon-location:before { content: "\ea4d"; }
|
||||
.icon-lock:before { content: "\ea4e"; }
|
||||
.icon-login:before { content: "\ea4f"; }
|
||||
.icon-mail:before { content: "\ea50"; }
|
||||
.icon-medium:before { content: "\ea51"; }
|
||||
.icon-menu:before { content: "\ea52"; }
|
||||
.icon-minus:before { content: "\ea53"; }
|
||||
.icon-moon-inv:before { content: "\ea54"; }
|
||||
.icon-moon:before { content: "\ea55"; }
|
||||
.icon-more:before { content: "\ea56"; }
|
||||
.icon-network:before { content: "\ea57"; }
|
||||
.icon-ok-circled:before { content: "\ea58"; }
|
||||
.icon-ok:before { content: "\ea59"; }
|
||||
.icon-palette:before { content: "\ea5a"; }
|
||||
.icon-pause:before { content: "\ea5b"; }
|
||||
.icon-phone:before { content: "\ea5c"; }
|
||||
.icon-photograph:before { content: "\ea5d"; }
|
||||
.icon-picture:before { content: "\ea5e"; }
|
||||
.icon-pinterest:before { content: "\ea5f"; }
|
||||
.icon-play:before { content: "\ea60"; }
|
||||
.icon-plus:before { content: "\ea61"; }
|
||||
.icon-qrcode:before { content: "\ea62"; }
|
||||
.icon-question:before { content: "\ea63"; }
|
||||
.icon-quote-right:before { content: "\ea64"; }
|
||||
.icon-random:before { content: "\ea65"; }
|
||||
.icon-reddit:before { content: "\ea66"; }
|
||||
.icon-refresh:before { content: "\ea67"; }
|
||||
.icon-right-dir:before { content: "\ea68"; }
|
||||
.icon-right-open:before { content: "\ea69"; }
|
||||
.icon-rocket:before { content: "\ea6a"; }
|
||||
.icon-search:before { content: "\ea6b"; }
|
||||
.icon-shield:before { content: "\ea6c"; }
|
||||
.icon-shuffle:before { content: "\ea6d"; }
|
||||
.icon-smile-o:before { content: "\ea6e"; }
|
||||
.icon-sort:before { content: "\ea6f"; }
|
||||
.icon-stackoverflow:before { content: "\ea70"; }
|
||||
.icon-stopwatch:before { content: "\ea71"; }
|
||||
.icon-string:before { content: "\ea72"; }
|
||||
.icon-sun-inv:before { content: "\ea73"; }
|
||||
.icon-telegram:before { content: "\ea74"; }
|
||||
.icon-trash-2:before { content: "\ea75"; }
|
||||
.icon-trash:before { content: "\ea76"; }
|
||||
.icon-twitter:before { content: "\ea77"; }
|
||||
.icon-underline:before { content: "\ea78"; }
|
||||
.icon-up-dir:before { content: "\ea79"; }
|
||||
.icon-up-open:before { content: "\ea7a"; }
|
||||
.icon-upload:before { content: "\ea7b"; }
|
||||
.icon-url:before { content: "\ea7c"; }
|
||||
.icon-user:before { content: "\ea7d"; }
|
||||
.icon-users:before { content: "\ea7e"; }
|
||||
.icon-videocam:before { content: "\ea7f"; }
|
||||
.icon-warning:before { content: "\ea80"; }
|
||||
.icon-whatsapp:before { content: "\ea81"; }
|
||||
.icon-wheelchair:before { content: "\ea82"; }
|
||||
.icon-windows:before { content: "\ea83"; }
|
||||
.icon-wrench:before { content: "\ea84"; }
|
||||
.icon-x:before { content: "\ea85"; }
|
||||
.icon-youtube-play:before { content: "\ea86"; }
|
||||
|
|
|
@ -16,9 +16,6 @@ class Event
|
|||
const AUDITS_QUEUE_NAME = 'v1-audits';
|
||||
const AUDITS_CLASS_NAME = 'AuditsV1';
|
||||
|
||||
const USAGE_QUEUE_NAME = 'v1-usage';
|
||||
const USAGE_CLASS_NAME = 'UsageV1';
|
||||
|
||||
const MAILS_QUEUE_NAME = 'v1-mails';
|
||||
const MAILS_CLASS_NAME = 'MailsV1';
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ class Exception extends \Exception
|
|||
const PROJECT_INVALID_SUCCESS_URL = 'project_invalid_success_url';
|
||||
const PROJECT_INVALID_FAILURE_URL = 'project_invalid_failure_url';
|
||||
const PROJECT_MISSING_USER_ID = 'project_missing_user_id';
|
||||
const PROJECT_RESERVED_PROJECT = 'project_reserved_project';
|
||||
|
||||
/** Webhooks */
|
||||
const WEBHOOK_NOT_FOUND = 'webhook_not_found';
|
||||
|
|
|
@ -1279,7 +1279,7 @@ trait AccountBase
|
|||
$expireTime = strpos($lastEmail['text'], 'expire='.$response['body']['expire'], 0);
|
||||
|
||||
$this->assertNotFalse($expireTime);
|
||||
|
||||
|
||||
$secretTest = strpos($lastEmail['text'], 'secret='.$response['body']['secret'], 0);
|
||||
|
||||
$this->assertNotFalse($secretTest);
|
||||
|
@ -1339,6 +1339,7 @@ trait AccountBase
|
|||
{
|
||||
$id = $data['id'] ?? '';
|
||||
$token = $data['token'] ?? '';
|
||||
$email = $data['email'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
|
@ -1361,6 +1362,20 @@ trait AccountBase
|
|||
$sessionId = $response['body']['$id'];
|
||||
$session = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']];
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session,
|
||||
]));
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertIsNumeric($response['body']['registration']);
|
||||
$this->assertEquals($response['body']['email'], $email);
|
||||
$this->assertTrue($response['body']['emailVerification']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
|
|
@ -1428,6 +1428,7 @@ trait DatabaseBase
|
|||
]), [
|
||||
'key' => 'probability',
|
||||
'required' => false,
|
||||
'default' => 0,
|
||||
'min' => 0,
|
||||
'max' => 1,
|
||||
]);
|
||||
|
|
|
@ -146,27 +146,6 @@ class HealthCustomServerTest extends Scope
|
|||
return [];
|
||||
}
|
||||
|
||||
public function testUsageSuccess(): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_GET, '/health/queue/usage', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(200, $response['headers']['status-code']);
|
||||
$this->assertIsInt($response['body']['size']);
|
||||
$this->assertLessThan(200, $response['body']['size']);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function testCertificatesSuccess(): array
|
||||
{
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue