1
0
Fork 0
mirror of synced 2024-09-20 11:37:45 +12:00

Merge remote-tracking branch 'origin/1.5.x' into 1.5.x

This commit is contained in:
shimon 2024-07-30 18:31:36 +03:00
commit 6d961d0789
17 changed files with 246 additions and 37 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1672,10 +1672,10 @@ App::post('/v1/account/tokens/magic-url')
->inject('queueForEvents') ->inject('queueForEvents')
->inject('queueForMails') ->inject('queueForMails')
->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) { ->action(function (string $userId, string $email, string $url, bool $phrase, Request $request, Response $response, Document $user, Document $project, Database $dbForProject, Locale $locale, Event $queueForEvents, Mail $queueForMails) {
if (empty(System::getEnv('_APP_SMTP_HOST'))) { if (empty(System::getEnv('_APP_SMTP_HOST'))) {
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled'); throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP disabled');
} }
$url = htmlentities($url);
if ($phrase === true) { if ($phrase === true) {
$phrase = Phrase::generate(); $phrase = Phrase::generate();
@ -2860,6 +2860,7 @@ App::post('/v1/account/recovery')
if (empty(System::getEnv('_APP_SMTP_HOST'))) { if (empty(System::getEnv('_APP_SMTP_HOST'))) {
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled'); throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
} }
$url = htmlentities($url);
$roles = Authorization::getRoles(); $roles = Authorization::getRoles();
$isPrivilegedUser = Auth::isPrivilegedUser($roles); $isPrivilegedUser = Auth::isPrivilegedUser($roles);
@ -3123,6 +3124,7 @@ App::post('/v1/account/verification')
throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled'); throw new Exception(Exception::GENERAL_SMTP_DISABLED, 'SMTP Disabled');
} }
$url = htmlentities($url);
if ($user->getAttribute('emailVerification')) { if ($user->getAttribute('emailVerification')) {
throw new Exception(Exception::USER_EMAIL_ALREADY_VERIFIED); throw new Exception(Exception::USER_EMAIL_ALREADY_VERIFIED);
} }

View file

@ -499,6 +499,8 @@ App::get('/v1/functions/:functionId/usage')
str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE), str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE),
str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS),
str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE),
str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_MB_SECONDS),
str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS)
]; ];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
@ -561,6 +563,10 @@ App::get('/v1/functions/:functionId/usage')
'buildsTime' => $usage[$metrics[4]]['data'], 'buildsTime' => $usage[$metrics[4]]['data'],
'executions' => $usage[$metrics[5]]['data'], 'executions' => $usage[$metrics[5]]['data'],
'executionsTime' => $usage[$metrics[6]]['data'], 'executionsTime' => $usage[$metrics[6]]['data'],
'buildsMbSecondsTotal' => $usage[$metrics[7]]['total'],
'buildsMbSeconds' => $usage[$metrics[7]]['data'],
'executionsMbSeconds' => $usage[$metrics[8]]['data'],
'executionsMbSecondsTotal' => $usage[$metrics[8]]['total']
]), Response::MODEL_USAGE_FUNCTION); ]), Response::MODEL_USAGE_FUNCTION);
}); });
@ -591,6 +597,8 @@ App::get('/v1/functions/usage')
METRIC_BUILDS_COMPUTE, METRIC_BUILDS_COMPUTE,
METRIC_EXECUTIONS, METRIC_EXECUTIONS,
METRIC_EXECUTIONS_COMPUTE, METRIC_EXECUTIONS_COMPUTE,
METRIC_BUILDS_MB_SECONDS,
METRIC_EXECUTIONS_MB_SECONDS,
]; ];
Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) { Authorization::skip(function () use ($dbForProject, $days, $metrics, &$stats) {
@ -654,6 +662,10 @@ App::get('/v1/functions/usage')
'buildsTime' => $usage[$metrics[5]]['data'], 'buildsTime' => $usage[$metrics[5]]['data'],
'executions' => $usage[$metrics[6]]['data'], 'executions' => $usage[$metrics[6]]['data'],
'executionsTime' => $usage[$metrics[7]]['data'], 'executionsTime' => $usage[$metrics[7]]['data'],
'buildsMbSecondsTotal' => $usage[$metrics[8]]['total'],
'buildsMbSeconds' => $usage[$metrics[8]]['data'],
'executionsMbSeconds' => $usage[$metrics[9]]['data'],
'executionsMbSecondsTotal' => $usage[$metrics[9]]['total'],
]), Response::MODEL_USAGE_FUNCTIONS); ]), Response::MODEL_USAGE_FUNCTIONS);
}); });
@ -1761,6 +1773,8 @@ App::post('/v1/functions/:functionId/executions')
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1) ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1)
->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project ->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
->addMetric(METRIC_EXECUTIONS_MB_SECONDS, (int)(512 * $execution->getAttribute('duration', 0)))
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS), (int)(512 * $execution->getAttribute('duration', 0)))
; ;
if ($function->getAttribute('logging')) { if ($function->getAttribute('logging')) {

View file

@ -40,6 +40,8 @@ App::get('/v1/project/usage')
$metrics = [ $metrics = [
'total' => [ 'total' => [
METRIC_EXECUTIONS, METRIC_EXECUTIONS,
METRIC_EXECUTIONS_MB_SECONDS,
METRIC_BUILDS_MB_SECONDS,
METRIC_DOCUMENTS, METRIC_DOCUMENTS,
METRIC_DATABASES, METRIC_DATABASES,
METRIC_USERS, METRIC_USERS,
@ -52,7 +54,9 @@ App::get('/v1/project/usage')
METRIC_NETWORK_INBOUND, METRIC_NETWORK_INBOUND,
METRIC_NETWORK_OUTBOUND, METRIC_NETWORK_OUTBOUND,
METRIC_USERS, METRIC_USERS,
METRIC_EXECUTIONS METRIC_EXECUTIONS,
METRIC_EXECUTIONS_MB_SECONDS,
METRIC_BUILDS_MB_SECONDS
] ]
]; ];
@ -161,6 +165,38 @@ App::get('/v1/project/usage')
]; ];
}, $dbForProject->find('functions')); }, $dbForProject->find('functions'));
$executionsMbSecondsBreakdown = array_map(function ($function) use ($dbForProject) {
$id = $function->getId();
$name = $function->getAttribute('name');
$metric = str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS);
$value = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
Query::equal('period', ['inf'])
]);
return [
'resourceId' => $id,
'name' => $name,
'value' => $value['value'] ?? 0,
];
}, $dbForProject->find('functions'));
$buildsMbSecondsBreakdown = array_map(function ($function) use ($dbForProject) {
$id = $function->getId();
$name = $function->getAttribute('name');
$metric = str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_MB_SECONDS);
$value = $dbForProject->findOne('stats', [
Query::equal('metric', [$metric]),
Query::equal('period', ['inf'])
]);
return [
'resourceId' => $id,
'name' => $name,
'value' => $value['value'] ?? 0,
];
}, $dbForProject->find('functions'));
// merge network inbound + outbound // merge network inbound + outbound
$projectBandwidth = []; $projectBandwidth = [];
foreach ($usage[METRIC_NETWORK_INBOUND] as $item) { foreach ($usage[METRIC_NETWORK_INBOUND] as $item) {
@ -188,6 +224,8 @@ App::get('/v1/project/usage')
'users' => ($usage[METRIC_USERS]), 'users' => ($usage[METRIC_USERS]),
'executions' => ($usage[METRIC_EXECUTIONS]), 'executions' => ($usage[METRIC_EXECUTIONS]),
'executionsTotal' => $total[METRIC_EXECUTIONS], 'executionsTotal' => $total[METRIC_EXECUTIONS],
'executionsMbSecondsTotal' => $total[METRIC_EXECUTIONS_MB_SECONDS],
'buildsMbSecondsTotal' => $total[METRIC_BUILDS_MB_SECONDS],
'documentsTotal' => $total[METRIC_DOCUMENTS], 'documentsTotal' => $total[METRIC_DOCUMENTS],
'databasesTotal' => $total[METRIC_DATABASES], 'databasesTotal' => $total[METRIC_DATABASES],
'usersTotal' => $total[METRIC_USERS], 'usersTotal' => $total[METRIC_USERS],
@ -195,6 +233,8 @@ App::get('/v1/project/usage')
'filesStorageTotal' => $total[METRIC_FILES_STORAGE], 'filesStorageTotal' => $total[METRIC_FILES_STORAGE],
'deploymentsStorageTotal' => $total[METRIC_DEPLOYMENTS_STORAGE], 'deploymentsStorageTotal' => $total[METRIC_DEPLOYMENTS_STORAGE],
'executionsBreakdown' => $executionsBreakdown, 'executionsBreakdown' => $executionsBreakdown,
'executionsMbSecondsBreakdown' => $executionsMbSecondsBreakdown,
'buildsMbSecondsBreakdown' => $buildsMbSecondsBreakdown,
'bucketsBreakdown' => $bucketsBreakdown, 'bucketsBreakdown' => $bucketsBreakdown,
'deploymentsStorageBreakdown' => $deploymentsStorageBreakdown, 'deploymentsStorageBreakdown' => $deploymentsStorageBreakdown,
]), Response::MODEL_USAGE_PROJECT); ]), Response::MODEL_USAGE_PROJECT);

