3636namespace OC \Core \Controller ;
3737
3838use Exception ;
39- use OC \Authentication \TwoFactorAuth \Manager ;
40- use OC \Core \Events \BeforePasswordResetEvent ;
41- use OC \Core \Events \PasswordResetEvent ;
42- use OC \Core \Exception \ResetPasswordException ;
4339use OCP \AppFramework \Controller ;
4440use OCP \AppFramework \Http \JSONResponse ;
4541use OCP \AppFramework \Http \TemplateResponse ;
5652use OCP \IUser ;
5753use OCP \IUserManager ;
5854use OCP \Mail \IMailer ;
59- use OCP \Security \VerificationToken \InvalidTokenException ;
6055use OCP \Security \VerificationToken \IVerificationToken ;
56+ use OCP \Security \VerificationToken \InvalidTokenException ;
57+ use OC \Authentication \TwoFactorAuth \Manager ;
58+ use OC \Core \Events \BeforePasswordResetEvent ;
59+ use OC \Core \Events \PasswordResetEvent ;
60+ use OC \Core \Exception \ResetPasswordException ;
61+ use OC \Security \RateLimiting \Exception \RateLimitExceededException ;
62+ use OC \Security \RateLimiting \Limiter ;
6163use Psr \Log \LoggerInterface ;
6264use function array_filter ;
6365use function count ;
@@ -84,6 +86,7 @@ class LostController extends Controller {
8486 private IInitialState $ initialState ;
8587 private IVerificationToken $ verificationToken ;
8688 private IEventDispatcher $ eventDispatcher ;
89+ private Limiter $ limiter ;
8790
8891 public function __construct (
8992 string $ appName ,
@@ -100,7 +103,8 @@ public function __construct(
100103 Manager $ twoFactorManager ,
101104 IInitialState $ initialState ,
102105 IVerificationToken $ verificationToken ,
103- IEventDispatcher $ eventDispatcher
106+ IEventDispatcher $ eventDispatcher ,
107+ Limiter $ limiter
104108 ) {
105109 parent ::__construct ($ appName , $ request );
106110 $ this ->urlGenerator = $ urlGenerator ;
@@ -116,6 +120,7 @@ public function __construct(
116120 $ this ->initialState = $ initialState ;
117121 $ this ->verificationToken = $ verificationToken ;
118122 $ this ->eventDispatcher = $ eventDispatcher ;
123+ $ this ->limiter = $ limiter ;
119124 }
120125
121126 /**
@@ -267,6 +272,12 @@ protected function sendEmail(string $input): void {
267272 throw new ResetPasswordException ('Could not send reset e-mail since there is no email for username ' . $ input );
268273 }
269274
275+ try {
276+ $ this ->limiter ->registerUserRequest ('lostpasswordemail ' , 5 , 1800 , $ user );
277+ } catch (RateLimitExceededException $ e ) {
278+ throw new ResetPasswordException ('Could not send reset e-mail, 5 of them were already sent in the last 30 minutes ' , 0 , $ e );
279+ }
280+
270281 // Generate the token. It is stored encrypted in the database with the
271282 // secret being the users' email address appended with the system secret.
272283 // This makes the token automatically invalidate once the user changes
0 commit comments