11"use strict" ;
2+ const crypto = require ( "crypto" ) ;
23
34const SENSITIVE_FAILURE_DELAY_MS = 2 * 1000 ;
45const SENSITIVE_FAILURE_RETENTION_MS = 10 * 60 * 1000 ;
@@ -28,9 +29,23 @@ module.exports = function registerAccountRoutes(ctx) {
2829
2930 function timeNow ( ) { return typeof now === "function" ? now ( ) : Date . now ( ) ; }
3031
31- function sensitiveKey ( username ) {
32- const value = typeof username === "string" ? username . trim ( ) : "" ;
33- return value ? value : null ;
32+ function sensitivePart ( value ) {
33+ if ( typeof value === "string" ) return value . trim ( ) ;
34+ if ( typeof value === "number" || typeof value === "boolean" ) return String ( value ) ;
35+ return "" ;
36+ }
37+
38+ function sensitiveKey ( kind , username , from , to , enabled ) {
39+ const userValue = sensitivePart ( username ) ;
40+ if ( ! userValue ) return null ;
41+
42+ const hash = crypto . createHash ( "sha256" ) ;
43+ for ( const part of [ kind , userValue , sensitivePart ( from ) , sensitivePart ( to ) , sensitivePart ( enabled ) ] ) {
44+ hash . update ( String ( Buffer . byteLength ( part ) ) ) ;
45+ hash . update ( ":" ) ;
46+ hash . update ( part ) ;
47+ }
48+ return hash . digest ( "hex" ) ;
3449 }
3550
3651 function pruneSensitiveFailures ( time ) {
@@ -54,6 +69,7 @@ module.exports = function registerAccountRoutes(ctx) {
5469 function acquireSensitiveAttempt ( key ) {
5570 if ( ! key ) return null ;
5671 const time = timeNow ( ) ;
72+ pruneSensitiveFailures ( time ) ;
5773 const entry = sensitiveFailures . get ( key ) ;
5874 if ( entry && entry . nextAllowedAt > time ) return throttlePayload ( entry . nextAllowedAt - time ) ;
5975 sensitiveFailures . set ( key , {
@@ -124,7 +140,7 @@ module.exports = function registerAccountRoutes(ctx) {
124140 if ( body ) return sendJson ( res , 401 , { success : false , msg : "No \"username\" parameter was found" } ) ;
125141 return ;
126142 }
127- const throttleKey = sensitiveKey ( body . username ) ;
143+ const throttleKey = sensitiveKey ( "subscribeEmail" , body . username , body . from , body . to , body . enabled ) ;
128144 const throttle = acquireSensitiveAttempt ( throttleKey ) ;
129145 if ( throttle ) return sendJson ( res , 429 , throttle ) ;
130146
0 commit comments