feat(core): Rate limit forgot password endpoint (#7604)
Github issue / Community forum post (link here to close automatically): --------- Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <netroy@users.noreply.github.com>
This commit is contained in:
@@ -129,6 +129,7 @@
|
||||
"express-handlebars": "^7.0.2",
|
||||
"express-openapi-validator": "^4.13.6",
|
||||
"express-prom-bundle": "^6.6.0",
|
||||
"express-rate-limit": "^7.1.3",
|
||||
"fast-glob": "^3.2.5",
|
||||
"flatted": "^3.2.4",
|
||||
"formidable": "^3.5.0",
|
||||
|
||||
@@ -55,6 +55,9 @@ export abstract class AbstractServer {
|
||||
this.app = express();
|
||||
this.app.disable('x-powered-by');
|
||||
|
||||
const proxyHops = config.getEnv('proxy_hops');
|
||||
if (proxyHops > 0) this.app.set('trust proxy', proxyHops);
|
||||
|
||||
this.protocol = config.getEnv('protocol');
|
||||
this.sslKey = config.getEnv('ssl_key');
|
||||
this.sslCert = config.getEnv('ssl_cert');
|
||||
|
||||
@@ -1344,4 +1344,11 @@ export const schema = {
|
||||
env: 'N8N_LEADER_SELECTION_CHECK_INTERVAL',
|
||||
},
|
||||
},
|
||||
|
||||
proxy_hops: {
|
||||
format: Number,
|
||||
default: 0,
|
||||
env: 'N8N_PROXY_HOPS',
|
||||
doc: 'Number of reverse-proxies n8n is running behind',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,12 +24,18 @@ import { isSamlCurrentAuthenticationMethod } from '@/sso/ssoHelpers';
|
||||
import { UserService } from '@/services/user.service';
|
||||
import { License } from '@/License';
|
||||
import { Container } from 'typedi';
|
||||
import { RESPONSE_ERROR_MESSAGES } from '@/constants';
|
||||
import { RESPONSE_ERROR_MESSAGES, inTest } from '@/constants';
|
||||
import { TokenExpiredError } from 'jsonwebtoken';
|
||||
import type { JwtPayload } from '@/services/jwt.service';
|
||||
import { JwtService } from '@/services/jwt.service';
|
||||
import { MfaService } from '@/Mfa/mfa.service';
|
||||
import { Logger } from '@/Logger';
|
||||
import { rateLimit } from 'express-rate-limit';
|
||||
|
||||
const throttle = rateLimit({
|
||||
windowMs: 5 * 60 * 1000, // 5 minutes
|
||||
limit: 5, // Limit each IP to 5 requests per `window` (here, per 5 minutes).
|
||||
});
|
||||
|
||||
@RestController()
|
||||
export class PasswordResetController {
|
||||
@@ -46,7 +52,9 @@ export class PasswordResetController {
|
||||
/**
|
||||
* Send a password reset email.
|
||||
*/
|
||||
@Post('/forgot-password')
|
||||
@Post('/forgot-password', {
|
||||
middlewares: !inTest ? [throttle] : [],
|
||||
})
|
||||
async forgotPassword(req: PasswordResetRequest.Email) {
|
||||
if (!this.mailer.isEmailSetUp) {
|
||||
this.logger.debug(
|
||||
|
||||
@@ -660,6 +660,7 @@
|
||||
"forgotPassword.sendingEmailError": "Problem sending email",
|
||||
"forgotPassword.ldapUserPasswordResetUnavailable": "Please contact your LDAP administrator to reset your password",
|
||||
"forgotPassword.smtpErrorContactAdministrator": "Please contact your administrator (problem with your SMTP setup)",
|
||||
"forgotPassword.tooManyRequests": "You’ve reached the password reset limit. Please try again in a few minutes.",
|
||||
"forms.resourceFiltersDropdown.filters": "Filters",
|
||||
"forms.resourceFiltersDropdown.ownedBy": "Owned by",
|
||||
"forms.resourceFiltersDropdown.sharedWith": "Shared with",
|
||||
|
||||
@@ -88,14 +88,20 @@ export default defineComponent({
|
||||
});
|
||||
} catch (error) {
|
||||
let message = this.$locale.baseText('forgotPassword.smtpErrorContactAdministrator');
|
||||
if (error.httpStatusCode === 422) {
|
||||
message = this.$locale.baseText(error.message);
|
||||
if (error.isAxiosError) {
|
||||
const { status } = error.response;
|
||||
if (status === 429) {
|
||||
message = this.$locale.baseText('forgotPassword.tooManyRequests');
|
||||
} else if (error.httpStatusCode === 422) {
|
||||
message = this.$locale.baseText(error.message);
|
||||
}
|
||||
|
||||
this.showMessage({
|
||||
type: 'error',
|
||||
title: this.$locale.baseText('forgotPassword.sendingEmailError'),
|
||||
message,
|
||||
});
|
||||
}
|
||||
this.showMessage({
|
||||
type: 'error',
|
||||
title: this.$locale.baseText('forgotPassword.sendingEmailError'),
|
||||
message,
|
||||
});
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user