View file

@ -401,6 +401,7 @@ App::post('/v1/teams/:teamId/memberships')
$isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
$url = htmlentities($url);
if (empty($url)) { if (empty($url)) {
if (!$isAPIKey && !$isPrivilegedUser) { if (!$isAPIKey && !$isPrivilegedUser) {
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'URL is required'); throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'URL is required');

View file

@ -310,6 +310,8 @@ function router(App $utopia, Database $dbForConsole, callable $getProjectDB, Swo
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1) ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1)
->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project ->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000)) // per project
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) // per function
->addMetric(METRIC_EXECUTIONS_MB_SECONDS, (int)(512 * $execution->getAttribute('duration', 0)))
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS), (int)(512 * $execution->getAttribute('duration', 0)))
; ;
if ($function->getAttribute('logging')) { if ($function->getAttribute('logging')) {

View file

@ -231,15 +231,19 @@ const METRIC_DEPLOYMENTS_STORAGE = 'deployments.storage';
const METRIC_BUILDS = 'builds'; const METRIC_BUILDS = 'builds';
const METRIC_BUILDS_STORAGE = 'builds.storage'; const METRIC_BUILDS_STORAGE = 'builds.storage';
const METRIC_BUILDS_COMPUTE = 'builds.compute'; const METRIC_BUILDS_COMPUTE = 'builds.compute';
const METRIC_BUILDS_MB_SECONDS = 'builds.mbSeconds';
const METRIC_FUNCTION_ID_BUILDS = '{functionInternalId}.builds'; const METRIC_FUNCTION_ID_BUILDS = '{functionInternalId}.builds';
const METRIC_FUNCTION_ID_BUILDS_STORAGE = '{functionInternalId}.builds.storage'; const METRIC_FUNCTION_ID_BUILDS_STORAGE = '{functionInternalId}.builds.storage';
const METRIC_FUNCTION_ID_BUILDS_COMPUTE = '{functionInternalId}.builds.compute'; const METRIC_FUNCTION_ID_BUILDS_COMPUTE = '{functionInternalId}.builds.compute';
const METRIC_FUNCTION_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments'; const METRIC_FUNCTION_ID_DEPLOYMENTS = '{resourceType}.{resourceInternalId}.deployments';
const METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage'; const METRIC_FUNCTION_ID_DEPLOYMENTS_STORAGE = '{resourceType}.{resourceInternalId}.deployments.storage';
const METRIC_FUNCTION_ID_BUILDS_MB_SECONDS = '{functionInternalId}.builds.mbSeconds';
const METRIC_EXECUTIONS = 'executions'; const METRIC_EXECUTIONS = 'executions';
const METRIC_EXECUTIONS_COMPUTE = 'executions.compute'; const METRIC_EXECUTIONS_COMPUTE = 'executions.compute';
const METRIC_EXECUTIONS_MB_SECONDS = 'executions.mbSeconds';
const METRIC_FUNCTION_ID_EXECUTIONS = '{functionInternalId}.executions'; const METRIC_FUNCTION_ID_EXECUTIONS = '{functionInternalId}.executions';
const METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE = '{functionInternalId}.executions.compute'; const METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE = '{functionInternalId}.executions.compute';
const METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS = '{functionInternalId}.executions.mbSeconds';
const METRIC_NETWORK_REQUESTS = 'network.requests'; const METRIC_NETWORK_REQUESTS = 'network.requests';
const METRIC_NETWORK_INBOUND = 'network.inbound'; const METRIC_NETWORK_INBOUND = 'network.inbound';
const METRIC_NETWORK_OUTBOUND = 'network.outbound'; const METRIC_NETWORK_OUTBOUND = 'network.outbound';

56
composer.lock generated
View file

@ -355,16 +355,16 @@
}, },
{ {
"name": "chillerlan/php-settings-container", "name": "chillerlan/php-settings-container",
"version": "2.1.5", "version": "2.1.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/chillerlan/php-settings-container.git", "url": "https://github.com/chillerlan/php-settings-container.git",
"reference": "f705310389264c3578fdd9ffb15aa2cd6d91772e" "reference": "5553558bd381fce5108c6d0343c12e488cfec6bb"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/f705310389264c3578fdd9ffb15aa2cd6d91772e", "url": "https://api.github.com/repos/chillerlan/php-settings-container/zipball/5553558bd381fce5108c6d0343c12e488cfec6bb",
"reference": "f705310389264c3578fdd9ffb15aa2cd6d91772e", "reference": "5553558bd381fce5108c6d0343c12e488cfec6bb",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -372,15 +372,16 @@
"php": "^7.4 || ^8.0" "php": "^7.4 || ^8.0"
}, },
"require-dev": { "require-dev": {
"phan/phan": "^5.4", "phpmd/phpmd": "^2.15",
"phpcsstandards/php_codesniffer": "^3.8", "phpstan/phpstan": "^1.11",
"phpmd/phpmd": "^2.13", "phpstan/phpstan-deprecation-rules": "^1.2",
"phpunit/phpunit": "^9.6" "phpunit/phpunit": "^9.6",
"squizlabs/php_codesniffer": "^3.10"
}, },
"type": "library", "type": "library",
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"chillerlan\\Settings\\": "src/" "chillerlan\\Settings\\": "src"
} }
}, },
"notification-url": "https://packagist.org/downloads/", "notification-url": "https://packagist.org/downloads/",
@ -417,7 +418,7 @@
"type": "ko_fi" "type": "ko_fi"
} }
], ],
"time": "2024-01-05T23:20:55+00:00" "time": "2024-07-17T01:04:28+00:00"
}, },
{ {
"name": "dragonmantank/cron-expression", "name": "dragonmantank/cron-expression",
@ -1719,16 +1720,16 @@
}, },
{ {
"name": "utopia-php/database", "name": "utopia-php/database",
"version": "0.50.0", "version": "0.50.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/database.git", "url": "https://github.com/utopia-php/database.git",
"reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7" "reference": "1745147bef29a9bddf5dd03fd9174ec29e2c26f0"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/database/zipball/ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", "url": "https://api.github.com/repos/utopia-php/database/zipball/1745147bef29a9bddf5dd03fd9174ec29e2c26f0",
"reference": "ce3eaccb2f3bbd34b2b97419836fec633b26b8f7", "reference": "1745147bef29a9bddf5dd03fd9174ec29e2c26f0",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1769,9 +1770,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/database/issues", "issues": "https://github.com/utopia-php/database/issues",
"source": "https://github.com/utopia-php/database/tree/0.50.0" "source": "https://github.com/utopia-php/database/tree/0.50.1"
}, },
"time": "2024-06-21T03:21:42+00:00" "time": "2024-07-26T11:56:05+00:00"
}, },
{ {
"name": "utopia-php/domains", "name": "utopia-php/domains",
@ -2170,16 +2171,16 @@
}, },
{ {
"name": "utopia-php/migration", "name": "utopia-php/migration",
"version": "0.5.1", "version": "0.5.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/utopia-php/migration.git", "url": "https://github.com/utopia-php/migration.git",
"reference": "f0e7ff0a76546de353d1ea1f49605b958d407ed2" "reference": "f18d44d4459f78c292dac9edde856fd156fe497a"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/f0e7ff0a76546de353d1ea1f49605b958d407ed2", "url": "https://api.github.com/repos/utopia-php/migration/zipball/f18d44d4459f78c292dac9edde856fd156fe497a",
"reference": "f0e7ff0a76546de353d1ea1f49605b958d407ed2", "reference": "f18d44d4459f78c292dac9edde856fd156fe497a",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2189,6 +2190,7 @@
"require-dev": { "require-dev": {
"laravel/pint": "1.*", "laravel/pint": "1.*",
"phpunit/phpunit": "9.*", "phpunit/phpunit": "9.*",
"utopia-php/cli": "^0.18.0",
"vlucas/phpdotenv": "5.*" "vlucas/phpdotenv": "5.*"
}, },
"type": "library", "type": "library",
@ -2211,9 +2213,9 @@
], ],
"support": { "support": {
"issues": "https://github.com/utopia-php/migration/issues", "issues": "https://github.com/utopia-php/migration/issues",
"source": "https://github.com/utopia-php/migration/tree/0.5.1" "source": "https://github.com/utopia-php/migration/tree/0.5.2"
}, },
"time": "2024-07-10T05:48:42+00:00" "time": "2024-07-22T09:27:07+00:00"
}, },
{ {
"name": "utopia-php/mongo", "name": "utopia-php/mongo",
@ -3156,16 +3158,16 @@
}, },
{ {
"name": "laravel/pint", "name": "laravel/pint",
"version": "v1.16.2", "version": "v1.17.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/laravel/pint.git", "url": "https://github.com/laravel/pint.git",
"reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca" "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/laravel/pint/zipball/51f1ba679a6afe0315621ad143d788bd7ded0eca", "url": "https://api.github.com/repos/laravel/pint/zipball/4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5",
"reference": "51f1ba679a6afe0315621ad143d788bd7ded0eca", "reference": "4dba80c1de4b81dc4c4fb10ea6f4781495eb29f5",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3218,7 +3220,7 @@
"issues": "https://github.com/laravel/pint/issues", "issues": "https://github.com/laravel/pint/issues",
"source": "https://github.com/laravel/pint" "source": "https://github.com/laravel/pint"
}, },
"time": "2024-07-09T15:58:08+00:00" "time": "2024-07-23T16:40:20+00:00"
}, },
{ {
"name": "matthiasmullie/minify", "name": "matthiasmullie/minify",

View file

@ -543,9 +543,11 @@ class Builds extends Action
->addMetric(METRIC_BUILDS, 1) // per project ->addMetric(METRIC_BUILDS, 1) // per project
->addMetric(METRIC_BUILDS_STORAGE, $build->getAttribute('size', 0)) ->addMetric(METRIC_BUILDS_STORAGE, $build->getAttribute('size', 0))
->addMetric(METRIC_BUILDS_COMPUTE, (int)$build->getAttribute('duration', 0) * 1000) ->addMetric(METRIC_BUILDS_COMPUTE, (int)$build->getAttribute('duration', 0) * 1000)
->addMetric(METRIC_BUILDS_MB_SECONDS, (int)(512 * $build->getAttribute('duration', 0)))
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS), 1) // per function ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS), 1) // per function
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE), $build->getAttribute('size', 0)) ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_STORAGE), $build->getAttribute('size', 0))
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE), (int)$build->getAttribute('duration', 0) * 1000) ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_COMPUTE), (int)$build->getAttribute('duration', 0) * 1000)
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_BUILDS_MB_SECONDS), (int)(512 * $build->getAttribute('duration', 0)))
->setProject($project) ->setProject($project)
->trigger(); ->trigger();
} }

