1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
/// Authenticator options for controlling device capabilities
#[derive(Debug, Clone)]
pub struct AuthenticatorOptions {
/// Resident key (discoverable credentials) support
pub rk: bool,
/// User presence capable
pub up: bool,
/// User verification capability
pub uv: Option<bool>,
/// Platform device (cannot be removed)
pub plat: bool,
/// Client PIN capability. When `Some(true)` and UV is available, the
/// browser/client may defer verification to the authenticator instead of
/// prompting the user locally.
pub client_pin: Option<bool>,
/// PIN/UV auth token support
pub pin_uv_auth_token: Option<bool>,
/// Credential management support
pub cred_mgmt: Option<bool>,
/// Biometric enrollment support
pub bio_enroll: Option<bool>,
/// Large blobs support
pub large_blobs: Option<bool>,
/// Enterprise attestation
pub ep: Option<bool>,
/// Always require user verification
pub always_uv: Option<bool>,
/// Make credential without UV (makeCredUvNotRqd)
///
/// When true, indicates that the authenticator can create credentials
/// without performing UV when UV is not required by the relying party.
/// This provides more flexible UV behavior for testing.
pub make_cred_uv_not_required: Option<bool>,
}
impl Default for AuthenticatorOptions {
fn default() -> Self {
Self {
rk: true,
up: true,
uv: None,
plat: false,
client_pin: Some(true),
pin_uv_auth_token: Some(true),
cred_mgmt: None,
bio_enroll: None,
large_blobs: None,
ep: None,
always_uv: None,
make_cred_uv_not_required: None,
}
}
}
impl AuthenticatorOptions {
/// Create new options with default values
pub fn new() -> Self {
Self::default()
}
/// Set resident key support
pub fn with_resident_keys(mut self, enabled: bool) -> Self {
self.rk = enabled;
self
}
/// Set user presence capability
pub fn with_user_presence(mut self, enabled: bool) -> Self {
self.up = enabled;
self
}
/// Set user verification capability
pub fn with_user_verification(mut self, state: Option<bool>) -> Self {
self.uv = state;
self
}
/// Set platform device flag
pub fn with_platform_device(mut self, is_platform: bool) -> Self {
self.plat = is_platform;
self
}
/// Set client PIN capability
pub fn with_client_pin(mut self, state: Option<bool>) -> Self {
self.client_pin = state;
self
}
/// Set PIN/UV auth token support
pub fn with_pin_uv_auth_token(mut self, state: Option<bool>) -> Self {
self.pin_uv_auth_token = state;
self
}
/// Set credential management support
pub fn with_credential_management(mut self, state: Option<bool>) -> Self {
self.cred_mgmt = state;
self
}
/// Set biometric enrollment support
pub fn with_biometric_enrollment(mut self, state: Option<bool>) -> Self {
self.bio_enroll = state;
self
}
/// Set large blobs support
pub fn with_large_blobs(mut self, state: Option<bool>) -> Self {
self.large_blobs = state;
self
}
/// Set enterprise attestation support
pub fn with_enterprise_attestation(mut self, state: Option<bool>) -> Self {
self.ep = state;
self
}
/// Set always require user verification
pub fn with_always_uv(mut self, state: Option<bool>) -> Self {
self.always_uv = state;
self
}
/// Set make credential without UV support
pub fn with_make_cred_uv_not_required(mut self, state: Option<bool>) -> Self {
self.make_cred_uv_not_required = state;
self
}
}