feat: event classes for different cases
This commit is contained in:
parent
2f9b9445dd
commit
87b8fc3c41
|
@ -60,7 +60,7 @@ App::post('/v1/account')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
|
@ -120,11 +120,8 @@ App::post('/v1/account')
|
|||
Authorization::setRole('role:' . Auth::USER_ROLE_MEMBER);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setResource('user/'.$user->getId())
|
||||
->setUser($user)
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
$usage
|
||||
|
@ -169,7 +166,7 @@ App::post('/v1/account/sessions')
|
|||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
|
@ -215,12 +212,8 @@ App::post('/v1/account/sessions')
|
|||
$profile = $dbForProject->updateDocument('users', $profile->getId(), $profile);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
->setResource('user/'.$profile->getId())
|
||||
->setUser($profile)
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$profile->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
|
@ -399,7 +392,7 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
|
@ -577,12 +570,8 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
->setResource('user/'.$user->getId())
|
||||
->setUser($user)
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
$usage
|
||||
|
@ -656,9 +645,9 @@ App::post('/v1/account/sessions/magic-url')
|
|||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
/** @var Appwrite\Event\Mail $mails */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception('SMTP Disabled', 503, Exception::GENERAL_SMTP_DISABLED);
|
||||
|
@ -703,8 +692,6 @@ App::post('/v1/account/sessions/magic-url')
|
|||
'search' => implode(' ', [$userId, $email]),
|
||||
'deleted' => false
|
||||
])));
|
||||
|
||||
$mails->setParam('event', 'users.create');
|
||||
}
|
||||
|
||||
$loginSecret = Auth::tokenGenerator();
|
||||
|
@ -740,14 +727,10 @@ App::post('/v1/account/sessions/magic-url')
|
|||
$url = Template::unParseURL($url);
|
||||
|
||||
$mails
|
||||
->setPayload([
|
||||
'from' => $project->getId(),
|
||||
'recipient' => $user->getAttribute('email'),
|
||||
'url' => $url,
|
||||
'locale' => $locale->default,
|
||||
'project' => $project->getAttribute('name', ['[APP-NAME]']),
|
||||
'type' => MAIL_TYPE_MAGIC_SESSION
|
||||
])
|
||||
->setType(MAIL_TYPE_MAGIC_SESSION)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->setUrl($url)
|
||||
->setLocale($locale->default)
|
||||
->trigger()
|
||||
;
|
||||
|
||||
|
@ -763,10 +746,8 @@ App::post('/v1/account/sessions/magic-url')
|
|||
($isPrivilegedUser || $isAppUser) ? $loginSecret : '');
|
||||
|
||||
$audits
|
||||
->setResource('user/'.$user->getId())
|
||||
->setUser($user)
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
$response
|
||||
|
@ -806,7 +787,7 @@ App::put('/v1/account/sessions/magic-url')
|
|||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
@ -871,13 +852,7 @@ App::put('/v1/account/sessions/magic-url')
|
|||
throw new Exception('Failed saving user to DB', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
$audits->setResource('user/'.$user->getId());
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
|
@ -943,7 +918,7 @@ App::post('/v1/account/sessions/anonymous')
|
|||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Stats\Stats $events */
|
||||
|
||||
|
@ -1022,13 +997,7 @@ App::post('/v1/account/sessions/anonymous')
|
|||
$user = $dbForProject->updateDocument('users', $user->getId(),
|
||||
$user->setAttribute('sessions', $session, Document::SET_TYPE_APPEND));
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
$audits->setResource('user/'.$user->getId());
|
||||
|
||||
$usage
|
||||
->setParam('users.sessions.create', 1)
|
||||
|
@ -1350,7 +1319,7 @@ App::patch('/v1/account/name')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Stats\Stats $events */
|
||||
|
||||
|
@ -1360,20 +1329,12 @@ App::patch('/v1/account/name')
|
|||
);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setResource('user/'.$user->getId())
|
||||
->setUser($user)
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
;
|
||||
$usage->setParam('users.update', 1);
|
||||
$events->setParam('userId', $user->getId());
|
||||
|
||||
$response->dynamic($user, Response::MODEL_USER);
|
||||
});
|
||||
|
@ -1402,7 +1363,7 @@ App::patch('/v1/account/password')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Stats\Stats $events */
|
||||
|
||||
|
@ -1417,20 +1378,12 @@ App::patch('/v1/account/password')
|
|||
);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setResource('user/'.$user->getId())
|
||||
->setUser($user)
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
;
|
||||
$usage->setParam('users.update', 1);
|
||||
$events->setParam('userId', $user->getId());
|
||||
|
||||
$response->dynamic($user, Response::MODEL_USER);
|
||||
});
|
||||
|
@ -1459,7 +1412,7 @@ App::patch('/v1/account/email')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Stats\Stats $events */
|
||||
|
||||
|
@ -1491,20 +1444,12 @@ App::patch('/v1/account/email')
|
|||
}
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setResource('user/'.$user->getId())
|
||||
->setUser($user)
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
;
|
||||
$usage->setParam('users.update', 1);
|
||||
$events->setParam('userId', $user->getId());
|
||||
|
||||
$response->dynamic($user, Response::MODEL_USER);
|
||||
});
|
||||
|
@ -1532,26 +1477,15 @@ App::patch('/v1/account/prefs')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('prefs', $prefs));
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
;
|
||||
$audits->setResource('user/'.$user->getId());
|
||||
$usage->setParam('users.update', 1);
|
||||
$events->setParam('userId', $user->getId());
|
||||
|
||||
$response->dynamic($user, Response::MODEL_USER);
|
||||
});
|
||||
|
@ -1579,7 +1513,7 @@ App::delete('/v1/account')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
|
@ -1597,10 +1531,8 @@ App::delete('/v1/account')
|
|||
*/
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'account.delete')
|
||||
->setParam('resource', 'user/' . $user->getId())
|
||||
->setParam('data', $user->getArrayCopy())
|
||||
->setResource('user/' . $user->getId())
|
||||
->setPayload($response->output($user, Response::MODEL_USER))
|
||||
;
|
||||
|
||||
$events
|
||||
|
@ -1609,14 +1541,11 @@ App::delete('/v1/account')
|
|||
;
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
$response
|
||||
->addHeader('X-Fallback-Cookies', \json_encode([]))
|
||||
;
|
||||
$response->addHeader('X-Fallback-Cookies', \json_encode([]));
|
||||
}
|
||||
|
||||
$usage
|
||||
->setParam('users.delete', 1)
|
||||
;
|
||||
$usage->setParam('users.delete', 1);
|
||||
|
||||
$response
|
||||
->addCookie(Auth::$cookieName . '_legacy', '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null)
|
||||
->addCookie(Auth::$cookieName, '', \time() - 3600, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
|
||||
|
@ -1651,7 +1580,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
|
@ -1668,11 +1597,7 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
|
||||
$dbForProject->deleteDocument('sessions', $session->getId());
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'account.sessions.delete')
|
||||
->setParam('resource', 'user/' . $user->getId())
|
||||
;
|
||||
$audits->setResource('user/' . $user->getId());
|
||||
|
||||
$session->setAttribute('current', false);
|
||||
|
||||
|
@ -1697,9 +1622,9 @@ App::delete('/v1/account/sessions/:sessionId')
|
|||
$dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('sessions', $sessions));
|
||||
|
||||
$events
|
||||
->setPayload($response->output($session, Response::MODEL_SESSION))
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
->setPayload($response->output($session, Response::MODEL_SESSION))
|
||||
;
|
||||
|
||||
$usage
|
||||
|
@ -1744,7 +1669,7 @@ App::patch('/v1/account/sessions/:sessionId')
|
|||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
|
@ -1773,7 +1698,7 @@ App::patch('/v1/account/sessions/:sessionId')
|
|||
$appSecret = $project->getAttribute('providers', [])[$provider.'Secret'] ?? '{}';
|
||||
|
||||
$className = 'Appwrite\\Auth\\OAuth2\\'.\ucfirst($provider);
|
||||
|
||||
|
||||
if (!\class_exists($className)) {
|
||||
throw new Exception('Provider is not supported', 501, Exception::PROJECT_PROVIDER_UNSUPPORTED);
|
||||
}
|
||||
|
@ -1793,16 +1718,12 @@ App::patch('/v1/account/sessions/:sessionId')
|
|||
$user->setAttribute("sessions", $sessions);
|
||||
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'account.sessions.update')
|
||||
->setParam('resource', 'user/' . $user->getId())
|
||||
;
|
||||
$audits->setResource('user/' . $user->getId());
|
||||
|
||||
$events
|
||||
->setPayload($response->output($session, Response::MODEL_SESSION))
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
->setPayload($response->output($session, Response::MODEL_SESSION))
|
||||
;
|
||||
|
||||
$usage
|
||||
|
@ -1843,7 +1764,7 @@ App::delete('/v1/account/sessions')
|
|||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
|
@ -1853,11 +1774,7 @@ App::delete('/v1/account/sessions')
|
|||
foreach ($sessions as $session) {/** @var Document $session */
|
||||
$dbForProject->deleteDocument('sessions', $session->getId());
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'account.sessions.delete')
|
||||
->setParam('resource', 'user/' . $user->getId())
|
||||
;
|
||||
$audits->setResource('user/' . $user->getId());
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
$response
|
||||
|
@ -1884,18 +1801,19 @@ App::delete('/v1/account/sessions')
|
|||
$numOfSessions = count($sessions);
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
->setPayload($response->output(new Document([
|
||||
'sessions' => $sessions,
|
||||
'total' => $numOfSessions,
|
||||
]), Response::MODEL_SESSION_LIST))
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $session->getId())
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('users.sessions.delete', $numOfSessions)
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
||||
|
@ -1930,8 +1848,8 @@ App::post('/v1/account/recovery')
|
|||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Mail $mails */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
|
@ -1978,40 +1896,33 @@ App::post('/v1/account/recovery')
|
|||
$url = Template::unParseURL($url);
|
||||
|
||||
$mails
|
||||
->setPayload([
|
||||
'from' => $project->getId(),
|
||||
'recipient' => $profile->getAttribute('email', ''),
|
||||
'name' => $profile->getAttribute('name', ''),
|
||||
'url' => $url,
|
||||
'locale' => $locale->default,
|
||||
'project' => $project->getAttribute('name', ['[APP-NAME]']),
|
||||
'type' => MAIL_TYPE_RECOVERY
|
||||
])
|
||||
->setType(MAIL_TYPE_RECOVERY)
|
||||
->setRecipient($profile->getAttribute('email', ''))
|
||||
->setUrl($url)
|
||||
->setLocale($locale->default)
|
||||
->setName($profile->getAttribute('name'))
|
||||
->trigger();
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData',
|
||||
$response->output($recovery->setAttribute('secret', $secret),
|
||||
Response::MODEL_TOKEN
|
||||
))
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('tokenId', $recovery->getId())
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('tokenId', $recovery->getId())
|
||||
->setPayload($response->output(
|
||||
$recovery->setAttribute('secret', $secret),
|
||||
Response::MODEL_TOKEN
|
||||
))
|
||||
;
|
||||
|
||||
$recovery // Hide secret for clients, sp
|
||||
->setAttribute('secret',
|
||||
($isPrivilegedUser || $isAppUser) ? $secret : '');
|
||||
|
||||
$audits
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('event', 'account.recovery.create')
|
||||
->setParam('resource', 'user/' . $profile->getId())
|
||||
;
|
||||
$audits->setResource('user/' . $profile->getId());
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($recovery, Response::MODEL_TOKEN);
|
||||
});
|
||||
|
@ -2042,7 +1953,7 @@ App::put('/v1/account/recovery')
|
|||
->action(function ($userId, $secret, $password, $passwordAgain, $response, $dbForProject, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
|
@ -2084,20 +1995,15 @@ App::put('/v1/account/recovery')
|
|||
|
||||
$dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens));
|
||||
|
||||
$audits
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('event', 'account.recovery.update')
|
||||
->setParam('resource', 'user/' . $profile->getId())
|
||||
;
|
||||
$audits->setResource('user/' . $profile->getId());
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
$usage->setParam('users.update', 1);
|
||||
|
||||
$events
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('tokenId', $recovery->getId())
|
||||
;
|
||||
|
||||
$response->dynamic($recovery, Response::MODEL_TOKEN);
|
||||
});
|
||||
|
||||
|
@ -2133,9 +2039,9 @@ App::post('/v1/account/verification')
|
|||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Locale\Locale $locale */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
/** @var Appwrite\Event\Mail $mails */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
|
@ -2171,40 +2077,30 @@ App::post('/v1/account/verification')
|
|||
$url = Template::unParseURL($url);
|
||||
|
||||
$mails
|
||||
->setPayload([
|
||||
'from' => $project->getId(),
|
||||
'recipient' => $user->getAttribute('email'),
|
||||
'name' => $user->getAttribute('name'),
|
||||
'url' => $url,
|
||||
'locale' => $locale->default,
|
||||
'project' => $project->getAttribute('name', ['[APP-NAME]']),
|
||||
'type' => MAIL_TYPE_VERIFICATION
|
||||
])
|
||||
->setType(MAIL_TYPE_VERIFICATION)
|
||||
->setRecipient($user->getAttribute('email'))
|
||||
->setUrl($url)
|
||||
->setLocale($locale->default)
|
||||
->setName($user->getAttribute('name'))
|
||||
->trigger()
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData',
|
||||
$response->output($verification->setAttribute('secret', $verificationSecret),
|
||||
Response::MODEL_TOKEN
|
||||
))
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('tokenId', $verification->getId())
|
||||
->setPayload($response->output(
|
||||
$verification->setAttribute('secret', $verificationSecret),
|
||||
Response::MODEL_TOKEN
|
||||
))
|
||||
;
|
||||
|
||||
$verification // Hide secret for clients, sp
|
||||
->setAttribute('secret',
|
||||
($isPrivilegedUser || $isAppUser) ? $verificationSecret : '');
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'account.verification.create')
|
||||
->setParam('resource', 'user/' . $user->getId())
|
||||
;
|
||||
$audits->setResource('user/' . $user->getId());
|
||||
$usage->setParam('users.update', 1);
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($verification, Response::MODEL_TOKEN);
|
||||
});
|
||||
|
@ -2235,7 +2131,7 @@ App::put('/v1/account/verification')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
|
@ -2269,15 +2165,9 @@ App::put('/v1/account/verification')
|
|||
|
||||
$dbForProject->updateDocument('users', $profile->getId(), $profile->setAttribute('tokens', $tokens));
|
||||
|
||||
$audits
|
||||
->setParam('userId', $profile->getId())
|
||||
->setParam('event', 'account.verification.update')
|
||||
->setParam('resource', 'user/' . $user->getId())
|
||||
;
|
||||
$audits->setResource('user/' . $user->getId());
|
||||
|
||||
$usage
|
||||
->setParam('users.update', 1)
|
||||
;
|
||||
$usage->setParam('users.update', 1);
|
||||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
|
|
|
@ -33,6 +33,8 @@ use Appwrite\Network\Validator\URL;
|
|||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Appwrite\Detector\Detector;
|
||||
use Appwrite\Event\Audit as EventAudit;
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Stats\Stats;
|
||||
|
||||
|
@ -43,13 +45,13 @@ use Appwrite\Stats\Stats;
|
|||
* @param Utopia\Database\Document $attribute
|
||||
* @param Appwrite\Utopia\Response $response
|
||||
* @param Utopia\Database\Database $dbForProject
|
||||
* @param Appwrite\Event\Event $database
|
||||
* @param Appwrite\Event\Event $audits
|
||||
* @param Appwrite\Event\Database $database
|
||||
* @param Appwrite\Event\Audit $audits
|
||||
* @param Appwrite\Stats\Stats $usage
|
||||
*
|
||||
* @return Document Newly created attribute document
|
||||
*/
|
||||
function createAttribute(string $collectionId, Document $attribute, Response $response, Database $dbForProject, Event $database, Event $audits, Stats $usage): Document
|
||||
function createAttribute(string $collectionId, Document $attribute, Response $response, Database $dbForProject, EventDatabase $database, EventAudit $audits, Event $events, Stats $usage): Document
|
||||
{
|
||||
$key = $attribute->getAttribute('key');
|
||||
$type = $attribute->getAttribute('type', '');
|
||||
|
@ -113,22 +115,23 @@ function createAttribute(string $collectionId, Document $attribute, Response $re
|
|||
$dbForProject->deleteCachedDocument('collections', $collectionId);
|
||||
$dbForProject->deleteCachedCollection('collection_' . $collection->getInternalId());
|
||||
|
||||
// Pass clone of $attribute object to workers
|
||||
// so we can later modify Document to fit response model
|
||||
$clone = clone $attribute;
|
||||
|
||||
$database
|
||||
->setParam('type', DATABASE_TYPE_CREATE_ATTRIBUTE)
|
||||
->setParam('collection', $collection)
|
||||
->setParam('document', $clone)
|
||||
;
|
||||
|
||||
$usage->setParam('database.collections.update', 1);
|
||||
|
||||
$database
|
||||
->setType(DATABASE_TYPE_CREATE_ATTRIBUTE)
|
||||
->setCollection($collection)
|
||||
->setDocument($attribute)
|
||||
;
|
||||
|
||||
$events
|
||||
->setTrigger($collection)
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('attributeId', $attribute->getId())
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.attributes.create')
|
||||
->setParam('resource', 'collection/'.$collectionId)
|
||||
->setParam('data', $clone)
|
||||
->setResource('collection/'.$collectionId)
|
||||
->setPayload($attribute->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
@ -139,7 +142,7 @@ function createAttribute(string $collectionId, Document $attribute, Response $re
|
|||
App::post('/v1/database/collections')
|
||||
->desc('Create Collection')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.collections.create')
|
||||
->label('event', 'collections.[collectionId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'database')
|
||||
|
@ -157,11 +160,13 @@ App::post('/v1/database/collections')
|
|||
->inject('dbForProject')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForProject, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $name, $permission, $read, $write, $response, $dbForProject, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$collectionId = $collectionId == 'unique()' ? $dbForProject->getId() : $collectionId;
|
||||
|
||||
|
@ -187,11 +192,11 @@ App::post('/v1/database/collections')
|
|||
}
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.collections.create')
|
||||
->setParam('resource', 'collection/'.$collectionId)
|
||||
->setParam('data', $collection->getArrayCopy())
|
||||
->setResource('collection/'.$collectionId)
|
||||
->setPayload($collection->getArrayCopy())
|
||||
;
|
||||
|
||||
$events->setParam('collectionId', $collection->getId());
|
||||
$usage->setParam('database.collections.create', 1);
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
@ -581,7 +586,7 @@ App::put('/v1/database/collections/:collectionId')
|
|||
->desc('Update Collection')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'database.collections.update')
|
||||
->label('event', 'collections.[collectionId].update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.method', 'updateCollection')
|
||||
|
@ -599,11 +604,13 @@ App::put('/v1/database/collections/:collectionId')
|
|||
->inject('dbForProject')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $name, $permission, $read, $write, $enabled, $response, $dbForProject, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $name, $permission, $read, $write, $enabled, $response, $dbForProject, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$collection = $dbForProject->getDocument('collections', $collectionId);
|
||||
|
||||
|
@ -633,14 +640,14 @@ App::put('/v1/database/collections/:collectionId')
|
|||
throw new Exception('Bad structure. '.$exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
|
||||
}
|
||||
|
||||
$usage->setParam('database.collections.update', 1);
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.collections.update')
|
||||
->setParam('resource', 'collection/'.$collectionId)
|
||||
->setParam('data', $collection->getArrayCopy())
|
||||
->setResource('collection/'.$collectionId)
|
||||
->setPayload($collection->getArrayCopy())
|
||||
;
|
||||
|
||||
$usage->setParam('database.collections.update', 1);
|
||||
$events->setParam('collectionId', $collection->getId());
|
||||
|
||||
$response->dynamic($collection, Response::MODEL_COLLECTION);
|
||||
});
|
||||
|
||||
|
@ -648,7 +655,7 @@ App::delete('/v1/database/collections/:collectionId')
|
|||
->desc('Delete Collection')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'database.collections.delete')
|
||||
->label('event', 'collections.[collectionId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.method', 'deleteCollection')
|
||||
|
@ -666,8 +673,8 @@ App::delete('/v1/database/collections/:collectionId')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Stats\Stats $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$collection = $dbForProject->getDocument('collections', $collectionId);
|
||||
|
||||
|
@ -682,20 +689,22 @@ App::delete('/v1/database/collections/:collectionId')
|
|||
$dbForProject->deleteCachedCollection('collection_' . $collection->getInternalId());
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $collection)
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_DOCUMENT,
|
||||
'document' => $collection
|
||||
])
|
||||
;
|
||||
|
||||
$usage->setParam('database.collections.delete', 1);
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($collection, Response::MODEL_COLLECTION))
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setPayload($response->output($collection, Response::MODEL_COLLECTION))
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.collections.delete')
|
||||
->setParam('resource', 'collection/'.$collectionId)
|
||||
->setParam('data', $collection->getArrayCopy())
|
||||
->setResource('collection/'.$collectionId)
|
||||
->setPayload($collection->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
@ -704,7 +713,7 @@ App::delete('/v1/database/collections/:collectionId')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/string')
|
||||
->desc('Create String Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'database')
|
||||
|
@ -724,12 +733,14 @@ App::post('/v1/database/collections/:collectionId/attributes/string')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $size, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $size, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
// Ensure attribute default is within required size
|
||||
$validator = new Text($size);
|
||||
|
@ -744,7 +755,7 @@ App::post('/v1/database/collections/:collectionId/attributes/string')
|
|||
'required' => $required,
|
||||
'default' => $default,
|
||||
'array' => $array,
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_STRING);
|
||||
});
|
||||
|
@ -752,7 +763,7 @@ App::post('/v1/database/collections/:collectionId/attributes/string')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/email')
|
||||
->desc('Create Email Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
|
@ -771,11 +782,12 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$attribute = createAttribute($collectionId, new Document([
|
||||
|
@ -786,7 +798,7 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
|
|||
'default' => $default,
|
||||
'array' => $array,
|
||||
'format' => APP_DATABASE_ATTRIBUTE_EMAIL,
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_EMAIL);
|
||||
});
|
||||
|
@ -794,7 +806,7 @@ App::post('/v1/database/collections/:collectionId/attributes/email')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/enum')
|
||||
->desc('Create Enum Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
|
@ -814,12 +826,14 @@ App::post('/v1/database/collections/:collectionId/attributes/enum')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $elements, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $elements, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
// use length of longest string as attribute size
|
||||
$size = 0;
|
||||
|
@ -845,7 +859,7 @@ App::post('/v1/database/collections/:collectionId/attributes/enum')
|
|||
'array' => $array,
|
||||
'format' => APP_DATABASE_ATTRIBUTE_ENUM,
|
||||
'formatOptions' => ['elements' => $elements],
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_ENUM);
|
||||
});
|
||||
|
@ -853,7 +867,7 @@ App::post('/v1/database/collections/:collectionId/attributes/enum')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/ip')
|
||||
->desc('Create IP Address Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
|
@ -872,11 +886,12 @@ App::post('/v1/database/collections/:collectionId/attributes/ip')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$attribute = createAttribute($collectionId, new Document([
|
||||
|
@ -887,7 +902,7 @@ App::post('/v1/database/collections/:collectionId/attributes/ip')
|
|||
'default' => $default,
|
||||
'array' => $array,
|
||||
'format' => APP_DATABASE_ATTRIBUTE_IP,
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_IP);
|
||||
});
|
||||
|
@ -895,7 +910,7 @@ App::post('/v1/database/collections/:collectionId/attributes/ip')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/url')
|
||||
->desc('Create URL Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
|
@ -914,11 +929,13 @@ App::post('/v1/database/collections/:collectionId/attributes/url')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$attribute = createAttribute($collectionId, new Document([
|
||||
'key' => $key,
|
||||
|
@ -928,7 +945,7 @@ App::post('/v1/database/collections/:collectionId/attributes/url')
|
|||
'default' => $default,
|
||||
'array' => $array,
|
||||
'format' => APP_DATABASE_ATTRIBUTE_URL,
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_URL);
|
||||
});
|
||||
|
@ -936,7 +953,7 @@ App::post('/v1/database/collections/:collectionId/attributes/url')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/integer')
|
||||
->desc('Create Integer Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
|
@ -957,12 +974,14 @@ App::post('/v1/database/collections/:collectionId/attributes/integer')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
// Ensure attribute default is within range
|
||||
$min = (is_null($min)) ? PHP_INT_MIN : \intval($min);
|
||||
|
@ -992,7 +1011,7 @@ App::post('/v1/database/collections/:collectionId/attributes/integer')
|
|||
'min' => $min,
|
||||
'max' => $max,
|
||||
],
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$formatOptions = $attribute->getAttribute('formatOptions', []);
|
||||
|
||||
|
@ -1007,7 +1026,7 @@ App::post('/v1/database/collections/:collectionId/attributes/integer')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/float')
|
||||
->desc('Create Float Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
|
@ -1027,13 +1046,15 @@ App::post('/v1/database/collections/:collectionId/attributes/float')
|
|||
->inject('dbForProject')
|
||||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('events')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->action(function ($collectionId, $key, $required, $min, $max, $default, $array, $response, $dbForProject, $database, $audits, $events, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
// Ensure attribute default is within range
|
||||
$min = (is_null($min)) ? -PHP_FLOAT_MAX : \floatval($min);
|
||||
|
@ -1066,7 +1087,7 @@ App::post('/v1/database/collections/:collectionId/attributes/float')
|
|||
'min' => $min,
|
||||
'max' => $max,
|
||||
],
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$formatOptions = $attribute->getAttribute('formatOptions', []);
|
||||
|
||||
|
@ -1081,7 +1102,7 @@ App::post('/v1/database/collections/:collectionId/attributes/float')
|
|||
App::post('/v1/database/collections/:collectionId/attributes/boolean')
|
||||
->desc('Create Boolean Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.attributes.create')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
|
@ -1100,12 +1121,14 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $required, $default, $array, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject*/
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$attribute = createAttribute($collectionId, new Document([
|
||||
'key' => $key,
|
||||
|
@ -1114,7 +1137,7 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean')
|
|||
'required' => $required,
|
||||
'default' => $default,
|
||||
'array' => $array,
|
||||
]), $response, $dbForProject, $database, $audits, $usage);
|
||||
]), $response, $dbForProject, $database, $audits, $events, $usage);
|
||||
|
||||
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_BOOLEAN);
|
||||
});
|
||||
|
@ -1221,7 +1244,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
|
|||
->desc('Delete Attribute')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'database.attributes.delete')
|
||||
->label('event', 'collections.[collectionId].attributes.[attributeId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.method', 'deleteAttribute')
|
||||
|
@ -1239,9 +1262,9 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
|
|||
->action(function ($collectionId, $key, $response, $dbForProject, $database, $events, $audits, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$collection = $dbForProject->getDocument('collections', $collectionId);
|
||||
|
@ -1265,9 +1288,9 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
|
|||
$dbForProject->deleteCachedCollection('collection_' . $collection->getInternalId());
|
||||
|
||||
$database
|
||||
->setParam('type', DATABASE_TYPE_DELETE_ATTRIBUTE)
|
||||
->setParam('collection', $collection)
|
||||
->setParam('document', $attribute)
|
||||
->setType(DATABASE_TYPE_DELETE_ATTRIBUTE)
|
||||
->setCollection($collection)
|
||||
->setDocument($attribute)
|
||||
;
|
||||
|
||||
$usage->setParam('database.collections.update', 1);
|
||||
|
@ -1291,13 +1314,15 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
|
|||
};
|
||||
|
||||
$events
|
||||
->setParam('payload', $response->output($attribute, $model))
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('attributeId', $attribute->getId())
|
||||
->setTrigger($collection)
|
||||
->setPayload($response->output($attribute, $model))
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.attributes.delete')
|
||||
->setParam('resource', 'collection/'.$collectionId)
|
||||
->setParam('data', $attribute->getArrayCopy())
|
||||
->setResource('collection/'.$collectionId)
|
||||
->setPayload($attribute->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
@ -1306,7 +1331,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:key')
|
|||
App::post('/v1/database/collections/:collectionId/indexes')
|
||||
->desc('Create Index')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.indexes.create')
|
||||
->label('event', 'collections.[collectionId].indexes.[indexId].create')
|
||||
->label('scope', 'collections.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'database')
|
||||
|
@ -1325,12 +1350,14 @@ App::post('/v1/database/collections/:collectionId/indexes')
|
|||
->inject('database')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($collectionId, $key, $type, $attributes, $orders, $response, $dbForProject, $database, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($collectionId, $key, $type, $attributes, $orders, $response, $dbForProject, $database, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Stats\Stats $audits */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$collection = $dbForProject->getDocument('collections', $collectionId);
|
||||
|
||||
|
@ -1393,17 +1420,22 @@ App::post('/v1/database/collections/:collectionId/indexes')
|
|||
$dbForProject->deleteCachedDocument('collections', $collectionId);
|
||||
|
||||
$database
|
||||
->setParam('type', DATABASE_TYPE_CREATE_INDEX)
|
||||
->setParam('collection', $collection)
|
||||
->setParam('document', $index)
|
||||
->setType(DATABASE_TYPE_CREATE_INDEX)
|
||||
->setCollection($collection)
|
||||
->setDocument($index)
|
||||
;
|
||||
|
||||
$usage->setParam('database.collections.update', 1);
|
||||
|
||||
$events
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('indexId', $index->getId())
|
||||
->setTrigger($collection)
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.indexes.create')
|
||||
->setParam('resource', 'collection/'.$collectionId)
|
||||
->setParam('data', $index->getArrayCopy())
|
||||
->setResource('collection/'.$collection->getId())
|
||||
->setPayload($index->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
@ -1493,7 +1525,7 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key')
|
|||
->desc('Delete Index')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('event', 'database.indexes.delete')
|
||||
->label('event', 'collections.[collectionId].indexes.[indexId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.method', 'deleteIndex')
|
||||
|
@ -1511,9 +1543,9 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key')
|
|||
->action(function ($collectionId, $key, $response, $dbForProject, $database, $events, $audits, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
||||
$collection = $dbForProject->getDocument('collections', $collectionId);
|
||||
|
@ -1536,21 +1568,23 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key')
|
|||
$dbForProject->deleteCachedDocument('collections', $collectionId);
|
||||
|
||||
$database
|
||||
->setParam('type', DATABASE_TYPE_DELETE_INDEX)
|
||||
->setParam('collection', $collection)
|
||||
->setParam('document', $index)
|
||||
->setType(DATABASE_TYPE_DELETE_INDEX)
|
||||
->setCollection($collection)
|
||||
->setDocument($index)
|
||||
;
|
||||
|
||||
$usage->setParam('database.collections.update', 1);
|
||||
|
||||
$events
|
||||
->setParam('payload', $response->output($index, Response::MODEL_INDEX))
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('indexId', $index->getId())
|
||||
->setTrigger($collection)
|
||||
->setPayload($response->output($index, Response::MODEL_INDEX))
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.indexes.delete')
|
||||
->setParam('resource', 'collection/'.$collectionId)
|
||||
->setParam('data', $index->getArrayCopy())
|
||||
->setResource('collection/'.$collection->getId())
|
||||
->setPayload($index->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
@ -1559,7 +1593,7 @@ App::delete('/v1/database/collections/:collectionId/indexes/:key')
|
|||
App::post('/v1/database/collections/:collectionId/documents')
|
||||
->desc('Create Document')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.documents.create')
|
||||
->label('event', 'collections.[collectionId].documents.[documentId].create')
|
||||
->label('scope', 'documents.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'database')
|
||||
|
@ -1584,7 +1618,7 @@ App::post('/v1/database/collections/:collectionId/documents')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var string $mode */
|
||||
|
@ -1658,7 +1692,11 @@ App::post('/v1/database/collections/:collectionId/documents')
|
|||
throw new Exception('Document already exists', 409, Exception::DOCUMENT_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
$events->setParam('collection', $collection->getArrayCopy());
|
||||
$events
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('documentId', $document->getId())
|
||||
->setTrigger($collection)
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('database.documents.create', 1)
|
||||
|
@ -1666,9 +1704,8 @@ App::post('/v1/database/collections/:collectionId/documents')
|
|||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.documents.create')
|
||||
->setParam('resource', 'document/'.$document->getId())
|
||||
->setParam('data', $document->getArrayCopy())
|
||||
->setResource('document/'.$document->getId())
|
||||
->setPayload($document->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
@ -1938,7 +1975,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId/logs')
|
|||
App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
||||
->desc('Update Document')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'database.documents.update')
|
||||
->label('event', 'collections.[collectionId].documents.[documentId].update')
|
||||
->label('scope', 'documents.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'database')
|
||||
|
@ -1961,7 +1998,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
|||
->action(function ($collectionId, $documentId, $data, $read, $write, $response, $dbForProject, $audits, $usage, $events, $mode) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var string $mode */
|
||||
|
@ -1999,7 +2036,7 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
|||
if (empty($data)) {
|
||||
throw new Exception('Missing payload', 400, Exception::DOCUMENT_MISSING_PAYLOAD);
|
||||
}
|
||||
|
||||
|
||||
if (!\is_array($data)) {
|
||||
throw new Exception('Data param should be a valid JSON object', 400, Exception::DOCUMENT_INVALID_STRUCTURE);
|
||||
}
|
||||
|
@ -2053,17 +2090,20 @@ App::patch('/v1/database/collections/:collectionId/documents/:documentId')
|
|||
throw new Exception($exception->getMessage(), 400, Exception::DOCUMENT_INVALID_STRUCTURE);
|
||||
}
|
||||
|
||||
$events->setParam('collection', $collection->getArrayCopy());
|
||||
$events
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('documentId', $document->getId())
|
||||
->setTrigger($collection)
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('database.documents.update', 1)
|
||||
->setParam('collectionId', $collectionId)
|
||||
;
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.documents.update')
|
||||
->setParam('resource', 'document/'.$document->getId())
|
||||
->setParam('data', $document->getArrayCopy())
|
||||
->setResource('document/'.$document->getId())
|
||||
->setPayload($document->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->dynamic($document, Response::MODEL_DOCUMENT);
|
||||
|
@ -2073,7 +2113,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
|
|||
->desc('Delete Document')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', 'documents.write')
|
||||
->label('event', 'database.documents.delete')
|
||||
->label('event', 'collections.[collectionId].documents.[documentId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'database')
|
||||
->label('sdk.method', 'deleteDocument')
|
||||
|
@ -2093,7 +2133,7 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var string $mode */
|
||||
|
@ -2142,24 +2182,27 @@ App::delete('/v1/database/collections/:collectionId/documents/:documentId')
|
|||
$document->setAttribute('$collection', $collectionId);
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_AUDIT)
|
||||
->setParam('document', $document)
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_AUDIT,
|
||||
'document' => $document
|
||||
])
|
||||
;
|
||||
|
||||
$usage
|
||||
->setParam('database.documents.delete', 1)
|
||||
->setParam('collectionId', $collectionId)
|
||||
;
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($document, Response::MODEL_DOCUMENT))
|
||||
->setParam('collection', $collection->getArrayCopy());
|
||||
->setParam('collectionId', $collection->getId())
|
||||
->setParam('documentId', $document->getId())
|
||||
->setTrigger($collection)
|
||||
->setPayload($response->output($document, Response::MODEL_DOCUMENT))
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'database.documents.delete')
|
||||
->setParam('resource', 'document/'.$document->getId())
|
||||
->setParam('data', $document->getArrayCopy()) // Audit document in case of malicious or disastrous action
|
||||
->setResource('document/'.$document->getId())
|
||||
->setPayload($document->getArrayCopy())
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
use Ahc\Jwt\JWT;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Validator\Event as ValidatorEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Utopia\Database\Validator\UID;
|
||||
|
@ -34,7 +35,7 @@ App::post('/v1/functions')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Create Function')
|
||||
->label('scope', 'functions.write')
|
||||
->label('event', 'functions.create')
|
||||
->label('event', 'functions.[functionId].create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'create')
|
||||
|
@ -47,14 +48,16 @@ App::post('/v1/functions')
|
|||
->param('execute', [], new ArrayList(new Text(64)), 'An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.')
|
||||
->param('runtime', '', new WhiteList(array_keys(Config::getParam('runtimes')), true), 'Execution runtime.')
|
||||
->param('vars', [], new Assoc(), 'Key-value JSON object that will be passed to the function as environment variables.', true)
|
||||
->param('events', [], new ArrayList(new WhiteList(array_keys(Config::getParam('events')), true)), 'Events list.', true)
|
||||
->param('events', [], new ArrayList(new ValidatorEvent()), 'Events list.', true)
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Function maximum execution time in seconds.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function ($functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $dbForProject) {
|
||||
->inject('events')
|
||||
->action(function ($functionId, $name, $execute, $runtime, $vars, $events, $schedule, $timeout, $response, $dbForProject, $eventsInstance) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $eventsInstance */
|
||||
|
||||
$functionId = ($functionId == 'unique()') ? $dbForProject->getId() : $functionId;
|
||||
$function = $dbForProject->createDocument('functions', new Document([
|
||||
|
@ -75,6 +78,8 @@ App::post('/v1/functions')
|
|||
'search' => implode(' ', [$functionId, $name, $runtime]),
|
||||
]));
|
||||
|
||||
$eventsInstance->setParam('functionId', $function->getId());
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($function, Response::MODEL_FUNCTION);
|
||||
});
|
||||
|
@ -144,7 +149,7 @@ App::get('/v1/functions/runtimes')
|
|||
return $runtimes[$key];
|
||||
}, array_keys($runtimes));
|
||||
|
||||
$response->dynamic(new Document([
|
||||
$response->dynamic(new Document([
|
||||
'total' => count($runtimes),
|
||||
'runtimes' => $runtimes
|
||||
]), Response::MODEL_RUNTIME_LIST);
|
||||
|
@ -202,9 +207,9 @@ App::get('/v1/functions/:functionId/usage')
|
|||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
$usage = [];
|
||||
if(App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
if (App::getEnv('_APP_USAGE_STATS', 'enabled') == 'enabled') {
|
||||
$periods = [
|
||||
'24h' => [
|
||||
'period' => '30m',
|
||||
|
@ -223,16 +228,16 @@ App::get('/v1/functions/:functionId/usage')
|
|||
'limit' => 90,
|
||||
],
|
||||
];
|
||||
|
||||
|
||||
$metrics = [
|
||||
"functions.$functionId.executions",
|
||||
"functions.$functionId.failures",
|
||||
"functions.$functionId.executions",
|
||||
"functions.$functionId.failures",
|
||||
"functions.$functionId.compute"
|
||||
];
|
||||
|
||||
$stats = [];
|
||||
|
||||
Authorization::skip(function() use ($dbForProject, $periods, $range, $metrics, &$stats) {
|
||||
Authorization::skip(function () use ($dbForProject, $periods, $range, $metrics, &$stats) {
|
||||
foreach ($metrics as $metric) {
|
||||
$limit = $periods[$range]['limit'];
|
||||
$period = $periods[$range]['period'];
|
||||
|
@ -241,7 +246,7 @@ App::get('/v1/functions/:functionId/usage')
|
|||
new Query('period', Query::TYPE_EQUAL, [$period]),
|
||||
new Query('metric', Query::TYPE_EQUAL, [$metric]),
|
||||
], $limit, 0, ['time'], [Database::ORDER_DESC]);
|
||||
|
||||
|
||||
$stats[$metric] = [];
|
||||
foreach ($requestDocs as $requestDoc) {
|
||||
$stats[$metric][] = [
|
||||
|
@ -254,7 +259,7 @@ App::get('/v1/functions/:functionId/usage')
|
|||
$backfill = $limit - \count($requestDocs);
|
||||
while ($backfill > 0) {
|
||||
$last = $limit - $backfill - 1; // array index of last added metric
|
||||
$diff = match($period) { // convert period to seconds for unix timestamp math
|
||||
$diff = match ($period) { // convert period to seconds for unix timestamp math
|
||||
'30m' => 1800,
|
||||
'1d' => 86400,
|
||||
};
|
||||
|
@ -265,7 +270,7 @@ App::get('/v1/functions/:functionId/usage')
|
|||
$backfill--;
|
||||
}
|
||||
$stats[$metric] = array_reverse($stats[$metric]);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$usage = new Document([
|
||||
|
@ -283,7 +288,7 @@ App::put('/v1/functions/:functionId')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Update Function')
|
||||
->label('scope', 'functions.write')
|
||||
->label('event', 'functions.update')
|
||||
->label('event', 'functions.[functionId].update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'update')
|
||||
|
@ -295,18 +300,20 @@ App::put('/v1/functions/:functionId')
|
|||
->param('name', '', new Text(128), 'Function name. Max length: 128 chars.')
|
||||
->param('execute', [], new ArrayList(new Text(64)), 'An array of strings with execution permissions. By default no user is granted with any execute permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.')
|
||||
->param('vars', [], new Assoc(), 'Key-value JSON object that will be passed to the function as environment variables.', true)
|
||||
->param('events', [], new ArrayList(new WhiteList(array_keys(Config::getParam('events')), true)), 'Events list.', true)
|
||||
->param('events', [], new ArrayList(new ValidatorEvent()), 'Events list.', true)
|
||||
->param('schedule', '', new Cron(), 'Schedule CRON syntax.', true)
|
||||
->param('timeout', 15, new Range(1, (int) App::getEnv('_APP_FUNCTIONS_TIMEOUT', 900)), 'Maximum execution time in seconds.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('user')
|
||||
->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForProject, $project, $user) {
|
||||
->inject('events')
|
||||
->action(function ($functionId, $name, $execute, $vars, $events, $schedule, $timeout, $response, $dbForProject, $project, $user, $eventsInstance) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Appwrite\Auth\User $user */
|
||||
/** @var Appwrite\Event\Event $eventsInstance */
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
||||
|
@ -341,6 +348,8 @@ App::put('/v1/functions/:functionId')
|
|||
]); // Async task rescheduale
|
||||
}
|
||||
|
||||
$eventsInstance->setParam('functionId', $function->getId());
|
||||
|
||||
$response->dynamic($function, Response::MODEL_FUNCTION);
|
||||
});
|
||||
|
||||
|
@ -348,7 +357,7 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Update Function Deployment')
|
||||
->label('scope', 'functions.write')
|
||||
->label('event', 'functions.deployments.update')
|
||||
->label('event', 'functions.[functionId].deployments.[deploymentId].update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'updateDeployment')
|
||||
|
@ -361,10 +370,12 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId')
|
|||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->action(function ($functionId, $deploymentId, $response, $dbForProject, $project) {
|
||||
->inject('events')
|
||||
->action(function ($functionId, $deploymentId, $response, $dbForProject, $project, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
|
@ -404,6 +415,11 @@ App::patch('/v1/functions/:functionId/deployments/:deploymentId')
|
|||
'trigger' => 'schedule',
|
||||
]); // Async task rescheduale
|
||||
}
|
||||
|
||||
$events
|
||||
->setParam('functionId', $function->getId())
|
||||
->setParam('deploymentId', $deployment->getId());
|
||||
|
||||
$response->dynamic($function, Response::MODEL_FUNCTION);
|
||||
});
|
||||
|
||||
|
@ -411,7 +427,7 @@ App::delete('/v1/functions/:functionId')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Delete Function')
|
||||
->label('scope', 'functions.write')
|
||||
->label('event', 'functions.delete')
|
||||
->label('event', 'functions.[functionId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'delete')
|
||||
|
@ -422,10 +438,12 @@ App::delete('/v1/functions/:functionId')
|
|||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('deletes')
|
||||
->action(function ($functionId, $response, $dbForProject, $deletes) {
|
||||
->inject('events')
|
||||
->action(function ($functionId, $response, $dbForProject, $deletes, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
||||
|
@ -437,10 +455,12 @@ App::delete('/v1/functions/:functionId')
|
|||
throw new Exception('Failed to remove function from DB', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $function)
|
||||
;
|
||||
$deletes->setPayload([
|
||||
'type' => DELETE_TYPE_DOCUMENT,
|
||||
'document' => $function
|
||||
]);
|
||||
|
||||
$events->setParam('functionId', $function->getId());
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
@ -449,7 +469,7 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Create Deployment')
|
||||
->label('scope', 'functions.write')
|
||||
->label('event', 'functions.deployments.create')
|
||||
->label('event', 'functions.[functionId].deployments.[deploymentId].create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'createDeployment')
|
||||
|
@ -467,16 +487,16 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
->inject('user')
|
||||
->inject('events')
|
||||
->inject('project')
|
||||
->inject('deviceFunctions')
|
||||
->inject('deviceLocal')
|
||||
->action(function ($functionId, $entrypoint, $file, $activate, $request, $response, $dbForProject, $usage, $user, $project, $deviceFunctions, $deviceLocal) {
|
||||
->action(function ($functionId, $entrypoint, $file, $activate, $request, $response, $dbForProject, $usage, $events, $project, $deviceFunctions, $deviceLocal) {
|
||||
/** @var Utopia\Swoole\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Auth\User $user */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Database\Document $project */
|
||||
/** @var Utopia\Storage\Device $deviceFunctions */
|
||||
/** @var Utopia\Storage\Device $deviceLocal */
|
||||
|
@ -515,7 +535,7 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
$end = $request->getContentRangeEnd();
|
||||
$fileSize = $request->getContentRangeSize();
|
||||
$deploymentId = $request->getHeader('x-appwrite-id', $deploymentId);
|
||||
if(is_null($start) || is_null($end) || is_null($fileSize)) {
|
||||
if (is_null($start) || is_null($end) || is_null($fileSize)) {
|
||||
throw new Exception('Invalid content-range header', 400, Exception::STORAGE_INVALID_CONTENT_RANGE);
|
||||
}
|
||||
|
||||
|
@ -539,8 +559,8 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
|
||||
// Save to storage
|
||||
$fileSize ??= $deviceLocal->getFileSize($fileTmpName);
|
||||
$path = $deviceFunctions->getPath($deploymentId.'.'.\pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
|
||||
$path = $deviceFunctions->getPath($deploymentId . '.' . \pathinfo($fileName, PATHINFO_EXTENSION));
|
||||
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
|
||||
$metadata = ['content_type' => $deviceLocal->getFileMimeType($fileTmpName)];
|
||||
|
@ -560,7 +580,7 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
|
||||
$activate = (bool) filter_var($activate, FILTER_VALIDATE_BOOLEAN);
|
||||
|
||||
if($chunksUploaded === $chunks) {
|
||||
if ($chunksUploaded === $chunks) {
|
||||
if ($activate) {
|
||||
// Remove deploy for all other deployments.
|
||||
$activeDeployments = $dbForProject->find('deployments', [
|
||||
|
@ -574,7 +594,7 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
$dbForProject->updateDocument('deployments', $activeDeployment->getId(), $activeDeployment);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$fileSize = $deviceFunctions->getFileSize($path);
|
||||
|
||||
if ($deployment->isEmpty()) {
|
||||
|
@ -604,11 +624,9 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
'type' => BUILD_TYPE_DEPLOYMENT
|
||||
]);
|
||||
|
||||
$usage
|
||||
->setParam('storage', $deployment->getAttribute('size', 0))
|
||||
;
|
||||
$usage->setParam('storage', $deployment->getAttribute('size', 0));
|
||||
} else {
|
||||
if($deployment->isEmpty()) {
|
||||
if ($deployment->isEmpty()) {
|
||||
$deployment = $dbForProject->createDocument('deployments', new Document([
|
||||
'$id' => $deploymentId,
|
||||
'$read' => ['role:all'],
|
||||
|
@ -632,6 +650,10 @@ App::post('/v1/functions/:functionId/deployments')
|
|||
|
||||
$metadata = null;
|
||||
|
||||
$events
|
||||
->setParam('functionId', $function->getId())
|
||||
->setParam('deploymentId', $deployment->getId());
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($deployment, Response::MODEL_DEPLOYMENT);
|
||||
});
|
||||
|
@ -742,7 +764,7 @@ App::delete('/v1/functions/:functionId/deployments/:deploymentId')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Delete Deployment')
|
||||
->label('scope', 'functions.write')
|
||||
->label('event', 'functions.deployments.delete')
|
||||
->label('event', 'functions.[functionId].deployments.[deploymentId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'deleteDeployment')
|
||||
|
@ -755,19 +777,21 @@ App::delete('/v1/functions/:functionId/deployments/:deploymentId')
|
|||
->inject('dbForProject')
|
||||
->inject('usage')
|
||||
->inject('deletes')
|
||||
->inject('events')
|
||||
->inject('deviceFunctions')
|
||||
->action(function ($functionId, $deploymentId, $response, $dbForProject, $usage, $deletes, $deviceFunctions) {
|
||||
->action(function ($functionId, $deploymentId, $response, $dbForProject, $usage, $deletes, $events, $deviceFunctions) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $usage */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Utopia\Storage\Device $deviceFunctions */
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
if ($deployment->isEmpty()) {
|
||||
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
|
||||
|
@ -783,20 +807,24 @@ App::delete('/v1/functions/:functionId/deployments/:deploymentId')
|
|||
}
|
||||
}
|
||||
|
||||
if($function->getAttribute('deployment') === $deployment->getId()) { // Reset function deployment
|
||||
if ($function->getAttribute('deployment') === $deployment->getId()) { // Reset function deployment
|
||||
$function = $dbForProject->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
|
||||
'deployment' => '',
|
||||
])));
|
||||
}
|
||||
|
||||
$usage
|
||||
->setParam('storage', $deployment->getAttribute('size', 0) * -1)
|
||||
;
|
||||
->setParam('storage', $deployment->getAttribute('size', 0) * -1);
|
||||
|
||||
$events
|
||||
->setParam('functionId', $function->getId())
|
||||
->setParam('deploymentId', $deployment->getId());
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $deployment)
|
||||
;
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_DOCUMENT,
|
||||
'document' => $deployment
|
||||
]);
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
|
@ -805,7 +833,7 @@ App::post('/v1/functions/:functionId/executions')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Create Execution')
|
||||
->label('scope', 'execution.write')
|
||||
->label('event', 'functions.executions.create')
|
||||
->label('event', 'functions.[functionId].executions.[executionId].create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'createExecution')
|
||||
|
@ -822,13 +850,15 @@ App::post('/v1/functions/:functionId/executions')
|
|||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('user')
|
||||
->action(function ($functionId, $data, $async, $response, $project, $dbForProject, $user) {
|
||||
->inject('events')
|
||||
->action(function ($functionId, $data, $async, $response, $project, $dbForProject, $user, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId));
|
||||
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
|
||||
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
|
||||
|
@ -842,7 +872,7 @@ App::post('/v1/functions/:functionId/executions')
|
|||
throw new Exception('Runtime "' . $function->getAttribute('runtime', '') . '" is not supported', 400, Exception::FUNCTION_RUNTIME_UNSUPPORTED);
|
||||
}
|
||||
|
||||
$deployment = Authorization::skip(fn() => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', '')));
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deployment', '')));
|
||||
|
||||
if ($deployment->getAttribute('resourceId') !== $function->getId()) {
|
||||
throw new Exception('Deployment not found. Deploy deployment before trying to execute a function', 404, Exception::DEPLOYMENT_NOT_FOUND);
|
||||
|
@ -853,7 +883,7 @@ App::post('/v1/functions/:functionId/executions')
|
|||
}
|
||||
|
||||
/** Check if build has completed */
|
||||
$build = Authorization::skip(fn() => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
if ($build->isEmpty()) {
|
||||
throw new Exception('Build not found', 404, Exception::BUILD_NOT_FOUND);
|
||||
}
|
||||
|
@ -870,7 +900,7 @@ App::post('/v1/functions/:functionId/executions')
|
|||
|
||||
$executionId = $dbForProject->getId();
|
||||
|
||||
$execution = Authorization::skip(fn() => $dbForProject->createDocument('executions', new Document([
|
||||
$execution = Authorization::skip(fn () => $dbForProject->createDocument('executions', new Document([
|
||||
'$id' => $executionId,
|
||||
'$read' => (!$user->isEmpty()) ? ['user:' . $user->getId()] : [],
|
||||
'$write' => [],
|
||||
|
@ -892,13 +922,14 @@ App::post('/v1/functions/:functionId/executions')
|
|||
$sessions = $user->getAttribute('sessions', []);
|
||||
$current = new Document();
|
||||
|
||||
foreach ($sessions as $session) { /** @var Utopia\Database\Document $session */
|
||||
foreach ($sessions as $session) {
|
||||
/** @var Utopia\Database\Document $session */
|
||||
if ($session->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
|
||||
$current = $session;
|
||||
}
|
||||
}
|
||||
|
||||
if(!$current->isEmpty()) {
|
||||
if (!$current->isEmpty()) {
|
||||
$jwtObj = new JWT(App::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 900, 10); // Instantiate with key, algo, maxAge and leeway.
|
||||
$jwt = $jwtObj->encode([
|
||||
'userId' => $user->getId(),
|
||||
|
@ -907,19 +938,30 @@ App::post('/v1/functions/:functionId/executions')
|
|||
}
|
||||
}
|
||||
|
||||
if ($async) {
|
||||
Resque::enqueue(Event::FUNCTIONS_QUEUE_NAME, Event::FUNCTIONS_CLASS_NAME, [
|
||||
'projectId' => $project->getId(),
|
||||
'functionId' => $function->getId(),
|
||||
'webhooks' => $project->getAttribute('webhooks', []),
|
||||
'executionId' => $execution->getId(),
|
||||
'trigger' => 'http',
|
||||
$events
|
||||
->setParam('functionId', $function->getId())
|
||||
->setParam('executionId', $execution->getId())
|
||||
->setPayload([
|
||||
'data' => $data,
|
||||
'userId' => $user->getId(),
|
||||
'jwt' => $jwt,
|
||||
]);
|
||||
'jwt' => $jwt
|
||||
])
|
||||
->setTrigger($execution);
|
||||
|
||||
if ($async) {
|
||||
$event = new Event(Event::FUNCTIONS_QUEUE_NAME, Event::FUNCTIONS_CLASS_NAME);
|
||||
$event
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
->setTrigger($execution)
|
||||
->setPayload([
|
||||
'data' => $data,
|
||||
'jwt' => $jwt
|
||||
])
|
||||
->trigger();
|
||||
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
||||
return $response->dynamic($execution, Response::MODEL_EXECUTION);
|
||||
}
|
||||
|
||||
|
@ -966,7 +1008,7 @@ App::post('/v1/functions/:functionId/executions')
|
|||
Console::error($th->getMessage());
|
||||
}
|
||||
|
||||
Authorization::skip(fn() => $dbForProject->updateDocument('executions', $executionId, $execution));
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('executions', $executionId, $execution));
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
|
@ -996,7 +1038,7 @@ App::get('/v1/functions/:functionId/executions')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
|
||||
$function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId));
|
||||
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
|
||||
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
|
||||
|
@ -1046,7 +1088,7 @@ App::get('/v1/functions/:functionId/executions/:executionId')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
|
||||
$function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId));
|
||||
$function = Authorization::skip(fn () => $dbForProject->getDocument('functions', $functionId));
|
||||
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND);
|
||||
|
@ -1069,7 +1111,7 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
|
|||
->groups(['api', 'functions'])
|
||||
->desc('Retry Build')
|
||||
->label('scope', 'functions.write')
|
||||
->label('event', 'functions.deployments.update')
|
||||
->label('event', 'functions.[functionId].deployments.[deploymentId].update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'functions')
|
||||
->label('sdk.method', 'retryBuild')
|
||||
|
@ -1082,10 +1124,12 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
|
|||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->action(function ($functionId, $deploymentId, $buildId, $response, $dbForProject, $project) {
|
||||
->inject('events')
|
||||
->action(function ($functionId, $deploymentId, $buildId, $response, $dbForProject, $project, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
|
@ -1098,7 +1142,7 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
|
|||
throw new Exception('Deployment not found', 404, Exception::DEPLOYMENT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$build = Authorization::skip(fn() => $dbForProject->getDocument('builds', $buildId));
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $buildId));
|
||||
|
||||
if ($build->isEmpty()) {
|
||||
throw new Exception('Build not found', 404, Exception::BUILD_NOT_FOUND);
|
||||
|
@ -1108,6 +1152,10 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
|
|||
throw new Exception('Build not failed', 400, Exception::BUILD_IN_PROGRESS);
|
||||
}
|
||||
|
||||
$events
|
||||
->setParam('functionId', $function->getId())
|
||||
->setParam('deploymentId', $deployment->getId());
|
||||
|
||||
// Enqueue a message to start the build
|
||||
Resque::enqueue(Event::BUILDS_QUEUE_NAME, Event::BUILDS_CLASS_NAME, [
|
||||
'projectId' => $project->getId(),
|
||||
|
@ -1117,4 +1165,4 @@ App::post('/v1/functions/:functionId/deployments/:deploymentId/builds/:buildId')
|
|||
]);
|
||||
|
||||
$response->noContent();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Auth\Validator\Password;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Event\Validator\Event;
|
||||
use Appwrite\Network\Validator\CNAME;
|
||||
use Appwrite\Network\Validator\Domain as DomainValidator;
|
||||
|
@ -557,8 +558,10 @@ App::delete('/v1/projects/:projectId')
|
|||
}
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $project)
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_DOCUMENT,
|
||||
'document' => $project
|
||||
])
|
||||
;
|
||||
|
||||
if (!$dbForConsole->deleteDocument('teams', $project->getAttribute('teamId', null))) {
|
||||
|
@ -1390,10 +1393,12 @@ App::patch('/v1/projects/:projectId/domains/:domainId/verification')
|
|||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
// Issue a TLS certificate when domain is verified
|
||||
Resque::enqueue('v1-certificates', 'CertificatesV1', [
|
||||
'document' => $domain->getArrayCopy(),
|
||||
'domain' => $domain->getAttribute('domain'),
|
||||
]);
|
||||
$event = new Certificate();
|
||||
$event
|
||||
->setDomain($domain)
|
||||
->setValidateCNAME(true)
|
||||
->setValidateTarget(true)
|
||||
->trigger();
|
||||
|
||||
$response->dynamic($domain, Response::MODEL_DOMAIN);
|
||||
});
|
||||
|
@ -1436,8 +1441,10 @@ App::delete('/v1/projects/:projectId/domains/:domainId')
|
|||
$dbForConsole->deleteCachedDocument('projects', $project->getId());
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_CERTIFICATES)
|
||||
->setParam('document', $domain)
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_CERTIFICATES,
|
||||
'document' => $domain
|
||||
])
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
|
|
@ -39,7 +39,7 @@ App::post('/v1/storage/buckets')
|
|||
->desc('Create bucket')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'buckets.write')
|
||||
->label('event', 'storage.buckets.create')
|
||||
->label('event', 'buckets.[bucketId].create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'createBucket')
|
||||
|
@ -61,11 +61,13 @@ App::post('/v1/storage/buckets')
|
|||
->inject('dbForProject')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($bucketId, $name, $permission, $read, $write, $enabled, $maximumFileSize, $allowedFileExtensions, $encryption, $antivirus, $response, $dbForProject, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($bucketId, $name, $permission, $read, $write, $enabled, $maximumFileSize, $allowedFileExtensions, $encryption, $antivirus, $response, $dbForProject, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$bucketId = $bucketId === 'unique()' ? $dbForProject->getId() : $bucketId;
|
||||
try {
|
||||
|
@ -124,9 +126,12 @@ App::post('/v1/storage/buckets')
|
|||
}
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.buckets.create')
|
||||
->setParam('resource', 'storage/buckets/' . $bucket->getId())
|
||||
->setParam('data', $bucket->getArrayCopy())
|
||||
->setResource('storage/buckets/' . $bucket->getId())
|
||||
->setPayload($bucket->getArrayCopy())
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('bucketId', $bucket->getId())
|
||||
;
|
||||
|
||||
$usage->setParam('storage.buckets.create', 1);
|
||||
|
@ -213,7 +218,7 @@ App::put('/v1/storage/buckets/:bucketId')
|
|||
->desc('Update Bucket')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'buckets.write')
|
||||
->label('event', 'storage.buckets.update')
|
||||
->label('event', 'buckets.[bucketId].update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'updateBucket')
|
||||
|
@ -235,11 +240,13 @@ App::put('/v1/storage/buckets/:bucketId')
|
|||
->inject('dbForProject')
|
||||
->inject('audits')
|
||||
->inject('usage')
|
||||
->action(function ($bucketId, $name, $permission, $read, $write, $enabled, $maximumFileSize, $allowedFileExtensions, $encryption, $antivirus, $response, $dbForProject, $audits, $usage) {
|
||||
->inject('events')
|
||||
->action(function ($bucketId, $name, $permission, $read, $write, $enabled, $maximumFileSize, $allowedFileExtensions, $encryption, $antivirus, $response, $dbForProject, $audits, $usage, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$bucket = $dbForProject->getDocument('buckets', $bucketId);
|
||||
|
||||
|
@ -247,13 +254,13 @@ App::put('/v1/storage/buckets/:bucketId')
|
|||
throw new Exception('Bucket not found', 404, Exception::STORAGE_BUCKET_NOT_FOUND);
|
||||
}
|
||||
|
||||
$read??=$bucket->getAttribute('$read', []); // By default inherit read permissions
|
||||
$write??=$bucket->getAttribute('$write', []); // By default inherit write permissions
|
||||
$maximumFileSize??=$bucket->getAttribute('maximumFileSize', (int) App::getEnv('_APP_STORAGE_LIMIT', 0));
|
||||
$allowedFileExtensions??=$bucket->getAttribute('allowedFileExtensions', []);
|
||||
$enabled??=$bucket->getAttribute('enabled', true);
|
||||
$encryption??=$bucket->getAttribute('encryption', true);
|
||||
$antivirus??=$bucket->getAttribute('antivirus', true);
|
||||
$read ??= $bucket->getAttribute('$read', []); // By default inherit read permissions
|
||||
$write ??= $bucket->getAttribute('$write', []); // By default inherit write permissions
|
||||
$maximumFileSize ??= $bucket->getAttribute('maximumFileSize', (int) App::getEnv('_APP_STORAGE_LIMIT', 0));
|
||||
$allowedFileExtensions ??= $bucket->getAttribute('allowedFileExtensions', []);
|
||||
$enabled ??= $bucket->getAttribute('enabled', true);
|
||||
$encryption ??= $bucket->getAttribute('encryption', true);
|
||||
$antivirus ??= $bucket->getAttribute('antivirus', true);
|
||||
|
||||
$bucket = $dbForProject->updateDocument('buckets', $bucket->getId(), $bucket
|
||||
->setAttribute('name', $name)
|
||||
|
@ -268,9 +275,12 @@ App::put('/v1/storage/buckets/:bucketId')
|
|||
);
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.buckets.update')
|
||||
->setParam('resource', 'storage/buckets/' . $bucket->getId())
|
||||
->setParam('data', $bucket->getArrayCopy())
|
||||
->setResource('storage/buckets/' . $bucket->getId())
|
||||
->setPayload($bucket->getArrayCopy())
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('bucketId', $bucket->getId())
|
||||
;
|
||||
|
||||
$usage->setParam('storage.buckets.update', 1);
|
||||
|
@ -282,7 +292,7 @@ App::delete('/v1/storage/buckets/:bucketId')
|
|||
->desc('Delete Bucket')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'buckets.write')
|
||||
->label('event', 'storage.buckets.delete')
|
||||
->label('event', 'buckets.[bucketId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'deleteBucket')
|
||||
|
@ -299,7 +309,7 @@ App::delete('/v1/storage/buckets/:bucketId')
|
|||
->action(function ($bucketId, $response, $dbForProject, $audits, $deletes, $events, $usage) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
|
@ -315,18 +325,21 @@ App::delete('/v1/storage/buckets/:bucketId')
|
|||
}
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $bucket)
|
||||
->setParam('bucketId', $bucket->getId())
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_DOCUMENT,
|
||||
'document' => $bucket
|
||||
])
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($bucket, Response::MODEL_BUCKET))
|
||||
->setParam('bucketId', $bucket->getId())
|
||||
->setPayload($response->output($bucket, Response::MODEL_BUCKET))
|
||||
;
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.buckets.delete')
|
||||
->setParam('resource', 'storage/buckets/' . $bucket->getId())
|
||||
->setParam('data', $bucket->getArrayCopy())
|
||||
->setResource('storage/buckets/' . $bucket->getId())
|
||||
->setPayload($bucket->getArrayCopy())
|
||||
;
|
||||
|
||||
$usage->setParam('storage.buckets.delete', 1);
|
||||
|
@ -339,7 +352,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
->desc('Create File')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'files.write')
|
||||
->label('event', 'storage.files.create')
|
||||
->label('event', 'buckets.[bucketId].files.[fileId].create')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'createFile')
|
||||
|
@ -369,7 +382,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Utopia\Storage\Device $deviceFiles */
|
||||
|
@ -581,9 +594,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
'metadata' => $metadata,
|
||||
]);
|
||||
if ($permissionBucket) {
|
||||
$file = Authorization::skip(function () use ($dbForProject, $bucket, $doc) {
|
||||
return $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc);
|
||||
});
|
||||
$file = Authorization::skip(fn () => $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc));
|
||||
} else {
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc);
|
||||
}
|
||||
|
@ -603,9 +614,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
->setAttribute('chunksUploaded', $chunksUploaded);
|
||||
|
||||
if ($permissionBucket) {
|
||||
$file = Authorization::skip(function () use ($dbForProject, $bucket, $fileId, $file) {
|
||||
return $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
|
||||
});
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file));
|
||||
} else {
|
||||
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
|
||||
}
|
||||
|
@ -618,8 +627,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
}
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.files.create')
|
||||
->setParam('resource', 'storage/files/' . $file->getId())
|
||||
->setResource('storage/files/' . $file->getId())
|
||||
;
|
||||
|
||||
$usage
|
||||
|
@ -651,9 +659,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
'metadata' => $metadata,
|
||||
]);
|
||||
if ($permissionBucket) {
|
||||
$file = Authorization::skip(function () use ($dbForProject, $bucket, $doc) {
|
||||
return $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc);
|
||||
});
|
||||
$file = Authorization::skip(fn () => $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc));
|
||||
} else {
|
||||
$file = $dbForProject->createDocument('bucket_' . $bucket->getInternalId(), $doc);
|
||||
}
|
||||
|
@ -663,9 +669,7 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
->setAttribute('metadata', $metadata);
|
||||
|
||||
if ($permissionBucket) {
|
||||
$file = Authorization::skip(function () use ($dbForProject, $bucket, $fileId, $file) {
|
||||
return $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
|
||||
});
|
||||
$file = Authorization::skip(fn () => $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file));
|
||||
} else {
|
||||
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
|
||||
}
|
||||
|
@ -677,13 +681,16 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
|||
}
|
||||
}
|
||||
|
||||
$events->setParam('bucket', $bucket->getArrayCopy());
|
||||
$events
|
||||
->setParam('bucketId', $bucket->getId())
|
||||
->setParam('fileId', $file->getId())
|
||||
->setTrigger($bucket)
|
||||
;
|
||||
|
||||
$metadata = null; // was causing leaks as it was passed by reference
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
$response->dynamic($file, Response::MODEL_FILE);
|
||||
;
|
||||
});
|
||||
|
||||
App::get('/v1/storage/buckets/:bucketId/files')
|
||||
|
@ -1323,7 +1330,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
|||
->desc('Update File')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'files.write')
|
||||
->label('event', 'storage.files.update')
|
||||
->label('event', 'buckets.[bucketId].files.[fileId].update')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'updateFile')
|
||||
|
@ -1346,7 +1353,7 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
|||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var string $mode */
|
||||
|
@ -1405,13 +1412,14 @@ App::put('/v1/storage/buckets/:bucketId/files/:fileId')
|
|||
$file = $dbForProject->updateDocument('bucket_' . $bucket->getInternalId(), $fileId, $file);
|
||||
}
|
||||
|
||||
$events->setParam('bucket', $bucket->getArrayCopy());
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.files.update')
|
||||
->setParam('resource', 'file/' . $file->getId())
|
||||
$events
|
||||
->setParam('bucketId', $bucket->getId())
|
||||
->setParam('fileId', $file->getId())
|
||||
->setTrigger($bucket)
|
||||
;
|
||||
|
||||
$audits->setResource('file/' . $file->getId());
|
||||
|
||||
$usage
|
||||
->setParam('storage.files.update', 1)
|
||||
->setParam('bucketId', $bucketId)
|
||||
|
@ -1425,7 +1433,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
|||
->desc('Delete File')
|
||||
->groups(['api', 'storage'])
|
||||
->label('scope', 'files.write')
|
||||
->label('event', 'storage.files.delete')
|
||||
->label('event', 'buckets.[bucketId].files.[fileId].delete')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'storage')
|
||||
->label('sdk.method', 'deleteFile')
|
||||
|
@ -1447,7 +1455,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
|||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Utopia\Storage\Device $deviceFiles */
|
||||
/** @var string $mode */
|
||||
|
@ -1505,10 +1513,7 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
|||
throw new Exception('Failed to delete file from device', 500, Exception::GENERAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('event', 'storage.files.delete')
|
||||
->setParam('resource', 'file/' . $file->getId())
|
||||
;
|
||||
$audits->setResource('file/' . $file->getId());
|
||||
|
||||
$usage
|
||||
->setParam('storage', $file->getAttribute('size', 0) * -1)
|
||||
|
@ -1517,8 +1522,10 @@ App::delete('/v1/storage/buckets/:bucketId/files/:fileId')
|
|||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($file, Response::MODEL_FILE))
|
||||
->setParam('bucket', $bucket->getArrayCopy())
|
||||
->setParam('bucketId', $bucket->getId())
|
||||
->setParam('fileId', $file->getId())
|
||||
->setTrigger($bucket)
|
||||
->setPayload($response->output($file, Response::MODEL_FILE))
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
|
|
@ -26,7 +26,7 @@ use Utopia\Validator\WhiteList;
|
|||
App::post('/v1/teams')
|
||||
->desc('Create Team')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.create')
|
||||
->label('event', 'teams.[teamId].create')
|
||||
->label('scope', 'teams.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
|
@ -85,6 +85,8 @@ App::post('/v1/teams')
|
|||
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
}
|
||||
|
||||
$events->setParam('teamId', $team->getId());
|
||||
|
||||
if (!empty($user->getId())) {
|
||||
$events->setParam('userId', $user->getId());
|
||||
}
|
||||
|
@ -169,7 +171,7 @@ App::get('/v1/teams/:teamId')
|
|||
App::put('/v1/teams/:teamId')
|
||||
->desc('Update Team')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.update')
|
||||
->label('event', 'teams.[teamId].update')
|
||||
->label('scope', 'teams.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
|
@ -182,9 +184,11 @@ App::put('/v1/teams/:teamId')
|
|||
->param('name', null, new Text(128), 'New team name. Max length: 128 chars.')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->action(function ($teamId, $name, $response, $dbForProject) {
|
||||
->inject('events')
|
||||
->action(function ($teamId, $name, $response, $dbForProject, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
|
||||
|
@ -197,13 +201,15 @@ App::put('/v1/teams/:teamId')
|
|||
->setAttribute('search', implode(' ', [$teamId, $name]))
|
||||
);
|
||||
|
||||
$events->setParam('teamId', $team->getId());
|
||||
|
||||
$response->dynamic($team, Response::MODEL_TEAM);
|
||||
});
|
||||
|
||||
App::delete('/v1/teams/:teamId')
|
||||
->desc('Delete Team')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.delete')
|
||||
->label('event', 'teams.[teamId].delete')
|
||||
->label('scope', 'teams.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
|
@ -244,12 +250,17 @@ App::delete('/v1/teams/:teamId')
|
|||
}
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $team)
|
||||
->setParam('teamId', $team->getId())
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_DOCUMENT,
|
||||
'document' => $team
|
||||
])
|
||||
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($team, Response::MODEL_TEAM))
|
||||
->setParam('teamId', $team->getId())
|
||||
->setPayload($response->output($team, Response::MODEL_TEAM))
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
@ -258,7 +269,7 @@ App::delete('/v1/teams/:teamId')
|
|||
App::post('/v1/teams/:teamId/memberships')
|
||||
->desc('Create Team Membership')
|
||||
->groups(['api', 'teams', 'auth'])
|
||||
->label('event', 'teams.memberships.create')
|
||||
->label('event', 'teams.[teamId].memberships.[membershipId].create')
|
||||
->label('scope', 'teams.write')
|
||||
->label('auth.type', 'invites')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
|
@ -281,13 +292,15 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
->inject('locale')
|
||||
->inject('audits')
|
||||
->inject('mails')
|
||||
->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForProject, $locale, $audits, $mails) {
|
||||
->inject('events')
|
||||
->action(function ($teamId, $email, $roles, $url, $name, $response, $project, $user, $dbForProject, $locale, $audits, $mails, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Event $mails */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Mail $mails */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
if(empty(App::getEnv('_APP_SMTP_HOST'))) {
|
||||
throw new Exception('SMTP Disabled', 503, Exception::GENERAL_SMTP_DISABLED);
|
||||
|
@ -398,24 +411,24 @@ App::post('/v1/teams/:teamId/memberships')
|
|||
|
||||
if (!$isPrivilegedUser && !$isAppUser) { // No need of confirmation when in admin or app mode
|
||||
$mails
|
||||
->setParam('event', 'teams.memberships.create')
|
||||
->setParam('from', $project->getId())
|
||||
->setParam('recipient', $email)
|
||||
->setParam('name', $name)
|
||||
->setParam('url', $url)
|
||||
->setParam('locale', $locale->default)
|
||||
->setParam('project', $project->getAttribute('name', ['[APP-NAME]']))
|
||||
->setParam('owner', $user->getAttribute('name', ''))
|
||||
->setParam('team', $team->getAttribute('name', '[TEAM-NAME]'))
|
||||
->setParam('type', MAIL_TYPE_INVITATION)
|
||||
->setType(MAIL_TYPE_INVITATION)
|
||||
->setRecipient($email)
|
||||
->setUrl($url)
|
||||
->setName($name)
|
||||
->setLocale($locale->default)
|
||||
->setTeam($team)
|
||||
->setUser($user)
|
||||
->trigger()
|
||||
;
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('userId', $invitee->getId())
|
||||
->setParam('event', 'teams.memberships.create')
|
||||
->setParam('resource', 'team/'.$teamId)
|
||||
->setResource('team/'.$teamId)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('teamId', $team->getId())
|
||||
->setParam('membershipId', $membership->getId())
|
||||
;
|
||||
|
||||
$response->setStatusCode(Response::STATUS_CODE_CREATED);
|
||||
|
@ -548,7 +561,7 @@ App::get('/v1/teams/:teamId/memberships/:membershipId')
|
|||
App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->desc('Update Membership Roles')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.memberships.update')
|
||||
->label('event', 'teams.[teamId].memberships.[membershipId].update')
|
||||
->label('scope', 'teams.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
|
@ -565,12 +578,14 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('audits')
|
||||
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForProject, $audits) {
|
||||
->inject('events')
|
||||
->action(function ($teamId, $membershipId, $roles, $request, $response, $user, $dbForProject, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
if ($team->isEmpty()) {
|
||||
|
@ -612,10 +627,11 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
|
||||
Authorization::skip(fn () => $dbForProject->updateDocument('users', $profile->getId(), $profile));
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'teams.memberships.update')
|
||||
->setParam('resource', 'team/' . $teamId);
|
||||
$audits->setResource('team/' . $teamId);
|
||||
|
||||
$events
|
||||
->setParam('teamId', $team->getId())
|
||||
->setParam('membershipId', $membership->getId());
|
||||
|
||||
$response->dynamic(
|
||||
$membership
|
||||
|
@ -628,7 +644,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId')
|
|||
App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
||||
->desc('Update Team Membership Status')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.memberships.update.status')
|
||||
->label('event', 'teams.[teamId].memberships.[membershipId].update.status')
|
||||
->label('scope', 'public')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
|
@ -647,13 +663,15 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
->inject('dbForProject')
|
||||
->inject('geodb')
|
||||
->inject('audits')
|
||||
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForProject, $geodb, $audits) {
|
||||
->inject('events')
|
||||
->action(function ($teamId, $membershipId, $userId, $secret, $request, $response, $user, $dbForProject, $geodb, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var MaxMind\Db\Reader $geodb */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
|
@ -677,7 +695,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
throw new Exception('Secret key not valid', 401, Exception::TEAM_INVALID_SECRET);
|
||||
}
|
||||
|
||||
if ($userId != $membership->getAttribute('userId')) {
|
||||
if ($userId !== $membership->getAttribute('userId')) {
|
||||
throw new Exception('Invite does not belong to current user ('.$user->getAttribute('email').')', 401, Exception::TEAM_INVITE_MISMATCH);
|
||||
}
|
||||
|
||||
|
@ -737,10 +755,11 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
|
||||
$team = Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team->setAttribute('total', $team->getAttribute('total', 0) + 1)));
|
||||
|
||||
$audits
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', 'teams.memberships.update.status')
|
||||
->setParam('resource', 'team/'.$teamId)
|
||||
$audits->setResource('team/'.$teamId);
|
||||
|
||||
$events
|
||||
->setParam('teamId', $team->getId())
|
||||
->setParam('membershipId', $membership->getId())
|
||||
;
|
||||
|
||||
if (!Config::getParam('domainVerification')) {
|
||||
|
@ -763,7 +782,7 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
||||
->desc('Delete Team Membership')
|
||||
->groups(['api', 'teams'])
|
||||
->label('event', 'teams.memberships.delete')
|
||||
->label('event', 'teams.[teamId].memberships.[membershipId].delete')
|
||||
->label('scope', 'teams.write')
|
||||
->label('sdk.auth', [APP_AUTH_TYPE_SESSION, APP_AUTH_TYPE_KEY, APP_AUTH_TYPE_JWT])
|
||||
->label('sdk.namespace', 'teams')
|
||||
|
@ -780,7 +799,7 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
|||
->action(function ($teamId, $membershipId, $response, $dbForProject, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$membership = $dbForProject->getDocument('memberships', $membershipId);
|
||||
|
@ -833,14 +852,12 @@ App::delete('/v1/teams/:teamId/memberships/:membershipId')
|
|||
Authorization::skip(fn() => $dbForProject->updateDocument('teams', $team->getId(), $team));
|
||||
}
|
||||
|
||||
$audits
|
||||
->setParam('userId', $membership->getAttribute('userId'))
|
||||
->setParam('event', 'teams.memberships.delete')
|
||||
->setParam('resource', 'team/'.$teamId)
|
||||
;
|
||||
$audits->setResource('team/'.$teamId);
|
||||
|
||||
$events
|
||||
->setParam('eventData', $response->output($membership, Response::MODEL_MEMBERSHIP))
|
||||
->setParam('teamId', $team->getId())
|
||||
->setParam('membershipId', $membership->getId())
|
||||
->setPayload($response->output($membership, Response::MODEL_MEMBERSHIP))
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
|
|
@ -466,7 +466,7 @@ App::patch('/v1/users/:userId/name')
|
|||
->action(function ($userId, $name, $response, $dbForProject, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
@ -478,9 +478,7 @@ App::patch('/v1/users/:userId/name')
|
|||
$user = $dbForProject->updateDocument('users', $user->getId(), $user->setAttribute('name', $name));
|
||||
|
||||
$audits
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
->setResource('user/'.$user->getId())
|
||||
;
|
||||
|
||||
$events
|
||||
|
@ -511,7 +509,7 @@ App::patch('/v1/users/:userId/password')
|
|||
->action(function ($userId, $password, $response, $dbForProject, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
@ -527,9 +525,7 @@ App::patch('/v1/users/:userId/password')
|
|||
$user = $dbForProject->updateDocument('users', $user->getId(), $user);
|
||||
|
||||
$audits
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
->setResource('user/'.$user->getId())
|
||||
;
|
||||
|
||||
$events
|
||||
|
@ -560,7 +556,7 @@ App::patch('/v1/users/:userId/email')
|
|||
->action(function ($userId, $email, $response, $dbForProject, $audits, $events) {
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
|
||||
$user = $dbForProject->getDocument('users', $userId);
|
||||
|
@ -584,9 +580,7 @@ App::patch('/v1/users/:userId/email')
|
|||
|
||||
|
||||
$audits
|
||||
->setPayload(array_merge($audits->getPayload(), [
|
||||
'resource' => 'user/'.$user->getId()
|
||||
]))
|
||||
->setResource('user/'.$user->getId())
|
||||
;
|
||||
|
||||
$events
|
||||
|
@ -690,6 +684,7 @@ App::delete('/v1/users/:userId/sessions/:sessionId')
|
|||
|
||||
$events
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('sessionId', $sessionId)
|
||||
;
|
||||
|
||||
$response->noContent();
|
||||
|
@ -794,8 +789,11 @@ App::delete('/v1/users/:userId')
|
|||
$dbForProject->updateDocument('users', $userId, $user);
|
||||
|
||||
$deletes
|
||||
->setParam('type', DELETE_TYPE_DOCUMENT)
|
||||
->setParam('document', $clone)
|
||||
->setParam('userId', $userId)
|
||||
->setPayload([
|
||||
'type' => DELETE_TYPE_DOCUMENT,
|
||||
'document' => $clone
|
||||
])
|
||||
;
|
||||
|
||||
$events
|
||||
|
|
|
@ -12,6 +12,7 @@ use Appwrite\Extend\Exception;
|
|||
use Utopia\Config\Config;
|
||||
use Utopia\Domains\Domain;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Event\Certificate;
|
||||
use Appwrite\Network\Validator\Origin;
|
||||
use Appwrite\Utopia\Response\Filters\V11 as ResponseV11;
|
||||
use Appwrite\Utopia\Response\Filters\V12 as ResponseV12;
|
||||
|
@ -90,12 +91,10 @@ App::init(function ($utopia, $request, $response, $console, $project, $dbForCons
|
|||
|
||||
Console::info('Issuing a TLS certificate for the master domain (' . $domain->get() . ') in a few seconds...');
|
||||
|
||||
Resque::enqueue('v1-certificates', 'CertificatesV1', [
|
||||
'document' => $domainDocument,
|
||||
'domain' => $domain->get(),
|
||||
'validateTarget' => false,
|
||||
'validateCNAME' => false,
|
||||
]);
|
||||
$event = new Certificate();
|
||||
$event
|
||||
->setDomain($domainDocument)
|
||||
->trigger();
|
||||
}
|
||||
|
||||
$domains[$domain->get()] = true;
|
||||
|
|
|
@ -7,14 +7,16 @@ use Utopia\App;
|
|||
use Appwrite\Extend\Exception;
|
||||
use Utopia\Abuse\Abuse;
|
||||
use Utopia\Abuse\Adapters\TimeLimit;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Storage\Device\DOSpaces;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Device\S3;
|
||||
use Utopia\Storage\Storage;
|
||||
|
||||
App::init(function ($utopia, $request, $response, $project, $user, $events, $audits, $usage, $deletes, $database, $dbForProject, $mode) {
|
||||
App::init(function ($utopia, $request, $response, $project, $user, $events, $audits, $mails, $usage, $deletes, $database, $dbForProject, $mode) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
|
@ -22,7 +24,8 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud
|
|||
/** @var Utopia\Database\Document $user */
|
||||
/** @var Utopia\Registry\Registry $register */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Event\Mail $mails */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
|
@ -94,28 +97,18 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud
|
|||
->setUser($user)
|
||||
;
|
||||
|
||||
$events
|
||||
->setParam('projectId', $project->getId())
|
||||
->setParam('webhooks', $project->getAttribute('webhooks', []))
|
||||
->setParam('userId', $user->getId())
|
||||
->setParam('event', $route->getLabel('event', ''))
|
||||
->setParam('eventData', [])
|
||||
->setParam('functionId', null)
|
||||
->setParam('executionId', null)
|
||||
->setParam('trigger', 'event')
|
||||
$mails
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
;
|
||||
|
||||
$audits
|
||||
->setMode($mode)
|
||||
->setUserAgent($request->getUserAgent(''))
|
||||
->setIP($request->getIP())
|
||||
->setEvent($route->getLabel('event', ''))
|
||||
->setProject($project)
|
||||
->setUser($user)
|
||||
->setPayload([
|
||||
'mode' => $mode,
|
||||
'userAgent' => $request->getUserAgent(''),
|
||||
'ip' => $request->getIP(),
|
||||
'data' => [],
|
||||
'resource' => ''
|
||||
])
|
||||
;
|
||||
|
||||
$usage
|
||||
|
@ -128,15 +121,10 @@ App::init(function ($utopia, $request, $response, $project, $user, $events, $aud
|
|||
->setParam('networkResponseSize', 0)
|
||||
->setParam('storage', 0)
|
||||
;
|
||||
|
||||
$deletes
|
||||
->setParam('projectId', $project->getId())
|
||||
;
|
||||
|
||||
$database
|
||||
->setParam('projectId', $project->getId())
|
||||
;
|
||||
}, ['utopia', 'request', 'response', 'project', 'user', 'events', 'audits', 'usage', 'deletes', 'database', 'dbForProject', 'mode'], 'api');
|
||||
$deletes->setProject($project);
|
||||
$database->setProject($project);
|
||||
}, ['utopia', 'request', 'response', 'project', 'user', 'events', 'audits', 'mails', 'usage', 'deletes', 'database', 'dbForProject', 'mode'], 'api');
|
||||
|
||||
App::init(function ($utopia, $request, $project) {
|
||||
/** @var Utopia\App $utopia */
|
||||
|
@ -191,56 +179,53 @@ App::init(function ($utopia, $request, $project) {
|
|||
|
||||
}, ['utopia', 'request', 'project'], 'auth');
|
||||
|
||||
App::shutdown(function ($utopia, $request, $response, $project, $events, $audits, $usage, $deletes, $database, $mode) {
|
||||
App::shutdown(function ($utopia, $request, $response, $project, $events, $audits, $usage, $deletes, $database, $mode, $dbForProject) {
|
||||
/** @var Utopia\App $utopia */
|
||||
/** @var Appwrite\Utopia\Request $request */
|
||||
/** @var Appwrite\Utopia\Response $response */
|
||||
/** @var Utopia\Database\Document $project */
|
||||
/** @var Appwrite\Event\Event $events */
|
||||
/** @var Appwrite\Event\Event $audits */
|
||||
/** @var Appwrite\Event\Audit $audits */
|
||||
/** @var Appwrite\Stats\Stats $usage */
|
||||
/** @var Appwrite\Event\Event $deletes */
|
||||
/** @var Appwrite\Event\Event $database */
|
||||
/** @var Appwrite\Event\Database $database */
|
||||
/** @var bool $mode */
|
||||
/** @var Utopia\Database\Database $dbForProject */
|
||||
|
||||
if (!empty($events->getEvent())) {
|
||||
$allEvents = Event::generateEvents($events->getEvent(), $events->getParams());
|
||||
var_dump($request->getRoute()->getPath(), $events->getEvent(), $allEvents);
|
||||
foreach ($project->getAttribute('webhooks', []) as $webhook) {
|
||||
/**
|
||||
* @var Document $webhook
|
||||
*/
|
||||
if (array_intersect($webhook->getAttribute('events', []), $allEvents)) {
|
||||
$events
|
||||
->setClass(Event::WEBHOOK_CLASS_NAME)
|
||||
->setQueue(Event::WEBHOOK_QUEUE_NAME)
|
||||
->setTrigger($webhook)
|
||||
->setPayload($response->getPayload())
|
||||
->trigger();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($events->getParam('event'))) {
|
||||
if (empty($events->getParam('eventData'))) {
|
||||
$events->setParam('eventData', $response->getPayload());
|
||||
}
|
||||
|
||||
$functions = clone $events;
|
||||
|
||||
$functions
|
||||
->setQueue('v1-functions')
|
||||
->setClass('FunctionsV1')
|
||||
/**
|
||||
* Trigger functions.
|
||||
*/
|
||||
$events
|
||||
->setClass(Event::FUNCTIONS_CLASS_NAME)
|
||||
->setQueue(Event::FUNCTIONS_QUEUE_NAME)
|
||||
->setPayload($response->getPayload())
|
||||
->trigger();
|
||||
|
||||
/**
|
||||
* Trigger webhooks.
|
||||
*/
|
||||
$events
|
||||
->setClass(Event::WEBHOOK_CLASS_NAME)
|
||||
->setQueue(Event::WEBHOOK_QUEUE_NAME)
|
||||
->setPayload($response->getPayload())
|
||||
->trigger();
|
||||
|
||||
/**
|
||||
* Trigger realtime.
|
||||
*/
|
||||
if ($project->getId() !== 'console') {
|
||||
$allEvents = Event::generateEvents($events->getEvent(), $events->getParams());
|
||||
$payload = new Document($response->getPayload());
|
||||
$collection = new Document($events->getParam('collection') ?? []);
|
||||
$bucket = new Document($events->getParam('bucket') ?? []);
|
||||
$trigger = $events->getTrigger() ?? false;
|
||||
|
||||
$collection = ($trigger && $trigger->getCollection() === 'collections') ? $trigger : null;
|
||||
$bucket = ($trigger && $trigger->getCollection() === 'buckets') ? $trigger : null;
|
||||
|
||||
$target = Realtime::fromPayload(
|
||||
event: $events->getParam('event'),
|
||||
payload: $payload,
|
||||
project: $project,
|
||||
event: $allEvents[0],
|
||||
payload: $payload,
|
||||
project: $project,
|
||||
collection: $collection,
|
||||
bucket: $bucket,
|
||||
);
|
||||
|
@ -248,7 +233,7 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
|
|||
Realtime::send(
|
||||
$target['projectId'] ?? $project->getId(),
|
||||
$response->getPayload(),
|
||||
$events->getParam('event'),
|
||||
$allEvents[0],
|
||||
$target['channels'],
|
||||
$target['roles'],
|
||||
[
|
||||
|
@ -259,15 +244,18 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
|
|||
}
|
||||
}
|
||||
|
||||
if (!empty($audits->getEvent())) {
|
||||
if (!empty($audits->getResource())) {
|
||||
foreach ($events->getParams() as $key => $value) {
|
||||
$audits->setParam($key, $value);
|
||||
}
|
||||
$audits->trigger();
|
||||
}
|
||||
|
||||
if (!empty($deletes->getParam('type')) && !empty($deletes->getParam('document'))) {
|
||||
if (!empty($deletes->getPayload())) {
|
||||
$deletes->trigger();
|
||||
}
|
||||
|
||||
if (!empty($database->getParam('type')) && !empty($database->getParam('document'))) {
|
||||
if (!empty($database->getType())) {
|
||||
$database->trigger();
|
||||
}
|
||||
|
||||
|
@ -277,11 +265,11 @@ App::shutdown(function ($utopia, $request, $response, $project, $events, $audits
|
|||
&& $mode !== APP_MODE_ADMIN // TODO: add check to make sure user is admin
|
||||
&& !empty($route->getLabel('sdk.namespace', null))) { // Don't calculate console usage on admin mode
|
||||
|
||||
$usage
|
||||
->setParam('networkRequestSize', $request->getSize() + $usage->getParam('storage'))
|
||||
->setParam('networkResponseSize', $response->getSize())
|
||||
->submit()
|
||||
;
|
||||
// $usage
|
||||
// ->setParam('networkRequestSize', $request->getSize() + $usage->getParam('storage'))
|
||||
// ->setParam('networkResponseSize', $response->getSize())
|
||||
// ->submit()
|
||||
// ;
|
||||
}
|
||||
|
||||
}, ['utopia', 'request', 'response', 'project', 'events', 'audits', 'usage', 'deletes', 'database', 'mode'], 'api');
|
||||
}, ['utopia', 'request', 'response', 'project', 'events', 'audits', 'usage', 'deletes', 'database', 'mode', 'dbForProject'], 'api');
|
12
app/init.php
12
app/init.php
|
@ -22,7 +22,11 @@ use Ahc\Jwt\JWT;
|
|||
use Ahc\Jwt\JWTException;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Auth\Auth;
|
||||
use Appwrite\Event\Audit;
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Network\Validator\Email;
|
||||
use Appwrite\Network\Validator\IP;
|
||||
use Appwrite\Network\Validator\URL;
|
||||
|
@ -604,10 +608,10 @@ App::setResource('locale', fn() => new Locale(App::getEnv('_APP_LOCALE', 'en')))
|
|||
|
||||
// Queues
|
||||
App::setResource('events', fn() => new Event('', ''));
|
||||
App::setResource('audits', fn() => new Event(Event::AUDITS_QUEUE_NAME, Event::AUDITS_CLASS_NAME));
|
||||
App::setResource('mails', fn() => new Event(Event::MAILS_QUEUE_NAME, Event::MAILS_CLASS_NAME));
|
||||
App::setResource('deletes', fn() => new Event(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME));
|
||||
App::setResource('database', fn() => new Event(Event::DATABASE_QUEUE_NAME, Event::DATABASE_CLASS_NAME));
|
||||
App::setResource('audits', fn() => new Audit());
|
||||
App::setResource('mails', fn() => new Mail());
|
||||
App::setResource('deletes', fn() => new Delete());
|
||||
App::setResource('database', fn() => new EventDatabase());
|
||||
App::setResource('usage', function($register) {
|
||||
return new Stats($register->get('statsd'));
|
||||
}, ['register']);
|
||||
|
|
|
@ -11,46 +11,56 @@ $cli
|
|||
->desc('Schedules maintenance tasks and publishes them to resque')
|
||||
->action(function () {
|
||||
Console::title('Maintenance V1');
|
||||
Console::success(APP_NAME.' maintenance process v1 has started');
|
||||
Console::success(APP_NAME . ' maintenance process v1 has started');
|
||||
|
||||
function notifyDeleteExecutionLogs(int $interval)
|
||||
{
|
||||
Resque::enqueue(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME, [
|
||||
'type' => DELETE_TYPE_EXECUTIONS,
|
||||
'timestamp' => time() - $interval
|
||||
'payload' => [
|
||||
'type' => DELETE_TYPE_EXECUTIONS,
|
||||
'timestamp' => time() - $interval
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function notifyDeleteAbuseLogs(int $interval)
|
||||
function notifyDeleteAbuseLogs(int $interval)
|
||||
{
|
||||
Resque::enqueue(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME, [
|
||||
'type' => DELETE_TYPE_ABUSE,
|
||||
'timestamp' => time() - $interval
|
||||
'payload' => [
|
||||
'type' => DELETE_TYPE_ABUSE,
|
||||
'timestamp' => time() - $interval
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function notifyDeleteAuditLogs(int $interval)
|
||||
function notifyDeleteAuditLogs(int $interval)
|
||||
{
|
||||
Resque::enqueue(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME, [
|
||||
'type' => DELETE_TYPE_AUDIT,
|
||||
'timestamp' => time() - $interval
|
||||
'payload' => [
|
||||
'type' => DELETE_TYPE_AUDIT,
|
||||
'timestamp' => time() - $interval
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function notifyDeleteUsageStats(int $interval30m, int $interval1d)
|
||||
function notifyDeleteUsageStats(int $interval30m, int $interval1d)
|
||||
{
|
||||
Resque::enqueue(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME, [
|
||||
'type' => DELETE_TYPE_USAGE,
|
||||
'timestamp1d' => time() - $interval1d,
|
||||
'timestamp30m' => time() - $interval30m,
|
||||
'payload' => [
|
||||
'type' => DELETE_TYPE_USAGE,
|
||||
'timestamp1d' => time() - $interval1d,
|
||||
'timestamp30m' => time() - $interval30m,
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
function notifyDeleteConnections()
|
||||
function notifyDeleteConnections()
|
||||
{
|
||||
Resque::enqueue(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME, [
|
||||
'type' => DELETE_TYPE_REALTIME,
|
||||
'timestamp' => time() - 60
|
||||
'payload' => [
|
||||
'type' => DELETE_TYPE_REALTIME,
|
||||
'timestamp' => time() - 60
|
||||
]
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -59,10 +69,10 @@ $cli
|
|||
$executionLogsRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_EXECUTION', '1209600');
|
||||
$auditLogRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_AUDIT', '1209600');
|
||||
$abuseLogsRetention = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_ABUSE', '86400');
|
||||
$usageStatsRetention30m = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_30M', '129600');//36 hours
|
||||
$usageStatsRetention30m = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_30M', '129600'); //36 hours
|
||||
$usageStatsRetention1d = (int) App::getEnv('_APP_MAINTENANCE_RETENTION_USAGE_1D', '8640000'); // 100 days
|
||||
|
||||
Console::loop(function() use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d) {
|
||||
Console::loop(function () use ($interval, $executionLogsRetention, $abuseLogsRetention, $auditLogRetention, $usageStatsRetention30m, $usageStatsRetention1d) {
|
||||
$time = date('d-m-Y H:i:s', time());
|
||||
Console::info("[{$time}] Notifying deletes workers every {$interval} seconds");
|
||||
notifyDeleteExecutionLogs($executionLogsRetention);
|
||||
|
@ -71,4 +81,4 @@ $cli
|
|||
notifyDeleteUsageStats($usageStatsRetention30m, $usageStatsRetention1d);
|
||||
notifyDeleteConnections();
|
||||
}, $interval);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,8 +2,10 @@
|
|||
|
||||
global $cli;
|
||||
|
||||
use Appwrite\Event\Certificate;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
$cli
|
||||
->task('ssl')
|
||||
|
@ -11,13 +13,13 @@ $cli
|
|||
->action(function () {
|
||||
$domain = App::getEnv('_APP_DOMAIN', '');
|
||||
|
||||
Console::log('Issue a TLS certificate for master domain ('.$domain.') in 30 seconds.
|
||||
Console::log('Issue a TLS certificate for master domain (' . $domain . ') in 30 seconds.
|
||||
Make sure your domain points to your server or restart to try again.');
|
||||
|
||||
ResqueScheduler::enqueueAt(\time() + 30, 'v1-certificates', 'CertificatesV1', [
|
||||
'document' => [],
|
||||
'domain' => $domain,
|
||||
'validateTarget' => false,
|
||||
'validateCNAME' => false,
|
||||
]);
|
||||
});
|
||||
$event = new Certificate();
|
||||
$event
|
||||
->setDomain(new Document([
|
||||
'domain' => $domain
|
||||
]))
|
||||
->trigger();
|
||||
});
|
||||
|
|
|
@ -24,19 +24,19 @@ class AuditsV1 extends Worker
|
|||
public function run(): void
|
||||
{
|
||||
$events = $this->args['events'];
|
||||
$payload = $this->args['payload'];
|
||||
$mode = $this->args['mode'];
|
||||
$resource = $this->args['resource'];
|
||||
$userAgent = $this->args['userAgent'];
|
||||
$ip = $this->args['ip'];
|
||||
|
||||
$user = new Document($this->args['user']);
|
||||
$project = new Document($this->args['project']);
|
||||
$payload = $this->args['payload'];
|
||||
|
||||
$userName = $user->getAttribute('name', '');
|
||||
$userEmail = $user->getAttribute('email', '');
|
||||
|
||||
$event = $events[0];
|
||||
$mode = $payload['mode'];
|
||||
$resource = $payload['resource'];
|
||||
$userAgent = $payload['userAgent'];
|
||||
$ip = $payload['ip'];
|
||||
$data = $payload['data'];
|
||||
|
||||
$dbForProject = $this->getProjectDB($project->getId());
|
||||
$audit = new Audit($dbForProject);
|
||||
|
@ -44,12 +44,11 @@ class AuditsV1 extends Worker
|
|||
'userName' => $userName,
|
||||
'userEmail' => $userEmail,
|
||||
'mode' => $mode,
|
||||
'data' => $data,
|
||||
'data' => $payload,
|
||||
]);
|
||||
}
|
||||
|
||||
public function shutdown(): void
|
||||
{
|
||||
// ... Remove environment for this job
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ Console::success(APP_NAME.' build worker v1 has started');
|
|||
|
||||
// TODO: Executor should return appropriate response codes.
|
||||
class BuildsV1 extends Worker
|
||||
{
|
||||
{
|
||||
/**
|
||||
* @var Executor
|
||||
*/
|
||||
|
@ -42,7 +42,7 @@ class BuildsV1 extends Worker
|
|||
$projectId = $this->args['projectId'] ?? '';
|
||||
$functionId = $this->args['resourceId'] ?? '';
|
||||
$deploymentId = $this->args['deploymentId'] ?? '';
|
||||
|
||||
|
||||
switch ($type) {
|
||||
case BUILD_TYPE_DEPLOYMENT:
|
||||
case BUILD_TYPE_RETRY:
|
||||
|
@ -61,7 +61,7 @@ class BuildsV1 extends Worker
|
|||
$dbForProject = $this->getProjectDB($projectId);
|
||||
$dbForConsole = $this->getConsoleDB();
|
||||
$project = $dbForConsole->getDocument('projects', $projectId);
|
||||
|
||||
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception('Function not found', 404);
|
||||
|
@ -177,7 +177,7 @@ class BuildsV1 extends Worker
|
|||
$build = $dbForProject->updateDocument('builds', $buildId, $build);
|
||||
|
||||
/**
|
||||
* Send realtime Event
|
||||
* Send realtime Event
|
||||
*/
|
||||
$target = Realtime::fromPayload('functions.deployments.update', $build, $project);
|
||||
Realtime::send(
|
||||
|
|
|
@ -42,16 +42,12 @@ class CertificatesV1 extends Worker
|
|||
|
||||
Authorization::disable();
|
||||
|
||||
// Args
|
||||
$document = $this->args['document'];
|
||||
$domain = $this->args['domain'];
|
||||
|
||||
// Validation Args
|
||||
$document = new Document($this->args['domain'] ?? []);
|
||||
$validateTarget = $this->args['validateTarget'] ?? true;
|
||||
$validateCNAME = $this->args['validateCNAME'] ?? true;
|
||||
|
||||
// Options
|
||||
$domain = new Domain((!empty($domain)) ? $domain : '');
|
||||
$domain = new Domain($document->getAttribute('domain'));
|
||||
$expiry = 60 * 60 * 24 * 30 * 2; // 60 days
|
||||
$safety = 60 * 60; // 1 hour
|
||||
$renew = (\time() + $expiry);
|
||||
|
@ -158,11 +154,10 @@ class CertificatesV1 extends Worker
|
|||
throw new Exception('Failed saving certificate to DB');
|
||||
}
|
||||
|
||||
if(!empty($document)) {
|
||||
$certificate = new Document(\array_merge($document, [
|
||||
'updated' => \time(),
|
||||
'certificateId' => $certificate->getId(),
|
||||
]));
|
||||
if($document->getId()) {
|
||||
$document
|
||||
->setAttribute('updated', \time())
|
||||
->setAttribute('certificateId', $certificate->getId());
|
||||
|
||||
$certificate = $dbForConsole->updateDocument('domains', $certificate->getId(), $certificate);
|
||||
|
||||
|
|
|
@ -20,12 +20,11 @@ class DatabaseV1 extends Worker
|
|||
public function run(): void
|
||||
{
|
||||
Authorization::disable();
|
||||
$projectId = $this->args['projectId'] ?? '';
|
||||
$type = $this->args['type'] ?? '';
|
||||
$collection = $this->args['collection'] ?? [];
|
||||
$collection = new Document($collection);
|
||||
$document = $this->args['document'] ?? [];
|
||||
$document = new Document($document);
|
||||
|
||||
$type = $this->args['type'];
|
||||
$project = new Document($this->args['project']);
|
||||
$collection = new Document($this->args['collection'] ?? []);
|
||||
$document = new Document($this->args['document'] ?? []);
|
||||
|
||||
if($collection->isEmpty()) {
|
||||
throw new Exception('Missing collection');
|
||||
|
@ -37,16 +36,16 @@ class DatabaseV1 extends Worker
|
|||
|
||||
switch (strval($type)) {
|
||||
case DATABASE_TYPE_CREATE_ATTRIBUTE:
|
||||
$this->createAttribute($collection, $document, $projectId);
|
||||
$this->createAttribute($collection, $document, $project->getId());
|
||||
break;
|
||||
case DATABASE_TYPE_DELETE_ATTRIBUTE:
|
||||
$this->deleteAttribute($collection, $document, $projectId);
|
||||
$this->deleteAttribute($collection, $document, $project->getId());
|
||||
break;
|
||||
case DATABASE_TYPE_CREATE_INDEX:
|
||||
$this->createIndex($collection, $document, $projectId);
|
||||
$this->createIndex($collection, $document, $project->getId());
|
||||
break;
|
||||
case DATABASE_TYPE_DELETE_INDEX:
|
||||
$this->deleteIndex($collection, $document, $projectId);
|
||||
$this->deleteIndex($collection, $document, $project->getId());
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -19,6 +19,7 @@ use Utopia\Audit\Audit;
|
|||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
Authorization::disable();
|
||||
Authorization::setDefaultStatus(false);
|
||||
|
||||
Console::title('Deletes V1 Worker');
|
||||
Console::success(APP_NAME . ' deletes worker v1 has started' . "\n");
|
||||
|
@ -40,34 +41,36 @@ class DeletesV1 extends Worker
|
|||
|
||||
public function run(): void
|
||||
{
|
||||
$projectId = $this->args['projectId'] ?? '';
|
||||
$type = $this->args['type'] ?? '';
|
||||
$project = new Document($this->args['project'] ?? []);
|
||||
$payload = $this->args['payload'] ?? [];
|
||||
|
||||
$type = $payload['type'] ?? '';
|
||||
|
||||
switch (strval($type)) {
|
||||
case DELETE_TYPE_DOCUMENT:
|
||||
$document = new Document($this->args['document'] ?? []);
|
||||
$document = new Document($payload['document'] ?? []);
|
||||
|
||||
switch ($document->getCollection()) {
|
||||
case DELETE_TYPE_COLLECTIONS:
|
||||
$this->deleteCollection($document, $projectId);
|
||||
$this->deleteCollection($document, $project->getId());
|
||||
break;
|
||||
case DELETE_TYPE_PROJECTS:
|
||||
$this->deleteProject($document);
|
||||
break;
|
||||
case DELETE_TYPE_FUNCTIONS:
|
||||
$this->deleteFunction($document, $projectId);
|
||||
$this->deleteFunction($document, $project->getId());
|
||||
break;
|
||||
case DELETE_TYPE_DEPLOYMENTS:
|
||||
$this->deleteDeployment($document, $projectId);
|
||||
$this->deleteDeployment($document, $project->getId());
|
||||
break;
|
||||
case DELETE_TYPE_USERS:
|
||||
$this->deleteUser($document, $projectId);
|
||||
$this->deleteUser($document, $project->getId());
|
||||
break;
|
||||
case DELETE_TYPE_TEAMS:
|
||||
$this->deleteMemberships($document, $projectId);
|
||||
$this->deleteMemberships($document, $project->getId());
|
||||
break;
|
||||
case DELETE_TYPE_BUCKETS:
|
||||
$this->deleteBucket($document, $projectId);
|
||||
$this->deleteBucket($document, $project->getId());
|
||||
break;
|
||||
default:
|
||||
Console::error('No lazy delete operation available for document of type: ' . $document->getCollection());
|
||||
|
@ -76,38 +79,38 @@ class DeletesV1 extends Worker
|
|||
break;
|
||||
|
||||
case DELETE_TYPE_EXECUTIONS:
|
||||
$this->deleteExecutionLogs($this->args['timestamp']);
|
||||
$this->deleteExecutionLogs($payload['timestamp']);
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_AUDIT:
|
||||
$timestamp = $this->args['timestamp'] ?? 0;
|
||||
$document = new Document($this->args['document'] ?? []);
|
||||
$timestamp = $payload['timestamp'] ?? 0;
|
||||
$document = new Document($payload['document'] ?? []);
|
||||
|
||||
if (!empty($timestamp)) {
|
||||
$this->deleteAuditLogs($this->args['timestamp']);
|
||||
$this->deleteAuditLogs($payload['timestamp']);
|
||||
}
|
||||
|
||||
if (!$document->isEmpty()) {
|
||||
$this->deleteAuditLogsByResource('document/' . $document->getId(), $projectId);
|
||||
$this->deleteAuditLogsByResource('document/' . $document->getId(), $project->getId());
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_ABUSE:
|
||||
$this->deleteAbuseLogs($this->args['timestamp']);
|
||||
$this->deleteAbuseLogs($payload['timestamp']);
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_REALTIME:
|
||||
$this->deleteRealtimeUsage($this->args['timestamp']);
|
||||
$this->deleteRealtimeUsage($payload['timestamp']);
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_CERTIFICATES:
|
||||
$document = new Document($this->args['document']);
|
||||
$document = new Document($payload['document']);
|
||||
$this->deleteCertificates($document);
|
||||
break;
|
||||
|
||||
case DELETE_TYPE_USAGE:
|
||||
$this->deleteUsageStats($this->args['timestamp1d'], $this->args['timestamp30m']);
|
||||
$this->deleteUsageStats($payload['timestamp1d'], $payload['timestamp30m']);
|
||||
break;
|
||||
default:
|
||||
Console::error('No delete operation for type: ' . $type);
|
||||
|
@ -205,7 +208,7 @@ class DeletesV1 extends Worker
|
|||
* DO NOT DELETE THE USER RECORD ITSELF.
|
||||
* WE RETAIN THE USER RECORD TO RESERVE THE USER ID AND ENSURE THAT THE USER ID IS NOT REUSED.
|
||||
*/
|
||||
|
||||
|
||||
$userId = $document->getId();
|
||||
$user = $this->getProjectDB($projectId)->getDocument('users', $userId);
|
||||
|
||||
|
@ -213,9 +216,10 @@ class DeletesV1 extends Worker
|
|||
$this->deleteByGroup('sessions', [
|
||||
new Query('userId', Query::TYPE_EQUAL, [$userId])
|
||||
], $this->getProjectDB($projectId));
|
||||
|
||||
|
||||
$user->setAttribute('sessions', []);
|
||||
$updated = $this->getProjectDB($projectId)->updateDocument('users', $userId, $user);
|
||||
|
||||
$this->getProjectDB($projectId)->updateDocument('users', $userId, $user);
|
||||
|
||||
// Delete Memberships and decrement team membership counts
|
||||
$this->deleteByGroup('memberships', [
|
||||
|
|
|
@ -7,7 +7,6 @@ use Appwrite\Stats\Stats;
|
|||
use Appwrite\Utopia\Response\Model\Execution;
|
||||
use Cron\CronExpression;
|
||||
use Executor\Executor;
|
||||
use Swoole\Runtime;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
|
@ -15,23 +14,19 @@ use Utopia\Database\Database;
|
|||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
|
||||
require_once __DIR__.'/../init.php';
|
||||
require_once __DIR__ . '/../init.php';
|
||||
|
||||
Console::title('Functions V1 Worker');
|
||||
Console::success(APP_NAME . ' functions worker v1 has started');
|
||||
|
||||
class FunctionsV1 extends Worker
|
||||
{
|
||||
/**
|
||||
* @var Executor
|
||||
*/
|
||||
private $executor = null;
|
||||
|
||||
private ?Executor $executor = null;
|
||||
public array $args = [];
|
||||
|
||||
public array $allowed = [];
|
||||
|
||||
public function getName(): string {
|
||||
public function getName(): string
|
||||
{
|
||||
return "functions";
|
||||
}
|
||||
|
||||
|
@ -42,19 +37,22 @@ class FunctionsV1 extends Worker
|
|||
|
||||
public function run(): void
|
||||
{
|
||||
$projectId = $this->args['projectId'] ?? '';
|
||||
$functionId = $this->args['functionId'] ?? '';
|
||||
$webhooks = $this->args['webhooks'] ?? [];
|
||||
$executionId = $this->args['executionId'] ?? '';
|
||||
$trigger = $this->args['trigger'] ?? '';
|
||||
$event = $this->args['event'] ?? '';
|
||||
$scheduleOriginal = $this->args['scheduleOriginal'] ?? '';
|
||||
$eventData = (!empty($this->args['eventData'])) ? json_encode($this->args['eventData']) : '';
|
||||
$data = $this->args['data'] ?? '';
|
||||
$userId = $this->args['userId'] ?? '';
|
||||
$jwt = $this->args['jwt'] ?? '';
|
||||
$events = $this->args['events'];
|
||||
$payload = $this->args['payload'];
|
||||
$user = new Document($this->args['user'] ?? []);
|
||||
$project = new Document($this->args['project'] ?? []);
|
||||
$execution = new Document($this->args['trigger'] ?? []);
|
||||
|
||||
$database = $this->getProjectDB($projectId);
|
||||
$event = $events[0] ?? '';
|
||||
$data = $payload['data'] ?? '';
|
||||
$jwt = $payload['jwt'] ?? '';
|
||||
$webhooks = $project->getAttribute('webhooks', []);
|
||||
$trigger = $execution->getAttribute('trigger', '');
|
||||
$scheduleOriginal = $execution->getAttribute('scheduleOriginal', '');
|
||||
$eventData = !empty($execution->getAttribute('eventData')) ? json_encode($execution->getAttribute('eventData')) : '';
|
||||
$jwt = $execution->getAttribute('jwt', '');
|
||||
|
||||
$database = $this->getProjectDB($project->getId());
|
||||
|
||||
switch ($trigger) {
|
||||
case 'event':
|
||||
|
@ -72,25 +70,23 @@ class FunctionsV1 extends Worker
|
|||
Console::log('Fetched ' . $sum . ' functions...');
|
||||
|
||||
foreach ($functions as $function) {
|
||||
$events = $function->getAttribute('events', []);
|
||||
|
||||
if (!\in_array($event, $events)) {
|
||||
if (!array_intersect($events, $function->getAttribute('events', []))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Console::success('Iterating function: ' . $function->getAttribute('name'));
|
||||
|
||||
$this->execute(
|
||||
projectId: $projectId,
|
||||
projectId: $project->getId(),
|
||||
function: $function,
|
||||
dbForProject: $database,
|
||||
executionId: $executionId,
|
||||
executionId: $execution->getId(),
|
||||
webhooks: $webhooks,
|
||||
trigger: $trigger,
|
||||
event: $event,
|
||||
eventData: $eventData,
|
||||
data: $data,
|
||||
userId: $userId,
|
||||
userId: $user->getId(),
|
||||
jwt: $jwt
|
||||
);
|
||||
|
||||
|
@ -98,9 +94,29 @@ class FunctionsV1 extends Worker
|
|||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case 'http':
|
||||
$function = Authorization::skip(fn() => $database->getDocument('functions', $execution->getAttribute('functionId')));
|
||||
|
||||
$this->execute(
|
||||
projectId: $project->getId(),
|
||||
function: $function,
|
||||
dbForProject: $database,
|
||||
executionId: $execution->getId(),
|
||||
webhooks: $webhooks,
|
||||
trigger: $trigger,
|
||||
event: '',
|
||||
eventData: '',
|
||||
data: $data,
|
||||
userId: $user->getId(),
|
||||
jwt: $jwt
|
||||
);
|
||||
|
||||
break;
|
||||
|
||||
case 'schedule':
|
||||
$function = Authorization::skip(fn() => $database->getDocument('functions', $execution->getAttribute('functionId')));
|
||||
|
||||
/*
|
||||
* 1. Get Original Task
|
||||
* 2. Check for updates
|
||||
|
@ -115,10 +131,8 @@ class FunctionsV1 extends Worker
|
|||
*/
|
||||
|
||||
// Reschedule
|
||||
$function = Authorization::skip(fn() => $database->getDocument('functions', $functionId));
|
||||
|
||||
if (empty($function->getId())) {
|
||||
throw new Exception('Function not found ('.$functionId.')');
|
||||
throw new Exception('Function not found (' . $function->getId() . ')');
|
||||
}
|
||||
|
||||
if ($scheduleOriginal && $scheduleOriginal !== $function->getAttribute('schedule')) { // Schedule has changed from previous run, ignore this run.
|
||||
|
@ -132,60 +146,39 @@ class FunctionsV1 extends Worker
|
|||
->setAttribute('scheduleNext', $next)
|
||||
->setAttribute('schedulePrevious', \time());
|
||||
|
||||
$function = Authorization::skip(function() use ($database, $function, $next, $functionId) {
|
||||
$function = $database->updateDocument('functions', $function->getId(), new Document(array_merge($function->getArrayCopy(), [
|
||||
$function = Authorization::skip(fn () => $database->updateDocument(
|
||||
'functions',
|
||||
$function->getId(),
|
||||
new Document(array_merge($function->getArrayCopy(), [
|
||||
'scheduleNext' => (int)$next,
|
||||
])));
|
||||
|
||||
if ($function === false) {
|
||||
throw new Exception('Function update failed (' . $functionId . ')');
|
||||
}
|
||||
return $function;
|
||||
});
|
||||
]))
|
||||
));
|
||||
|
||||
if ($function === false) {
|
||||
throw new Exception('Function update failed.');
|
||||
}
|
||||
|
||||
ResqueScheduler::enqueueAt($next, Event::FUNCTIONS_QUEUE_NAME, Event::FUNCTIONS_CLASS_NAME, [
|
||||
'projectId' => $projectId,
|
||||
'projectId' => $project->getId(),
|
||||
'webhooks' => $webhooks,
|
||||
'functionId' => $function->getId(),
|
||||
'userId' => $userId,
|
||||
'userId' => $user->getId(),
|
||||
'executionId' => null,
|
||||
'trigger' => 'schedule',
|
||||
'scheduleOriginal' => $function->getAttribute('schedule', ''),
|
||||
]); // Async task reschedule
|
||||
|
||||
$this->execute(
|
||||
projectId: $projectId,
|
||||
projectId: $project->getId(),
|
||||
function: $function,
|
||||
dbForProject: $database,
|
||||
executionId: $executionId,
|
||||
executionId: $execution->getId(),
|
||||
webhooks: $webhooks,
|
||||
trigger: $trigger,
|
||||
event: $event,
|
||||
eventData: $eventData,
|
||||
data: $data,
|
||||
userId: $userId,
|
||||
jwt: $jwt
|
||||
);
|
||||
break;
|
||||
|
||||
case 'http':
|
||||
$function = Authorization::skip(fn() => $database->getDocument('functions', $functionId));
|
||||
|
||||
if (empty($function->getId())) {
|
||||
throw new Exception('Function not found ('.$functionId.')');
|
||||
}
|
||||
|
||||
$this->execute(
|
||||
projectId: $projectId,
|
||||
function: $function,
|
||||
dbForProject: $database,
|
||||
executionId: $executionId,
|
||||
webhooks: $webhooks,
|
||||
trigger: $trigger,
|
||||
event: $event,
|
||||
eventData: $eventData,
|
||||
data: $data,
|
||||
userId: $userId,
|
||||
userId: $user->getId(),
|
||||
jwt: $jwt
|
||||
);
|
||||
|
||||
|
@ -200,7 +193,7 @@ class FunctionsV1 extends Worker
|
|||
string $executionId,
|
||||
array $webhooks,
|
||||
string $trigger,
|
||||
string $event,
|
||||
string $event,
|
||||
string $eventData,
|
||||
string $data,
|
||||
string $userId,
|
||||
|
@ -211,7 +204,7 @@ class FunctionsV1 extends Worker
|
|||
$deploymentId = $function->getAttribute('deployment', '');
|
||||
|
||||
/** Check if deployment exists */
|
||||
$deployment = Authorization::skip(fn() => $dbForProject->getDocument('deployments', $deploymentId));
|
||||
$deployment = Authorization::skip(fn () => $dbForProject->getDocument('deployments', $deploymentId));
|
||||
|
||||
if ($deployment->getAttribute('resourceId') !== $functionId) {
|
||||
throw new Exception('Deployment not found. Create deployment before trying to execute a function', 404);
|
||||
|
@ -222,7 +215,7 @@ class FunctionsV1 extends Worker
|
|||
}
|
||||
|
||||
/** Check if build has exists */
|
||||
$build = Authorization::skip(fn() => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
$build = Authorization::skip(fn () => $dbForProject->getDocument('builds', $deployment->getAttribute('buildId', '')));
|
||||
if ($build->isEmpty()) {
|
||||
throw new Exception('Build not found', 404);
|
||||
}
|
||||
|
@ -233,14 +226,15 @@ class FunctionsV1 extends Worker
|
|||
|
||||
/** Check if runtime is supported */
|
||||
$runtimes = Config::getParam('runtimes', []);
|
||||
$runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null;
|
||||
|
||||
if (\is_null($runtime)) {
|
||||
if (!\array_key_exists($function->getAttribute('runtime'), $runtimes)) {
|
||||
throw new Exception('Runtime "' . $function->getAttribute('runtime', '') . '" is not supported', 400);
|
||||
}
|
||||
|
||||
$runtime = $runtimes[$function->getAttribute('runtime')];
|
||||
|
||||
/** Create execution or update execution status */
|
||||
$execution = Authorization::skip(function() use ($dbForProject, &$executionId, $functionId, $deploymentId, $trigger, $userId) {
|
||||
$execution = Authorization::skip(function () use ($dbForProject, &$executionId, $functionId, $deploymentId, $trigger, $userId) {
|
||||
$execution = $dbForProject->getDocument('executions', $executionId);
|
||||
if ($execution->isEmpty()) {
|
||||
$executionId = $dbForProject->getId();
|
||||
|
@ -259,13 +253,14 @@ class FunctionsV1 extends Worker
|
|||
'time' => 0.0,
|
||||
'search' => implode(' ', [$functionId, $executionId]),
|
||||
]));
|
||||
|
||||
|
||||
if ($execution->isEmpty()) {
|
||||
throw new Exception('Failed to create or read execution');
|
||||
}
|
||||
}
|
||||
$execution->setAttribute('status', 'processing');
|
||||
$execution = $dbForProject->updateDocument('executions', $executionId, $execution);
|
||||
|
||||
return $execution;
|
||||
});
|
||||
|
||||
|
@ -301,19 +296,21 @@ class FunctionsV1 extends Worker
|
|||
);
|
||||
|
||||
/** Update execution status */
|
||||
$execution->setAttribute('status', $executionResponse['status']);
|
||||
$execution->setAttribute('statusCode', $executionResponse['statusCode']);
|
||||
$execution->setAttribute('stdout', $executionResponse['stdout']);
|
||||
$execution->setAttribute('stderr', $executionResponse['stderr']);
|
||||
$execution->setAttribute('time', $executionResponse['time']);
|
||||
$execution
|
||||
->setAttribute('status', $executionResponse['status'])
|
||||
->setAttribute('statusCode', $executionResponse['statusCode'])
|
||||
->setAttribute('stdout', $executionResponse['stdout'])
|
||||
->setAttribute('stderr', $executionResponse['stderr'])
|
||||
->setAttribute('time', $executionResponse['time']);
|
||||
} catch (\Throwable $th) {
|
||||
$execution->setAttribute('status', 'failed');
|
||||
$execution->setAttribute('statusCode', $th->getCode());
|
||||
$execution->setAttribute('stderr', $th->getMessage());
|
||||
$execution
|
||||
->setAttribute('status', 'failed')
|
||||
->setAttribute('statusCode', $th->getCode())
|
||||
->setAttribute('stderr', $th->getMessage());
|
||||
Console::error($th->getMessage());
|
||||
}
|
||||
|
||||
$execution = Authorization::skip(fn() => $dbForProject->updateDocument('executions', $executionId, $execution));
|
||||
$execution = Authorization::skip(fn () => $dbForProject->updateDocument('executions', $executionId, $execution));
|
||||
|
||||
/** Trigger Webhook */
|
||||
$executionModel = new Execution();
|
||||
|
@ -323,8 +320,8 @@ class FunctionsV1 extends Worker
|
|||
->setParam('userId', $userId)
|
||||
->setParam('webhooks', $webhooks)
|
||||
->setParam('event', 'functions.executions.update')
|
||||
->setParam('eventData', $execution->getArrayCopy(array_keys($executionModel->getRules())));
|
||||
$executionUpdate->trigger();
|
||||
->setParam('eventData', $execution->getArrayCopy(array_keys($executionModel->getRules())))
|
||||
->trigger();
|
||||
|
||||
/** Trigger realtime event */
|
||||
$target = Realtime::fromPayload('functions.executions.update', $execution);
|
||||
|
@ -357,7 +354,6 @@ class FunctionsV1 extends Worker
|
|||
->setParam('networkRequestSize', 0)
|
||||
->setParam('networkResponseSize', 0)
|
||||
->submit();
|
||||
$usage->submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -31,28 +31,30 @@ class MailsV1 extends Worker
|
|||
return;
|
||||
}
|
||||
|
||||
$payload = $this->args['payload'];
|
||||
$project = new Document($this->args['project']);
|
||||
$user = new Document($this->args['user'] ?? []);
|
||||
$team = new Document($this->args['team'] ?? []);
|
||||
|
||||
$recipient = $payload['recipient'];
|
||||
$url = $payload['url'];
|
||||
$project = $payload['project'];
|
||||
$type = $payload['type'];
|
||||
$name = $payload['name'] ?? $recipient;
|
||||
$recipient = $this->args['recipient'];
|
||||
$url = $this->args['url'];
|
||||
$name = $this->args['name'];
|
||||
$type = $this->args['type'];
|
||||
$prefix = $this->getPrefix($type);
|
||||
$locale = new Locale($payload['locale']);
|
||||
$locale = new Locale($this->args['locale']);
|
||||
$projectName = $project->getAttribute('name', ['[APP-NAME]']);
|
||||
|
||||
if (!$this->doesLocaleExist($locale, $prefix)) {
|
||||
$locale->setDefault('en');
|
||||
}
|
||||
|
||||
$from = $payload['from'] === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $project);
|
||||
$from = $project->getId() === 'console' ? '' : \sprintf($locale->getText('emails.sender'), $projectName);
|
||||
$body = Template::fromFile(__DIR__ . '/../config/locale/templates/email-base.tpl');
|
||||
$subject = '';
|
||||
switch ($type) {
|
||||
case MAIL_TYPE_INVITATION:
|
||||
$subject = \sprintf($locale->getText("$prefix.subject"), $payload['team'], $project);
|
||||
$body->setParam('{{owner}}', $payload['owner']);
|
||||
$body->setParam('{{team}}', $payload['team']);
|
||||
$subject = \sprintf($locale->getText("$prefix.subject"), $team->getAttribute('name'), $projectName);
|
||||
$body->setParam('{{owner}}', $user->getAttribute('name'));
|
||||
$body->setParam('{{team}}', $team->getAttribute('name'));
|
||||
break;
|
||||
case MAIL_TYPE_RECOVERY:
|
||||
case MAIL_TYPE_VERIFICATION:
|
||||
|
@ -72,7 +74,7 @@ class MailsV1 extends Worker
|
|||
->setParam('{{footer}}', $locale->getText("$prefix.footer"))
|
||||
->setParam('{{thanks}}', $locale->getText("$prefix.thanks"))
|
||||
->setParam('{{signature}}', $locale->getText("$prefix.signature"))
|
||||
->setParam('{{project}}', $project)
|
||||
->setParam('{{project}}', $projectName)
|
||||
->setParam('{{direction}}', $locale->getText('settings.direction'))
|
||||
->setParam('{{bg-body}}', '#f7f7f7')
|
||||
->setParam('{{bg-content}}', '#ffffff')
|
||||
|
|
|
@ -12,6 +12,8 @@ Console::success(APP_NAME . ' webhooks worker v1 has started');
|
|||
|
||||
class WebhooksV1 extends Worker
|
||||
{
|
||||
protected array $errors = [];
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return "webhooks";
|
||||
|
@ -23,15 +25,24 @@ class WebhooksV1 extends Worker
|
|||
|
||||
public function run(): void
|
||||
{
|
||||
$errors = [];
|
||||
|
||||
// Event
|
||||
$events = $this->args['events'];
|
||||
$user = new Document($this->args['user']);
|
||||
$payload = json_encode($this->args['payload']);
|
||||
$project = new Document($this->args['project']);
|
||||
$webhook = new Document($this->args['trigger'] ?? []);
|
||||
$payload = \json_encode($this->args['payload']);
|
||||
$user = new Document($this->args['user'] ?? []);
|
||||
|
||||
foreach ($project->getAttribute('webhooks', []) as $webhook) {
|
||||
if (array_intersect($webhook->getAttribute('events', []), $events)) {
|
||||
$this->execute($events, $payload, $webhook, $user, $project);
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->errors)) {
|
||||
throw new Exception(\implode(" / \n\n", $this->errors));
|
||||
}
|
||||
}
|
||||
|
||||
protected function execute(array $events, string $payload, Document $webhook, Document $user, Document $project): void
|
||||
{
|
||||
$httpUser = $webhook->getAttribute('httpUser');
|
||||
$httpPass = $webhook->getAttribute('httpPass');
|
||||
|
||||
|
@ -72,17 +83,14 @@ class WebhooksV1 extends Worker
|
|||
}
|
||||
|
||||
if (false === \curl_exec($ch)) {
|
||||
$errors[] = \curl_error($ch) . ' in events ' . implode(', ', $events) . ' for webhook ' . $webhook->getAttribute('name');
|
||||
$this->errors[] = \curl_error($ch) . ' in events ' . implode(', ', $events) . ' for webhook ' . $webhook->getAttribute('name');
|
||||
}
|
||||
|
||||
\curl_close($ch);
|
||||
|
||||
if (!empty($errors)) {
|
||||
throw new Exception(\implode(" / \n\n", $errors));
|
||||
}
|
||||
}
|
||||
|
||||
public function shutdown(): void
|
||||
{
|
||||
$this->errors = [];
|
||||
}
|
||||
}
|
||||
|
|
81
src/Appwrite/Event/Audit.php
Normal file
81
src/Appwrite/Event/Audit.php
Normal file
|
@ -0,0 +1,81 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Resque;
|
||||
|
||||
class Audit extends Event
|
||||
{
|
||||
protected string $resource = '';
|
||||
protected string $mode = '';
|
||||
protected string $userAgent = '';
|
||||
protected string $ip = '';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Event::AUDITS_QUEUE_NAME, Event::AUDITS_CLASS_NAME);
|
||||
}
|
||||
|
||||
public function setResource(string $resource): self
|
||||
{
|
||||
$this->resource = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getResource(): string
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
public function setMode(string $mode): self
|
||||
{
|
||||
$this->mode = $mode;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getMode(): string
|
||||
{
|
||||
return $this->mode;
|
||||
}
|
||||
|
||||
public function setUserAgent(string $userAgent): self
|
||||
{
|
||||
$this->userAgent = $userAgent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserAgent(): string
|
||||
{
|
||||
return $this->userAgent;
|
||||
}
|
||||
|
||||
public function setIP(string $ip): self
|
||||
{
|
||||
$this->ip = $ip;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getIP(): string
|
||||
{
|
||||
return $this->ip;
|
||||
}
|
||||
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
return Resque::enqueue($this->queue, $this->class, [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'payload' => $this->payload,
|
||||
'trigger' => $this->trigger,
|
||||
'resource' => $this->resource,
|
||||
'mode' => $this->mode,
|
||||
'ip' => $this->ip,
|
||||
'userAgent' => $this->userAgent,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
]);
|
||||
}
|
||||
}
|
64
src/Appwrite/Event/Certificate.php
Normal file
64
src/Appwrite/Event/Certificate.php
Normal file
|
@ -0,0 +1,64 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Resque;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class Certificate extends Event
|
||||
{
|
||||
protected ?Document $domain = null;
|
||||
protected bool $validateTarget = false;
|
||||
protected bool $validateCNAME = false;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Event::CERTIFICATES_QUEUE_NAME, Event::CERTIFICATES_CLASS_NAME);
|
||||
}
|
||||
|
||||
public function setDomain(Document $domain): self
|
||||
{
|
||||
$this->domain = $domain;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDomain(): ?Document
|
||||
{
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
public function setValidateTarget(bool $validateTarget): self
|
||||
{
|
||||
$this->validateTarget = $validateTarget;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getValidateTarget(): bool
|
||||
{
|
||||
return $this->validateTarget;
|
||||
}
|
||||
|
||||
public function setValidateCNAME(bool $validateCNAME): self
|
||||
{
|
||||
$this->validateCNAME = $validateCNAME;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getValidateCNAME(): bool
|
||||
{
|
||||
return $this->validateCNAME;
|
||||
}
|
||||
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
return Resque::enqueue($this->queue, $this->class, [
|
||||
'project' => $this->project,
|
||||
'domain' => $this->domain,
|
||||
'validateTarget' => $this->validateTarget,
|
||||
'validateCNAME' => $this->validateCNAME
|
||||
]);
|
||||
}
|
||||
}
|
66
src/Appwrite/Event/Database.php
Normal file
66
src/Appwrite/Event/Database.php
Normal file
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Resque;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class Database extends Event
|
||||
{
|
||||
protected string $type = '';
|
||||
protected ?Document $collection = null;
|
||||
protected ?Document $document = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Event::DATABASE_QUEUE_NAME, Event::DATABASE_CLASS_NAME);
|
||||
}
|
||||
|
||||
public function setType(string $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setCollection(Document $collection): self
|
||||
{
|
||||
$this->collection = $collection;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getCollection(): Document
|
||||
{
|
||||
return $this->collection;
|
||||
}
|
||||
|
||||
public function setDocument(Document $document): self
|
||||
{
|
||||
$this->document = $document;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDocument(): Document
|
||||
{
|
||||
return $this->document;
|
||||
}
|
||||
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
return Resque::enqueue($this->queue, $this->class, [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'type' => $this->type,
|
||||
'collection' => $this->collection,
|
||||
'document' => $this->document,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
]);
|
||||
}
|
||||
}
|
50
src/Appwrite/Event/Delete.php
Normal file
50
src/Appwrite/Event/Delete.php
Normal file
|
@ -0,0 +1,50 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Resque;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class Delete extends Event
|
||||
{
|
||||
protected string $type = '';
|
||||
protected ?Document $document = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Event::DELETE_QUEUE_NAME, Event::DELETE_CLASS_NAME);
|
||||
}
|
||||
|
||||
public function setType(string $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setDocument(Document $document): self
|
||||
{
|
||||
$this->document = $document;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getDocument(): Document
|
||||
{
|
||||
return $this->document;
|
||||
}
|
||||
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
return Resque::enqueue($this->queue, $this->class, [
|
||||
'project' => $this->project,
|
||||
'type' => $this->type,
|
||||
'document' => $this->document,
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -103,26 +103,26 @@ class Event
|
|||
|
||||
public function setProject(Document $project): self
|
||||
{
|
||||
$this->projectId = $project;
|
||||
$this->project = $project;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getProjectId(): Document
|
||||
public function getProject(): Document
|
||||
{
|
||||
return $this->projectId;
|
||||
return $this->project;
|
||||
}
|
||||
|
||||
public function setUser(Document $user): self
|
||||
{
|
||||
$this->userId = $user;
|
||||
$this->user = $user;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUserId(): Document
|
||||
public function getUser(): Document
|
||||
{
|
||||
return $this->userId;
|
||||
return $this->user;
|
||||
}
|
||||
|
||||
public function setPayload(array $payload): self
|
||||
|
@ -144,7 +144,7 @@ class Event
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getTrigger(): Document
|
||||
public function getTrigger(): ?Document
|
||||
{
|
||||
return $this->trigger;
|
||||
}
|
||||
|
@ -215,8 +215,8 @@ class Event
|
|||
public function trigger(): string|bool
|
||||
{
|
||||
return Resque::enqueue($this->queue, $this->class, [
|
||||
'project' => $this->projectId,
|
||||
'user' => $this->userId,
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'payload' => $this->payload,
|
||||
'trigger' => $this->trigger,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
|
@ -294,11 +294,11 @@ class Event
|
|||
$action = $parsed['action'];
|
||||
$attribute = $parsed['attribute'];
|
||||
|
||||
if ($resource && !\in_array(\trim($resource, '[]'), $paramKeys)) {
|
||||
if ($resource && !\in_array(\trim($resource, "\[\]"), $paramKeys)) {
|
||||
throw new InvalidArgumentException("{$resource} is missing from the params.");
|
||||
}
|
||||
|
||||
if ($subResource && !\in_array(\trim($subResource, '[]'), $paramKeys)) {
|
||||
if ($subResource && !\in_array(\trim($subResource, "\[\]"), $paramKeys)) {
|
||||
throw new InvalidArgumentException("{$subResource} is missing from the params.");
|
||||
}
|
||||
|
||||
|
|
110
src/Appwrite/Event/Mail.php
Normal file
110
src/Appwrite/Event/Mail.php
Normal file
|
@ -0,0 +1,110 @@
|
|||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Resque;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
class Mail extends Event
|
||||
{
|
||||
protected string $recipient = '';
|
||||
protected string $url = '';
|
||||
protected string $type = '';
|
||||
protected string $name = '';
|
||||
protected string $locale = '';
|
||||
protected ?Document $team = null;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(Event::MAILS_QUEUE_NAME, Event::MAILS_CLASS_NAME);
|
||||
}
|
||||
|
||||
public function setTeam(Document $team): self
|
||||
{
|
||||
$this->team = $team;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getTeam(): Document
|
||||
{
|
||||
return $this->team;
|
||||
}
|
||||
|
||||
public function setRecipient(string $recipient): self
|
||||
{
|
||||
$this->recipient = $recipient;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getRecipient(): string
|
||||
{
|
||||
return $this->recipient;
|
||||
}
|
||||
|
||||
public function setUrl(string $url): self
|
||||
{
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getURL(): string
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
public function setType(string $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
public function setName(string $name): self
|
||||
{
|
||||
$this->name = $name;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getName(): string
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
public function setLocale(string $locale): self
|
||||
{
|
||||
$this->locale = $locale;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLocale(): string
|
||||
{
|
||||
return $this->locale;
|
||||
}
|
||||
|
||||
public function trigger(): string|bool
|
||||
{
|
||||
return Resque::enqueue($this->queue, $this->class, [
|
||||
'project' => $this->project,
|
||||
'user' => $this->user,
|
||||
'payload' => $this->payload,
|
||||
'trigger' => $this->trigger,
|
||||
'recipient' => $this->recipient,
|
||||
'url' => $this->url,
|
||||
'locale' => $this->locale,
|
||||
'type' => $this->type,
|
||||
'name' => $this->name,
|
||||
'team' => $this->team,
|
||||
'events' => Event::generateEvents($this->getEvent(), $this->getParams())
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -246,77 +246,72 @@ class Realtime extends Adapter
|
|||
$roles = [];
|
||||
$permissionsChanged = false;
|
||||
$projectId = null;
|
||||
$parts = explode('.', $event);
|
||||
|
||||
switch (true) {
|
||||
case strpos($event, 'account.recovery.') === 0:
|
||||
case strpos($event, 'account.sessions.') === 0:
|
||||
case strpos($event, 'account.verification.') === 0:
|
||||
switch ($parts[0]) {
|
||||
case 'users':
|
||||
$channels[] = 'account';
|
||||
$channels[] = 'account.' . $payload->getAttribute('userId');
|
||||
$roles = ['user:' . $payload->getAttribute('userId')];
|
||||
$channels[] = 'account.' . $parts[1];
|
||||
$roles = ['user:' . $parts[1]];
|
||||
|
||||
break;
|
||||
case strpos($event, 'account.') === 0:
|
||||
$channels[] = 'account';
|
||||
$channels[] = 'account.' . $payload->getId();
|
||||
$roles = ['user:' . $payload->getId()];
|
||||
|
||||
break;
|
||||
case strpos($event, 'teams.memberships') === 0:
|
||||
$permissionsChanged = in_array($event, ['teams.memberships.update', 'teams.memberships.delete', 'teams.memberships.update.status']);
|
||||
$channels[] = 'memberships';
|
||||
$channels[] = 'memberships.' . $payload->getId();
|
||||
$roles = ['team:' . $payload->getAttribute('teamId')];
|
||||
|
||||
break;
|
||||
case strpos($event, 'teams.') === 0:
|
||||
$permissionsChanged = $event === 'teams.create';
|
||||
$channels[] = 'teams';
|
||||
$channels[] = 'teams.' . $payload->getId();
|
||||
$roles = ['team:' . $payload->getId()];
|
||||
|
||||
break;
|
||||
case strpos($event, 'database.attributes.') === 0:
|
||||
case strpos($event, 'database.indexes.') === 0:
|
||||
$channels[] = 'console';
|
||||
$projectId = 'console';
|
||||
$roles = ['team:' . $project->getAttribute('teamId')];
|
||||
|
||||
break;
|
||||
case strpos($event, 'database.documents.') === 0:
|
||||
if ($collection->isEmpty()) {
|
||||
throw new \Exception('Collection needs to be passed to Realtime for Document events in the Database.');
|
||||
case 'teams':
|
||||
if ($parts[2] === 'memberships') {
|
||||
$permissionsChanged = $parts[4] ?? false;
|
||||
$channels[] = 'memberships';
|
||||
$channels[] = 'memberships.' . $parts[3];
|
||||
$roles = ['team:' . $parts[1]];
|
||||
} else {
|
||||
$permissionsChanged = $parts[2] === 'create';
|
||||
$channels[] = 'teams';
|
||||
$channels[] = 'teams.' . $parts[1];
|
||||
$roles = ['team:' . $parts[1]];
|
||||
}
|
||||
|
||||
$channels[] = 'documents';
|
||||
$channels[] = 'collections.' . $payload->getAttribute('$collection') . '.documents';
|
||||
$channels[] = 'collections.' . $payload->getAttribute('$collection') . '.documents.' . $payload->getId();
|
||||
|
||||
$roles = ($collection->getAttribute('permission') === 'collection') ? $collection->getRead() : $payload->getRead();
|
||||
|
||||
break;
|
||||
case strpos($event, 'storage.files') === 0:
|
||||
if($bucket->isEmpty()) {
|
||||
throw new \Exception('Bucket needs to be pased to Realtime for File events in the Storage.');
|
||||
}
|
||||
$channels[] = 'files';
|
||||
$channels[] = 'buckets.' . $payload->getAttribute('bucketId') . '.files';
|
||||
$channels[] = 'buckets.' . $payload->getAttribute('bucketId') . '.files.' . $payload->getId();
|
||||
$roles = $payload->getRead();
|
||||
|
||||
break;
|
||||
case strpos($event, 'functions.executions.') === 0:
|
||||
if (!empty($payload->getRead())) {
|
||||
case 'collections':
|
||||
if (in_array($parts[2], ['attributes', 'indexes'])) {
|
||||
$channels[] = 'console';
|
||||
$channels[] = 'executions';
|
||||
$channels[] = 'executions.' . $payload->getId();
|
||||
$channels[] = 'functions.' . $payload->getAttribute('functionId');
|
||||
$roles = $payload->getRead();
|
||||
$projectId = 'console';
|
||||
$roles = ['team:' . $project->getAttribute('teamId')];
|
||||
} elseif ($parts[2] === 'documents') {
|
||||
if ($collection->isEmpty()) {
|
||||
throw new \Exception('Collection needs to be passed to Realtime for Document events in the Database.');
|
||||
}
|
||||
|
||||
$channels[] = 'documents';
|
||||
$channels[] = 'collections.' . $payload->getCollection() . '.documents';
|
||||
$channels[] = 'collections.' . $payload->getCollection() . '.documents.' . $payload->getId();
|
||||
|
||||
$roles = ($collection->getAttribute('permission') === 'collection') ? $collection->getRead() : $payload->getRead();
|
||||
}
|
||||
break;
|
||||
case strpos($event, 'functions.deployments.') === 0:
|
||||
$channels[] = 'console';
|
||||
$roles = ['team:' . $project->getAttribute('teamId')];
|
||||
case 'buckets':
|
||||
if ($parts[2] === 'files') {
|
||||
if($bucket->isEmpty()) {
|
||||
throw new \Exception('Bucket needs to be pased to Realtime for File events in the Storage.');
|
||||
}
|
||||
$channels[] = 'files';
|
||||
$channels[] = 'buckets.' . $payload->getAttribute('bucketId') . '.files';
|
||||
$channels[] = 'buckets.' . $payload->getAttribute('bucketId') . '.files.' . $payload->getId();
|
||||
$roles = ($bucket->getAttribute('permission') === 'collection') ? $bucket->getRead() : $payload->getRead();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 'functions':
|
||||
if ($parts[2] === 'executions') {
|
||||
if (!empty($payload->getRead())) {
|
||||
$channels[] = 'console';
|
||||
$channels[] = 'executions';
|
||||
$channels[] = 'executions.' . $payload->getId();
|
||||
$channels[] = 'functions.' . $payload->getAttribute('functionId');
|
||||
$roles = $payload->getRead();
|
||||
}
|
||||
} elseif ($parts[2] === 'deployments') {
|
||||
$channels[] = 'console';
|
||||
$roles = ['team:' . $project->getAttribute('teamId')];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ class FunctionsConsoleClientTest extends Scope
|
|||
'funcKey3' => 'funcValue3',
|
||||
],
|
||||
'events' => [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'users.*.create',
|
||||
'users.*.delete',
|
||||
],
|
||||
'schedule' => '0 0 1 1 *',
|
||||
'timeout' => 10,
|
||||
|
|
|
@ -33,8 +33,8 @@ class FunctionsCustomClientTest extends Scope
|
|||
'funcKey3' => 'funcValue3',
|
||||
],
|
||||
'events' => [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'users.*.create',
|
||||
'users.*.delete',
|
||||
],
|
||||
'schedule' => '0 0 1 1 *',
|
||||
'timeout' => 10,
|
||||
|
@ -65,8 +65,8 @@ class FunctionsCustomClientTest extends Scope
|
|||
'funcKey3' => 'funcValue3',
|
||||
],
|
||||
'events' => [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'users.*.create',
|
||||
'users.*.delete',
|
||||
],
|
||||
'schedule' => '0 0 1 1 *',
|
||||
'timeout' => 10,
|
||||
|
|
|
@ -16,7 +16,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
use ProjectCustom;
|
||||
use SideServer;
|
||||
|
||||
public function testCreate():array
|
||||
public function testCreate(): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
|
@ -34,8 +34,8 @@ class FunctionsCustomServerTest extends Scope
|
|||
'funcKey3' => 'funcValue3',
|
||||
],
|
||||
'events' => [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'users.*.create',
|
||||
'users.*.delete',
|
||||
],
|
||||
'schedule' => '0 0 1 1 *',
|
||||
'timeout' => 10,
|
||||
|
@ -56,12 +56,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
'funcKey3' => 'funcValue3',
|
||||
], $response1['body']['vars']);
|
||||
$this->assertEquals([
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'users.*.create',
|
||||
'users.*.delete',
|
||||
], $response1['body']['events']);
|
||||
$this->assertEquals('0 0 1 1 *', $response1['body']['schedule']);
|
||||
$this->assertEquals(10, $response1['body']['timeout']);
|
||||
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
@ -74,7 +74,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testCreate
|
||||
*/
|
||||
public function testList(array $data):array
|
||||
public function testList(array $data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
|
@ -132,8 +132,8 @@ class FunctionsCustomServerTest extends Scope
|
|||
'funcKey3' => 'funcValue3',
|
||||
],
|
||||
'events' => [
|
||||
'account.create',
|
||||
'account.delete',
|
||||
'users.*.create',
|
||||
'users.*.delete',
|
||||
],
|
||||
'schedule' => '0 0 1 1 *',
|
||||
'timeout' => 10,
|
||||
|
@ -193,7 +193,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testList
|
||||
*/
|
||||
public function testGet(array $data):array
|
||||
public function testGet(array $data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
|
@ -222,12 +222,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testGet
|
||||
*/
|
||||
public function testUpdate($data):array
|
||||
public function testUpdate($data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response1 = $this->client->call(Client::METHOD_PUT, '/functions/'.$data['functionId'], array_merge([
|
||||
$response1 = $this->client->call(Client::METHOD_PUT, '/functions/' . $data['functionId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -238,8 +238,8 @@ class FunctionsCustomServerTest extends Scope
|
|||
'key6' => 'value6',
|
||||
],
|
||||
'events' => [
|
||||
'account.update.name',
|
||||
'account.update.email',
|
||||
'users.*.update.name',
|
||||
'users.*.update.email',
|
||||
],
|
||||
'schedule' => '0 0 1 1 *',
|
||||
'timeout' => 5,
|
||||
|
@ -257,12 +257,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
'key6' => 'value6',
|
||||
], $response1['body']['vars']);
|
||||
$this->assertEquals([
|
||||
'account.update.name',
|
||||
'account.update.email',
|
||||
'users.*.update.name',
|
||||
'users.*.update.email',
|
||||
], $response1['body']['events']);
|
||||
$this->assertEquals('0 0 1 1 *', $response1['body']['schedule']);
|
||||
$this->assertEquals(5, $response1['body']['timeout']);
|
||||
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
@ -273,16 +273,16 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testUpdate
|
||||
*/
|
||||
public function testCreateDeployment($data):array
|
||||
public function testCreateDeployment($data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$folder = 'php';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/deployments', array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -306,16 +306,17 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testUpdate
|
||||
*/
|
||||
public function testCreateDeploymentLarge($data): array {
|
||||
public function testCreateDeploymentLarge($data): array
|
||||
{
|
||||
/**
|
||||
* Test for Large Code File SUCCESS
|
||||
*/
|
||||
|
||||
$folder = 'php-large';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$chunkSize = 5*1024*1024;
|
||||
$chunkSize = 5 * 1024 * 1024;
|
||||
$handle = @fopen($code, "rb");
|
||||
$mimeType = 'application/x-gzip';
|
||||
$counter = 0;
|
||||
|
@ -328,10 +329,10 @@ class FunctionsCustomServerTest extends Scope
|
|||
while (!feof($handle)) {
|
||||
$curlFile = new \CURLFile('data://' . $mimeType . ';base64,' . base64_encode(@fread($handle, $chunkSize)), $mimeType, 'php-large-fx.tar.gz');
|
||||
$headers['content-range'] = 'bytes ' . ($counter * $chunkSize) . '-' . min(((($counter * $chunkSize) + $chunkSize) - 1), $size) . '/' . $size;
|
||||
if(!empty($id)) {
|
||||
if (!empty($id)) {
|
||||
$headers['x-appwrite-id'] = $id;
|
||||
}
|
||||
$largeTag = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/deployments', array_merge($headers, $this->getHeaders()), [
|
||||
$largeTag = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/deployments', array_merge($headers, $this->getHeaders()), [
|
||||
'entrypoint' => 'index.php',
|
||||
'code' => $curlFile,
|
||||
]);
|
||||
|
@ -345,19 +346,19 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertIsInt($largeTag['body']['dateCreated']);
|
||||
$this->assertEquals('index.php', $largeTag['body']['entrypoint']);
|
||||
$this->assertGreaterThan(10000, $largeTag['body']['size']);
|
||||
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @depends testCreateDeployment
|
||||
*/
|
||||
public function testUpdateDeployment($data):array
|
||||
public function testUpdateDeployment($data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/functions/'.$data['functionId'].'/deployments/'.$data['deploymentId'], array_merge([
|
||||
$response = $this->client->call(Client::METHOD_PATCH, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
@ -367,7 +368,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertIsInt($response['body']['dateCreated']);
|
||||
$this->assertIsInt($response['body']['dateUpdated']);
|
||||
$this->assertEquals($data['deploymentId'], $response['body']['deployment']);
|
||||
|
||||
|
||||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
|
@ -378,12 +379,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testCreateDeployment
|
||||
*/
|
||||
public function testListDeployments(array $data):array
|
||||
public function testListDeployments(array $data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -396,7 +397,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* Test search queries
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders(), [
|
||||
|
@ -409,7 +410,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertCount(2, $function['body']['deployments']);
|
||||
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
|
||||
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders(), [
|
||||
|
@ -422,7 +423,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertCount(2, $function['body']['deployments']);
|
||||
$this->assertEquals($function['body']['deployments'][0]['$id'], $data['deploymentId']);
|
||||
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments', array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders(), [
|
||||
|
@ -441,12 +442,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testCreateDeployment
|
||||
*/
|
||||
public function testGetDeployment(array $data):array
|
||||
public function testGetDeployment(array $data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments/' . $data['deploymentId'], array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -456,7 +457,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments/x', array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/x', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -469,12 +470,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testUpdateDeployment
|
||||
*/
|
||||
public function testCreateExecution($data):array
|
||||
public function testCreateExecution($data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/executions', array_merge([
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -496,7 +497,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
sleep(5);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions/'.$executionId, array_merge([
|
||||
$execution = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -529,12 +530,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testCreateExecution
|
||||
*/
|
||||
public function testListExecutions(array $data):array
|
||||
public function testListExecutions(array $data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions', array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -549,7 +550,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
* Test search queries
|
||||
*/
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions', array_merge([
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -562,7 +563,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertCount(1, $response['body']['executions']);
|
||||
$this->assertEquals($data['functionId'], $response['body']['executions'][0]['functionId']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions', array_merge([
|
||||
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -581,12 +582,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testUpdateDeployment
|
||||
*/
|
||||
public function testSyncCreateExecution($data):array
|
||||
public function testSyncCreateExecution($data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$data['functionId'].'/executions', array_merge([
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $data['functionId'] . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -610,12 +611,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testListExecutions
|
||||
*/
|
||||
public function testGetExecution(array $data):array
|
||||
public function testGetExecution(array $data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions/' . $data['executionId'], array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions/' . $data['executionId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -626,7 +627,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* Test for FAILURE
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/executions/x', array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/executions/x', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -639,12 +640,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testGetExecution
|
||||
*/
|
||||
public function testDeleteDeployment($data):array
|
||||
public function testDeleteDeployment($data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_DELETE, '/functions/'.$data['functionId'].'/deployments/' . $data['deploymentId'], array_merge([
|
||||
$function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -652,11 +653,11 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(204, $function['headers']['status-code']);
|
||||
$this->assertEmpty($function['body']);
|
||||
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/'.$data['functionId'].'/deployments/' . $data['deploymentId'], array_merge([
|
||||
$function = $this->client->call(Client::METHOD_GET, '/functions/' . $data['functionId'] . '/deployments/' . $data['deploymentId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
|
||||
$this->assertEquals(404, $function['headers']['status-code']);
|
||||
|
||||
/**
|
||||
|
@ -669,12 +670,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
/**
|
||||
* @depends testCreateDeployment
|
||||
*/
|
||||
public function testDelete($data):array
|
||||
public function testDelete($data): array
|
||||
{
|
||||
/**
|
||||
* Test for SUCCESS
|
||||
*/
|
||||
$function = $this->client->call(Client::METHOD_DELETE, '/functions/'. $data['functionId'], array_merge([
|
||||
$function = $this->client->call(Client::METHOD_DELETE, '/functions/' . $data['functionId'], array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -686,7 +687,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
|
||||
$this->assertEquals(404, $function['headers']['status-code']);
|
||||
|
||||
/**
|
||||
|
@ -702,15 +703,15 @@ class FunctionsCustomServerTest extends Scope
|
|||
$entrypoint = 'index.php';
|
||||
$timeout = 2;
|
||||
$folder = 'timeout';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test '.$name,
|
||||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [],
|
||||
'events' => [],
|
||||
|
@ -722,7 +723,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -735,8 +736,8 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
// Allow build step to run
|
||||
sleep(20);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -744,12 +745,12 @@ class FunctionsCustomServerTest extends Scope
|
|||
]);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
sleep(5);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -768,7 +769,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals($executions['body']['executions'][0]['stderr'], 'Execution timed out.');
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
|
@ -786,7 +787,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$entrypoint = 'index.php';
|
||||
$timeout = 2;
|
||||
$folder = 'php-fn';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$function = $this->client->call(Client::METHOD_POST, '/functions', array_merge([
|
||||
|
@ -794,7 +795,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test '.$name,
|
||||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [],
|
||||
'events' => [],
|
||||
|
@ -806,7 +807,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -820,14 +821,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
// Allow build step to run
|
||||
sleep(10);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_PATCH, '/functions/'.$functionId.'/deployments/'.$deploymentId, array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_PATCH, '/functions/' . $functionId . '/deployments/' . $deploymentId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), []);
|
||||
|
||||
$this->assertEquals(200, $deployment['headers']['status-code']);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -835,14 +836,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
]);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
sleep(10);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -852,7 +853,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
$this->assertEquals('completed', $executions['body']['status']);
|
||||
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
|
||||
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals('Test ' . $name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
|
||||
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
|
||||
$this->assertEquals('PHP', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
|
||||
|
@ -864,11 +865,11 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
|
||||
$this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
|
||||
$this->assertEquals($executions['headers']['status-code'], 200);
|
||||
$this->assertEquals($executions['body']['total'], 1);
|
||||
$this->assertIsArray($executions['body']['executions']);
|
||||
|
@ -878,7 +879,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']);
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
|
@ -892,9 +893,9 @@ class FunctionsCustomServerTest extends Scope
|
|||
{
|
||||
$name = 'node-17.0';
|
||||
$folder = 'node';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
|
||||
$entrypoint = 'index.js';
|
||||
$timeout = 2;
|
||||
|
||||
|
@ -903,7 +904,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test '.$name,
|
||||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [
|
||||
'CUSTOM_VARIABLE' => 'variable',
|
||||
|
@ -917,7 +918,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -932,7 +933,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
// Allow build step to run
|
||||
sleep(10);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -940,14 +941,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
]);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
sleep(10);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -957,7 +958,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
$this->assertEquals('completed', $executions['body']['status']);
|
||||
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
|
||||
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals('Test ' . $name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
|
||||
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
|
||||
$this->assertEquals('Node.js', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
|
||||
|
@ -970,11 +971,11 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
|
||||
$this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
|
||||
$this->assertEquals($executions['headers']['status-code'], 200);
|
||||
$this->assertEquals($executions['body']['total'], 1);
|
||||
$this->assertIsArray($executions['body']['executions']);
|
||||
|
@ -984,7 +985,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']);
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
|
@ -997,7 +998,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
{
|
||||
$name = 'python-3.9';
|
||||
$folder = 'python';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
$entrypoint = 'main.py';
|
||||
|
@ -1008,7 +1009,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test '.$name,
|
||||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [
|
||||
'CUSTOM_VARIABLE' => 'variable',
|
||||
|
@ -1022,7 +1023,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -1037,7 +1038,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
// Allow build step to run
|
||||
sleep(30);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -1045,14 +1046,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
]);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
sleep(30);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -1062,7 +1063,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
$this->assertEquals('completed', $executions['body']['status']);
|
||||
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
|
||||
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals('Test ' . $name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
|
||||
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
|
||||
$this->assertEquals('Python', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
|
||||
|
@ -1075,11 +1076,11 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
|
||||
$this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
|
||||
$this->assertEquals($executions['headers']['status-code'], 200);
|
||||
$this->assertEquals($executions['body']['total'], 1);
|
||||
$this->assertIsArray($executions['body']['executions']);
|
||||
|
@ -1089,7 +1090,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']);
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
|
@ -1102,9 +1103,9 @@ class FunctionsCustomServerTest extends Scope
|
|||
{
|
||||
$name = 'dart-2.15';
|
||||
$folder = 'dart';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
|
||||
$entrypoint = 'main.dart';
|
||||
$timeout = 2;
|
||||
|
||||
|
@ -1113,7 +1114,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test '.$name,
|
||||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [
|
||||
'CUSTOM_VARIABLE' => 'variable',
|
||||
|
@ -1127,7 +1128,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -1142,7 +1143,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
// Allow build step to run
|
||||
sleep(40);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -1150,14 +1151,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
]);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
sleep(10);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -1167,7 +1168,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
$this->assertEquals('completed', $executions['body']['status']);
|
||||
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
|
||||
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals('Test ' . $name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
|
||||
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
|
||||
$this->assertEquals('Dart', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
|
||||
|
@ -1180,11 +1181,11 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
|
||||
$this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
|
||||
$this->assertEquals($executions['headers']['status-code'], 200);
|
||||
$this->assertEquals($executions['body']['total'], 1);
|
||||
$this->assertIsArray($executions['body']['executions']);
|
||||
|
@ -1194,7 +1195,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']);
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
|
@ -1207,9 +1208,9 @@ class FunctionsCustomServerTest extends Scope
|
|||
{
|
||||
$name = 'ruby-3.1';
|
||||
$folder = 'ruby';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions') . "/$folder/code.tar.gz";
|
||||
$this->packageCode($folder);
|
||||
|
||||
|
||||
$entrypoint = 'main.rb';
|
||||
$timeout = 2;
|
||||
|
||||
|
@ -1218,7 +1219,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'functionId' => 'unique()',
|
||||
'name' => 'Test '.$name,
|
||||
'name' => 'Test ' . $name,
|
||||
'runtime' => $name,
|
||||
'vars' => [
|
||||
'CUSTOM_VARIABLE' => 'variable',
|
||||
|
@ -1232,7 +1233,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
|
||||
$this->assertEquals(201, $function['headers']['status-code']);
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -1247,7 +1248,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
// Allow build step to run
|
||||
sleep(30);
|
||||
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$execution = $this->client->call(Client::METHOD_POST, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
|
@ -1255,14 +1256,14 @@ class FunctionsCustomServerTest extends Scope
|
|||
]);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
$this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
$executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
sleep(10);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions/' . $executionId, array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
@ -1272,7 +1273,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEquals(200, $executions['headers']['status-code']);
|
||||
$this->assertEquals('completed', $executions['body']['status']);
|
||||
$this->assertEquals($functionId, $output['APPWRITE_FUNCTION_ID']);
|
||||
$this->assertEquals('Test '.$name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals('Test ' . $name, $output['APPWRITE_FUNCTION_NAME']);
|
||||
$this->assertEquals($deploymentId, $output['APPWRITE_FUNCTION_DEPLOYMENT']);
|
||||
$this->assertEquals('http', $output['APPWRITE_FUNCTION_TRIGGER']);
|
||||
$this->assertEquals('Ruby', $output['APPWRITE_FUNCTION_RUNTIME_NAME']);
|
||||
|
@ -1285,11 +1286,11 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertEmpty($output['APPWRITE_FUNCTION_JWT']);
|
||||
$this->assertEquals($this->getProject()['$id'], $output['APPWRITE_FUNCTION_PROJECT_ID']);
|
||||
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions', array_merge([
|
||||
$executions = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/executions', array_merge([
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
|
||||
|
||||
$this->assertEquals($executions['headers']['status-code'], 200);
|
||||
$this->assertEquals($executions['body']['total'], 1);
|
||||
$this->assertIsArray($executions['body']['executions']);
|
||||
|
@ -1299,7 +1300,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertStringContainsString('foobar', $executions['body']['executions'][0]['stdout']);
|
||||
|
||||
// Cleanup : Delete function
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/'. $functionId, [
|
||||
$response = $this->client->call(Client::METHOD_DELETE, '/functions/' . $functionId, [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey'],
|
||||
|
@ -1314,7 +1315,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
// $folder = 'swift';
|
||||
// $code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
// $this->packageCode($folder);
|
||||
|
||||
|
||||
// $entrypoint = 'index.swift';
|
||||
// $timeout = 5;
|
||||
|
||||
|
@ -1360,11 +1361,11 @@ class FunctionsCustomServerTest extends Scope
|
|||
// ]);
|
||||
|
||||
// $executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
// $this->assertEquals(201, $execution['headers']['status-code']);
|
||||
|
||||
// $executionId = $execution['body']['$id'] ?? '';
|
||||
|
||||
|
||||
// sleep(10);
|
||||
|
||||
// $executions = $this->client->call(Client::METHOD_GET, '/functions/'.$functionId.'/executions/'.$executionId, array_merge([
|
||||
|
@ -1394,7 +1395,7 @@ class FunctionsCustomServerTest extends Scope
|
|||
// 'content-type' => 'application/json',
|
||||
// 'x-appwrite-project' => $this->getProject()['$id'],
|
||||
// ], $this->getHeaders()));
|
||||
|
||||
|
||||
// $this->assertEquals($executions['headers']['status-code'], 200);
|
||||
// $this->assertEquals($executions['body']['total'], 1);
|
||||
// $this->assertIsArray($executions['body']['executions']);
|
||||
|
@ -1432,6 +1433,5 @@ class FunctionsCustomServerTest extends Scope
|
|||
$this->assertArrayHasKey('image', $runtime);
|
||||
$this->assertArrayHasKey('base', $runtime);
|
||||
$this->assertArrayHasKey('supports', $runtime);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -278,7 +278,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.update.name', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.update.name", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$this->assertEquals($name, $response['data']['payload']['name']);
|
||||
|
@ -307,7 +307,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.update.password', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.update.password", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$this->assertEquals($name, $response['data']['payload']['name']);
|
||||
|
@ -335,7 +335,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.update.email', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.update.email", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$this->assertEquals('torsten@appwrite.io', $response['data']['payload']['email']);
|
||||
|
@ -343,7 +343,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
/**
|
||||
* Test Account Verification Create
|
||||
*/
|
||||
$this->client->call(Client::METHOD_POST, '/account/verification', array_merge([
|
||||
$verification = $this->client->call(Client::METHOD_POST, '/account/verification', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
|
@ -362,7 +362,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.verification.create', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.verification.{$verification['body']['$id']}.create", $response['data']['event']);
|
||||
|
||||
$lastEmail = $this->getLastEmail();
|
||||
$verification = substr($lastEmail['text'], strpos($lastEmail['text'], '&secret=', 0) + 8, 256);
|
||||
|
@ -370,7 +370,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
/**
|
||||
* Test Account Verification Complete
|
||||
*/
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([
|
||||
$verification = $this->client->call(Client::METHOD_PUT, '/account/verification', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
|
@ -390,7 +390,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.verification.update', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.verification.{$verification['body']['$id']}.update", $response['data']['event']);
|
||||
|
||||
/**
|
||||
* Test Acoount Prefs Update
|
||||
|
@ -417,7 +417,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.update.prefs', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.update.prefs", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
/**
|
||||
|
@ -445,7 +445,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.sessions.create', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.sessions.{$sessionNewId}.create", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
/**
|
||||
|
@ -468,13 +468,13 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.sessions.delete', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.sessions.{$sessionNewId}.delete", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
/**
|
||||
* Test Account Create Recovery
|
||||
*/
|
||||
$this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([
|
||||
$recovery = $this->client->call(Client::METHOD_POST, '/account/recovery', array_merge([
|
||||
'origin' => 'http://localhost',
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $projectId,
|
||||
|
@ -482,7 +482,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
'email' => 'torsten@appwrite.io',
|
||||
'url' => 'http://localhost/recovery',
|
||||
]);
|
||||
|
||||
$recoveryId = $recovery['body']['$id'];
|
||||
$response = json_decode($client->receive(), true);
|
||||
|
||||
$lastEmail = $this->getLastEmail();
|
||||
|
@ -496,7 +496,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.recovery.create', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.recovery.{$recoveryId}.create", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', array_merge([
|
||||
|
@ -520,7 +520,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertArrayHasKey('timestamp', $response['data']);
|
||||
$this->assertContains('account', $response['data']['channels']);
|
||||
$this->assertContains('account.' . $userId, $response['data']['channels']);
|
||||
$this->assertEquals('account.recovery.update', $response['data']['event']);
|
||||
$this->assertEquals("users.{$userId}.recovery.{$recoveryId}.update", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$client->close();
|
||||
|
@ -610,7 +610,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('documents', $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents.' . $document['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $actors['body']['$id'] . '.documents', $response['data']['channels']);
|
||||
$this->assertEquals('database.documents.create', $response['data']['event']);
|
||||
$this->assertEquals("collections.{$data['actorsId']}.documents.{$document['body']['$id']}.create", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
$this->assertEquals($response['data']['payload']['name'], 'Chris Evans');
|
||||
|
||||
|
@ -642,7 +642,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('documents', $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents.' . $data['documentId'], $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents', $response['data']['channels']);
|
||||
$this->assertEquals('database.documents.update', $response['data']['event']);
|
||||
$this->assertEquals("collections.{$data['actorsId']}.documents.{$data['documentId']}.update", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$this->assertEquals($response['data']['payload']['name'], 'Chris Evans 2');
|
||||
|
@ -680,7 +680,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('documents', $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents.' . $document['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents', $response['data']['channels']);
|
||||
$this->assertEquals('database.documents.delete', $response['data']['event']);
|
||||
$this->assertEquals("collections.{$data['actorsId']}.documents.{$document['body']['$id']}.delete", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
$this->assertEquals($response['data']['payload']['name'], 'Bradley Cooper');
|
||||
|
||||
|
@ -771,7 +771,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('documents', $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents.' . $document['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $actors['body']['$id'] . '.documents', $response['data']['channels']);
|
||||
$this->assertEquals('database.documents.create', $response['data']['event']);
|
||||
$this->assertEquals("collections.{$data['actorsId']}.documents.{$document['body']['$id']}.create", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
$this->assertEquals($response['data']['payload']['name'], 'Chris Evans');
|
||||
|
||||
|
@ -802,7 +802,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('documents', $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents.' . $data['documentId'], $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents', $response['data']['channels']);
|
||||
$this->assertEquals('database.documents.update', $response['data']['event']);
|
||||
$this->assertEquals("collections.{$data['actorsId']}.documents.{$document['body']['$id']}.update", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$this->assertEquals($response['data']['payload']['name'], 'Chris Evans 2');
|
||||
|
@ -840,7 +840,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('documents', $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents.' . $document['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('collections.' . $data['actorsId'] . '.documents', $response['data']['channels']);
|
||||
$this->assertEquals('database.documents.delete', $response['data']['event']);
|
||||
$this->assertEquals("collections.{$data['actorsId']}.documents.{$document['body']['$id']}.delete", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
$this->assertEquals($response['data']['payload']['name'], 'Bradley Cooper');
|
||||
|
||||
|
@ -908,7 +908,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('files', $response['data']['channels']);
|
||||
$this->assertContains('buckets.' . $data['bucketId'] . '.files.' . $file['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('buckets.' . $data['bucketId'] . '.files', $response['data']['channels']);
|
||||
$this->assertEquals('storage.files.create', $response['data']['event']);
|
||||
$this->assertEquals("buckets.{$data['bucketId']}.files.{$file['body']['$id']}.create", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$data['fileId'] = $file['body']['$id'];
|
||||
|
@ -935,7 +935,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('files', $response['data']['channels']);
|
||||
$this->assertContains('buckets.' . $data['bucketId'] . '.files.' . $file['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('buckets.' . $data['bucketId'] . '.files', $response['data']['channels']);
|
||||
$this->assertEquals('storage.files.update', $response['data']['event']);
|
||||
$this->assertEquals("buckets.{$data['bucketId']}.files.{$file['body']['$id']}.update", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
/**
|
||||
|
@ -957,7 +957,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('files', $response['data']['channels']);
|
||||
$this->assertContains('buckets.' . $data['bucketId'] . '.files.' . $file['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('buckets.' . $data['bucketId'] . '.files', $response['data']['channels']);
|
||||
$this->assertEquals('storage.files.delete', $response['data']['event']);
|
||||
$this->assertEquals("buckets.{$data['bucketId']}.files.{$file['body']['$id']}.delete", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$client->close();
|
||||
|
@ -1010,7 +1010,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$stdout= '';
|
||||
$code = realpath(__DIR__ . '/../../../resources/functions'). "/$folder/code.tar.gz";
|
||||
Console::execute('cd '.realpath(__DIR__ . "/../../../resources/functions") . "/$folder && tar --exclude code.tar.gz -czf code.tar.gz .", '', $stdout, $stderr);
|
||||
|
||||
|
||||
$deployment = $this->client->call(Client::METHOD_POST, '/functions/'.$functionId.'/deployments', array_merge([
|
||||
'content-type' => 'multipart/form-data',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
|
@ -1058,7 +1058,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('executions', $response['data']['channels']);
|
||||
$this->assertContains('executions.' . $execution['body']['$id'], $response['data']['channels']);
|
||||
$this->assertContains('functions.' . $execution['body']['functionId'], $response['data']['channels']);
|
||||
$this->assertEquals('functions.executions.create', $response['data']['event']);
|
||||
$this->assertEquals("functions.{$functionId}.executions.{$execution['body']['$id']}.create", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$this->assertArrayHasKey('type', $responseUpdate);
|
||||
|
@ -1071,7 +1071,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertContains('executions', $responseUpdate['data']['channels']);
|
||||
$this->assertContains('executions.' . $execution['body']['$id'], $responseUpdate['data']['channels']);
|
||||
$this->assertContains('functions.' . $execution['body']['functionId'], $responseUpdate['data']['channels']);
|
||||
$this->assertEquals('functions.executions.update', $responseUpdate['data']['event']);
|
||||
$this->assertEquals("functions.{$functionId}.executions.{$execution['body']['$id']}.update", $responseUpdate['data']['event']);
|
||||
$this->assertNotEmpty($responseUpdate['data']['payload']);
|
||||
|
||||
$client->close();
|
||||
|
@ -1134,7 +1134,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('teams', $response['data']['channels']);
|
||||
$this->assertContains('teams.' . $teamId, $response['data']['channels']);
|
||||
$this->assertEquals('teams.create', $response['data']['event']);
|
||||
$this->assertEquals("teams.{$teamId}.create", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
/**
|
||||
|
@ -1160,7 +1160,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('teams', $response['data']['channels']);
|
||||
$this->assertContains('teams.' . $teamId, $response['data']['channels']);
|
||||
$this->assertEquals('teams.update', $response['data']['event']);
|
||||
$this->assertEquals("teams.{$teamId}.update", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$client->close();
|
||||
|
@ -1224,7 +1224,7 @@ class RealtimeCustomClientTest extends Scope
|
|||
$this->assertCount(2, $response['data']['channels']);
|
||||
$this->assertContains('memberships', $response['data']['channels']);
|
||||
$this->assertContains('memberships.' . $membershipId, $response['data']['channels']);
|
||||
$this->assertEquals('teams.memberships.update', $response['data']['event']);
|
||||
$this->assertEquals("teams.{$teamId}.memberships.{$membershipId}.update", $response['data']['event']);
|
||||
$this->assertNotEmpty($response['data']['payload']);
|
||||
|
||||
$client->close();
|
||||
|
|
Loading…
Reference in a new issue