View file

@ -507,6 +507,8 @@ class Functions extends Action
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1) ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS), 1)
->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000))// per project ->addMetric(METRIC_EXECUTIONS_COMPUTE, (int)($execution->getAttribute('duration') * 1000))// per project
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000)) ->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_COMPUTE), (int)($execution->getAttribute('duration') * 1000))
->addMetric(METRIC_EXECUTIONS_MB_SECONDS, (int)(512 * $execution->getAttribute('duration', 0)))
->addMetric(str_replace('{functionInternalId}', $function->getInternalId(), METRIC_FUNCTION_ID_EXECUTIONS_MB_SECONDS), (int)(512 * $execution->getAttribute('duration', 0)))
->trigger() ->trigger()
; ;
} }

View file

@ -46,6 +46,12 @@ class UsageFunction extends Model
'default' => 0, 'default' => 0,
'example' => 0, 'example' => 0,
]) ])
->addRule('buildsMbSecondsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated sum of function builds mbSeconds.',
'default' => 0,
'example' => 0,
])
->addRule('executionsTotal', [ ->addRule('executionsTotal', [
'type' => self::TYPE_INTEGER, 'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated number of function executions.', 'description' => 'Total aggregated number of function executions.',
@ -58,6 +64,12 @@ class UsageFunction extends Model
'default' => 0, 'default' => 0,
'example' => 0, 'example' => 0,
]) ])
->addRule('executionsMbSecondsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated sum of function executions mbSeconds.',
'default' => 0,
'example' => 0,
])
->addRule('deployments', [ ->addRule('deployments', [
'type' => Response::MODEL_METRIC, 'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of function deployments per period.', 'description' => 'Aggregated number of function deployments per period.',
@ -93,6 +105,13 @@ class UsageFunction extends Model
'example' => [], 'example' => [],
'array' => true 'array' => true
]) ])
->addRule('buildsMbSeconds', [
'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of function builds mbSeconds per period.',
'default' => [],
'example' => [],
'array' => true
])
->addRule('executions', [ ->addRule('executions', [
'type' => Response::MODEL_METRIC, 'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of function executions per period.', 'description' => 'Aggregated number of function executions per period.',
@ -108,6 +127,13 @@ class UsageFunction extends Model
'example' => [], 'example' => [],
'array' => true 'array' => true
]) ])
->addRule('executionsMbSeconds', [
'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of function mbSeconds per period.',
'default' => [],
'example' => [],
'array' => true
])
; ;
} }

