From b70316e6d30e4146d637d6f4e269db438c52c346 Mon Sep 17 00:00:00 2001 From: Stefan Melmuk Date: Sat, 8 Oct 2022 18:31:34 +0200 Subject: [PATCH] make invitation expiration time configurable configure the number of hours after which organization invites, emergency access invites, email verification emails and account deletion requests expire (defaults to 5 days or 120 hours and must be atleast 1) --- .env.template | 4 ++++ src/auth.rs | 12 ++++++++---- src/config.rs | 7 +++++++ 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/.env.template b/.env.template index 66a04343..60b5b73b 100644 --- a/.env.template +++ b/.env.template @@ -245,6 +245,10 @@ ## Name shown in the invitation emails that don't come from a specific organization # INVITATION_ORG_NAME=Vaultwarden +## The number of hours after which an organization invite token, emergency access invite token, +## email verification token and deletion request token will expire (must be at least 1) +# INVITATION_EXPIRATION_HOURS=120 + ## Per-organization attachment storage limit (KB) ## Max kilobytes of attachment storage allowed per organization. ## When this limit is reached, organization members will not be allowed to upload further attachments for ciphers owned by that organization. diff --git a/src/auth.rs b/src/auth.rs index f99fbd39..92445f52 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -148,9 +148,10 @@ pub fn generate_invite_claims( invited_by_email: Option, ) -> InviteJwtClaims { let time_now = Utc::now().naive_utc(); + let expire_hours = i64::from(CONFIG.invitation_expiration_hours()); InviteJwtClaims { nbf: time_now.timestamp(), - exp: (time_now + Duration::days(5)).timestamp(), + exp: (time_now + Duration::hours(expire_hours)).timestamp(), iss: JWT_INVITE_ISSUER.to_string(), sub: uuid, email, @@ -185,9 +186,10 @@ pub fn generate_emergency_access_invite_claims( grantor_email: Option, ) -> EmergencyAccessInviteJwtClaims { let time_now = Utc::now().naive_utc(); + let expire_hours = i64::from(CONFIG.invitation_expiration_hours()); EmergencyAccessInviteJwtClaims { nbf: time_now.timestamp(), - exp: (time_now + Duration::days(5)).timestamp(), + exp: (time_now + Duration::hours(expire_hours)).timestamp(), iss: JWT_EMERGENCY_ACCESS_INVITE_ISSUER.to_string(), sub: uuid, email, @@ -211,9 +213,10 @@ pub struct BasicJwtClaims { pub fn generate_delete_claims(uuid: String) -> BasicJwtClaims { let time_now = Utc::now().naive_utc(); + let expire_hours = i64::from(CONFIG.invitation_expiration_hours()); BasicJwtClaims { nbf: time_now.timestamp(), - exp: (time_now + Duration::days(5)).timestamp(), + exp: (time_now + Duration::hours(expire_hours)).timestamp(), iss: JWT_DELETE_ISSUER.to_string(), sub: uuid, } @@ -221,9 +224,10 @@ pub fn generate_delete_claims(uuid: String) -> BasicJwtClaims { pub fn generate_verify_email_claims(uuid: String) -> BasicJwtClaims { let time_now = Utc::now().naive_utc(); + let expire_hours = i64::from(CONFIG.invitation_expiration_hours()); BasicJwtClaims { nbf: time_now.timestamp(), - exp: (time_now + Duration::days(5)).timestamp(), + exp: (time_now + Duration::hours(expire_hours)).timestamp(), iss: JWT_VERIFYEMAIL_ISSUER.to_string(), sub: uuid, } diff --git a/src/config.rs b/src/config.rs index b8f3246b..1d9e53f5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -430,6 +430,9 @@ make_config! { org_creation_users: String, true, def, "".to_string(); /// Allow invitations |> Controls whether users can be invited by organization admins, even when signups are otherwise disabled invitations_allowed: bool, true, def, true; + /// Invitation token expiration time (in hours) |> The number of hours after which an organization invite token, emergency access invite token, + /// email verification token and deletion request token will expire (must be at least 1) + invitation_expiration_hours: u32, false, def, 120; /// Allow emergency access |> Controls whether users can enable emergency access to their accounts. This setting applies globally to all users. emergency_access_allowed: bool, true, def, true; /// Password iterations |> Number of server-side passwords hashing iterations. @@ -726,6 +729,10 @@ fn validate_config(cfg: &ConfigItems) -> Result<(), Error> { _ => err!("Only HTTP 301/302 and 307/308 redirects are supported"), } + if cfg.invitation_expiration_hours < 1 { + err!("`INVITATION_EXPIRATION_HOURS` has a minimum size of 1") + } + Ok(()) }