-
Notifications
You must be signed in to change notification settings - Fork 89
Enhance rate limit handling, add email config param #483
Conversation
app/routes/report-routes.ts
Outdated
@@ -95,9 +96,12 @@ const extractTestResult = (req: Request): TestResult | undefined => { | |||
}; | |||
|
|||
const createReportRateLimit = rateLimit({ | |||
max: 20, // allowed requests per window | |||
max: config.RATE_LIMIT, // allowed requests per window | |||
windowMs: 24 * 60 * 60 * 1000, // 24 hour window, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we should add windowMs
to the config as well? Makes sense as RATE_LIMIT
option by itself doesn't really indicate how strict it is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@michaelmcmillan perfect idea! I've added it in the latest commit, now we have:
RATE_LIMIT_COUNT
and RATE_LIMIT_WINDOW
new params - feel free to suggest better names :-)
I might later add config params README as the number of params starts to grow 😅
b7a8a14
to
bf69942
Compare
app/routes/report-routes.ts
Outdated
windowMs: config.RATE_LIMIT_WINDOW, // window length in miliseconds | ||
keyGenerator: req => determineRemoteAddress(req), | ||
onLimitReached(req, res) { | ||
return res.redirect(`${res.locals.urls.limit}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice, you don't really need the template literals here, return res.redirect(res.locals.urls.limit);
will do
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice catch, thank you, fixing
app/routes/various-routes.ts
Outdated
@@ -22,6 +22,10 @@ router.get(`${urls.contributors}`, (req, res) => { | |||
return res.render('pages/contributors'); | |||
}); | |||
|
|||
router.get(`${urls.limit}`, (req, res) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
router.get(`${urls.limit}`, (req, res) => { | |
router.get(urls.limit, (req, res) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@fossecode i see also all other router.get
above are using the same notation, why to change it specifically for this route?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably just a copy/paste error. Would have made sense to use template literals if we were to have a variable in the route, e.g.
router.get(`/${countryCode}/privacy-statement`, (req, res) => {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it has been copied from
router.get(`${urls.profile}/:passcode`, async (req, res) => {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, okay, thanks for explanation :-) I can change & fix all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix commited
app/config.ts
Outdated
@@ -26,6 +26,7 @@ const fallbackConfig: Config = { | |||
MAP_CENTER: process.env.MAP_CENTER || '10.7522, 63.9139', | |||
MAP_ZOOM: parseInt(process.env.MAP_ZOOM || '4', 10), | |||
MAP_MAX_ZOOM: parseInt(process.env.MAP_MAX_ZOOM || '13', 10), | |||
EMAIL: process.env.EMAIL, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know about the rest of you, but I feel we have been a bit inconsistent on what we put in the config vs what we put in the translations. We discussed this at one point, and I think we decided to put URLs, emails etc in the translation file. I also believe that is easier to maintain than the config (although both is hard 😓). In my opinion, we could at least move EMAIL
, TWITTER
(and possibly ZIP_PLACEHOLDER
) to the translations. If we e.g. use __(`[email protected]`)
when rendering the email, it would automatically fallback to [email protected] if it is not overriden. Thoughts on this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would support the idea, but- AFAIK minority of the domains have email system configured for the domain. That's why I made it optional and only enable when explicitely enabled in the config. In this case I don't think it's good to move it to the translation files as most of those will use [email protected]
what can be a bit misleading.
I tried to create the contact partial dynamic and only display email when it's set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I get the point. But do you think that it is better to don't display a contact email at all if it is not set? We have gotten a few questions and comments from different countries on our email, so it could be nice to have a fallback?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I didn't realize that, it makes sense to have the fallback email 👍
So, should I move it to the translations then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah or you could also do EMAIL: process.env.EMAIL || '[email protected]'
. I think I would prefer translations, but you can use the config if it is easier :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay. According to these info, I will use the default value here and:
- Keep
EMAIL
in the config to have it next to theTWITTER
- Move both
EMAIL
andTWITTER
in another PR to the translations (I guess moving the TW would require much more effort due to the testing of all other parts where TW is actually used)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
change commited
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if it's worth to add the option to config.example.json
yet, not to confuse people if it's gonna move out soon.
Since this a page that is not part of the ordinary flow, I guess it is ok to merge it without getting translations for all languages first. In the rare case where people hit the rate limit, it should be ok that it is in english. |
Could you fix the conflicts, and then we'll merge! |
Is this one ready to be merged? |
Going to rebase and will be ready soon :-) |
7c1c3b8
to
c883f7f
Compare
c883f7f
to
2f074a6
Compare
app/server.ts
Outdated
@@ -82,6 +83,8 @@ app.use((req, res, next) => { | |||
res.locals.localeToFlag = localeToFlag; | |||
res.locals.currentLocale = req.getLocale(); | |||
res.locals.formatNumber = createNumberFormatter(config.THOUSAND_SEPARATOR); | |||
res.locals.rateLimitCount = config.RATE_LIMIT_COUNT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This and the next line can be removed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks, removed!
Changes
RATE_LIMIT_COUNT
RATE_LIMIT_WINDOW
EMAIL
limit
route & page viewcontact
partial404
&500
views to use the contact partialDetails
Rate limit enhancements
The original
express-rate-limit
code returns default generic message on exceeding the configured rate limit:Too many requests, please try again later.
(English only). What's worse, administrators don't have any clue this is happening.Users often share their IPv4 IP address as operators are using IPv6 and provide a shared IPv4 IP for hundreds of users. I've already experienced this on the SK deployment when users were affected unable to submit their reports until one user notified me having no clue what's going on.
This PR tries to address this situation and brings new
/limit
route, that can provide more localized info for users and also give us (admins) information, the rate limit has been reached (seeing/limit
route in the analytics).Email as a config param
Twitter handler was the only configurable contact available on the site. There are countries where twitter is not very popular or used, or some people don't have twitter account unable to contact us.