View file

@ -52,6 +52,12 @@ class UsageFunctions extends Model
'default' => 0, 'default' => 0,
'example' => 0, 'example' => 0,
]) ])
->addRule('buildsMbSecondsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated sum of functions build mbSeconds.',
'default' => 0,
'example' => 0,
])
->addRule('executionsTotal', [ ->addRule('executionsTotal', [
'type' => self::TYPE_INTEGER, 'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated number of functions execution.', 'description' => 'Total aggregated number of functions execution.',
@ -64,6 +70,12 @@ class UsageFunctions extends Model
'default' => 0, 'default' => 0,
'example' => 0, 'example' => 0,
]) ])
->addRule('executionsMbSecondsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated sum of functions execution mbSeconds.',
'default' => 0,
'example' => 0,
])
->addRule('functions', [ ->addRule('functions', [
'type' => Response::MODEL_METRIC, 'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of functions per period.', 'description' => 'Aggregated number of functions per period.',
@ -106,6 +118,13 @@ class UsageFunctions extends Model
'example' => [], 'example' => [],
'array' => true 'array' => true
]) ])
->addRule('buildsMbSeconds', [
'type' => Response::MODEL_METRIC,
'description' => 'Aggregated sum of functions build mbSeconds per period.',
'default' => [],
'example' => [],
'array' => true
])
->addRule('executions', [ ->addRule('executions', [
'type' => Response::MODEL_METRIC, 'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of functions execution per period.', 'description' => 'Aggregated number of functions execution per period.',
@ -121,6 +140,13 @@ class UsageFunctions extends Model
'example' => [], 'example' => [],
'array' => true 'array' => true
]) ])
->addRule('executionsMbSeconds', [
'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of functions mbSeconds per period.',
'default' => [],
'example' => [],
'array' => true
])
; ;
} }

