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

get project db key by region

This commit is contained in:
shimon 2024-08-05 15:56:45 +03:00
parent 6b3051f131
commit d6dfe7dfb3
2 changed files with 66 additions and 69 deletions

View file

@ -133,6 +133,12 @@ App::post('/v1/projects')
throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project."); throw new Exception(Exception::PROJECT_RESERVED_PROJECT, "'console' is a reserved project.");
} }
var_dump([
'_APP_DATABASE_SHARED_TABLES' => System::getEnv('_APP_DATABASE_SHARED_TABLES', ''),
'region' => $region,
'dsn' => $dsn,
]);
// TODO: Temporary until all projects are using shared tables. // TODO: Temporary until all projects are using shared tables.
$sharedTablesKeys = explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')); $sharedTablesKeys = explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
if (in_array($dsn->getHost(), $sharedTablesKeys)) { if (in_array($dsn->getHost(), $sharedTablesKeys)) {
@ -146,12 +152,6 @@ App::post('/v1/projects')
} }
} }
var_dump([
'_APP_DATABASE_SHARED_TABLES' => System::getEnv('_APP_DATABASE_SHARED_TABLES', ''),
'region' => $region,
'dsn' => $dsn,
]);
try { try {
$project = $dbForConsole->createDocument('projects', new Document([ $project = $dbForConsole->createDocument('projects', new Document([
'$id' => $projectId, '$id' => $projectId,

View file

@ -43,7 +43,7 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
$replace = $parts[1] ?? ''; $replace = $parts[1] ?? '';
$params = match ($namespace) { $params = match ($namespace) {
'user' => (array)$user, 'user' => (array) $user,
'request' => $requestParams, 'request' => $requestParams,
default => $responsePayload, default => $responsePayload,
}; };
@ -52,6 +52,7 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
$label = \str_replace($find, $params[$replace], $label); $label = \str_replace($find, $params[$replace], $label);
} }
} }
return $label; return $label;
}; };
@ -88,13 +89,12 @@ $databaseListener = function (string $event, Document $document, Document $proje
->addReduce($document); ->addReduce($document);
} }
break; break;
case str_starts_with($document->getCollection(), 'database_') && !str_contains($document->getCollection(), 'collection'): //collections case str_starts_with($document->getCollection(), 'database_') && ! str_contains($document->getCollection(), 'collection'): //collections
$parts = explode('_', $document->getCollection()); $parts = explode('_', $document->getCollection());
$databaseInternalId = $parts[1] ?? 0; $databaseInternalId = $parts[1] ?? 0;
$queueForUsage $queueForUsage
->addMetric(METRIC_COLLECTIONS, $value) // per project ->addMetric(METRIC_COLLECTIONS, $value) // per project
->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_COLLECTIONS), $value) // per database ->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_COLLECTIONS), $value); // per database
;
if ($event === Database::EVENT_DOCUMENT_DELETE) { if ($event === Database::EVENT_DOCUMENT_DELETE) {
$queueForUsage $queueForUsage
@ -103,7 +103,7 @@ $databaseListener = function (string $event, Document $document, Document $proje
break; break;
case str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_'): //documents case str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_'): //documents
$parts = explode('_', $document->getCollection()); $parts = explode('_', $document->getCollection());
$databaseInternalId = $parts[1] ?? 0; $databaseInternalId = $parts[1] ?? 0;
$collectionInternalId = $parts[3] ?? 0; $collectionInternalId = $parts[3] ?? 0;
$queueForUsage $queueForUsage
->addMetric(METRIC_DOCUMENTS, $value) // per project ->addMetric(METRIC_DOCUMENTS, $value) // per project
@ -120,7 +120,7 @@ $databaseListener = function (string $event, Document $document, Document $proje
break; break;
case str_starts_with($document->getCollection(), 'bucket_'): // files case str_starts_with($document->getCollection(), 'bucket_'): // files
$parts = explode('_', $document->getCollection()); $parts = explode('_', $document->getCollection());
$bucketInternalId = $parts[1]; $bucketInternalId = $parts[1];
$queueForUsage $queueForUsage
->addMetric(METRIC_FILES, $value) // per project ->addMetric(METRIC_FILES, $value) // per project
->addMetric(METRIC_FILES_STORAGE, $document->getAttribute('sizeOriginal') * $value) // per project ->addMetric(METRIC_FILES_STORAGE, $document->getAttribute('sizeOriginal') * $value) // per project
@ -197,9 +197,9 @@ App::init()
$authKey = $request->getHeader('x-appwrite-key', ''); $authKey = $request->getHeader('x-appwrite-key', '');
if (!empty($authKey)) { // API Key authentication if (! empty($authKey)) { // API Key authentication
// Do not allow API key and session to be set at the same time // Do not allow API key and session to be set at the same time
if (!$user->isEmpty()) { if (! $user->isEmpty()) {
throw new Exception(Exception::USER_API_KEY_AND_SESSION_SET); throw new Exception(Exception::USER_API_KEY_AND_SESSION_SET);
} }
@ -209,7 +209,7 @@ App::init()
$user = new Document([ $user = new Document([
'$id' => '', '$id' => '',
'status' => true, 'status' => true,
'email' => 'app.' . $project->getId() . '@service.' . $request->getHostname(), 'email' => 'app.'.$project->getId().'@service.'.$request->getHostname(),
'password' => '', 'password' => '',
'name' => $project->getAttribute('name', 'Untitled'), 'name' => $project->getAttribute('name', 'Untitled'),
]); ]);
@ -218,7 +218,7 @@ App::init()
$scopes = \array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', [])); $scopes = \array_merge($roles[$role]['scopes'], $key->getAttribute('scopes', []));
$expire = $key->getAttribute('expire'); $expire = $key->getAttribute('expire');
if (!empty($expire) && $expire < DateTime::formatTz(DateTime::now())) { if (! empty($expire) && $expire < DateTime::formatTz(DateTime::now())) {
throw new Exception(Exception::PROJECT_KEY_EXPIRED); throw new Exception(Exception::PROJECT_KEY_EXPIRED);
} }
@ -236,7 +236,7 @@ App::init()
$sdk = $request->getHeader('x-sdk-name', 'UNKNOWN'); $sdk = $request->getHeader('x-sdk-name', 'UNKNOWN');
if ($sdkValidator->isValid($sdk)) { if ($sdkValidator->isValid($sdk)) {
$sdks = $key->getAttribute('sdks', []); $sdks = $key->getAttribute('sdks', []);
if (!in_array($sdk, $sdks)) { if (! in_array($sdk, $sdks)) {
array_push($sdks, $sdk); array_push($sdks, $sdk);
$key->setAttribute('sdks', $sdks); $key->setAttribute('sdks', $sdks);
@ -256,24 +256,24 @@ App::init()
} }
$service = $route->getLabel('sdk.namespace', ''); $service = $route->getLabel('sdk.namespace', '');
if (!empty($service)) { if (! empty($service)) {
if ( if (
array_key_exists($service, $project->getAttribute('services', [])) array_key_exists($service, $project->getAttribute('services', []))
&& !$project->getAttribute('services', [])[$service] && ! $project->getAttribute('services', [])[$service]
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles())) && ! (Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
) { ) {
throw new Exception(Exception::GENERAL_SERVICE_DISABLED); throw new Exception(Exception::GENERAL_SERVICE_DISABLED);
} }
} }
if (!\in_array($scope, $scopes)) { if (! \in_array($scope, $scopes)) {
if ($project->isEmpty()) { // Check if permission is denied because project is missing if ($project->isEmpty()) { // Check if permission is denied because project is missing
throw new Exception(Exception::PROJECT_NOT_FOUND); throw new Exception(Exception::PROJECT_NOT_FOUND);
} }
throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE, $user->getAttribute('email', 'User') . ' (role: ' . \strtolower($roles[$role]['label']) . ') missing scope (' . $scope . ')'); throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE, $user->getAttribute('email', 'User').' (role: '.\strtolower($roles[$role]['label']).') missing scope ('.$scope.')');
} }
if (false === $user->getAttribute('status')) { // Account is blocked if ($user->getAttribute('status') === false) { // Account is blocked
throw new Exception(Exception::USER_BLOCKED); throw new Exception(Exception::USER_BLOCKED);
} }
@ -288,7 +288,7 @@ App::init()
$hasMoreFactors = $hasVerifiedEmail || $hasVerifiedPhone || $hasVerifiedAuthenticator; $hasMoreFactors = $hasVerifiedEmail || $hasVerifiedPhone || $hasVerifiedAuthenticator;
$minimumFactors = ($mfaEnabled && $hasMoreFactors) ? 2 : 1; $minimumFactors = ($mfaEnabled && $hasMoreFactors) ? 2 : 1;
if (!in_array('mfa', $route->getGroups())) { if (! in_array('mfa', $route->getGroups())) {
if ($session && \count($session->getAttribute('factors', [])) < $minimumFactors) { if ($session && \count($session->getAttribute('factors', [])) < $minimumFactors) {
throw new Exception(Exception::USER_MORE_FACTORS_REQUIRED); throw new Exception(Exception::USER_MORE_FACTORS_REQUIRED);
} }
@ -317,8 +317,8 @@ App::init()
if ( if (
array_key_exists('rest', $project->getAttribute('apis', [])) array_key_exists('rest', $project->getAttribute('apis', []))
&& !$project->getAttribute('apis', [])['rest'] && ! $project->getAttribute('apis', [])['rest']
&& !(Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles())) && ! (Auth::isPrivilegedUser(Authorization::getRoles()) || Auth::isAppUser(Authorization::getRoles()))
) { ) {
throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED); throw new AppwriteException(AppwriteException::GENERAL_API_DISABLED);
} }
@ -329,7 +329,7 @@ App::init()
$abuseKeyLabel = $route->getLabel('abuse-key', 'url:{url},ip:{ip}'); $abuseKeyLabel = $route->getLabel('abuse-key', 'url:{url},ip:{ip}');
$timeLimitArray = []; $timeLimitArray = [];
$abuseKeyLabel = (!is_array($abuseKeyLabel)) ? [$abuseKeyLabel] : $abuseKeyLabel; $abuseKeyLabel = (! is_array($abuseKeyLabel)) ? [$abuseKeyLabel] : $abuseKeyLabel;
foreach ($abuseKeyLabel as $abuseKey) { foreach ($abuseKeyLabel as $abuseKey) {
$start = $request->getContentRangeStart(); $start = $request->getContentRangeStart();
@ -340,7 +340,7 @@ App::init()
->setParam('{userId}', $user->getId()) ->setParam('{userId}', $user->getId())
->setParam('{userAgent}', $request->getUserAgent('')) ->setParam('{userAgent}', $request->getUserAgent(''))
->setParam('{ip}', $request->getIP()) ->setParam('{ip}', $request->getIP())
->setParam('{url}', $request->getHostname() . $route->getPath()) ->setParam('{url}', $request->getHostname().$route->getPath())
->setParam('{method}', $request->getMethod()) ->setParam('{method}', $request->getMethod())
->setParam('{chunkId}', (int) ($start / ($end + 1 - $start))); ->setParam('{chunkId}', (int) ($start / ($end + 1 - $start)));
$timeLimitArray[] = $timeLimit; $timeLimitArray[] = $timeLimit;
@ -354,8 +354,8 @@ App::init()
foreach ($timeLimitArray as $timeLimit) { foreach ($timeLimitArray as $timeLimit) {
foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys foreach ($request->getParams() as $key => $value) { // Set request params as potential abuse keys
if (!empty($value)) { if (! empty($value)) {
$timeLimit->setParam('{param-' . $key . '}', (\is_array($value)) ? \json_encode($value) : $value); $timeLimit->setParam('{param-'.$key.'}', (\is_array($value)) ? \json_encode($value) : $value);
} }
} }
@ -376,8 +376,8 @@ App::init()
if ( if (
$enabled // Abuse is enabled $enabled // Abuse is enabled
&& !$isAppUser // User is not API key && ! $isAppUser // User is not API key
&& !$isPrivilegedUser // User is not an admin && ! $isPrivilegedUser // User is not an admin
&& $abuse->check() // Route is rate-limited && $abuse->check() // Route is rate-limited
) { ) {
throw new Exception(Exception::GENERAL_RATE_LIMIT_EXCEEDED); throw new Exception(Exception::GENERAL_RATE_LIMIT_EXCEEDED);
@ -411,26 +411,26 @@ App::init()
$useCache = $route->getLabel('cache', false); $useCache = $route->getLabel('cache', false);
if ($useCache) { if ($useCache) {
$key = md5($request->getURI() . '*' . implode('*', $request->getParams()) . '*' . APP_CACHE_BUSTER); $key = md5($request->getURI().'*'.implode('*', $request->getParams()).'*'.APP_CACHE_BUSTER);
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
$cache = new Cache( $cache = new Cache(
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId()) new Filesystem(APP_STORAGE_CACHE.DIRECTORY_SEPARATOR.'app-'.$project->getId())
); );
$timestamp = 60 * 60 * 24 * 30; $timestamp = 60 * 60 * 24 * 30;
$data = $cache->load($key, $timestamp); $data = $cache->load($key, $timestamp);
if (!empty($data) && !$cacheLog->isEmpty()) { if (! empty($data) && ! $cacheLog->isEmpty()) {
$parts = explode('/', $cacheLog->getAttribute('resourceType')); $parts = explode('/', $cacheLog->getAttribute('resourceType'));
$type = $parts[0] ?? null; $type = $parts[0] ?? null;
if ($type === 'bucket') { if ($type === 'bucket') {
$bucketId = $parts[1] ?? null; $bucketId = $parts[1] ?? null;
$bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId)); $bucket = Authorization::skip(fn () => $dbForProject->getDocument('buckets', $bucketId));
$isAPIKey = Auth::isAppUser(Authorization::getRoles()); $isAPIKey = Auth::isAppUser(Authorization::getRoles());
$isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles()); $isPrivilegedUser = Auth::isPrivilegedUser(Authorization::getRoles());
if ($bucket->isEmpty() || (!$bucket->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) { if ($bucket->isEmpty() || (! $bucket->getAttribute('enabled') && ! $isAPIKey && ! $isPrivilegedUser)) {
throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND); throw new Exception(Exception::STORAGE_BUCKET_NOT_FOUND);
} }
@ -438,17 +438,17 @@ App::init()
$validator = new Authorization(Database::PERMISSION_READ); $validator = new Authorization(Database::PERMISSION_READ);
$valid = $validator->isValid($bucket->getRead()); $valid = $validator->isValid($bucket->getRead());
if (!$fileSecurity && !$valid) { if (! $fileSecurity && ! $valid) {
throw new Exception(Exception::USER_UNAUTHORIZED); throw new Exception(Exception::USER_UNAUTHORIZED);
} }
$parts = explode('/', $cacheLog->getAttribute('resource')); $parts = explode('/', $cacheLog->getAttribute('resource'));
$fileId = $parts[1] ?? null; $fileId = $parts[1] ?? null;
if ($fileSecurity && !$valid) { if ($fileSecurity && ! $valid) {
$file = $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId); $file = $dbForProject->getDocument('bucket_'.$bucket->getInternalId(), $fileId);
} else { } else {
$file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_' . $bucket->getInternalId(), $fileId)); $file = Authorization::skip(fn () => $dbForProject->getDocument('bucket_'.$bucket->getInternalId(), $fileId));
} }
if ($file->isEmpty()) { if ($file->isEmpty()) {
@ -457,7 +457,7 @@ App::init()
} }
$response $response
->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $timestamp) . ' GMT') ->addHeader('Expires', \date('D, d M Y H:i:s', \time() + $timestamp).' GMT')
->addHeader('X-Appwrite-Cache', 'hit') ->addHeader('X-Appwrite-Cache', 'hit')
->setContentType($cacheLog->getAttribute('mimeType')) ->setContentType($cacheLog->getAttribute('mimeType'))
->send($data); ->send($data);
@ -466,8 +466,7 @@ App::init()
->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate') ->addHeader('Cache-Control', 'no-cache, no-store, must-revalidate')
->addHeader('Pragma', 'no-cache') ->addHeader('Pragma', 'no-cache')
->addHeader('Expires', 0) ->addHeader('Expires', 0)
->addHeader('X-Appwrite-Cache', 'miss') ->addHeader('X-Appwrite-Cache', 'miss');
;
} }
} }
}); });
@ -481,7 +480,7 @@ App::init()
return; return;
} }
if (!$user->isEmpty()) { if (! $user->isEmpty()) {
throw new Exception(Exception::USER_SESSION_ALREADY_EXISTS); throw new Exception(Exception::USER_SESSION_ALREADY_EXISTS);
} }
}); });
@ -548,7 +547,7 @@ App::shutdown()
$responsePayload = $response->getPayload(); $responsePayload = $response->getPayload();
if (!empty($queueForEvents->getEvent())) { if (! empty($queueForEvents->getEvent())) {
if (empty($queueForEvents->getPayload())) { if (empty($queueForEvents->getPayload())) {
$queueForEvents->setPayload($responsePayload); $queueForEvents->setPayload($responsePayload);
} }
@ -597,7 +596,7 @@ App::shutdown()
roles: $target['roles'], roles: $target['roles'],
options: [ options: [
'permissionsChanged' => $target['permissionsChanged'], 'permissionsChanged' => $target['permissionsChanged'],
'userId' => $queueForEvents->getParam('userId') 'userId' => $queueForEvents->getParam('userId'),
] ]
); );
} }
@ -610,24 +609,24 @@ App::shutdown()
* Audit labels * Audit labels
*/ */
$pattern = $route->getLabel('audits.resource', null); $pattern = $route->getLabel('audits.resource', null);
if (!empty($pattern)) { if (! empty($pattern)) {
$resource = $parseLabel($pattern, $responsePayload, $requestParams, $user); $resource = $parseLabel($pattern, $responsePayload, $requestParams, $user);
if (!empty($resource) && $resource !== $pattern) { if (! empty($resource) && $resource !== $pattern) {
$queueForAudits->setResource($resource); $queueForAudits->setResource($resource);
} }
} }
if (!$user->isEmpty()) { if (! $user->isEmpty()) {
$queueForAudits->setUser($user); $queueForAudits->setUser($user);
} }
if (!empty($queueForAudits->getResource()) && !empty($queueForAudits->getUser()->getId())) { if (! empty($queueForAudits->getResource()) && ! empty($queueForAudits->getUser()->getId())) {
/** /**
* audits.payload is switched to default true * audits.payload is switched to default true
* in order to auto audit payload for all endpoints * in order to auto audit payload for all endpoints
*/ */
$pattern = $route->getLabel('audits.payload', true); $pattern = $route->getLabel('audits.payload', true);
if (!empty($pattern)) { if (! empty($pattern)) {
$queueForAudits->setPayload($responsePayload); $queueForAudits->setPayload($responsePayload);
} }
@ -637,19 +636,19 @@ App::shutdown()
$queueForAudits->trigger(); $queueForAudits->trigger();
} }
if (!empty($queueForDeletes->getType())) { if (! empty($queueForDeletes->getType())) {
$queueForDeletes->trigger(); $queueForDeletes->trigger();
} }
if (!empty($queueForDatabase->getType())) { if (! empty($queueForDatabase->getType())) {
$queueForDatabase->trigger(); $queueForDatabase->trigger();
} }
if (!empty($queueForBuilds->getType())) { if (! empty($queueForBuilds->getType())) {
$queueForBuilds->trigger(); $queueForBuilds->trigger();
} }
if (!empty($queueForMessaging->getType())) { if (! empty($queueForMessaging->getType())) {
$queueForMessaging->trigger(); $queueForMessaging->trigger();
} }
@ -660,20 +659,20 @@ App::shutdown()
if ($useCache) { if ($useCache) {
$resource = $resourceType = null; $resource = $resourceType = null;
$data = $response->getPayload(); $data = $response->getPayload();
if (!empty($data['payload'])) { if (! empty($data['payload'])) {
$pattern = $route->getLabel('cache.resource', null); $pattern = $route->getLabel('cache.resource', null);
if (!empty($pattern)) { if (! empty($pattern)) {
$resource = $parseLabel($pattern, $responsePayload, $requestParams, $user); $resource = $parseLabel($pattern, $responsePayload, $requestParams, $user);
} }
$pattern = $route->getLabel('cache.resourceType', null); $pattern = $route->getLabel('cache.resourceType', null);
if (!empty($pattern)) { if (! empty($pattern)) {
$resourceType = $parseLabel($pattern, $responsePayload, $requestParams, $user); $resourceType = $parseLabel($pattern, $responsePayload, $requestParams, $user);
} }
$key = md5($request->getURI() . '*' . implode('*', $request->getParams()) . '*' . APP_CACHE_BUSTER); $key = md5($request->getURI().'*'.implode('*', $request->getParams()).'*'.APP_CACHE_BUSTER);
$signature = md5($data['payload']); $signature = md5($data['payload']);
$cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key)); $cacheLog = Authorization::skip(fn () => $dbForProject->getDocument('cache', $key));
$accessedAt = $cacheLog->getAttribute('accessedAt', ''); $accessedAt = $cacheLog->getAttribute('accessedAt', '');
$now = DateTime::now(); $now = DateTime::now();
if ($cacheLog->isEmpty()) { if ($cacheLog->isEmpty()) {
@ -692,20 +691,18 @@ App::shutdown()
if ($signature !== $cacheLog->getAttribute('signature')) { if ($signature !== $cacheLog->getAttribute('signature')) {
$cache = new Cache( $cache = new Cache(
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $project->getId()) new Filesystem(APP_STORAGE_CACHE.DIRECTORY_SEPARATOR.'app-'.$project->getId())
); );
$cache->save($key, $data['payload']); $cache->save($key, $data['payload']);
} }
} }
} }
if ($project->getId() !== 'console') { if ($project->getId() !== 'console') {
if (!Auth::isPrivilegedUser(Authorization::getRoles())) { if (! Auth::isPrivilegedUser(Authorization::getRoles())) {
$fileSize = 0; $fileSize = 0;
$file = $request->getFiles('file'); $file = $request->getFiles('file');
if (!empty($file)) { if (! empty($file)) {
$fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size']; $fileSize = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size'];
} }
@ -723,12 +720,12 @@ App::shutdown()
/** /**
* Update user last activity * Update user last activity
*/ */
if (!$user->isEmpty()) { if (! $user->isEmpty()) {
$accessedAt = $user->getAttribute('accessedAt', ''); $accessedAt = $user->getAttribute('accessedAt', '');
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_USER_ACCCESS)) > $accessedAt) { if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_USER_ACCCESS)) > $accessedAt) {
$user->setAttribute('accessedAt', DateTime::now()); $user->setAttribute('accessedAt', DateTime::now());
if (APP_MODE_ADMIN !== $mode) { if ($mode !== APP_MODE_ADMIN) {
$dbForProject->updateDocument('users', $user->getId(), $user); $dbForProject->updateDocument('users', $user->getId(), $user);
} else { } else {
$dbForConsole->updateDocument('users', $user->getId(), $user); $dbForConsole->updateDocument('users', $user->getId(), $user);