Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion cmd/passless/src/authenticator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,12 @@ impl<S: CredentialStorage> AuthenticatorCallbacks for PasslessCallbacks<S> {
return Ok(UpResult::Accepted);
}

match show_verification_notification(info, Some(rp), user) {
match show_verification_notification(
info,
Some(rp),
user,
self.security_config.notification_timeout,
) {
Ok(crate::notification::NotificationResult::Accepted) => Ok(UpResult::Accepted),
Ok(crate::notification::NotificationResult::Denied) => Ok(UpResult::Denied),
Err(e) => {
Expand Down Expand Up @@ -343,6 +348,7 @@ mod tests {
constant_signature_counter: false,
user_verification_registration: true,
user_verification_authentication: true,
notification_timeout: 30,
};

let service = AuthenticatorService::new(storage, security_config);
Expand Down
14 changes: 2 additions & 12 deletions cmd/passless/src/notification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,21 +48,11 @@ fn requires_default_action() -> bool {
}

/// Show a user verification notification and wait for response
///
/// # Arguments
///
/// * `operation` - Description of the operation (e.g., "Registration", "Authentication")
/// * `relying_party` - Optional relying party identifier
/// * `user` - Optional user identifier
///
/// # Returns
///
/// Result indicating whether the user accepted or denied the operation,
/// or an error if the notification failed to show.
pub fn show_verification_notification(
operation: &str,
relying_party: Option<&str>,
user: Option<&str>,
timeout_seconds: u32,
) -> Result<NotificationResult, String> {
// Build notification message
let mut message = format!("Operation: {}", operation);
Expand All @@ -88,7 +78,7 @@ pub fn show_verification_notification(
.summary("🔒 User Verification Required")
.body(&message)
.icon("security-high")
.timeout(Timeout::Never); // Wait for user action
.timeout(Timeout::Milliseconds(timeout_seconds * 1000));

if default_means_user_present {
// For servers that don't support action buttons properly,
Expand Down
10 changes: 10 additions & 0 deletions passless-core/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,16 @@ pub struct SecurityConfig {
#[serde(default)]
#[default(true)]
pub user_verification_authentication: bool,

/// Notification timeout in seconds (0 = no timeout)
#[arg(
long = "notification-timeout",
env = "PASSLESS_NOTIFICATION_TIMEOUT",
value_name = "SECONDS"
)]
#[serde(default)]
#[default(30)]
pub notification_timeout: u32,
}

impl SecurityConfig {
Expand Down
Loading