pub struct TwoFactorPlugin { /* private fields */ }Expand description
Two-factor authentication plugin providing TOTP, OTP, and backup code flows.
Implementations§
Source§impl TwoFactorPlugin
impl TwoFactorPlugin
pub fn new() -> Self
pub fn with_config(config: TwoFactorConfig) -> Self
pub fn allow_passwordless(self, val: bool) -> Self
pub fn totp_allow_passwordless(self, val: bool) -> Self
pub fn backup_allow_passwordless(self, val: bool) -> Self
pub fn backup_code_amount(self, val: f64) -> Self
pub fn backup_code_length(self, val: f64) -> Self
pub fn account_lockout(self, val: AccountLockoutConfig) -> Self
pub fn issuer(self, val: String) -> Self
pub fn skip_verification_on_enable(self, val: bool) -> Self
pub fn trust_device_max_age(self, val: f64) -> Self
pub fn totp_period(self, val: f64) -> Self
pub fn totp_digits(self, val: f64) -> Self
pub fn totp_issuer(self, val: String) -> Self
pub fn totp_disabled(self, val: bool) -> Self
pub fn otp_digits(self, val: f64) -> Self
pub fn otp_period_minutes(self, val: f64) -> Self
pub fn otp_allowed_attempts(self, val: f64) -> Self
Source§impl TwoFactorPlugin
impl TwoFactorPlugin
Sourcepub fn generate_backup_codes_endpoint(
input: GenerateBackupCodesInput,
) -> ServerEndpoint<BackupCodesOutput>
pub fn generate_backup_codes_endpoint( input: GenerateBackupCodesInput, ) -> ServerEndpoint<BackupCodesOutput>
Replace the authenticated owner’s recovery-code set.
Sourcepub fn verify_backup_code_endpoint(
input: VerifyBackupCodeInput,
) -> ServerEndpoint<BackupCodeVerified>
pub fn verify_backup_code_endpoint( input: VerifyBackupCodeInput, ) -> ServerEndpoint<BackupCodeVerified>
Consume a recovery code for the current owner or pending sign-in challenge.
Sourcepub fn verify_two_factor_otp_endpoint(
input: VerifyOtpInput,
) -> ServerEndpoint<TotpVerified>
pub fn verify_two_factor_otp_endpoint( input: VerifyOtpInput, ) -> ServerEndpoint<TotpVerified>
Verify a delivered code for the current session or pending sign-in challenge.
Sourcepub fn send_two_factor_otp_endpoint() -> ServerEndpoint<TwoFactorOtpSent>
pub fn send_two_factor_otp_endpoint() -> ServerEndpoint<TwoFactorOtpSent>
Persist and deliver a code for the session owner or pending sign-in challenge.
Sourcepub fn verify_totp_endpoint(
input: VerifyTotpInput,
) -> ServerEndpoint<TotpVerified>
pub fn verify_totp_endpoint( input: VerifyTotpInput, ) -> ServerEndpoint<TotpVerified>
Verify an authenticator code for enrollment or a pending sign-in challenge.
Sourcepub fn get_totp_uri_endpoint(
input: GetTotpUriInput,
) -> ServerEndpoint<TotpUriOutput>
pub fn get_totp_uri_endpoint( input: GetTotpUriInput, ) -> ServerEndpoint<TotpUriOutput>
Recover the signed-in owner’s authenticator URI using configured password policy.
Sourcepub fn disable_two_factor_endpoint(
input: DisableTwoFactorInput,
) -> ServerEndpoint<TwoFactorDisabled>
pub fn disable_two_factor_endpoint( input: DisableTwoFactorInput, ) -> ServerEndpoint<TwoFactorDisabled>
Disable the persistent session owner’s factor and rotate that session.
Sourcepub fn enable_two_factor_endpoint(
input: EnableTwoFactorInput,
) -> ServerEndpoint<TwoFactorEnabled>
pub fn enable_two_factor_endpoint( input: EnableTwoFactorInput, ) -> ServerEndpoint<TwoFactorEnabled>
Enroll the signed-in owner using the configured factor and backup-code policies.
Sourcepub fn view_backup_codes_endpoint(
user_id: impl Into<String>,
) -> ServerEndpoint<BackupCodesOutput>
pub fn view_backup_codes_endpoint( user_id: impl Into<String>, ) -> ServerEndpoint<BackupCodesOutput>
Read trusted server-only backup codes through installed endpoint hooks.
Sourcepub fn generate_totp_endpoint(
secret: impl Into<String>,
) -> ServerEndpoint<TotpOutput>
pub fn generate_totp_endpoint( secret: impl Into<String>, ) -> ServerEndpoint<TotpOutput>
Generate a TOTP through installed endpoint hooks and current configured policy.
Source§impl TwoFactorPlugin
impl TwoFactorPlugin
Sourcepub fn custom_send_otp(self, sender: Arc<dyn SendTwoFactorOtp>) -> Self
pub fn custom_send_otp(self, sender: Arc<dyn SendTwoFactorOtp>) -> Self
Install a custom OTP sender.
Sourcepub fn generate_totp(&self, secret: &str) -> AuthResult<String>
pub fn generate_totp(&self, secret: &str) -> AuthResult<String>
Generate a current TOTP from an application-owned UTF-8 secret.
This corresponds to auth.api.generateTOTP; it has no public HTTP route.
§Errors
Returns an error if the secret cannot be decoded or the TOTP configuration is invalid.
Sourcepub async fn view_backup_codes<S: AuthSchema>(
&self,
user_id: &str,
ctx: &AuthContext<S>,
) -> AuthResult<Value>
pub async fn view_backup_codes<S: AuthSchema>( &self, user_id: &str, ctx: &AuthContext<S>, ) -> AuthResult<Value>
Read the currently stored backup JSON for a user.
Installed storage may contain any truthy JSON value. Dates are revived with the pinned grammar and numbers use JavaScript JSON serialization; generated code arrays retain their ordinary array-of-strings shape.
This is the Rust server-side equivalent of the TypeScript
auth.api.viewBackupCodes capability. It is intentionally not exposed
as a public HTTP route.
§Errors
Returns an error if backup codes are unavailable, cannot be decrypted, or cannot be loaded.
Trait Implementations§
Source§impl<S: AuthSchema> AuthPlugin<S> for TwoFactorPlugin
impl<S: AuthSchema> AuthPlugin<S> for TwoFactorPlugin
Source§fn on_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
req: &'life1 AuthRequest,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = AuthResult<Option<AuthResponse>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
req: &'life1 AuthRequest,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = AuthResult<Option<AuthResponse>>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn static_openapi_metadata(&self) -> PluginOpenApiMetadata
fn static_openapi_metadata(&self) -> PluginOpenApiMetadata
Source§fn openapi_metadata(&self, ctx: &AuthInitContext<S>) -> PluginOpenApiMetadata
fn openapi_metadata(&self, ctx: &AuthInitContext<S>) -> PluginOpenApiMetadata
Source§fn rate_limits(&self) -> Vec<PluginRateLimit>
fn rate_limits(&self) -> Vec<PluginRateLimit>
Source§fn server_endpoints(&self) -> Vec<EndpointDefinition>
fn server_endpoints(&self) -> Vec<EndpointDefinition>
Source§fn validate_endpoint(
&self,
call: &EndpointCall,
_ctx: &AuthContext<S>,
) -> AuthResult<EndpointInput>
fn validate_endpoint( &self, call: &EndpointCall, _ctx: &AuthContext<S>, ) -> AuthResult<EndpointInput>
Source§fn on_endpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
call: &'life1 EndpointCall,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = AuthResult<EndpointResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn on_endpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
call: &'life1 EndpointCall,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = AuthResult<EndpointResponse>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Source§fn on_init<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 mut AuthInitContext<S>,
) -> Pin<Box<dyn Future<Output = AuthResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn on_init<'life0, 'life1, 'async_trait>(
&'life0 self,
ctx: &'life1 mut AuthInitContext<S>,
) -> Pin<Box<dyn Future<Output = AuthResult<()>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Source§fn endpoint_hooks(&self) -> Vec<&dyn EndpointHook<S>>
fn endpoint_hooks(&self) -> Vec<&dyn EndpointHook<S>>
Source§fn allowed_media_types(&self, _route: &AuthRoute) -> Vec<&'static str>
fn allowed_media_types(&self, _route: &AuthRoute) -> Vec<&'static str>
Source§fn origin_check_skip_paths(&self) -> Vec<&'static str>
fn origin_check_skip_paths(&self) -> Vec<&'static str>
Source§fn session_fields(&self) -> IndexMap<String, FieldConfig>
fn session_fields(&self) -> IndexMap<String, FieldConfig>
fn user_fields(&self) -> IndexMap<String, FieldConfig>
fn account_fields(&self) -> IndexMap<String, FieldConfig>
Source§fn on_http_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<AuthResponse>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_http_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<AuthResponse>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn on_http_request_action<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
req: &'life1 AuthRequest,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<HttpRequestAction>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_http_request_action<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
req: &'life1 AuthRequest,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<HttpRequestAction>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
on_http_request implementations. Request-local configuration has already
been resolved from the incoming request, matching the Source HTTP handler.Source§fn on_http_response<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
_response: &'life3 AuthResponse,
) -> Pin<Box<dyn Future<Output = Result<Option<AuthResponse>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
fn on_http_response<'life0, 'life1, 'life2, 'life3, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
_response: &'life3 AuthResponse,
) -> Pin<Box<dyn Future<Output = Result<Option<AuthResponse>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
'life3: 'async_trait,
Self: 'async_trait,
Source§fn before_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<BeforeRequestAction>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn before_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<BeforeRequestAction>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn on_http_endpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
req: &'life1 AuthRequest,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<HttpEndpointResponse>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_http_endpoint<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
req: &'life1 AuthRequest,
ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<Option<HttpEndpointResponse>, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
on_request; plugins returning a native raw response can
override this method to bypass the endpoint after-hook pipeline.Source§fn after_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
response: AuthResponse,
) -> Pin<Box<dyn Future<Output = Result<AuthResponse, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn after_request<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_req: &'life1 AuthRequest,
_ctx: &'life2 AuthContext<S>,
response: AuthResponse,
) -> Pin<Box<dyn Future<Output = Result<AuthResponse, AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn on_user_created<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_user: &'life1 <S as AuthSchema>::User,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_user_created<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_user: &'life1 <S as AuthSchema>::User,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn on_session_created<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_session: &'life1 <S as AuthSchema>::Session,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_session_created<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_session: &'life1 <S as AuthSchema>::Session,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn on_user_deleted<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_user_id: &'life1 str,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_user_deleted<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_user_id: &'life1 str,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§fn on_session_deleted<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_session_token: &'life1 str,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
fn on_session_deleted<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
_session_token: &'life1 str,
_ctx: &'life2 AuthContext<S>,
) -> Pin<Box<dyn Future<Output = Result<(), AuthError>> + Send + 'async_trait>>where
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Self: 'async_trait,
Source§impl Clone for TwoFactorPlugin
impl Clone for TwoFactorPlugin
Source§impl Debug for TwoFactorPlugin
impl Debug for TwoFactorPlugin
Auto Trait Implementations§
impl !RefUnwindSafe for TwoFactorPlugin
impl !UnwindSafe for TwoFactorPlugin
impl Freeze for TwoFactorPlugin
impl Send for TwoFactorPlugin
impl Sync for TwoFactorPlugin
impl Unpin for TwoFactorPlugin
impl UnsafeUnpin for TwoFactorPlugin
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> ErasedDestructor for Twhere
T: 'static,
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more