Skip to content

Commit cea8d1a

Browse files
committed
feat: phone number rate limit whitelist
1 parent 76297ba commit cea8d1a

File tree

6 files changed

+22
-4
lines changed

6 files changed

+22
-4
lines changed

.env.example

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ HG_HOMESERVER_PUBKY=ufibwbmed6jeq9k4p583go95wofakh9fwpp4k734trq79pd9u1uy
2525
# HG_MAX_SMS_VERIFICATIONS_PER_WEEK=2
2626
# HG_MAX_SMS_VERIFICATIONS_PER_YEAR=4
2727

28+
# Phone numbers to exempt from SMS verification rate limits (comma-separated, E.164 format)
29+
# HG_SMS_VERIFICATIONS_LIMIT_WHITELIST=+1234567890,+0987654321
30+
2831
# Lightning Verification Settings
2932
# HG_LIGHTNING_INVOICE_PRICE_SAT=1000
3033
# HG_LIGHTNING_INVOICE_EXPIRY_SECONDS=600

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
/target
22
.env
3-
./claude
3+
.claude/*

src/infrastructure/config.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ pub struct EnvConfig {
2222
pub max_sms_verifications_per_week: u32,
2323
#[serde(default = "default_max_sms_verifications_per_year")]
2424
pub max_sms_verifications_per_year: u32,
25+
#[serde(default)]
26+
pub sms_verifications_limit_whitelist: Vec<String>,
2527
#[serde(default = "default_lightning_verification_price_sat")]
2628
pub lightning_invoice_price_sat: u64,
2729
#[serde(default = "default_lightning_verification_expiry_seconds")]
@@ -89,6 +91,7 @@ impl EnvConfig {
8991
homeserver_pubky: "test-homeserver-pubky".to_string(),
9092
max_sms_verifications_per_week: 2,
9193
max_sms_verifications_per_year: 4,
94+
sms_verifications_limit_whitelist: vec![],
9295
allow_cors: true,
9396
lightning_invoice_price_sat: 1000,
9497
lightning_invoice_expiry_seconds: 60 * 10,

src/sms_verification/app_state.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ impl AppState {
2323
homeserver_admin_api.clone(),
2424
config.max_sms_verifications_per_week,
2525
config.max_sms_verifications_per_year,
26+
config.sms_verifications_limit_whitelist.clone(),
2627
);
2728
Self {
2829
db,

src/sms_verification/service.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub struct SmsVerificationService {
1818
hasher_argon2id: HasherArgon2id,
1919
max_verifications_per_week: u32,
2020
max_verifications_per_year: u32,
21+
limit_whitelist: Vec<String>,
2122
}
2223

2324
impl SmsVerificationService {
@@ -26,22 +27,28 @@ impl SmsVerificationService {
2627
homeserver_admin_api: HomeserverAdminAPI,
2728
max_verifications_per_week: u32,
2829
max_verifications_per_year: u32,
30+
limit_whitelist: Vec<String>,
2931
) -> Self {
3032
Self {
3133
prelude_api,
3234
homeserver_admin_api,
3335
hasher_argon2id: HasherArgon2id::new(),
3436
max_verifications_per_week,
3537
max_verifications_per_year,
38+
limit_whitelist,
3639
}
3740
}
3841

3942
/// Check if a phone number has reached its limits for new verificaitons
4043
pub async fn check_verification_limit(
4144
&mut self,
4245
executor: &mut UnifiedExecutor<'_>,
46+
phone_number: &str,
4347
phone_number_hash: &str,
4448
) -> Result<(), SmsVerificationError> {
49+
if self.limit_whitelist.iter().any(|w| w == phone_number) {
50+
return Ok(());
51+
}
4552
let weekly_count = SmsVerificationRepository::count_verified_sessions_in_last_days(
4653
executor,
4754
phone_number_hash,
@@ -90,8 +97,12 @@ impl SmsVerificationService {
9097

9198
let mut executor: UnifiedExecutor<'_> = db.pool().into();
9299

93-
self.check_verification_limit(&mut executor, &phone_number_hash)
94-
.await?;
100+
self.check_verification_limit(
101+
&mut executor,
102+
request.phone_number.as_str(),
103+
&phone_number_hash,
104+
)
105+
.await?;
95106

96107
let prelude_response = self
97108
.prelude_api

src/sms_verification/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ async fn create_service_with_mocked_apis(servers: &WiremockServers) -> SmsVerifi
4444
&config.homeserver_admin_password,
4545
&config.homeserver_pubky,
4646
);
47-
SmsVerificationService::new(prelude_api, homeserver_admin_api, 2, 4)
47+
SmsVerificationService::new(prelude_api, homeserver_admin_api, 2, 4, vec![])
4848
}
4949

5050
#[sqlx::test]

0 commit comments

Comments
 (0)