View file

@ -52,6 +52,18 @@ class UsageProject extends Model
'default' => 0, 'default' => 0,
'example' => 0, 'example' => 0,
]) ])
->addRule('executionsMbSecondsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated number of function executions mbSeconds.',
'default' => 0,
'example' => 0,
])
->addRule('buildsMbSecondsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated number of function builds mbSeconds.',
'default' => 0,
'example' => 0,
])
->addRule('requests', [ ->addRule('requests', [
'type' => Response::MODEL_METRIC, 'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of requests per period.', 'description' => 'Aggregated number of requests per period.',
@ -94,6 +106,20 @@ class UsageProject extends Model
'example' => [], 'example' => [],
'array' => true 'array' => true
]) ])
->addRule('executionsMbSecondsBreakdown', [
'type' => Response::MODEL_METRIC_BREAKDOWN,
'description' => 'Aggregated breakdown in totals of execution mbSeconds by functions.',
'default' => [],
'example' => [],
'array' => true
])
->addRule('buildsMbSecondsBreakdown', [
'type' => Response::MODEL_METRIC_BREAKDOWN,
'description' => 'Aggregated breakdown in totals of build mbSeconds by functions.',
'default' => [],
'example' => [],
'array' => true
])
->addRule('deploymentsStorageBreakdown', [ ->addRule('deploymentsStorageBreakdown', [
'type' => Response::MODEL_METRIC_BREAKDOWN, 'type' => Response::MODEL_METRIC_BREAKDOWN,
'description' => 'Aggregated breakdown in totals of deployments storage size (in bytes).', 'description' => 'Aggregated breakdown in totals of deployments storage size (in bytes).',

View file

@ -140,7 +140,7 @@ class UsageTest extends Scope
); );
$this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(14, count($response['body'])); $this->assertEquals(18, count($response['body']));
$this->validateDates($response['body']['network']); $this->validateDates($response['body']['network']);
$this->validateDates($response['body']['requests']); $this->validateDates($response['body']['requests']);
$this->validateDates($response['body']['users']); $this->validateDates($response['body']['users']);
@ -321,7 +321,7 @@ class UsageTest extends Scope
] ]
); );
$this->assertEquals(14, count($response['body'])); $this->assertEquals(18, count($response['body']));
$this->assertEquals(1, count($response['body']['requests'])); $this->assertEquals(1, count($response['body']['requests']));
$this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']); $this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']);
$this->validateDates($response['body']['requests']); $this->validateDates($response['body']['requests']);
@ -542,7 +542,7 @@ class UsageTest extends Scope
] ]
); );
$this->assertEquals(14, count($response['body'])); $this->assertEquals(18, count($response['body']));
$this->assertEquals(1, count($response['body']['requests'])); $this->assertEquals(1, count($response['body']['requests']));
$this->assertEquals(1, count($response['body']['network'])); $this->assertEquals(1, count($response['body']['network']));
$this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']); $this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']);
@ -774,15 +774,19 @@ class UsageTest extends Scope
); );
$this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(15, count($response['body'])); $this->assertEquals(19, count($response['body']));
$this->assertEquals('30d', $response['body']['range']); $this->assertEquals('30d', $response['body']['range']);
$this->assertIsArray($response['body']['deployments']); $this->assertIsArray($response['body']['deployments']);
$this->assertIsArray($response['body']['deploymentsStorage']); $this->assertIsArray($response['body']['deploymentsStorage']);
$this->assertIsNumeric($response['body']['deploymentsStorageTotal']); $this->assertIsNumeric($response['body']['deploymentsStorageTotal']);
$this->assertIsNumeric($response['body']['buildsMbSecondsTotal']);
$this->assertIsNumeric($response['body']['executionsMbSecondsTotal']);
$this->assertIsArray($response['body']['builds']); $this->assertIsArray($response['body']['builds']);
$this->assertIsArray($response['body']['buildsTime']); $this->assertIsArray($response['body']['buildsTime']);
$this->assertIsArray($response['body']['buildsMbSeconds']);
$this->assertIsArray($response['body']['executions']); $this->assertIsArray($response['body']['executions']);
$this->assertIsArray($response['body']['executionsTime']); $this->assertIsArray($response['body']['executionsTime']);
$this->assertIsArray($response['body']['executionsMbSeconds']);
$this->assertEquals($executions, $response['body']['executions'][array_key_last($response['body']['executions'])]['value']); $this->assertEquals($executions, $response['body']['executions'][array_key_last($response['body']['executions'])]['value']);
$this->validateDates($response['body']['executions']); $this->validateDates($response['body']['executions']);
$this->assertEquals($executionTime, $response['body']['executionsTime'][array_key_last($response['body']['executionsTime'])]['value']); $this->assertEquals($executionTime, $response['body']['executionsTime'][array_key_last($response['body']['executionsTime'])]['value']);
@ -795,15 +799,17 @@ class UsageTest extends Scope
); );
$this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(17, count($response['body'])); $this->assertEquals(21, count($response['body']));
$this->assertEquals($response['body']['range'], '30d'); $this->assertEquals($response['body']['range'], '30d');
$this->assertIsArray($response['body']['functions']); $this->assertIsArray($response['body']['functions']);
$this->assertIsArray($response['body']['deployments']); $this->assertIsArray($response['body']['deployments']);
$this->assertIsArray($response['body']['deploymentsStorage']); $this->assertIsArray($response['body']['deploymentsStorage']);
$this->assertIsArray($response['body']['builds']); $this->assertIsArray($response['body']['builds']);
$this->assertIsArray($response['body']['buildsTime']); $this->assertIsArray($response['body']['buildsTime']);
$this->assertIsArray($response['body']['buildsMbSeconds']);
$this->assertIsArray($response['body']['executions']); $this->assertIsArray($response['body']['executions']);
$this->assertIsArray($response['body']['executionsTime']); $this->assertIsArray($response['body']['executionsTime']);
$this->assertIsArray($response['body']['executionsMbSeconds']);
$this->assertEquals($executions, $response['body']['executions'][array_key_last($response['body']['executions'])]['value']); $this->assertEquals($executions, $response['body']['executions'][array_key_last($response['body']['executions'])]['value']);
$this->validateDates($response['body']['executions']); $this->validateDates($response['body']['executions']);
$this->assertEquals($executionTime, $response['body']['executionsTime'][array_key_last($response['body']['executionsTime'])]['value']); $this->assertEquals($executionTime, $response['body']['executionsTime'][array_key_last($response['body']['executionsTime'])]['value']);

