Browse Source

Use the email token settings for Send verification codes

Reuse `EMAIL_EXPIRATION_TIME` and `EMAIL_ATTEMPTS_LIMIT`, like the email
2FA codes, instead of hardcoded values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pull/7861/head
ICantThinkOfAName-tech 5 days ago
parent
commit
8c551de2ab
  1. 2
      src/auth/send.rs
  2. 12
      src/db/models/send.rs
  3. 2
      src/static/templates/email/send_access_otp.hbs
  4. 2
      src/static/templates/email/send_access_otp.html.hbs

2
src/auth/send.rs

@ -171,7 +171,7 @@ impl SendTokens {
let Some(stored) = stored else { let Some(stored) = stored else {
return Self::expected_error("Email and OTP required", "email_and_otp_required"); return Self::expected_error("Email and OTP required", "email_and_otp_required");
}; };
if stored.is_expired() || stored.attempts >= SendAccessOtp::MAX_ATTEMPTS { if stored.is_expired() || stored.attempts_exhausted() {
stored.delete(conn).await?; stored.delete(conn).await?;
return Self::expected_error("Email and OTP required", "email_and_otp_required"); return Self::expected_error("Email and OTP required", "email_and_otp_required");
} }

12
src/db/models/send.rs

@ -400,10 +400,6 @@ pub struct SendAccessOtp {
} }
impl SendAccessOtp { impl SendAccessOtp {
/// How long a code stays valid.
const VALIDITY_MINUTES: i64 = 5;
/// Wrong guesses allowed before a code is discarded.
pub const MAX_ATTEMPTS: i32 = 5;
/// Minimum time before a new code can be requested, so the endpoint can't be used to spam a /// Minimum time before a new code can be requested, so the endpoint can't be used to spam a
/// recipient or keep invalidating the code they are about to type. /// recipient or keep invalidating the code they are about to type.
const RESEND_COOLDOWN_SECONDS: i64 = 60; const RESEND_COOLDOWN_SECONDS: i64 = 60;
@ -416,10 +412,16 @@ impl SendAccessOtp {
code, code,
attempts: 0, attempts: 0,
creation_date: now, creation_date: now,
expiration_date: now + TimeDelta::minutes(Self::VALIDITY_MINUTES), // Same settings as the email 2FA codes
expiration_date: now + TimeDelta::seconds(CONFIG.email_expiration_time().cast_signed()),
} }
} }
/// Wrong guesses allowed before a code is discarded.
pub fn attempts_exhausted(&self) -> bool {
u64::try_from(self.attempts).unwrap_or(u64::MAX) >= CONFIG.email_attempts_limit()
}
pub fn is_expired(&self) -> bool { pub fn is_expired(&self) -> bool {
Utc::now().naive_utc() >= self.expiration_date Utc::now().naive_utc() >= self.expiration_date
} }

2
src/static/templates/email/send_access_otp.hbs

@ -2,5 +2,5 @@ Your Vaultwarden Send Verification Code
<!----------------> <!---------------->
Your email verification code is: {{token}} Your email verification code is: {{token}}
Use this code to view the Send that was shared with you. It expires in 5 minutes. Use this code to view the Send that was shared with you.
{{> email/email_footer_text }} {{> email/email_footer_text }}

2
src/static/templates/email/send_access_otp.html.hbs

@ -9,7 +9,7 @@ Your Vaultwarden Send Verification Code
</tr> </tr>
<tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;"> <tr style="margin: 0; font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: none;">
<td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top"> <td class="content-block" style="font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; box-sizing: border-box; font-size: 16px; color: #333; line-height: 25px; margin: 0; -webkit-font-smoothing: antialiased; padding: 0 0 10px; -webkit-text-size-adjust: none;" valign="top">
Use this code to view the Send that was shared with you. It expires in 5 minutes. Use this code to view the Send that was shared with you.
</td> </td>
</tr> </tr>
</table> </table>

Loading…
Cancel
Save