diff --git a/app/config/collections/projects.php b/app/config/collections/projects.php index 704b941505..d475cdd05c 100644 --- a/app/config/collections/projects.php +++ b/app/config/collections/projects.php @@ -2462,7 +2462,18 @@ return [ 'default' => null, 'array' => false, 'filters' => ['datetime'], - ] + ], + [ + '$id' => ID::custom('accessedAt'), + 'type' => Database::VAR_DATETIME, + 'format' => '', + 'size' => 0, + 'signed' => false, + 'required' => false, + 'default' => null, + 'array' => false, + 'filters' => ['datetime'], + ], ], 'indexes' => [ [ @@ -2472,7 +2483,13 @@ return [ 'lengths' => [], 'orders' => [Database::ORDER_ASC], ], - + [ + '$id' => '_key_accessedAt', + 'type' => Database::INDEX_KEY, + 'attributes' => ['accessedAt'], + 'lengths' => [], + 'orders' => [], + ], ], ], ]; diff --git a/app/init/constants.php b/app/init/constants.php index 2b15f9fa0b..3a625980b8 100644 --- a/app/init/constants.php +++ b/app/init/constants.php @@ -29,6 +29,7 @@ const APP_LIMIT_LIST_DEFAULT = 25; // Default maximum number of items to return const APP_KEY_ACCESS = 24 * 60 * 60; // 24 hours const APP_USER_ACCESS = 24 * 60 * 60; // 24 hours const APP_PROJECT_ACCESS = 24 * 60 * 60; // 24 hours +const APP_RESOURCE_TOKEN_ACCESS = 24 * 60 * 60; // 24 hours const APP_FILE_ACCESS = 24 * 60 * 60; // 24 hours const APP_CACHE_UPDATE = 24 * 60 * 60; // 24 hours const APP_CACHE_BUSTER = 4318; diff --git a/app/init/resources.php b/app/init/resources.php index f4ccca3f26..41e866c617 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -930,6 +930,12 @@ App::setResource('resourceToken', function ($project, $dbForProject, $request) { return new Document([]); } + $accessedAt = $token->getAttribute('accessedAt', 0); + if (empty($accessedAt) || DatabaseDateTime::formatTz(DatabaseDateTime::addSeconds(new \DateTime(), - APP_RESOURCE_TOKEN_ACCESS)) > $accessedAt) { + $token->setAttribute('accessedAt', DatabaseDateTime::now()); + Authorization::skip(fn () => $dbForProject->updateDocument('resourceTokens', $token->getId(), $token)); + } + return new Document([ 'bucketId' => $ids[0], 'fileId' => $ids[1], diff --git a/src/Appwrite/Utopia/Response/Model/ResourceToken.php b/src/Appwrite/Utopia/Response/Model/ResourceToken.php index 074cb2c154..a49f272a7b 100644 --- a/src/Appwrite/Utopia/Response/Model/ResourceToken.php +++ b/src/Appwrite/Utopia/Response/Model/ResourceToken.php @@ -40,18 +40,18 @@ class ResourceToken extends Model 'default' => '', 'example' => 'file', ]) - ->addRule('secret', [ - 'type' => self::TYPE_STRING, - 'description' => 'Token secret for the resource.', - 'default' => '', - 'example' => 'Bpw_g9c2TGXxfgLshDbSaL8tsCcqgczQ', - ]) ->addRule('expire', [ 'type' => self::TYPE_DATETIME, 'description' => 'Token expiration date in ISO 8601 format.', 'default' => '', 'example' => self::TYPE_DATETIME_EXAMPLE, ]) + ->addRule('accessedAt', [ + 'type' => self::TYPE_DATETIME, + 'description' => 'Most recent access date in ISO 8601 format. This attribute is only updated again after ' . APP_RESOURCE_TOKEN_ACCESS / 60 / 60 . ' hours.', + 'default' => '', + 'example' => self::TYPE_DATETIME_EXAMPLE + ]) ; }