Implement Variable Session Duration
This commit is contained in:
parent
1b0abf4643
commit
d34359fd49
|
@ -633,6 +633,17 @@ $collections = [
|
|||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('sessionDuration'),
|
||||
'type' => Database::VAR_INTEGER,
|
||||
'format' => '',
|
||||
'size' => 32,
|
||||
'signed' => true,
|
||||
'required' => false,
|
||||
'default' => 525600, // 1 Year
|
||||
'array' => false,
|
||||
'filters' => [],
|
||||
],
|
||||
[
|
||||
'$id' => ID::custom('services'),
|
||||
'type' => Database::VAR_STRING,
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -165,10 +165,11 @@ App::post('/v1/account/sessions/email')
|
|||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('events')
|
||||
->action(function (string $email, string $password, Request $request, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Event $events) {
|
||||
->action(function (string $email, string $password, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $events) {
|
||||
|
||||
$email = \strtolower($email);
|
||||
$protocol = $request->getProtocol();
|
||||
|
@ -185,9 +186,11 @@ App::post('/v1/account/sessions/email')
|
|||
throw new Exception(Exception::USER_BLOCKED); // User is in status blocked
|
||||
}
|
||||
|
||||
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
|
||||
$secret = Auth::tokenGenerator();
|
||||
$session = new Document(array_merge(
|
||||
[
|
||||
|
@ -525,10 +528,11 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
|||
}
|
||||
|
||||
// Create session token, verify user account and update OAuth2 ID and Access Token
|
||||
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$secret = Auth::tokenGenerator();
|
||||
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
|
||||
|
||||
$session = new Document(array_merge([
|
||||
'$id' => ID::unique(),
|
||||
|
@ -759,10 +763,11 @@ App::put('/v1/account/sessions/magic-url')
|
|||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('events')
|
||||
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Event $events) {
|
||||
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $events) {
|
||||
|
||||
/** @var Utopia\Database\Document $user */
|
||||
|
||||
|
@ -778,10 +783,11 @@ App::put('/v1/account/sessions/magic-url')
|
|||
throw new Exception(Exception::USER_INVALID_TOKEN);
|
||||
}
|
||||
|
||||
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$secret = Auth::tokenGenerator();
|
||||
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
|
||||
|
||||
$session = new Document(array_merge(
|
||||
[
|
||||
|
@ -996,10 +1002,11 @@ App::put('/v1/account/sessions/phone')
|
|||
->inject('request')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('locale')
|
||||
->inject('geodb')
|
||||
->inject('events')
|
||||
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Event $events) {
|
||||
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $events) {
|
||||
|
||||
$user = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId));
|
||||
|
||||
|
@ -1013,10 +1020,11 @@ App::put('/v1/account/sessions/phone')
|
|||
throw new Exception(Exception::USER_INVALID_TOKEN);
|
||||
}
|
||||
|
||||
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$secret = Auth::tokenGenerator();
|
||||
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
|
||||
|
||||
$session = new Document(array_merge(
|
||||
[
|
||||
|
@ -1164,11 +1172,11 @@ App::post('/v1/account/sessions/anonymous')
|
|||
])));
|
||||
|
||||
// Create session token
|
||||
|
||||
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$secret = Auth::tokenGenerator();
|
||||
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
|
||||
|
||||
$session = new Document(array_merge(
|
||||
[
|
||||
|
|
|
@ -32,6 +32,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Projects;
|
|||
use Utopia\Validator\ArrayList;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Hostname;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
@ -67,10 +68,11 @@ App::post('/v1/projects')
|
|||
->param('legalCity', '', new Text(256), 'Project legal City. Max length: 256 chars.', true)
|
||||
->param('legalAddress', '', new Text(256), 'Project legal Address. Max length: 256 chars.', true)
|
||||
->param('legalTaxId', '', new Text(256), 'Project legal Tax ID. Max length: 256 chars.', true)
|
||||
->param('sessionDuration', 525600, new Integer(), 'Session duration in minutes. Defaults to 1 year', true)
|
||||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->inject('dbForProject')
|
||||
->action(function (string $projectId, string $name, string $teamId, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Database $dbForProject) {
|
||||
->action(function (string $projectId, string $name, string $teamId, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, int $sessionDuration, Response $response, Database $dbForConsole, Database $dbForProject) {
|
||||
|
||||
$team = $dbForConsole->getDocument('teams', $teamId);
|
||||
|
||||
|
@ -112,6 +114,7 @@ App::post('/v1/projects')
|
|||
'legalCity' => $legalCity,
|
||||
'legalAddress' => $legalAddress,
|
||||
'legalTaxId' => ID::custom($legalTaxId),
|
||||
'sessionDuration' => $sessionDuration,
|
||||
'services' => new stdClass(),
|
||||
'platforms' => null,
|
||||
'authProviders' => [],
|
||||
|
@ -374,9 +377,10 @@ App::patch('/v1/projects/:projectId')
|
|||
->param('legalCity', '', new Text(256), 'Project legal city. Max length: 256 chars.', true)
|
||||
->param('legalAddress', '', new Text(256), 'Project legal address. Max length: 256 chars.', true)
|
||||
->param('legalTaxId', '', new Text(256), 'Project legal tax ID. Max length: 256 chars.', true)
|
||||
->param('sessionDuration', null, new Integer(true), 'Project session length in minutes. Max length: 525600 minutes.', true)
|
||||
->inject('response')
|
||||
->inject('dbForConsole')
|
||||
->action(function (string $projectId, string $name, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole) {
|
||||
->action(function (string $projectId, string $name, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, int $sessionDuration, Response $response, Database $dbForConsole) {
|
||||
|
||||
$project = $dbForConsole->getDocument('projects', $projectId);
|
||||
|
||||
|
@ -384,6 +388,10 @@ App::patch('/v1/projects/:projectId')
|
|||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
if ($sessionDuration < 0 || $sessionDuration > 525600) {
|
||||
throw new Exception('Session length must be between 0 and 525600 minutes');
|
||||
}
|
||||
|
||||
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
|
||||
->setAttribute('name', $name)
|
||||
->setAttribute('description', $description)
|
||||
|
@ -395,6 +403,7 @@ App::patch('/v1/projects/:projectId')
|
|||
->setAttribute('legalCity', $legalCity)
|
||||
->setAttribute('legalAddress', $legalAddress)
|
||||
->setAttribute('legalTaxId', $legalTaxId)
|
||||
->setAttribute('sessionDuration', $sessionDuration)
|
||||
->setAttribute('search', implode(' ', [$projectId, $name])));
|
||||
|
||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||
|
|
|
@ -677,9 +677,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
->inject('response')
|
||||
->inject('user')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('geodb')
|
||||
->inject('events')
|
||||
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Reader $geodb, Event $events) {
|
||||
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Reader $geodb, Event $events) {
|
||||
$protocol = $request->getProtocol();
|
||||
|
||||
$membership = $dbForProject->getDocument('memberships', $membershipId);
|
||||
|
@ -731,7 +732,8 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
|
|||
|
||||
$detector = new Detector($request->getUserAgent('UNKNOWN'));
|
||||
$record = $geodb->get($request->getIP());
|
||||
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
||||
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
||||
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
|
||||
$secret = Auth::tokenGenerator();
|
||||
$session = new Document(array_merge([
|
||||
'$id' => ID::unique(),
|
||||
|
|
|
@ -917,6 +917,7 @@ App::setResource('console', function () {
|
|||
'legalCity' => '',
|
||||
'legalAddress' => '',
|
||||
'legalTaxId' => '',
|
||||
'sessionDuration' => 525600, // 1 Year in minutes
|
||||
'auths' => [
|
||||
'limit' => (App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user
|
||||
],
|
||||
|
|
|
@ -99,7 +99,7 @@ $cli
|
|||
{
|
||||
(new Delete())
|
||||
->setType(DELETE_TYPE_SESSIONS)
|
||||
->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * Auth::TOKEN_EXPIRATION_LOGIN_LONG))
|
||||
->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * Auth::TOKEN_EXPIRATION_LOGIN_LONG)) //TODO: Update to use project session expiration instead of default.
|
||||
->trigger();
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,12 @@ class Project extends Model
|
|||
'default' => '',
|
||||
'example' => '131102020',
|
||||
])
|
||||
->addRule('sessionDuration', [
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Session duration in minutes.',
|
||||
'default' => '',
|
||||
'example' => '30',
|
||||
])
|
||||
->addRule('authLimit', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Max users allowed. 0 is unlimited.',
|
||||
|
|
|
@ -53,6 +53,7 @@ trait ProjectCustom
|
|||
'legalCity' => '',
|
||||
'legalAddress' => '',
|
||||
'legalTaxId' => '',
|
||||
'sessionDuration' => 525600
|
||||
]);
|
||||
|
||||
$this->assertEquals(201, $project['headers']['status-code']);
|
||||
|
|
Loading…
Reference in a new issue