@@ -94,13 +94,17 @@ class LoginPresenter extends BasePresenter
9494 /**
9595 * Sends response with an access token, if the user exists.
9696 * @param User $user
97+ * @param int|null $expiration in seconds, null for default expiration
9798 * @throws AuthenticationException
9899 * @throws ForbiddenRequestException
99100 * @throws InvalidAccessTokenException
100101 */
101- private function sendAccessTokenResponse (User $ user )
102+ private function sendAccessTokenResponse (User $ user, ? int $ expiration = null )
102103 {
103- $ token = $ this ->accessManager ->issueToken ($ user , null , [TokenScope::MASTER , TokenScope::REFRESH ]);
104+ if ($ expiration !== null && ($ expiration > $ this ->accessManager ->getExpiration () || $ expiration <= 0 )) {
105+ $ expiration = null ; // invalid values are ignored
106+ }
107+ $ token = $ this ->accessManager ->issueToken ($ user , null , [TokenScope::MASTER , TokenScope::REFRESH ], $ expiration );
104108 $ this ->getUser ()->login (new Identity ($ user , $ this ->accessManager ->decodeToken ($ token )));
105109
106110 $ this ->sendSuccessResponse (
@@ -121,11 +125,13 @@ private function sendAccessTokenResponse(User $user)
121125 */
122126 #[Post("username " , new VEmail (), "User's E-mail " )]
123127 #[Post("password " , new VString (1 ), "Password " )]
128+ #[Post("expiration " , new VInt (), "Token expiration in seconds (not greater than the default) " , required: false )]
124129 public function actionDefault ()
125130 {
126131 $ req = $ this ->getRequest ();
127132 $ username = $ req ->getPost ("username " );
128133 $ password = $ req ->getPost ("password " );
134+ $ expiration = $ req ->getPost ("expiration " );
129135
130136 $ user = $ this ->credentialsAuthenticator ->authenticate ($ username , $ password );
131137 $ this ->verifyUserIpLock ($ user );
@@ -135,7 +141,7 @@ public function actionDefault()
135141 $ event = SecurityEvent::createLoginEvent ($ this ->getHttpRequest ()->getRemoteAddress (), $ user );
136142 $ this ->securityEvents ->persist ($ event );
137143
138- $ this ->sendAccessTokenResponse ($ user );
144+ $ this ->sendAccessTokenResponse ($ user, $ expiration );
139145 }
140146
141147 /**
@@ -148,6 +154,7 @@ public function actionDefault()
148154 * @throws BadRequestException
149155 */
150156 #[Post("token " , new VString (1 ), "JWT external authentication token " )]
157+ #[Post("expiration " , new VInt (), "Token expiration in seconds (not greater than the default) " , required: false )]
151158 #[Path("authenticatorName " , new VString (), "Identifier of the external authenticator " , required: true )]
152159 public function actionExternal ($ authenticatorName )
153160 {
@@ -160,7 +167,7 @@ public function actionExternal($authenticatorName)
160167 $ event = SecurityEvent::createExternalLoginEvent ($ this ->getHttpRequest ()->getRemoteAddress (), $ user );
161168 $ this ->securityEvents ->persist ($ event );
162169
163- $ this ->sendAccessTokenResponse ($ user );
170+ $ this ->sendAccessTokenResponse ($ user, $ req -> getPost ( " expiration " ) );
164171 }
165172
166173 public function checkTakeOver ($ userId )
0 commit comments