View file

@ -92,23 +92,27 @@ class FunctionsConsoleClientTest extends Scope
]); ]);
$this->assertEquals(200, $response['headers']['status-code']); $this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(15, count($response['body'])); $this->assertEquals(19, count($response['body']));
$this->assertEquals('24h', $response['body']['range']); $this->assertEquals('24h', $response['body']['range']);
$this->assertIsNumeric($response['body']['deploymentsTotal']); $this->assertIsNumeric($response['body']['deploymentsTotal']);
$this->assertIsNumeric($response['body']['deploymentsStorageTotal']); $this->assertIsNumeric($response['body']['deploymentsStorageTotal']);
$this->assertIsNumeric($response['body']['buildsTotal']); $this->assertIsNumeric($response['body']['buildsTotal']);
$this->assertIsNumeric($response['body']['buildsStorageTotal']); $this->assertIsNumeric($response['body']['buildsStorageTotal']);
$this->assertIsNumeric($response['body']['buildsTimeTotal']); $this->assertIsNumeric($response['body']['buildsTimeTotal']);
$this->assertIsNumeric($response['body']['buildsMbSecondsTotal']);
$this->assertIsNumeric($response['body']['executionsTotal']); $this->assertIsNumeric($response['body']['executionsTotal']);
$this->assertIsNumeric($response['body']['executionsTimeTotal']); $this->assertIsNumeric($response['body']['executionsTimeTotal']);
$this->assertIsNumeric($response['body']['executionsMbSecondsTotal']);
$this->assertIsArray($response['body']['deployments']); $this->assertIsArray($response['body']['deployments']);
$this->assertIsArray($response['body']['deploymentsStorage']); $this->assertIsArray($response['body']['deploymentsStorage']);
$this->assertIsArray($response['body']['builds']); $this->assertIsArray($response['body']['builds']);
$this->assertIsArray($response['body']['buildsTime']); $this->assertIsArray($response['body']['buildsTime']);
$this->assertIsArray($response['body']['buildsStorage']); $this->assertIsArray($response['body']['buildsStorage']);
$this->assertIsArray($response['body']['buildsTime']); $this->assertIsArray($response['body']['buildsTime']);
$this->assertIsArray($response['body']['buildsMbSeconds']);
$this->assertIsArray($response['body']['executions']); $this->assertIsArray($response['body']['executions']);
$this->assertIsArray($response['body']['executionsTime']); $this->assertIsArray($response['body']['executionsTime']);
$this->assertIsArray($response['body']['executionsMbSeconds']);
} }
/** /**

View file

@ -2,6 +2,7 @@
namespace Tests\E2E\Services\Teams; namespace Tests\E2E\Services\Teams;
use Tests\E2E\Client;
use Tests\E2E\Scopes\ProjectCustom; use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\Scope; use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\SideClient; use Tests\E2E\Scopes\SideClient;
@ -12,4 +13,55 @@ class TeamsCustomClientTest extends Scope
use TeamsBaseClient; use TeamsBaseClient;
use ProjectCustom; use ProjectCustom;
use SideClient; use SideClient;
/**
* @depends testUpdateTeamMembership
*/
public function testTeamsInviteHTMLInjection($data): array
{
$teamUid = $data['teamUid'] ?? '';
$email = uniqid() . 'friend@localhost.test';
$name = 'Friend User';
$password = 'password';
// Create a user account before we create a invite so we can check if the user has permissions when it shouldn't
$user = $this->client->call(Client::METHOD_POST, '/account', [
'content-type' => 'application/json',
'x-appwrite-project' => 'console'], [
'userId' => 'unique()',
'email' => $email,
'password' => $password,
'name' => $name,
], false);
$this->assertEquals(201, $user['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/teams/' . $teamUid . '/memberships', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'email' => $email,
'name' => $name,
'roles' => ['admin', 'editor'],
'url' => 'http://localhost:5000/join-us\"></a><h1>INJECTED</h1>'
]);
$this->assertEquals(201, $response['headers']['status-code']);
$email = $this->getLastEmail();
$encoded = 'http://localhost:5000/join-us\&quot;&gt;&lt;/a&gt;&lt;h1&gt;INJECTED&lt;/h1&gt;?';
$this->assertStringNotContainsString('<h1>INJECTED</h1>', $email['html']);
$this->assertStringContainsString($encoded, $email['html']);
$this->assertStringContainsString($encoded, $email['text']);
$response = $this->client->call(Client::METHOD_DELETE, '/teams/' . $teamUid . '/memberships/'.$response['body']['$id'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()));
$this->assertEquals(204, $response['headers']['status-code']);
return $data;
}
} }