Merge branch '0.14.x' of https://github.com/appwrite/appwrite into feat-new-event-model
This commit is contained in:
commit
12557f7143
10
Dockerfile
10
Dockerfile
|
@ -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/
|
||||
|
||||
|
@ -24,14 +24,14 @@ COPY public /usr/local/src/public
|
|||
RUN npm ci
|
||||
RUN npm run build
|
||||
|
||||
FROM php:8.0.14-cli-alpine3.15 as compile
|
||||
FROM php:8.0.18-cli-alpine3.15 as compile
|
||||
|
||||
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
|
||||
|
@ -123,7 +123,7 @@ RUN \
|
|||
./configure && \
|
||||
make && make install
|
||||
|
||||
FROM php:8.0.14-cli-alpine3.15 as final
|
||||
FROM php:8.0.18-cli-alpine3.15 as final
|
||||
|
||||
LABEL maintainer="team@appwrite.io"
|
||||
|
||||
|
|
|
@ -2425,7 +2425,7 @@ $collections = [
|
|||
'$id' => 'value',
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 0,
|
||||
'size' => 8,
|
||||
'signed' => false,
|
||||
'required' => true,
|
||||
'default' => null,
|
||||
|
|
|
@ -676,7 +676,7 @@ App::post('/v1/account/sessions/magic-url')
|
|||
'emailVerification' => false,
|
||||
'status' => true,
|
||||
'password' => null,
|
||||
'passwordUpdate' => \time(),
|
||||
'passwordUpdate' => 0,
|
||||
'registration' => \time(),
|
||||
'reset' => false,
|
||||
'prefs' => new \stdClass(),
|
||||
|
@ -833,6 +833,7 @@ App::put('/v1/account/sessions/magic-url')
|
|||
}
|
||||
|
||||
$user
|
||||
->setAttribute('emailVerification', true)
|
||||
->setAttribute('sessions', $session, Document::SET_TYPE_APPEND)
|
||||
->setAttribute('tokens', $tokens);
|
||||
|
||||
|
@ -862,9 +863,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)
|
||||
|
@ -942,7 +941,7 @@ App::post('/v1/account/sessions/anonymous')
|
|||
'emailVerification' => false,
|
||||
'status' => true,
|
||||
'password' => null,
|
||||
'passwordUpdate' => \time(),
|
||||
'passwordUpdate' => 0,
|
||||
'registration' => \time(),
|
||||
'reset' => false,
|
||||
'name' => null,
|
||||
|
@ -1008,9 +1007,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)
|
||||
|
@ -1257,10 +1254,7 @@ App::get('/v1/account/sessions/: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)))
|
||||
|
@ -1587,7 +1581,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')) {
|
||||
|
@ -1767,7 +1761,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'])
|
||||
|
|
|
@ -79,6 +79,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')
|
||||
|
|
|
@ -185,7 +185,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
|
||||
|
|
|
@ -75,6 +75,11 @@ class DatabaseV1 extends Worker
|
|||
'collectionId' => $collection->getId(),
|
||||
'attributeId' => $attribute->getId()
|
||||
]);
|
||||
/**
|
||||
* Fetch attribute from the database, since with Resque float values are loosing informations.
|
||||
*/
|
||||
$attribute = $dbForProject->getDocument('attributes', $attribute->getId());
|
||||
|
||||
$collectionId = $collection->getId();
|
||||
$key = $attribute->getAttribute('key', '');
|
||||
$type = $attribute->getAttribute('type', '');
|
||||
|
|
|
@ -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": {
|
||||
|
|
82
composer.lock
generated
82
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",
|
||||
|
|
|
@ -14,7 +14,7 @@ version: '3'
|
|||
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:2.5
|
||||
image: traefik:2.7
|
||||
<<: *x-logging
|
||||
container_name: appwrite-traefik
|
||||
command:
|
||||
|
|
|
@ -1 +1 @@
|
|||
Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth and Team Invites, oldPassword is optional.
|
||||
Update currently logged in user password. For validation, user is required to pass in the new password, and the old password. For users created with OAuth, Team Invites and Magic URL, oldPassword is optional.
|
|
@ -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"; }
|
||||
|
|
|
@ -18,9 +18,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);
|
||||
|
@ -1327,6 +1327,7 @@ trait AccountBase
|
|||
|
||||
$data['token'] = $token;
|
||||
$data['id'] = $userId;
|
||||
$data['email'] = $email;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
@ -1338,6 +1339,7 @@ trait AccountBase
|
|||
{
|
||||
$id = $data['id'] ?? '';
|
||||
$token = $data['token'] ?? '';
|
||||
$email = $data['email'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
|
@ -1357,6 +1359,23 @@ trait AccountBase
|
|||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertNotEmpty($response['body']['userId']);
|
||||
|
||||
$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
|
||||
*/
|
||||
|
@ -1382,6 +1401,102 @@ trait AccountBase
|
|||
|
||||
$this->assertEquals(401, $response['headers']['status-code']);
|
||||
|
||||
|
||||
$data['sessionId'] = $sessionId;
|
||||
$data['session'] = $session;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateSessionWithMagicUrl
|
||||
*/
|
||||
public function testUpdateAccountPasswordWithMagicUrl($data):array
|
||||
{
|
||||
$email = $data['email'] ?? '';
|
||||
$session = $data['session'] ?? '';
|
||||
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session,
|
||||
]), [
|
||||
'password' => 'new-password'
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 200);
|
||||
$this->assertIsArray($response['body']);
|
||||
$this->assertNotEmpty($response['body']);
|
||||
$this->assertNotEmpty($response['body']['$id']);
|
||||
$this->assertIsNumeric($response['body']['registration']);
|
||||
$this->assertEquals($response['body']['email'], $email);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
]), [
|
||||
'email' => $email,
|
||||
'password' => 'new-password',
|
||||
]);
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 201);
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
]));
|
||||
|
||||
$this->assertEquals($response['headers']['status-code'], 401);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', 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'], 400);
|
||||
|
||||
/**
|
||||
* Existing user tries to update password by passing wrong old password -> SHOULD FAIL
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session,
|
||||
]), [
|
||||
'password' => 'new-password',
|
||||
'oldPassword' => 'wrong-password',
|
||||
]);
|
||||
$this->assertEquals($response['headers']['status-code'], 401);
|
||||
|
||||
/**
|
||||
* Existing user tries to update password without passing old password -> SHOULD FAIL
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'cookie' => 'a_session_'.$this->getProject()['$id'].'=' . $session,
|
||||
]), [
|
||||
'password' => 'new-password'
|
||||
]);
|
||||
$this->assertEquals($response['headers']['status-code'], 401);
|
||||
|
||||
$data['password'] = 'new-password';
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
}
|
|
@ -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